Skip to content

Commit 4e882f8

Browse files
authored
Merge pull request #277 from proto-kit/feature/simulator-expansion
Added tx hashes to TransactionSender & Actions to simulator
2 parents f14da2e + 3de9f4b commit 4e882f8

File tree

3 files changed

+54
-16
lines changed

3 files changed

+54
-16
lines changed

packages/sequencer/src/settlement/SettlementModule.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,15 @@ export class SettlementModule
206206

207207
this.utils.signTransaction(tx, [feepayer], this.getContractKeys());
208208

209-
await this.transactionSender.proveAndSendTransaction(tx, "included");
209+
const { hash: transactionHash } =
210+
await this.transactionSender.proveAndSendTransaction(tx, "included");
210211

211212
log.info("Settlement transaction send queued");
212213

213214
const settlement = {
214215
batches: [batch.height],
215216
promisedMessagesHash: latestSequenceStateHash.toString(),
217+
transactionHash,
216218
};
217219

218220
await this.settlementStorage.pushSettlement(settlement);

packages/sequencer/src/settlement/transactions/MinaTransactionSender.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ export interface TxEvents extends EventsRecord {
2525
rejected: [any];
2626
}
2727

28+
export type TxSendResult<Input extends "sent" | "included" | "none"> =
29+
Input extends "none" ? void : { hash: string };
30+
2831
@injectable()
2932
export class MinaTransactionSender {
3033
private txStatusEmitters: Record<string, EventEmitter<TxEvents>> = {};
@@ -113,10 +116,12 @@ export class MinaTransactionSender {
113116
return eventEmitter;
114117
}
115118

116-
public async proveAndSendTransaction(
119+
public async proveAndSendTransaction<
120+
Wait extends "sent" | "included" | "none",
121+
>(
117122
transaction: Transaction<false, true>,
118-
waitOnStatus: "sent" | "included" | "none" = "none"
119-
) {
123+
waitOnStatus: Wait
124+
): Promise<TxSendResult<Wait>> {
120125
const { publicKey, nonce } = transaction.transaction.feePayer.body;
121126

122127
log.debug(
@@ -167,16 +172,24 @@ export class MinaTransactionSender {
167172
const txStatus = await this.sendOrQueue(result.transaction);
168173

169174
if (waitOnStatus !== "none") {
170-
await new Promise<void>((resolve, reject) => {
171-
txStatus.on(waitOnStatus, () => {
172-
log.info("Tx included");
173-
resolve();
174-
});
175-
txStatus.on("rejected", (error) => {
176-
reject(error);
177-
});
178-
});
175+
const waitInstruction: "sent" | "included" = waitOnStatus;
176+
const hash = await new Promise<TxSendResult<"sent" | "included">>(
177+
(resolve, reject) => {
178+
txStatus.on(waitInstruction, (txSendResult) => {
179+
log.info(`Tx ${txSendResult.hash} included`);
180+
resolve(txSendResult);
181+
});
182+
txStatus.on("rejected", (error) => {
183+
reject(error);
184+
});
185+
}
186+
);
187+
188+
// Yeah that's not super clean, but couldn't figure out a better way tbh
189+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
190+
return hash as TxSendResult<Wait>;
179191
}
180-
return txStatus;
192+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
193+
return undefined as TxSendResult<Wait>;
181194
}
182195
}

packages/sequencer/src/settlement/transactions/MinaTransactionSimulator.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@ import {
1111
UInt32,
1212
Transaction,
1313
} from "o1js";
14-
import { ReturnType } from "@proto-kit/protocol";
14+
import {
15+
ACTIONS_EMPTY_HASH,
16+
MINA_EVENT_PREFIXES,
17+
ReturnType,
18+
} from "@proto-kit/protocol";
1519
import { match } from "ts-pattern";
1620
import { inject, injectable } from "tsyringe";
17-
import { noop } from "@proto-kit/common";
21+
import { hashWithPrefix, noop, range } from "@proto-kit/common";
1822

1923
import { distinctByPredicate } from "../../helpers/utils";
2024
import type { MinaBaseLayer } from "../../protocol/baselayer/MinaBaseLayer";
@@ -277,13 +281,32 @@ export class MinaTransactionSimulator {
277281
}).verificationKey = update.verificationKey.value;
278282
}
279283

284+
this.applyZkApp(account, au.body);
285+
}
286+
287+
private applyZkApp(
288+
account: Account,
289+
{ update, actions }: AccountUpdate["body"]
290+
) {
280291
if (account.zkapp !== undefined) {
281292
const { appState } = update;
282293
for (let i = 0; i < 8; i++) {
283294
if (appState[i].isSome.toBoolean()) {
284295
account.zkapp.appState[i] = appState[i].value;
285296
}
286297
}
298+
299+
if (actions.data.length > 0) {
300+
// We don't care about the correct historical array, so we just
301+
// populate the full array with the current value
302+
const previousActionState =
303+
account.zkapp.actionState.at(0) ?? ACTIONS_EMPTY_HASH;
304+
const newActionsHash = hashWithPrefix(
305+
MINA_EVENT_PREFIXES.sequenceEvents,
306+
[previousActionState, actions.hash]
307+
);
308+
account.zkapp.actionState = range(0, 5).map(() => newActionsHash);
309+
}
287310
}
288311
}
289312
}

0 commit comments

Comments
 (0)