From 7227b487f97e26a3f8f2aa8086fb7c2c7b0de557 Mon Sep 17 00:00:00 2001 From: just-mitch <68168980+just-mitch@users.noreply.github.com> Date: Mon, 2 Dec 2024 16:44:57 -0500 Subject: [PATCH] chore: fix sassy-salamander chores v1 (#10218) Handful of chores. fix #10074 fix #10075 fix #10077 --- .../circuit-types/src/tx_execution_request.ts | 5 ++ yarn-project/end-to-end/src/spartan/utils.ts | 6 +- yarn-project/foundation/package.json | 2 +- yarn-project/prover-client/package.json | 2 +- .../pxe/src/pxe_service/pxe_service.ts | 36 ++++++++--- .../src/sequencer/sequencer.test.ts | 2 +- .../src/sequencer/sequencer.ts | 59 ++++++++----------- .../sequencer-client/src/sequencer/utils.ts | 2 +- 8 files changed, 66 insertions(+), 48 deletions(-) diff --git a/yarn-project/circuit-types/src/tx_execution_request.ts b/yarn-project/circuit-types/src/tx_execution_request.ts index 2a99636da2e..bdd90e28550 100644 --- a/yarn-project/circuit-types/src/tx_execution_request.ts +++ b/yarn-project/circuit-types/src/tx_execution_request.ts @@ -4,6 +4,7 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { bufferToHex, hexToBuffer } from '@aztec/foundation/string'; import { type FieldsOf } from '@aztec/foundation/types'; +import { inspect } from 'util'; import { z } from 'zod'; import { AuthWitness } from './auth_witness.js'; @@ -141,4 +142,8 @@ export class TxExecutionRequest { [AuthWitness.random()], ); } + + [inspect.custom]() { + return `TxExecutionRequest(${this.origin} called ${this.functionSelector})`; + } } diff --git a/yarn-project/end-to-end/src/spartan/utils.ts b/yarn-project/end-to-end/src/spartan/utils.ts index fe34c31534a..3152de9c53d 100644 --- a/yarn-project/end-to-end/src/spartan/utils.ts +++ b/yarn-project/end-to-end/src/spartan/utils.ts @@ -355,7 +355,11 @@ export async function awaitL2BlockNumber( await sleep(1000); tips = await rollupCheatCodes.getTips(); } - logger.info(`Reached L2 Block ${tips.pending}`); + if (tips.pending < blockNumber) { + throw new Error(`Timeout waiting for L2 Block ${blockNumber}, only reached ${tips.pending}`); + } else { + logger.info(`Reached L2 Block ${tips.pending}`); + } } export async function restartBot(namespace: string, logger: Logger) { diff --git a/yarn-project/foundation/package.json b/yarn-project/foundation/package.json index 149a879c05c..cdaaafa04e9 100644 --- a/yarn-project/foundation/package.json +++ b/yarn-project/foundation/package.json @@ -164,4 +164,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/prover-client/package.json b/yarn-project/prover-client/package.json index 65012f1a178..b8766542083 100644 --- a/yarn-project/prover-client/package.json +++ b/yarn-project/prover-client/package.json @@ -104,4 +104,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 4a5ab7a7576..201d69ba2b0 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -67,6 +67,8 @@ import { } from '@aztec/protocol-contracts'; import { type AcirSimulator } from '@aztec/simulator'; +import { inspect } from 'util'; + import { type PXEServiceConfig, getPackageInfo } from '../config/index.js'; import { ContractDataOracle } from '../contract_data_oracle/index.js'; import { IncomingNoteDao } from '../database/incoming_note_dao.js'; @@ -519,8 +521,7 @@ export class PXEService implements PXE { return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof!); }) .catch(err => { - this.log.error(err); - throw err; + throw this.contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult)); }); } @@ -576,8 +577,15 @@ export class PXEService implements PXE { ); }) .catch(err => { - this.log.error(err); - throw err; + throw this.contextualizeError( + err, + inspect(txRequest), + `simulatePublic=${simulatePublic}`, + `msgSender=${msgSender?.toString() ?? 'undefined'}`, + `skipTxValidation=${skipTxValidation}`, + `profile=${profile}`, + `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`, + ); }); } @@ -588,8 +596,7 @@ export class PXEService implements PXE { } this.log.info(`Sending transaction ${txHash}`); await this.node.sendTx(tx).catch(err => { - this.log.error(err); - throw err; + throw this.contextualizeError(err, inspect(tx)); }); this.log.info(`Sent transaction ${txHash}`); return txHash; @@ -613,8 +620,12 @@ export class PXEService implements PXE { return executionResult; }) .catch(err => { - this.log.error(err); - throw err; + const stringifiedArgs = args.map(arg => arg.toString()).join(', '); + throw this.contextualizeError( + err, + `simulateUnconstrained ${to}:${functionName}(${stringifiedArgs})`, + `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`, + ); }); } @@ -986,4 +997,13 @@ export class PXEService implements PXE { async resetNoteSyncData() { return await this.db.resetNoteSyncData(); } + + private contextualizeError(err: Error, ...context: string[]): Error { + this.log.error(err.name, err); + this.log.debug('Context:'); + for (const c of context) { + this.log.debug(c); + } + return err; + } } diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index e5a55462b97..5acbbd261f6 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -843,7 +843,7 @@ class TestSubject extends Sequencer { } public override doRealWork() { - this.setState(SequencerState.IDLE, 0, true /** force */); + this.setState(SequencerState.IDLE, 0n, true /** force */); return super.doRealWork(); } } diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index 8c9750ff043..325a2dd2d44 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -189,7 +189,7 @@ export class Sequencer { public start() { this.runningPromise = new RunningPromise(this.work.bind(this), this.pollingIntervalMs); this.runningPromise.start(); - this.setState(SequencerState.IDLE, 0, true /** force */); + this.setState(SequencerState.IDLE, 0n, true /** force */); this.log.info('Sequencer started'); return Promise.resolve(); } @@ -201,7 +201,7 @@ export class Sequencer { this.log.debug(`Stopping sequencer`); await this.runningPromise?.stop(); this.publisher.interrupt(); - this.setState(SequencerState.STOPPED, 0, true /** force */); + this.setState(SequencerState.STOPPED, 0n, true /** force */); this.log.info('Stopped sequencer'); } @@ -212,7 +212,7 @@ export class Sequencer { this.log.info('Restarting sequencer'); this.publisher.restart(); this.runningPromise!.start(); - this.setState(SequencerState.IDLE, 0, true /** force */); + this.setState(SequencerState.IDLE, 0n, true /** force */); } /** @@ -232,7 +232,7 @@ export class Sequencer { * - If our block for some reason is not included, revert the state */ protected async doRealWork() { - this.setState(SequencerState.SYNCHRONIZING, 0); + this.setState(SequencerState.SYNCHRONIZING, 0n); // Update state when the previous block has been synced const prevBlockSynced = await this.isBlockSynced(); // Do not go forward with new block if the previous one has not been mined and processed @@ -243,7 +243,7 @@ export class Sequencer { this.log.debug('Previous block has been mined and processed'); - this.setState(SequencerState.PROPOSER_CHECK, 0); + this.setState(SequencerState.PROPOSER_CHECK, 0n); const chainTip = await this.l2BlockSource.getBlock(-1); const historicalHeader = chainTip?.header; @@ -277,9 +277,8 @@ export class Sequencer { if (!this.shouldProposeBlock(historicalHeader, {})) { return; } - const secondsIntoSlot = getSecondsIntoSlot(this.l1GenesisTime, this.aztecSlotDuration, Number(slot)); - this.setState(SequencerState.WAITING_FOR_TXS, secondsIntoSlot); + this.setState(SequencerState.WAITING_FOR_TXS, slot); // Get txs to build the new block. const pendingTxs = this.p2pClient.getTxs('pending'); @@ -325,7 +324,7 @@ export class Sequencer { } catch (err) { this.log.error(`Error assembling block`, (err as any).stack); } - this.setState(SequencerState.IDLE, 0); + this.setState(SequencerState.IDLE, 0n); } protected async work() { @@ -339,7 +338,7 @@ export class Sequencer { throw err; } } finally { - this.setState(SequencerState.IDLE, 0); + this.setState(SequencerState.IDLE, 0n); } } @@ -398,13 +397,23 @@ export class Sequencer { return true; } - setState(proposedState: SequencerState, secondsIntoSlot: number, force: boolean = false) { + /** + * Sets the sequencer state and checks if we have enough time left in the slot to transition to the new state. + * @param proposedState - The new state to transition to. + * @param currentSlotNumber - The current slot number. + * @param force - Whether to force the transition even if the sequencer is stopped. + * + * @dev If the `currentSlotNumber` doesn't matter (e.g. transitioning to IDLE), pass in `0n`; + * it is only used to check if we have enough time left in the slot to transition to the new state. + */ + setState(proposedState: SequencerState, currentSlotNumber: bigint, force: boolean = false) { if (this.state === SequencerState.STOPPED && force !== true) { this.log.warn( `Cannot set sequencer from ${this.state} to ${proposedState} as it is stopped. Set force=true to override.`, ); return; } + const secondsIntoSlot = getSecondsIntoSlot(this.l1GenesisTime, this.aztecSlotDuration, Number(currentSlotNumber)); if (!this.doIHaveEnoughTimeLeft(proposedState, secondsIntoSlot)) { throw new SequencerTooSlowError(this.state, proposedState, this.timeTable[proposedState], secondsIntoSlot); } @@ -567,12 +576,7 @@ export class Sequencer { this.metrics.recordNewBlock(newGlobalVariables.blockNumber.toNumber(), validTxs.length); const workTimer = new Timer(); - const secondsIntoSlot = getSecondsIntoSlot( - this.l1GenesisTime, - this.aztecSlotDuration, - newGlobalVariables.slotNumber.toNumber(), - ); - this.setState(SequencerState.CREATING_BLOCK, secondsIntoSlot); + this.setState(SequencerState.CREATING_BLOCK, newGlobalVariables.slotNumber.toBigInt()); this.log.info( `Building blockNumber=${newGlobalVariables.blockNumber.toNumber()} txCount=${ validTxs.length @@ -688,23 +692,13 @@ export class Sequencer { this.log.info('Creating block proposal'); const proposal = await this.validatorClient.createBlockProposal(block.header, block.archive.root, txHashes); - let secondsIntoSlot = getSecondsIntoSlot( - this.l1GenesisTime, - this.aztecSlotDuration, - block.header.globalVariables.slotNumber.toNumber(), - ); + const slotNumber = block.header.globalVariables.slotNumber.toBigInt(); - this.setState(SequencerState.PUBLISHING_BLOCK_TO_PEERS, secondsIntoSlot); + this.setState(SequencerState.PUBLISHING_BLOCK_TO_PEERS, slotNumber); this.log.info('Broadcasting block proposal to validators'); this.validatorClient.broadcastBlockProposal(proposal); - secondsIntoSlot = getSecondsIntoSlot( - this.l1GenesisTime, - this.aztecSlotDuration, - block.header.globalVariables.slotNumber.toNumber(), - ); - - this.setState(SequencerState.WAITING_FOR_ATTESTATIONS, secondsIntoSlot); + this.setState(SequencerState.WAITING_FOR_ATTESTATIONS, slotNumber); const attestations = await this.validatorClient.collectAttestations(proposal, numberOfRequiredAttestations); this.log.info(`Collected attestations from validators, number of attestations: ${attestations.length}`); @@ -761,13 +755,8 @@ export class Sequencer { txHashes?: TxHash[], proofQuote?: EpochProofQuote, ) { - const secondsIntoSlot = getSecondsIntoSlot( - this.l1GenesisTime, - this.aztecSlotDuration, - block.header.globalVariables.slotNumber.toNumber(), - ); // Publishes new block to the network and awaits the tx to be mined - this.setState(SequencerState.PUBLISHING_BLOCK, secondsIntoSlot); + this.setState(SequencerState.PUBLISHING_BLOCK, block.header.globalVariables.slotNumber.toBigInt()); const publishedL2Block = await this.publisher.proposeL2Block(block, attestations, txHashes, proofQuote); if (!publishedL2Block) { diff --git a/yarn-project/sequencer-client/src/sequencer/utils.ts b/yarn-project/sequencer-client/src/sequencer/utils.ts index 4c16e8c8a9b..8bb4b440dc2 100644 --- a/yarn-project/sequencer-client/src/sequencer/utils.ts +++ b/yarn-project/sequencer-client/src/sequencer/utils.ts @@ -75,5 +75,5 @@ export function orderAttestations(attestations: BlockAttestation[], orderAddress export function getSecondsIntoSlot(l1GenesisTime: number, aztecSlotDuration: number, slotNumber: number): number { const slotStartTimestamp = l1GenesisTime + slotNumber * aztecSlotDuration; - return Date.now() / 1000 - slotStartTimestamp; + return Number((Date.now() / 1000 - slotStartTimestamp).toFixed(3)); }