Skip to content

Commit

Permalink
Verify block built against synced world state
Browse files Browse the repository at this point in the history
  • Loading branch information
spalladino committed Nov 29, 2024
1 parent 4bf34a3 commit f5d4941
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 28 deletions.
13 changes: 5 additions & 8 deletions yarn-project/circuit-types/src/interfaces/world_state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@ export interface WorldStateSynchronizerStatus {
}

/** Provides writeable forks of the world state at a given block number. */
export interface ForkMerkleTreeWriteOperations {
export interface ForkMerkleTreeOperations {
/** Forks the world state at the given block number, defaulting to the latest one. */
fork(block?: number): Promise<MerkleTreeWriteOperations>;

/** Gets a handle that allows reading the state as it was at the given block number. */
getSnapshot(blockNumber: number): MerkleTreeReadOperations;
}

/** Defines the interface for a world state synchronizer. */
export interface WorldStateSynchronizer extends ForkMerkleTreeWriteOperations {
export interface WorldStateSynchronizer extends ForkMerkleTreeOperations {
/**
* Starts the synchronizer.
* @returns A promise that resolves once the initial sync is completed.
Expand Down Expand Up @@ -61,10 +64,4 @@ export interface WorldStateSynchronizer extends ForkMerkleTreeWriteOperations {
* Returns an instance of MerkleTreeAdminOperations that will not include uncommitted data.
*/
getCommitted(): MerkleTreeReadOperations;

/**
* Returns a readonly instance of MerkleTreeAdminOperations where the state is as it was at the given block number
* @param block - The block number to look at
*/
getSnapshot(block: number): MerkleTreeReadOperations;
}
23 changes: 20 additions & 3 deletions yarn-project/prover-client/src/mocks/test_context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { type BBProverConfig } from '@aztec/bb-prover';
import {
type L2Block,
type ProcessedTx,
type ProcessedTxHandler,
type PublicExecutionRequest,
Expand All @@ -8,7 +9,7 @@ import {
type TxValidator,
} from '@aztec/circuit-types';
import { makeBloatedProcessedTx } from '@aztec/circuit-types/test';
import { type Gas, type GlobalVariables, Header } from '@aztec/circuits.js';
import { type AppendOnlyTreeSnapshot, type Gas, type GlobalVariables, Header } from '@aztec/circuits.js';
import { times } from '@aztec/foundation/collection';
import { Fr } from '@aztec/foundation/fields';
import { type DebugLogger } from '@aztec/foundation/log';
Expand Down Expand Up @@ -49,7 +50,7 @@ export class TestContext {
public globalVariables: GlobalVariables,
public prover: ServerCircuitProver,
public proverAgent: ProverAgent,
public orchestrator: ProvingOrchestrator,
public orchestrator: TestProvingOrchestrator,
public blockNumber: number,
public directoriesToCleanup: string[],
public logger: DebugLogger,
Expand Down Expand Up @@ -112,7 +113,7 @@ export class TestContext {
}

const queue = new MemoryProvingQueue(telemetry);
const orchestrator = new ProvingOrchestrator(ws, queue, telemetry, Fr.ZERO);
const orchestrator = new TestProvingOrchestrator(ws, queue, telemetry, Fr.ZERO);
const agent = new ProverAgent(localProver, proverCount);

queue.start();
Expand Down Expand Up @@ -256,3 +257,19 @@ export class TestContext {
return await this.publicProcessor.process(txs, maxTransactions, txHandler, txValidator);
}
}

class TestProvingOrchestrator extends ProvingOrchestrator {
public isVerifyBuiltBlockAgainstSyncedStateEnabled = false;

// Disable this check by default, since it requires seeding world state with the block being built
// This is only enabled in some tests with multiple blocks that populate the pending chain via makePendingBlock
protected override verifyBuiltBlockAgainstSyncedState(
l2Block: L2Block,
newArchive: AppendOnlyTreeSnapshot,
): Promise<void> {
if (this.isVerifyBuiltBlockAgainstSyncedStateEnabled) {
return super.verifyBuiltBlockAgainstSyncedState(l2Block, newArchive);
}
return Promise.resolve();
}
}
19 changes: 17 additions & 2 deletions yarn-project/prover-client/src/orchestrator/orchestrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import {
} from '@aztec/circuit-types';
import {
type EpochProver,
type ForkMerkleTreeWriteOperations,
type ForkMerkleTreeOperations,
type MerkleTreeWriteOperations,
type ProofAndVerificationKey,
} from '@aztec/circuit-types/interfaces';
import { type CircuitName } from '@aztec/circuit-types/stats';
import {
AVM_PROOF_LENGTH_IN_FIELDS,
AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS,
type AppendOnlyTreeSnapshot,
type BaseOrMergeRollupPublicInputs,
BaseParityInputs,
type BaseRollupHints,
Expand Down Expand Up @@ -102,7 +103,7 @@ export class ProvingOrchestrator implements EpochProver {
private dbs: Map<number, MerkleTreeWriteOperations> = new Map();

constructor(
private dbProvider: ForkMerkleTreeWriteOperations,
private dbProvider: ForkMerkleTreeOperations,
private prover: ServerCircuitProver,
telemetryClient: TelemetryClient,
private readonly proverId: Fr = Fr.ZERO,
Expand Down Expand Up @@ -439,10 +440,24 @@ export class ProvingOrchestrator implements EpochProver {
);
}

await this.verifyBuiltBlockAgainstSyncedState(l2Block, newArchive);

logger.verbose(`Orchestrator finalised block ${l2Block.number}`);
provingState.block = l2Block;
}

// Flagged as protected to disable in certain unit tests
protected async verifyBuiltBlockAgainstSyncedState(l2Block: L2Block, newArchive: AppendOnlyTreeSnapshot) {
const syncedArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.dbProvider.getSnapshot(l2Block.number));
if (!syncedArchive.equals(newArchive)) {
throw new Error(
`Archive tree mismatch for block ${l2Block.number}: world state synced to ${inspect(
syncedArchive,
)} but built ${inspect(newArchive)}`,
);
}
}

// Enqueues the proving of the required padding transactions
// If the fully proven padding transaction is not available, this will first be proven
private enqueuePaddingTxs(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ describe('prover/orchestrator/multi-block', () => {

beforeEach(async () => {
context = await TestContext.new(logger);
context.orchestrator.isVerifyBuiltBlockAgainstSyncedStateEnabled = true;
});

afterEach(async () => {
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/prover-client/src/prover-client/factory.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type ForkMerkleTreeWriteOperations, type ProvingJobBroker } from '@aztec/circuit-types';
import { type ForkMerkleTreeOperations, type ProvingJobBroker } from '@aztec/circuit-types';
import { type TelemetryClient } from '@aztec/telemetry-client';
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';

Expand All @@ -7,7 +7,7 @@ import { ProverClient } from './prover-client.js';

export function createProverClient(
config: ProverClientConfig,
worldState: ForkMerkleTreeWriteOperations,
worldState: ForkMerkleTreeOperations,
broker: ProvingJobBroker,
telemetry: TelemetryClient = new NoopTelemetryClient(),
) {
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/prover-client/src/prover-client/prover-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
type ActualProverConfig,
type EpochProver,
type EpochProverManager,
type ForkMerkleTreeWriteOperations,
type ForkMerkleTreeOperations,
type ProverCache,
type ProvingJobBroker,
type ProvingJobConsumer,
Expand Down Expand Up @@ -34,7 +34,7 @@ export class ProverClient implements EpochProverManager {

private constructor(
private config: ProverClientConfig,
private worldState: ForkMerkleTreeWriteOperations,
private worldState: ForkMerkleTreeOperations,
private telemetry: TelemetryClient,
private orchestratorClient: ProvingJobProducer,
private agentClient?: ProvingJobConsumer,
Expand Down Expand Up @@ -107,7 +107,7 @@ export class ProverClient implements EpochProverManager {
*/
public static async new(
config: ProverClientConfig,
worldState: ForkMerkleTreeWriteOperations,
worldState: ForkMerkleTreeOperations,
broker: ProvingJobBroker,
telemetry: TelemetryClient,
) {
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/prover-node/src/job/epoch-proving-job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
EmptyTxValidator,
type EpochProver,
type EpochProvingJobState,
type ForkMerkleTreeWriteOperations,
type ForkMerkleTreeOperations,
type L1ToL2MessageSource,
type L2Block,
type L2BlockSource,
Expand Down Expand Up @@ -35,7 +35,7 @@ export class EpochProvingJob {
private runPromise: Promise<void> | undefined;

constructor(
private dbProvider: ForkMerkleTreeWriteOperations,
private dbProvider: ForkMerkleTreeOperations,
private epochNumber: bigint,
private blocks: L2Block[],
private prover: EpochProver,
Expand Down
10 changes: 2 additions & 8 deletions yarn-project/world-state/src/world-state-db/merkle_tree_db.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type L2Block, type MerkleTreeId } from '@aztec/circuit-types';
import { type ForkMerkleTreeWriteOperations, type MerkleTreeReadOperations } from '@aztec/circuit-types/interfaces';
import { type ForkMerkleTreeOperations, type MerkleTreeReadOperations } from '@aztec/circuit-types/interfaces';
import { type Fr, MAX_NULLIFIERS_PER_TX, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX } from '@aztec/circuits.js';
import { type IndexedTreeSnapshot, type TreeSnapshot } from '@aztec/merkle-tree';

Expand Down Expand Up @@ -32,7 +32,7 @@ export type TreeSnapshots = {
[MerkleTreeId.ARCHIVE]: TreeSnapshot<Fr>;
};

export interface MerkleTreeAdminDatabase extends ForkMerkleTreeWriteOperations {
export interface MerkleTreeAdminDatabase extends ForkMerkleTreeOperations {
/**
* Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree).
* @param block - The L2 block to handle.
Expand All @@ -45,12 +45,6 @@ export interface MerkleTreeAdminDatabase extends ForkMerkleTreeWriteOperations {
*/
getCommitted(): MerkleTreeReadOperations;

/**
* Gets a handle that allows reading the state as it was at the given block number
* @param blockNumber - The block number to get the snapshot for
*/
getSnapshot(blockNumber: number): MerkleTreeReadOperations;

/**
* Removes all historical snapshots up to but not including the given block number
* @param toBlockNumber The block number of the new oldest historical block
Expand Down

0 comments on commit f5d4941

Please sign in to comment.