Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/sequencer/src/settlement/SettlementModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,13 +206,15 @@ export class SettlementModule

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

await this.transactionSender.proveAndSendTransaction(tx, "included");
const { hash: transactionHash } =
await this.transactionSender.proveAndSendTransaction(tx, "included");

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

const settlement = {
batches: [batch.height],
promisedMessagesHash: latestSequenceStateHash.toString(),
transactionHash,
};

await this.settlementStorage.pushSettlement(settlement);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ export interface TxEvents extends EventsRecord {
rejected: [any];
}

export type TxSendResult<Input extends "sent" | "included" | "none"> =
Input extends "none" ? void : { hash: string };

@injectable()
export class MinaTransactionSender {
private txStatusEmitters: Record<string, EventEmitter<TxEvents>> = {};
Expand Down Expand Up @@ -113,10 +116,12 @@ export class MinaTransactionSender {
return eventEmitter;
}

public async proveAndSendTransaction(
public async proveAndSendTransaction<
Wait extends "sent" | "included" | "none",
>(
transaction: Transaction<false, true>,
waitOnStatus: "sent" | "included" | "none" = "none"
) {
waitOnStatus: Wait
): Promise<TxSendResult<Wait>> {
const { publicKey, nonce } = transaction.transaction.feePayer.body;

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

if (waitOnStatus !== "none") {
await new Promise<void>((resolve, reject) => {
txStatus.on(waitOnStatus, () => {
log.info("Tx included");
resolve();
});
txStatus.on("rejected", (error) => {
reject(error);
});
});
const waitInstruction: "sent" | "included" = waitOnStatus;
const hash = await new Promise<TxSendResult<"sent" | "included">>(
(resolve, reject) => {
txStatus.on(waitInstruction, (txSendResult) => {
log.info(`Tx ${txSendResult.hash} included`);
resolve(txSendResult);
});
txStatus.on("rejected", (error) => {
reject(error);
});
}
);

// Yeah that's not super clean, but couldn't figure out a better way tbh
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return hash as TxSendResult<Wait>;
}
return txStatus;
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return undefined as TxSendResult<Wait>;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ import {
UInt32,
Transaction,
} from "o1js";
import { ReturnType } from "@proto-kit/protocol";
import {
ACTIONS_EMPTY_HASH,
MINA_EVENT_PREFIXES,
ReturnType,
} from "@proto-kit/protocol";
import { match } from "ts-pattern";
import { inject, injectable } from "tsyringe";
import { noop } from "@proto-kit/common";
import { hashWithPrefix, noop, range } from "@proto-kit/common";

import { distinctByPredicate } from "../../helpers/utils";
import type { MinaBaseLayer } from "../../protocol/baselayer/MinaBaseLayer";
Expand Down Expand Up @@ -277,13 +281,32 @@ export class MinaTransactionSimulator {
}).verificationKey = update.verificationKey.value;
}

this.applyZkApp(account, au.body);
}

private applyZkApp(
account: Account,
{ update, actions }: AccountUpdate["body"]
) {
if (account.zkapp !== undefined) {
const { appState } = update;
for (let i = 0; i < 8; i++) {
if (appState[i].isSome.toBoolean()) {
account.zkapp.appState[i] = appState[i].value;
}
}

if (actions.data.length > 0) {
// We don't care about the correct historical array, so we just
// populate the full array with the current value
const previousActionState =
account.zkapp.actionState.at(0) ?? ACTIONS_EMPTY_HASH;
const newActionsHash = hashWithPrefix(
MINA_EVENT_PREFIXES.sequenceEvents,
[previousActionState, actions.hash]
);
account.zkapp.actionState = range(0, 5).map(() => newActionsHash);
}
}
}
}