From 9e09d177f7c55cc408cc489890443d32e2cdea83 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Fri, 6 Oct 2023 14:41:28 -0300 Subject: [PATCH 1/7] chore: Measure block building time --- scripts/ci/aggregate_e2e_benchmark.js | 28 ++++++++++++++++++- scripts/ci/benchmark_shared.js | 8 ++++-- yarn-project/foundation/src/timer/elapsed.ts | 12 ++++---- .../pxe/src/kernel_prover/proof_creator.ts | 12 ++++---- .../src/sequencer/sequencer.ts | 17 +++++++++-- .../src/simulator/public_kernel.ts | 8 +++--- .../sequencer-client/src/simulator/rollup.ts | 12 ++++---- .../server_world_state_synchronizer.ts | 4 +-- 8 files changed, 71 insertions(+), 30 deletions(-) diff --git a/scripts/ci/aggregate_e2e_benchmark.js b/scripts/ci/aggregate_e2e_benchmark.js index d59a1330910..3fceea9a36a 100644 --- a/scripts/ci/aggregate_e2e_benchmark.js +++ b/scripts/ci/aggregate_e2e_benchmark.js @@ -27,6 +27,10 @@ const { NOTE_SUCCESSFUL_DECRYPTING_TIME, NOTE_TRIAL_DECRYPTING_TIME, NOTE_PROCESSOR_CAUGHT_UP, + L2_BLOCK_BUILT, + L2_BLOCK_BUILD_TIME, + L2_BLOCK_ROLLUP_SIMULATION_TIME, + L2_BLOCK_PUBLIC_TX_PROCESS_TIME, ROLLUP_SIZES, BENCHMARK_FILE_JSON, } = require("./benchmark_shared.js"); @@ -34,7 +38,7 @@ const { // Folder where to load logs from const logsDir = process.env.LOGS_DIR ?? `log`; -// Appends a datapoint to the final results for the given metric in the given bucket +// Appends a data point to the final results for the given metric in the given bucket function append(results, metric, bucket, value) { if (value === undefined) { console.error(`Undefined value for ${metric} in bucket ${bucket}`); @@ -88,6 +92,26 @@ function processNoteProcessorCaughtUp(entry, results) { append(results, NOTE_TRIAL_DECRYPTING_TIME, seen, entry.duration); } +// Processes an entry with event name 'l2-block-built' and updates results +// Buckets are rollup sizes +function processL2BlockBuilt(entry, results) { + const bucket = entry.txCount; + if (!ROLLUP_SIZES.includes(bucket)) return; + append(results, L2_BLOCK_BUILD_TIME, bucket, entry.duration); + append( + results, + L2_BLOCK_ROLLUP_SIMULATION_TIME, + bucket, + entry.rollupCircuitsDuration + ); + append( + results, + L2_BLOCK_PUBLIC_TX_PROCESS_TIME, + bucket, + entry.publicProcessDuration + ); +} + // Processes a parsed entry from a logfile and updates results function processEntry(entry, results) { switch (entry.eventName) { @@ -99,6 +123,8 @@ function processEntry(entry, results) { return processCircuitSimulation(entry, results); case NOTE_PROCESSOR_CAUGHT_UP: return processNoteProcessorCaughtUp(entry, results); + case L2_BLOCK_BUILT: + return processL2BlockBuilt(entry, results); default: return; } diff --git a/scripts/ci/benchmark_shared.js b/scripts/ci/benchmark_shared.js index df0548eab1c..4b8e1bbbb1e 100644 --- a/scripts/ci/benchmark_shared.js +++ b/scripts/ci/benchmark_shared.js @@ -15,11 +15,15 @@ module.exports = { CIRCUIT_SIMULATION_TIME: "circuit_simulation_time_in_ms", CIRCUIT_INPUT_SIZE: "circuit_input_size_in_bytes", CIRCUIT_OUTPUT_SIZE: "circuit_output_size_in_bytes", - NOTE_SUCCESSFUL_DECRYPTING_TIME: "note_successful_decrypting_time", - NOTE_TRIAL_DECRYPTING_TIME: "note_unsuccessful_decrypting_time", + NOTE_SUCCESSFUL_DECRYPTING_TIME: "note_successful_decrypting_time_in_ms", + NOTE_TRIAL_DECRYPTING_TIME: "note_unsuccessful_decrypting_time_in_ms", + L2_BLOCK_BUILD_TIME: "l2_block_building_time_in_ms", + L2_BLOCK_ROLLUP_SIMULATION_TIME: "l2_block_rollup_simulation_time_in_ms", + L2_BLOCK_PUBLIC_TX_PROCESS_TIME: "l2_block_public_tx_process_time_in_ms", // Events to track L2_BLOCK_PUBLISHED_TO_L1: "rollup-published-to-l1", L2_BLOCK_SYNCED: "l2-block-handled", + L2_BLOCK_BUILT: "l2-block-built", CIRCUIT_SIMULATED: "circuit-simulation", NOTE_PROCESSOR_CAUGHT_UP: "note-processor-caught-up", // Other diff --git a/yarn-project/foundation/src/timer/elapsed.ts b/yarn-project/foundation/src/timer/elapsed.ts index c400816665c..168aaf82537 100644 --- a/yarn-project/foundation/src/timer/elapsed.ts +++ b/yarn-project/foundation/src/timer/elapsed.ts @@ -3,21 +3,21 @@ import { Timer } from './timer.js'; /** * Measures the elapsed execution time of a function call or promise once it is awaited. * @param fn - Function or promise. - * @returns A timer object and the result. + * @returns The number of ms and the result. */ -export async function elapsed(fn: Promise | (() => T | Promise)): Promise<[Timer, T]> { +export async function elapsed(fn: Promise | (() => T | Promise)): Promise<[number, T]> { const timer = new Timer(); const result = await (typeof fn === 'function' ? fn() : fn); - return [timer, result]; + return [timer.ms(), result]; } /** * Measures the elapsed execution time of a synchronous function call once it is awaited. * @param fn - Function. - * @returns A timer object and the result. + * @returns The number of ms and the result. */ -export function elapsedSync(fn: () => T): [Timer, T] { +export function elapsedSync(fn: () => T): [number, T] { const timer = new Timer(); const result = fn(); - return [timer, result]; + return [timer.ms(), result]; } diff --git a/yarn-project/pxe/src/kernel_prover/proof_creator.ts b/yarn-project/pxe/src/kernel_prover/proof_creator.ts index 016018ba808..ba8c2b037d7 100644 --- a/yarn-project/pxe/src/kernel_prover/proof_creator.ts +++ b/yarn-project/pxe/src/kernel_prover/proof_creator.ts @@ -109,14 +109,14 @@ export class KernelProofCreator implements ProofCreator { public async createProofInit(privateInputs: PrivateKernelInputsInit): Promise { const wasm = await CircuitsWasm.get(); - const [time, result] = await elapsed(() => privateKernelSimInit(wasm, privateInputs)); + const [duration, result] = await elapsed(() => privateKernelSimInit(wasm, privateInputs)); if (result instanceof CircuitError) { throw new CircuitError(result.code, result.message); } this.log(`Simulated private kernel init`, { eventName: 'circuit-simulation', circuitName: 'private-kernel-init', - duration: time.ms(), + duration, inputSize: privateInputs.toBuffer().length, outputSize: result.toBuffer().length, }); @@ -131,14 +131,14 @@ export class KernelProofCreator implements ProofCreator { public async createProofInner(privateInputs: PrivateKernelInputsInner): Promise { const wasm = await CircuitsWasm.get(); - const [time, result] = await elapsed(() => privateKernelSimInner(wasm, privateInputs)); + const [duration, result] = await elapsed(() => privateKernelSimInner(wasm, privateInputs)); if (result instanceof CircuitError) { throw new CircuitError(result.code, result.message); } this.log(`Simulated private kernel inner`, { eventName: 'circuit-simulation', circuitName: 'private-kernel-inner', - duration: time.ms(), + duration, inputSize: privateInputs.toBuffer().length, outputSize: result.toBuffer().length, }); @@ -154,14 +154,14 @@ export class KernelProofCreator implements ProofCreator { public async createProofOrdering(privateInputs: PrivateKernelInputsOrdering): Promise { const wasm = await CircuitsWasm.get(); this.log('Executing private kernel simulation ordering...'); - const [time, result] = await elapsed(() => privateKernelSimOrdering(wasm, privateInputs)); + const [duration, result] = await elapsed(() => privateKernelSimOrdering(wasm, privateInputs)); if (result instanceof CircuitError) { throw new CircuitError(result.code, result.message); } this.log(`Simulated private kernel ordering`, { eventName: 'circuit-simulation', circuitName: 'private-kernel-ordering', - duration: time.ms(), + duration, inputSize: privateInputs.toBuffer().length, outputSize: result.toBuffer().length, }); diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index 4398545fc30..1323c2cc484 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -2,6 +2,7 @@ import { GlobalVariables } from '@aztec/circuits.js'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { RunningPromise } from '@aztec/foundation/running-promise'; +import { Timer, elapsed } from '@aztec/foundation/timer'; import { P2P } from '@aztec/p2p'; import { ContractDataSource, L1ToL2MessageSource, L2Block, L2BlockSource, MerkleTreeId, Tx } from '@aztec/types'; import { WorldStateStatus, WorldStateSynchronizer } from '@aztec/world-state'; @@ -116,6 +117,7 @@ export class Sequencer { // Do not go forward with new block if the previous one has not been mined and processed if (!prevBlockSynced) return; + const workTimer = new Timer(); this.state = SequencerState.WAITING_FOR_TXS; // Get txs to build the new block @@ -139,7 +141,7 @@ export class Sequencer { // Process txs and drop the ones that fail processing // We create a fresh processor each time to reset any cached state (eg storage writes) const processor = await this.publicProcessorFactory.create(prevGlobalVariables, newGlobalVariables); - const [processedTxs, failedTxs] = await processor.process(validTxs); + const [publicProcessorDuration, [processedTxs, failedTxs]] = await elapsed(() => processor.process(validTxs)); if (failedTxs.length > 0) { const failedTxData = failedTxs.map(fail => fail.tx); this.log(`Dropping failed txs ${(await Tx.getHashes(failedTxData)).join(', ')}`); @@ -166,8 +168,17 @@ export class Sequencer { this.log(`Assembling block with txs ${processedValidTxs.map(tx => tx.hash).join(', ')}`); const emptyTx = await processor.makeEmptyProcessedTx(); - const block = await this.buildBlock(processedValidTxs, l1ToL2Messages, emptyTx, newGlobalVariables); - this.log(`Assembled block ${block.number}`); + const [rollupCircuitsDuration, block] = await elapsed(() => + this.buildBlock(processedValidTxs, l1ToL2Messages, emptyTx, newGlobalVariables), + ); + + this.log(`Assembled block ${block.number}`, { + eventName: 'l2-block-built', + duration: workTimer.ms(), + publicProcessDuration: publicProcessorDuration, + rollupCircuitsDuration: rollupCircuitsDuration, + ...block.getStats(), + }); await this.publishExtendedContractData(validTxs, block); diff --git a/yarn-project/sequencer-client/src/simulator/public_kernel.ts b/yarn-project/sequencer-client/src/simulator/public_kernel.ts index 3ba43adf5c2..3a21d3a2696 100644 --- a/yarn-project/sequencer-client/src/simulator/public_kernel.ts +++ b/yarn-project/sequencer-client/src/simulator/public_kernel.ts @@ -17,11 +17,11 @@ export class WasmPublicKernelCircuitSimulator implements PublicKernelCircuitSimu */ public async publicKernelCircuitPrivateInput(input: PublicKernelInputs): Promise { if (!input.previousKernel.publicInputs.isPrivate) throw new Error(`Expected private kernel previous inputs`); - const [time, result] = await elapsed(() => simulatePublicKernelCircuit(input)); + const [duration, result] = await elapsed(() => simulatePublicKernelCircuit(input)); this.log(`Simulated public kernel circuit with private input`, { eventName: 'circuit-simulation', circuitName: 'public-kernel-private-input', - duration: time.ms(), + duration, inputSize: input.toBuffer().length, outputSize: result.toBuffer().length, }); @@ -35,11 +35,11 @@ export class WasmPublicKernelCircuitSimulator implements PublicKernelCircuitSimu */ public async publicKernelCircuitNonFirstIteration(input: PublicKernelInputs): Promise { if (input.previousKernel.publicInputs.isPrivate) throw new Error(`Expected public kernel previous inputs`); - const [time, result] = await elapsed(() => simulatePublicKernelCircuit(input)); + const [duration, result] = await elapsed(() => simulatePublicKernelCircuit(input)); this.log(`Simulated public kernel circuit non-first iteration`, { eventName: 'circuit-simulation', circuitName: 'public-kernel-non-first-iteration', - duration: time.ms(), + duration, inputSize: input.toBuffer().length, outputSize: result.toBuffer().length, }); diff --git a/yarn-project/sequencer-client/src/simulator/rollup.ts b/yarn-project/sequencer-client/src/simulator/rollup.ts index d9a1f97442b..4a31a4fc0d1 100644 --- a/yarn-project/sequencer-client/src/simulator/rollup.ts +++ b/yarn-project/sequencer-client/src/simulator/rollup.ts @@ -28,7 +28,7 @@ export class WasmRollupCircuitSimulator implements RollupSimulator { */ public async baseRollupCircuit(input: BaseRollupInputs): Promise { const wasm = await CircuitsWasm.get(); - const [time, result] = await elapsed(() => baseRollupSim(wasm, input)); + const [duration, result] = await elapsed(() => baseRollupSim(wasm, input)); if (result instanceof CircuitError) { throw new CircuitError(result.code, result.message); } @@ -36,7 +36,7 @@ export class WasmRollupCircuitSimulator implements RollupSimulator { this.log(`Simulated base rollup circuit`, { eventName: 'circuit-simulation', circuitName: 'base-rollup', - duration: time.ms(), + duration, inputSize: input.toBuffer().length, outputSize: result.toBuffer().length, }); @@ -50,7 +50,7 @@ export class WasmRollupCircuitSimulator implements RollupSimulator { */ public async mergeRollupCircuit(input: MergeRollupInputs): Promise { const wasm = await CircuitsWasm.get(); - const [time, result] = await elapsed(() => mergeRollupSim(wasm, input)); + const [duration, result] = await elapsed(() => mergeRollupSim(wasm, input)); if (result instanceof CircuitError) { throw new CircuitError(result.code, result.message); } @@ -58,7 +58,7 @@ export class WasmRollupCircuitSimulator implements RollupSimulator { this.log(`Simulated merge rollup circuit`, { eventName: 'circuit-simulation', circuitName: 'merge-rollup', - duration: time.ms(), + duration, inputSize: input.toBuffer().length, outputSize: result.toBuffer().length, }); @@ -73,7 +73,7 @@ export class WasmRollupCircuitSimulator implements RollupSimulator { */ public async rootRollupCircuit(input: RootRollupInputs): Promise { const wasm = await CircuitsWasm.get(); - const [time, result] = await elapsed(() => rootRollupSim(wasm, input)); + const [duration, result] = await elapsed(() => rootRollupSim(wasm, input)); if (result instanceof CircuitError) { throw new CircuitError(result.code, result.message); } @@ -81,7 +81,7 @@ export class WasmRollupCircuitSimulator implements RollupSimulator { this.log(`Simulated root rollup circuit`, { eventName: 'circuit-simulation', circuitName: 'root-rollup', - duration: time.ms(), + duration, inputSize: input.toBuffer().length, outputSize: result.toBuffer().length, }); diff --git a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts index 144d2cd49b7..b0010250c8c 100644 --- a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts +++ b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts @@ -184,10 +184,10 @@ export class ServerWorldStateSynchronizer implements WorldStateSynchronizer { */ private async handleL2Blocks(l2Blocks: L2Block[]) { for (const l2Block of l2Blocks) { - const [time, result] = await elapsed(() => this.handleL2Block(l2Block)); + const [duration, result] = await elapsed(() => this.handleL2Block(l2Block)); this.log(`Handled new L2 block`, { eventName: 'l2-block-handled', - duration: time.ms(), + duration, isBlockOurs: result.isBlockOurs, ...l2Block.getStats(), }); From 4a501529cbbfa74b73d241df357a46de39f6d8a7 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Fri, 6 Oct 2023 19:24:52 -0300 Subject: [PATCH 2/7] Measure history processing time --- .circleci/config.yml | 23 +++- scripts/ci/aggregate_e2e_benchmark.js | 29 ++++- scripts/ci/benchmark_shared.js | 20 +++- .../benchmarks/bench_process_history.test.ts | 85 +++++++++++++++ .../benchmarks/bench_publish_rollup.test.ts | 61 +++-------- .../end-to-end/src/benchmarks/utils.ts | 100 ++++++++++++++++++ .../pxe/src/note_processor/note_processor.ts | 8 +- .../src/client/sequencer-client.ts | 10 +- yarn-project/sequencer-client/src/config.ts | 14 ++- .../sequencer-client/src/sequencer/config.ts | 10 -- .../src/sequencer/sequencer.test.ts | 4 - .../src/sequencer/sequencer.ts | 22 ++-- 12 files changed, 302 insertions(+), 84 deletions(-) create mode 100644 yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts create mode 100644 yarn-project/end-to-end/src/benchmarks/utils.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index cd068b43e2f..9d56b6b719f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -955,9 +955,20 @@ jobs: name: "Benchmark" command: cond_run_script end-to-end ./scripts/run_tests_local benchmarks/bench_publish_rollup.test.ts environment: - { - DEBUG: "aztec:benchmarks:*,aztec:sequencer,aztec:world_state,aztec:merkle_trees", - } + DEBUG: "aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" + + bench-process-history: + machine: + image: ubuntu-2204:2023.07.2 + resource_class: large + steps: + - *checkout + - *setup_env + - run: + name: "Benchmark" + command: cond_run_script end-to-end ./scripts/run_tests_local benchmarks/bench_process_history.test.ts + environment: + DEBUG: "aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" build-docs: machine: @@ -1307,6 +1318,7 @@ workflows: - guides-sample-dapp: *e2e_test - guides-up-quick-start: *e2e_test - bench-publish-rollup: *e2e_test + - bench-process-history: *e2e_test - e2e-end: requires: @@ -1344,15 +1356,16 @@ workflows: - guides-dapp-testing - guides-sample-dapp - guides-up-quick-start - - bench-publish-rollup <<: *defaults - bench-summary: requires: - e2e-end + - bench-publish-rollup + - bench-process-history <<: *defaults - # Deployment and Canary tests + # Deployment and Canary tests - deploy-dockerhub: requires: - e2e-end diff --git a/scripts/ci/aggregate_e2e_benchmark.js b/scripts/ci/aggregate_e2e_benchmark.js index 3fceea9a36a..b626ec6bdfe 100644 --- a/scripts/ci/aggregate_e2e_benchmark.js +++ b/scripts/ci/aggregate_e2e_benchmark.js @@ -31,8 +31,14 @@ const { L2_BLOCK_BUILD_TIME, L2_BLOCK_ROLLUP_SIMULATION_TIME, L2_BLOCK_PUBLIC_TX_PROCESS_TIME, + NODE_HISTORY_SYNC_TIME, + NODE_SYNCED_CHAIN, + NOTE_HISTORY_TRIAL_DECRYPTING_TIME, + NOTE_HISTORY_SUCCESSFUL_DECRYPTING_TIME, ROLLUP_SIZES, + CHAIN_LENGTHS, BENCHMARK_FILE_JSON, + BLOCK_SIZE, } = require("./benchmark_shared.js"); // Folder where to load logs from @@ -83,13 +89,17 @@ function processCircuitSimulation(entry, results) { } // Processes an entry with event name 'note-processor-caught-up' and updates results -// Buckets are rollup sizes +// Buckets are rollup sizes for NOTE_DECRYPTING_TIME, or chain sizes for NOTE_HISTORY_DECRYPTING_TIME function processNoteProcessorCaughtUp(entry, results) { - const { seen, decrypted } = entry; + const { seen, decrypted, blocks, txs, duration } = entry; if (ROLLUP_SIZES.includes(decrypted)) - append(results, NOTE_SUCCESSFUL_DECRYPTING_TIME, decrypted, entry.duration); + append(results, NOTE_SUCCESSFUL_DECRYPTING_TIME, decrypted, duration); if (ROLLUP_SIZES.includes(seen) && decrypted === 0) - append(results, NOTE_TRIAL_DECRYPTING_TIME, seen, entry.duration); + append(results, NOTE_TRIAL_DECRYPTING_TIME, seen, duration); + if (CHAIN_LENGTHS.includes(blocks) && decrypted > 0) + append(results, NOTE_HISTORY_SUCCESSFUL_DECRYPTING_TIME, blocks, duration); + if (CHAIN_LENGTHS.includes(blocks) && decrypted === 0) + append(results, NOTE_HISTORY_TRIAL_DECRYPTING_TIME, blocks, duration); } // Processes an entry with event name 'l2-block-built' and updates results @@ -112,6 +122,15 @@ function processL2BlockBuilt(entry, results) { ); } +// Processes entries with event name node-synced-chain-history emitted by benchmark tests +// Buckets are chain lengths +function processNodeSyncedChain(entry, results) { + const bucket = entry.blockCount; + if (!CHAIN_LENGTHS.includes(bucket)) return; + if (entry.txsPerBlock !== BLOCK_SIZE) return; + append(results, NODE_HISTORY_SYNC_TIME, bucket, entry.duration); +} + // Processes a parsed entry from a logfile and updates results function processEntry(entry, results) { switch (entry.eventName) { @@ -125,6 +144,8 @@ function processEntry(entry, results) { return processNoteProcessorCaughtUp(entry, results); case L2_BLOCK_BUILT: return processL2BlockBuilt(entry, results); + case NODE_SYNCED_CHAIN: + return processNodeSyncedChain(entry, results); default: return; } diff --git a/scripts/ci/benchmark_shared.js b/scripts/ci/benchmark_shared.js index 4b8e1bbbb1e..1d4bb7a81c4 100644 --- a/scripts/ci/benchmark_shared.js +++ b/scripts/ci/benchmark_shared.js @@ -1,8 +1,16 @@ -// Rollup sizes to track (duplicated from yarn-project/end-to-end/src/benchmarks/bench_publish_rollup.test.ts) +// Block sizes to track (duplicated from yarn-project/end-to-end/src/benchmarks/bench_publish_rollup.test.ts) const ROLLUP_SIZES = process.env.ROLLUP_SIZES ? process.env.ROLLUP_SIZES.split(",").map(Number) : [8, 32, 128]; +// Block size to use for building chains of multiple length (duplicated from yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts) +const BLOCK_SIZE = process.env.BLOCK_SIZE ? +process.env.BLOCK_SIZE : 32; + +// Chain lengths to test (duplicated from yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts) +const CHAIN_LENGTHS = process.env.CHAIN_LENGTHS + ? process.env.CHAIN_LENGTHS.split(",").map(Number) + : [10, 20, 50]; + // Output files const BENCHMARK_FILE_JSON = process.env.BENCHMARK_FILE_JSON ?? "benchmark.json"; @@ -16,17 +24,25 @@ module.exports = { CIRCUIT_INPUT_SIZE: "circuit_input_size_in_bytes", CIRCUIT_OUTPUT_SIZE: "circuit_output_size_in_bytes", NOTE_SUCCESSFUL_DECRYPTING_TIME: "note_successful_decrypting_time_in_ms", - NOTE_TRIAL_DECRYPTING_TIME: "note_unsuccessful_decrypting_time_in_ms", + NOTE_TRIAL_DECRYPTING_TIME: "note_trial_decrypting_time_in_ms", L2_BLOCK_BUILD_TIME: "l2_block_building_time_in_ms", L2_BLOCK_ROLLUP_SIMULATION_TIME: "l2_block_rollup_simulation_time_in_ms", L2_BLOCK_PUBLIC_TX_PROCESS_TIME: "l2_block_public_tx_process_time_in_ms", + NODE_HISTORY_SYNC_TIME: "node_history_sync_time_in_ms", + NOTE_HISTORY_SUCCESSFUL_DECRYPTING_TIME: + "note_history_successful_decrypting_time_in_ms", + NOTE_HISTORY_TRIAL_DECRYPTING_TIME: + "note_history_trial_decrypting_time_in_ms", // Events to track L2_BLOCK_PUBLISHED_TO_L1: "rollup-published-to-l1", L2_BLOCK_SYNCED: "l2-block-handled", L2_BLOCK_BUILT: "l2-block-built", CIRCUIT_SIMULATED: "circuit-simulation", NOTE_PROCESSOR_CAUGHT_UP: "note-processor-caught-up", + NODE_SYNCED_CHAIN: "node-synced-chain-history", // Other ROLLUP_SIZES, + BLOCK_SIZE, + CHAIN_LENGTHS, BENCHMARK_FILE_JSON, }; diff --git a/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts new file mode 100644 index 00000000000..6f5c98bc01b --- /dev/null +++ b/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts @@ -0,0 +1,85 @@ +import { AztecNodeService } from '@aztec/aztec-node'; +import { Fr, GrumpkinScalar } from '@aztec/circuits.js'; +import { sleep } from '@aztec/foundation/sleep'; +import { elapsed } from '@aztec/foundation/timer'; +import { BenchmarkingContract } from '@aztec/noir-contracts/types'; +import { SequencerClient } from '@aztec/sequencer-client'; +import { INITIAL_L2_BLOCK_NUM } from '@aztec/types'; + +import { EndToEndContext } from '../fixtures/utils.js'; +import { benchmarkSetup, sendTxs, waitNewPXESynced, waitRegisteredAccountSynced } from './utils.js'; + +const BLOCK_SIZE = process.env.BLOCK_SIZE ? +process.env.BLOCK_SIZE : 32; +const CHAIN_LENGTHS = process.env.CHAIN_LENGTHS ? process.env.CHAIN_LENGTHS.split(',').map(Number) : [10, 20, 50]; +const MAX_CHAIN_LENGTH = CHAIN_LENGTHS[CHAIN_LENGTHS.length - 1]; +const SETUP_BLOCK_COUNT = 2; // deploy account + deploy contract + +describe('benchmarks/process_history', () => { + let context: EndToEndContext; + let contract: BenchmarkingContract; + let sequencer: SequencerClient; + + beforeEach(async () => { + ({ context, contract, sequencer } = await benchmarkSetup({ maxTxsPerBlock: BLOCK_SIZE })); + }, 60_000); + + it( + `processes chain history of ${MAX_CHAIN_LENGTH} with ${BLOCK_SIZE}-tx blocks`, + async () => { + // Ensure each block has exactly BLOCK_SIZE txs + sequencer.updateSequencerConfig({ minTxsPerBlock: BLOCK_SIZE }); + let lastBlock = 0; + + for (const chainLength of CHAIN_LENGTHS) { + // Send enough txs to move the chain to the next block number checkpoint + const txCount = (chainLength - lastBlock) * BLOCK_SIZE; + const sentTxs = await sendTxs(txCount, context, contract); + await sentTxs[sentTxs.length - 1].wait({ timeout: 5 * 60_000 }); + await sleep(100); + + // Create a new node and measure how much time it takes it to sync + const [nodeSyncTime, node] = await elapsed(async () => { + const node = await AztecNodeService.createAndSync({ ...context.config, disableSequencer: true }); + await node.getTreeRoots(); + return node; + }); + + const blockNumber = await node.getBlockNumber(); + expect(blockNumber).toEqual(chainLength + SETUP_BLOCK_COUNT); + + context.logger(`Node synced chain up to block ${chainLength}`, { + eventName: 'node-synced-chain-history', + txCount: BLOCK_SIZE * chainLength, + txsPerBlock: BLOCK_SIZE, + duration: nodeSyncTime, + blockNumber, + blockCount: chainLength, + }); + + // Create a new pxe and measure how much time it takes it to sync with failed and successful decryption + // Skip the first two blocks used for setup (create account contract and deploy benchmarking contract) + context.logger(`Starting new pxe`); + const pxe = await waitNewPXESynced(node, contract, INITIAL_L2_BLOCK_NUM + SETUP_BLOCK_COUNT); + + // Register the owner account and wait until it's synced so we measure how much time it took + context.logger(`Registering owner account on new pxe`); + const partialAddress = context.wallet.getCompleteAddress().partialAddress; + const privateKey = context.wallet.getEncryptionPrivateKey(); + await waitRegisteredAccountSynced(pxe, privateKey, partialAddress); + + // Repeat for another account that didn't receive any notes for them, so we measure trial-decrypts + context.logger(`Registering fresh account on new pxe`); + await waitRegisteredAccountSynced(pxe, GrumpkinScalar.random(), Fr.random()); + + // Stop the external node and pxe + await pxe.stop(); + await node.stop(); + + lastBlock = chainLength; + } + + await context.teardown(); + }, + 60 * 60_000, + ); +}); diff --git a/yarn-project/end-to-end/src/benchmarks/bench_publish_rollup.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_publish_rollup.test.ts index 91791aeedb1..16ef88b7377 100644 --- a/yarn-project/end-to-end/src/benchmarks/bench_publish_rollup.test.ts +++ b/yarn-project/end-to-end/src/benchmarks/bench_publish_rollup.test.ts @@ -1,55 +1,30 @@ -/* eslint-disable camelcase */ import { AztecNodeService } from '@aztec/aztec-node'; -import { AztecAddress, BatchCall } from '@aztec/aztec.js'; -import { EthAddress, Fr, GrumpkinScalar } from '@aztec/circuits.js'; -import { retryUntil } from '@aztec/foundation/retry'; -import { sleep } from '@aztec/foundation/sleep'; +import { Fr, GrumpkinScalar } from '@aztec/circuits.js'; import { BenchmarkingContract } from '@aztec/noir-contracts/types'; -import { createPXEService } from '@aztec/pxe'; import { SequencerClient } from '@aztec/sequencer-client'; -import times from 'lodash.times'; - -import { setup } from '../fixtures/utils.js'; +import { EndToEndContext } from '../fixtures/utils.js'; +import { benchmarkSetup, sendTxs, waitNewPXESynced, waitRegisteredAccountSynced } from './utils.js'; const ROLLUP_SIZES = process.env.ROLLUP_SIZES ? process.env.ROLLUP_SIZES.split(',').map(Number) : [8, 32, 128]; describe('benchmarks/publish_rollup', () => { - let context: Awaited>; + let context: EndToEndContext; let contract: BenchmarkingContract; - let owner: AztecAddress; let sequencer: SequencerClient; beforeEach(async () => { - context = await setup(2, { maxTxsPerBlock: 1024 }); - [owner] = context.accounts.map(a => a.address); - contract = await BenchmarkingContract.deploy(context.wallet).send().deployed(); - context.logger(`Deployed benchmarking contract at ${contract.address}`); - sequencer = (context.aztecNode as AztecNodeService).getSequencer()!; - await sequencer.stop(); + ({ context, contract, sequencer } = await benchmarkSetup({ maxTxsPerBlock: 1024 })); }, 60_000); - // Each tx has a private execution (account entrypoint), a nested private call (create_note), - // a public call (increment_balance), and a nested public call (broadcast). These include - // emitting one private note and one unencrypted log, two storage reads and one write. - const makeBatchCall = (i: number) => - new BatchCall(context.wallet, [ - contract.methods.create_note(owner, i + 1).request(), - contract.methods.increment_balance(owner, i + 1).request(), - ]); - it.each(ROLLUP_SIZES)( `publishes a rollup with %d txs`, async (txCount: number) => { - context.logger(`Assembling rollup with ${txCount} txs`); - // Simulate and simultaneously send ROLLUP_SIZE txs. These should not yet be processed since sequencer is stopped. - const calls = times(txCount, makeBatchCall); - calls.forEach(call => call.simulate({ skipPublicSimulation: true })); - const sentTxs = calls.map(call => call.send()); + await sequencer.stop(); - // Awaiting txHash waits until the aztec node has received the tx into its p2p pool - await Promise.all(sentTxs.map(tx => tx.getTxHash())); - await sleep(100); + // Simulate and simultaneously send ROLLUP_SIZE txs. These should not yet be processed since sequencer is stopped. + context.logger(`Assembling rollup with ${txCount} txs`); + const sentTxs = await sendTxs(txCount, context, contract); // Restart sequencer to process all txs together sequencer.restart(); @@ -66,25 +41,17 @@ describe('benchmarks/publish_rollup', () => { // Spin up a new pxe and sync it, we'll use it to test sync times of new accounts for the last block context.logger(`Starting new pxe`); - const pxe = await createPXEService(node, { l2BlockPollingIntervalMS: 100, l2StartingBlock: blockNumber! - 1 }); - await pxe.addContracts([{ ...contract, portalContract: EthAddress.ZERO }]); - await retryUntil(() => pxe.isGlobalStateSynchronized(), 'pxe-global-sync'); - const { publicKey, partialAddress } = context.wallet.getCompleteAddress(); - const privateKey = context.wallet.getEncryptionPrivateKey(); - const l2Block = await node.getBlockNumber(); + const pxe = await waitNewPXESynced(node, contract, blockNumber! - 1); // Register the owner account and wait until it's synced so we measure how much time it took context.logger(`Registering owner account on new pxe`); - await pxe.registerAccount(privateKey, partialAddress); - const isOwnerSynced = async () => (await pxe.getSyncStatus()).notes[publicKey.toString()] === l2Block; - await retryUntil(isOwnerSynced, 'pxe-owner-sync'); + const partialAddress = context.wallet.getCompleteAddress().partialAddress; + const privateKey = context.wallet.getEncryptionPrivateKey(); + await waitRegisteredAccountSynced(pxe, privateKey, partialAddress); // Repeat for another account that didn't receive any notes for them, so we measure trial-decrypts context.logger(`Registering fresh account on new pxe`); - const newAccount = await pxe.registerAccount(GrumpkinScalar.random(), Fr.random()); - const isNewAccountSynced = async () => - (await pxe.getSyncStatus()).notes[newAccount.publicKey.toString()] === l2Block; - await retryUntil(isNewAccountSynced, 'pxe-new-account-sync'); + await waitRegisteredAccountSynced(pxe, GrumpkinScalar.random(), Fr.random()); // Stop the external node and pxe await pxe.stop(); diff --git a/yarn-project/end-to-end/src/benchmarks/utils.ts b/yarn-project/end-to-end/src/benchmarks/utils.ts new file mode 100644 index 00000000000..8660054aa8c --- /dev/null +++ b/yarn-project/end-to-end/src/benchmarks/utils.ts @@ -0,0 +1,100 @@ +import { AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node'; +import { BatchCall, SentTx } from '@aztec/aztec.js'; +import { GrumpkinScalar } from '@aztec/circuits.js'; +import { retryUntil } from '@aztec/foundation/retry'; +import { sleep } from '@aztec/foundation/sleep'; +import { BenchmarkingContract } from '@aztec/noir-contracts/types'; +import { PXEService, createPXEService } from '@aztec/pxe'; +import { AztecNode, INITIAL_L2_BLOCK_NUM, PXE, PartialAddress } from '@aztec/types'; + +import times from 'lodash.times'; + +import { EndToEndContext, setup } from '../fixtures/utils.js'; + +/** + * Setup for benchmarks. Initializes a sandbox node with a single account and deploys a benchmark contract. + */ +export async function benchmarkSetup(opts: Partial) { + const context = await setup(1, opts); + const contract = await BenchmarkingContract.deploy(context.wallet).send().deployed(); + context.logger(`Deployed benchmarking contract at ${contract.address}`); + const sequencer = (context.aztecNode as AztecNodeService).getSequencer()!; + return { context, contract, sequencer }; +} + +/** + * Returns a call to the benchmark contract. Each call has a private execution (account entrypoint), + * a nested private call (create_note), a public call (increment_balance), and a nested public + * call (broadcast). These include emitting one private note and one unencrypted log, two storage + * reads and one write. + * @param index - Index of the call within a block. + * @param context - End to end context. + * @param contract - Benchmarking contract. + * @returns A BatchCall instance. + */ +export function makeCall(index: number, context: EndToEndContext, contract: BenchmarkingContract) { + const owner = context.wallet.getAddress(); + return new BatchCall(context.wallet, [ + contract.methods.create_note(owner, index + 1).request(), + contract.methods.increment_balance(owner, index + 1).request(), + ]); +} + +/** + * Assembles and sends multiple transactions simultaneously to the node in context. + * Each tx is the result of calling makeCall. + * @param txCount - How many txs to send + * @param context - End to end context. + * @param contract - Target contract. + * @returns Array of sent txs. + */ +export async function sendTxs( + txCount: number, + context: EndToEndContext, + contract: BenchmarkingContract, +): Promise { + const calls = times(txCount, index => makeCall(index, context, contract)); + calls.forEach(call => call.simulate({ skipPublicSimulation: true })); + const sentTxs = calls.map(call => call.send()); + + // Awaiting txHash waits until the aztec node has received the tx into its p2p pool + await Promise.all(sentTxs.map(tx => tx.getTxHash())); + await sleep(100); + + return sentTxs; +} + +/** + * Creates a new PXE and awaits until it's synced with the node. + * @param node - Node to connect the pxe to. + * @param contract - Benchmark contract to add to the pxe. + * @param startingBlock - First l2 block to process. + * @returns The new PXE. + */ +export async function waitNewPXESynced( + node: AztecNode, + contract: BenchmarkingContract, + startingBlock: number = INITIAL_L2_BLOCK_NUM, +): Promise { + const pxe = await createPXEService(node, { l2BlockPollingIntervalMS: 100, l2StartingBlock: startingBlock }); + await pxe.addContracts([contract]); + await retryUntil(() => pxe.isGlobalStateSynchronized(), 'pxe-global-sync'); + return pxe; +} + +/** + * Retisters a new account in a pxe and waits until it's synced all its notes. + * @param pxe - PXE where to register the account. + * @param privateKey - Private key of the account to register. + * @param partialAddress - Partial address of the account to register. + */ +export async function waitRegisteredAccountSynced( + pxe: PXE, + privateKey: GrumpkinScalar, + partialAddress: PartialAddress, +) { + const l2Block = await pxe.getBlockNumber(); + const { publicKey } = await pxe.registerAccount(privateKey, partialAddress); + const isAccountSynced = async () => (await pxe.getSyncStatus()).notes[publicKey.toString()] === l2Block; + await retryUntil(isAccountSynced, 'pxe-notes-sync'); +} diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index 01caa613732..9853251ea71 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -31,6 +31,10 @@ type NoteProcessorStats = { decrypted: number; /** How many notes failed processing. */ failed: number; + /** How many blocks were spanned. */ + blocks: number; + /** How many txs were spanned. */ + txs: number; }; /** @@ -45,7 +49,7 @@ export class NoteProcessor { public readonly timer: Timer = new Timer(); /** Stats accumulated for this processor. */ - public readonly stats: NoteProcessorStats = { seen: 0, decrypted: 0, failed: 0 }; + public readonly stats: NoteProcessorStats = { seen: 0, decrypted: 0, failed: 0, blocks: 0, txs: 0 }; constructor( /** @@ -106,6 +110,7 @@ export class NoteProcessor { // Iterate over both blocks and encrypted logs. for (let blockIndex = 0; blockIndex < encryptedL2BlockLogs.length; ++blockIndex) { + this.stats.blocks++; const { txLogs } = encryptedL2BlockLogs[blockIndex]; const block = l2BlockContexts[blockIndex].block; const dataStartIndexForBlock = block.startPrivateDataTreeSnapshot.nextAvailableLeafIndex; @@ -117,6 +122,7 @@ export class NoteProcessor { // Iterate over all the encrypted logs and try decrypting them. If successful, store the note spending info. for (let indexOfTxInABlock = 0; indexOfTxInABlock < txLogs.length; ++indexOfTxInABlock) { + this.stats.txs++; const dataStartIndexForTx = dataStartIndexForBlock + indexOfTxInABlock * MAX_NEW_COMMITMENTS_PER_TX; const newCommitments = block.newCommitments.slice( indexOfTxInABlock * MAX_NEW_COMMITMENTS_PER_TX, diff --git a/yarn-project/sequencer-client/src/client/sequencer-client.ts b/yarn-project/sequencer-client/src/client/sequencer-client.ts index 22af9491e4e..577ae727639 100644 --- a/yarn-project/sequencer-client/src/client/sequencer-client.ts +++ b/yarn-project/sequencer-client/src/client/sequencer-client.ts @@ -5,7 +5,7 @@ import { WorldStateSynchronizer } from '@aztec/world-state'; import { SoloBlockBuilder } from '../block_builder/solo_block_builder.js'; import { SequencerClientConfig } from '../config.js'; import { getGlobalVariableBuilder } from '../global_variable_builder/index.js'; -import { Sequencer, getL1Publisher, getVerificationKeys } from '../index.js'; +import { Sequencer, SequencerConfig, getL1Publisher, getVerificationKeys } from '../index.js'; import { EmptyRollupProver } from '../prover/empty.js'; import { PublicProcessorFactory } from '../sequencer/public_processor.js'; import { WasmRollupCircuitSimulator } from '../simulator/rollup.js'; @@ -64,6 +64,14 @@ export class SequencerClient { return new SequencerClient(sequencer); } + /** + * Updates sequencer config. + * @param config - New parameters. + */ + public updateSequencerConfig(config: SequencerConfig) { + this.sequencer.updateConfig(config); + } + /** * Stops the sequencer from processing new txs. */ diff --git a/yarn-project/sequencer-client/src/config.ts b/yarn-project/sequencer-client/src/config.ts index 5a75ff6980b..5ceffb81a41 100644 --- a/yarn-project/sequencer-client/src/config.ts +++ b/yarn-project/sequencer-client/src/config.ts @@ -5,10 +5,22 @@ import { GlobalReaderConfig } from './global_variable_builder/index.js'; import { PublisherConfig, TxSenderConfig } from './publisher/config.js'; import { SequencerConfig } from './sequencer/config.js'; +/** Chain configuration. */ +type ChainConfig = { + /** The chain id of the ethereum host. */ + chainId: number; + /** The version of the rollup. */ + version: number; +}; + /** * Configuration settings for the SequencerClient. */ -export type SequencerClientConfig = PublisherConfig & TxSenderConfig & SequencerConfig & GlobalReaderConfig; +export type SequencerClientConfig = PublisherConfig & + TxSenderConfig & + SequencerConfig & + GlobalReaderConfig & + ChainConfig; /** * Creates an instance of SequencerClientConfig out of environment variables using sensible defaults for integration testing if not set. diff --git a/yarn-project/sequencer-client/src/sequencer/config.ts b/yarn-project/sequencer-client/src/sequencer/config.ts index 3e8a818c814..82c6e10db16 100644 --- a/yarn-project/sequencer-client/src/sequencer/config.ts +++ b/yarn-project/sequencer-client/src/sequencer/config.ts @@ -14,14 +14,4 @@ export interface SequencerConfig { * The minimum number of txs to include in a block. */ minTxsPerBlock?: number; - - /** - * The chain id of the ethereum host. - */ - chainId: number; - - /** - * The version of the rollup. - */ - version: number; } diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index 1ec5c92280a..5966ca6c1bf 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -94,10 +94,6 @@ describe('sequencer', () => { l1ToL2MessageSource, contractDataSource, publicProcessorFactory, - { - chainId: Number(chainId.value), - version: Number(version.value), - }, ); }); diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index 1323c2cc484..010d855cb05 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -28,7 +28,7 @@ import { PublicProcessorFactory } from './public_processor.js'; */ export class Sequencer { private runningPromise?: RunningPromise; - private pollingIntervalMs: number; + private pollingIntervalMs: number = 1000; private maxTxsPerBlock = 32; private minTxsPerBLock = 1; private lastPublishedBlock = 0; @@ -44,19 +44,23 @@ export class Sequencer { private l1ToL2MessageSource: L1ToL2MessageSource, private contractDataSource: ContractDataSource, private publicProcessorFactory: PublicProcessorFactory, - config: SequencerConfig, + config: SequencerConfig = {}, private log = createDebugLogger('aztec:sequencer'), ) { - this.pollingIntervalMs = config.transactionPollingIntervalMS ?? 1_000; - if (config.maxTxsPerBlock) { - this.maxTxsPerBlock = config.maxTxsPerBlock; - } - if (config.minTxsPerBlock) { - this.minTxsPerBLock = config.minTxsPerBlock; - } + this.updateConfig(config); this.log(`Initialized sequencer with ${this.minTxsPerBLock}-${this.maxTxsPerBlock} txs per block.`); } + /** + * Updates sequencer config. + * @param config - New parameters. + */ + public updateConfig(config: SequencerConfig) { + if (config.transactionPollingIntervalMS) this.pollingIntervalMs = config.transactionPollingIntervalMS; + if (config.maxTxsPerBlock) this.maxTxsPerBlock = config.maxTxsPerBlock; + if (config.minTxsPerBlock) this.minTxsPerBLock = config.minTxsPerBlock; + } + /** * Starts the sequencer and moves to IDLE state. Blocks until the initial sync is complete. */ From 4a1f57f6f26ee13e76129397c36def9841ef584a Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Sat, 7 Oct 2023 14:43:41 -0300 Subject: [PATCH 3/7] Add dbsize metrics for node and pxe --- scripts/ci/aggregate_e2e_benchmark.js | 9 ++++-- scripts/ci/benchmark_shared.js | 4 ++- .../src/structs/complete_address.ts | 3 ++ yarn-project/end-to-end/.gitignore | 1 + yarn-project/end-to-end/package.json | 1 + .../benchmarks/bench_process_history.test.ts | 19 +++++++++--- .../end-to-end/src/benchmarks/utils.ts | 30 ++++++++++++++++++- yarn-project/pxe/src/database/database.ts | 6 ++++ yarn-project/pxe/src/database/memory_db.ts | 10 ++++++- .../src/database/note_spending_info_dao.ts | 11 +++++++ .../pxe/src/pxe_service/pxe_service.ts | 5 ++++ .../pxe/src/synchronizer/synchronizer.ts | 1 + yarn-project/yarn.lock | 29 ++++++++++++++++++ 13 files changed, 120 insertions(+), 9 deletions(-) diff --git a/scripts/ci/aggregate_e2e_benchmark.js b/scripts/ci/aggregate_e2e_benchmark.js index b626ec6bdfe..53eb747cf6c 100644 --- a/scripts/ci/aggregate_e2e_benchmark.js +++ b/scripts/ci/aggregate_e2e_benchmark.js @@ -35,10 +35,12 @@ const { NODE_SYNCED_CHAIN, NOTE_HISTORY_TRIAL_DECRYPTING_TIME, NOTE_HISTORY_SUCCESSFUL_DECRYPTING_TIME, + PXE_DB_SIZE, ROLLUP_SIZES, CHAIN_LENGTHS, BENCHMARK_FILE_JSON, BLOCK_SIZE, + NODE_DB_SIZE, } = require("./benchmark_shared.js"); // Folder where to load logs from @@ -91,13 +93,15 @@ function processCircuitSimulation(entry, results) { // Processes an entry with event name 'note-processor-caught-up' and updates results // Buckets are rollup sizes for NOTE_DECRYPTING_TIME, or chain sizes for NOTE_HISTORY_DECRYPTING_TIME function processNoteProcessorCaughtUp(entry, results) { - const { seen, decrypted, blocks, txs, duration } = entry; + const { seen, decrypted, blocks, duration, dbSize } = entry; if (ROLLUP_SIZES.includes(decrypted)) append(results, NOTE_SUCCESSFUL_DECRYPTING_TIME, decrypted, duration); if (ROLLUP_SIZES.includes(seen) && decrypted === 0) append(results, NOTE_TRIAL_DECRYPTING_TIME, seen, duration); - if (CHAIN_LENGTHS.includes(blocks) && decrypted > 0) + if (CHAIN_LENGTHS.includes(blocks) && decrypted > 0) { append(results, NOTE_HISTORY_SUCCESSFUL_DECRYPTING_TIME, blocks, duration); + append(results, PXE_DB_SIZE, blocks, dbSize); + } if (CHAIN_LENGTHS.includes(blocks) && decrypted === 0) append(results, NOTE_HISTORY_TRIAL_DECRYPTING_TIME, blocks, duration); } @@ -129,6 +133,7 @@ function processNodeSyncedChain(entry, results) { if (!CHAIN_LENGTHS.includes(bucket)) return; if (entry.txsPerBlock !== BLOCK_SIZE) return; append(results, NODE_HISTORY_SYNC_TIME, bucket, entry.duration); + append(results, NODE_DB_SIZE, bucket, entry.dbSize); } // Processes a parsed entry from a logfile and updates results diff --git a/scripts/ci/benchmark_shared.js b/scripts/ci/benchmark_shared.js index 1d4bb7a81c4..34c2d87ca1c 100644 --- a/scripts/ci/benchmark_shared.js +++ b/scripts/ci/benchmark_shared.js @@ -9,7 +9,7 @@ const BLOCK_SIZE = process.env.BLOCK_SIZE ? +process.env.BLOCK_SIZE : 32; // Chain lengths to test (duplicated from yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts) const CHAIN_LENGTHS = process.env.CHAIN_LENGTHS ? process.env.CHAIN_LENGTHS.split(",").map(Number) - : [10, 20, 50]; + : [10, 20, 30]; // Output files const BENCHMARK_FILE_JSON = process.env.BENCHMARK_FILE_JSON ?? "benchmark.json"; @@ -33,6 +33,8 @@ module.exports = { "note_history_successful_decrypting_time_in_ms", NOTE_HISTORY_TRIAL_DECRYPTING_TIME: "note_history_trial_decrypting_time_in_ms", + NODE_DB_SIZE: "node_database_size_in_bytes", + PXE_DB_SIZE: "pxe_database_size_in_bytes", // Events to track L2_BLOCK_PUBLISHED_TO_L1: "rollup-published-to-l1", L2_BLOCK_SYNCED: "l2-block-handled", diff --git a/yarn-project/circuits.js/src/structs/complete_address.ts b/yarn-project/circuits.js/src/structs/complete_address.ts index 37a95c2b004..e35c98d252c 100644 --- a/yarn-project/circuits.js/src/structs/complete_address.ts +++ b/yarn-project/circuits.js/src/structs/complete_address.ts @@ -27,6 +27,9 @@ export class CompleteAddress { public partialAddress: PartialAddress, ) {} + /** Size in bytes of an instance */ + static readonly SIZE_IN_BYTES = 32 * 4; + static async create( address: AztecAddress, publicKey: PublicKey, diff --git a/yarn-project/end-to-end/.gitignore b/yarn-project/end-to-end/.gitignore index a174be95ed3..c9bba6e4021 100644 --- a/yarn-project/end-to-end/.gitignore +++ b/yarn-project/end-to-end/.gitignore @@ -1,2 +1,3 @@ addresses.json /log +/data diff --git a/yarn-project/end-to-end/package.json b/yarn-project/end-to-end/package.json index 6d3d3426817..1aec35f5b59 100644 --- a/yarn-project/end-to-end/package.json +++ b/yarn-project/end-to-end/package.json @@ -50,6 +50,7 @@ "@types/lodash.zipwith": "^4.2.7", "@types/memdown": "^3.0.3", "@types/node": "^18.7.23", + "glob": "^10.3.10", "jest": "^29.5.0", "koa": "^2.14.2", "koa-static": "^5.0.0", diff --git a/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts index 6f5c98bc01b..94975e30ed9 100644 --- a/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts +++ b/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts @@ -1,4 +1,4 @@ -import { AztecNodeService } from '@aztec/aztec-node'; +import { AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node'; import { Fr, GrumpkinScalar } from '@aztec/circuits.js'; import { sleep } from '@aztec/foundation/sleep'; import { elapsed } from '@aztec/foundation/timer'; @@ -7,10 +7,17 @@ import { SequencerClient } from '@aztec/sequencer-client'; import { INITIAL_L2_BLOCK_NUM } from '@aztec/types'; import { EndToEndContext } from '../fixtures/utils.js'; -import { benchmarkSetup, sendTxs, waitNewPXESynced, waitRegisteredAccountSynced } from './utils.js'; +import { + benchmarkSetup, + getFolderSize, + makeDataDirectory, + sendTxs, + waitNewPXESynced, + waitRegisteredAccountSynced, +} from './utils.js'; const BLOCK_SIZE = process.env.BLOCK_SIZE ? +process.env.BLOCK_SIZE : 32; -const CHAIN_LENGTHS = process.env.CHAIN_LENGTHS ? process.env.CHAIN_LENGTHS.split(',').map(Number) : [10, 20, 50]; +const CHAIN_LENGTHS = process.env.CHAIN_LENGTHS ? process.env.CHAIN_LENGTHS.split(',').map(Number) : [10, 20, 30]; const MAX_CHAIN_LENGTH = CHAIN_LENGTHS[CHAIN_LENGTHS.length - 1]; const SETUP_BLOCK_COUNT = 2; // deploy account + deploy contract @@ -38,8 +45,11 @@ describe('benchmarks/process_history', () => { await sleep(100); // Create a new node and measure how much time it takes it to sync + const dataDirectory = makeDataDirectory(chainLength); + context.logger(`Set up data directory at ${dataDirectory}`); + const nodeConfig: AztecNodeConfig = { ...context.config, disableSequencer: true, dataDirectory }; const [nodeSyncTime, node] = await elapsed(async () => { - const node = await AztecNodeService.createAndSync({ ...context.config, disableSequencer: true }); + const node = await AztecNodeService.createAndSync(nodeConfig); await node.getTreeRoots(); return node; }); @@ -54,6 +64,7 @@ describe('benchmarks/process_history', () => { duration: nodeSyncTime, blockNumber, blockCount: chainLength, + dbSize: getFolderSize(dataDirectory), }); // Create a new pxe and measure how much time it takes it to sync with failed and successful decryption diff --git a/yarn-project/end-to-end/src/benchmarks/utils.ts b/yarn-project/end-to-end/src/benchmarks/utils.ts index 8660054aa8c..b88366c41c0 100644 --- a/yarn-project/end-to-end/src/benchmarks/utils.ts +++ b/yarn-project/end-to-end/src/benchmarks/utils.ts @@ -7,7 +7,10 @@ import { BenchmarkingContract } from '@aztec/noir-contracts/types'; import { PXEService, createPXEService } from '@aztec/pxe'; import { AztecNode, INITIAL_L2_BLOCK_NUM, PXE, PartialAddress } from '@aztec/types'; +import { mkdirpSync } from 'fs-extra'; +import { globSync } from 'glob'; import times from 'lodash.times'; +import { join } from 'path'; import { EndToEndContext, setup } from '../fixtures/utils.js'; @@ -15,13 +18,38 @@ import { EndToEndContext, setup } from '../fixtures/utils.js'; * Setup for benchmarks. Initializes a sandbox node with a single account and deploys a benchmark contract. */ export async function benchmarkSetup(opts: Partial) { - const context = await setup(1, opts); + const context = await setup(1, { ...opts }); const contract = await BenchmarkingContract.deploy(context.wallet).send().deployed(); context.logger(`Deployed benchmarking contract at ${contract.address}`); const sequencer = (context.aztecNode as AztecNodeService).getSequencer()!; return { context, contract, sequencer }; } +/** + * Creates and returns a directory with the current job name and a random number. + * @param index - Index to merge into the dir path. + * @returns A path to a created dir. + */ +export function makeDataDirectory(index: number) { + const random = Math.random().toString().slice(2); + const testName = expect.getState().currentTestName!.split(' ')[0].replaceAll('/', '_'); + const db = join('data', testName, index.toString(), random); + mkdirpSync(db); + return db; +} + +/** + * Returns the size in disk of a folder. + * @param path - Path to the folder. + * @returns Size in bytes. + */ +export function getFolderSize(path: string): number { + return globSync('**', { stat: true, cwd: path, nodir: true, withFileTypes: true }).reduce( + (accum, file) => accum + (file as any as { /** Size */ size: number }).size, + 0, + ); +} + /** * Returns a call to the benchmark contract. Each call has a private execution (account entrypoint), * a nested private call (create_note), a public call (increment_balance), and a nested public diff --git a/yarn-project/pxe/src/database/database.ts b/yarn-project/pxe/src/database/database.ts index 0809cf7e0e2..8696d035c1c 100644 --- a/yarn-project/pxe/src/database/database.ts +++ b/yarn-project/pxe/src/database/database.ts @@ -128,4 +128,10 @@ export interface Database extends ContractDatabase { * @returns A promise that resolves to an array of AztecAddress instances. */ getCompleteAddresses(): Promise; + + /** + * Returns the estimated size in bytes of this db. + * @returns The estimated size in bytes of this db. + */ + estimateSize(): number; } diff --git a/yarn-project/pxe/src/database/memory_db.ts b/yarn-project/pxe/src/database/memory_db.ts index 208096fd106..dde7b86a7bc 100644 --- a/yarn-project/pxe/src/database/memory_db.ts +++ b/yarn-project/pxe/src/database/memory_db.ts @@ -6,7 +6,7 @@ import { MerkleTreeId, PublicKey } from '@aztec/types'; import { MemoryContractDatabase } from '../contract_database/index.js'; import { Database } from './database.js'; -import { NoteSpendingInfoDao } from './note_spending_info_dao.js'; +import { NoteSpendingInfoDao, getNoteSpendingInfoDaoSize } from './note_spending_info_dao.js'; /** * The MemoryDB class provides an in-memory implementation of a database to manage transactions and auxiliary data. @@ -144,4 +144,12 @@ export class MemoryDB extends MemoryContractDatabase implements Database { public getCompleteAddresses(): Promise { return Promise.resolve(this.addresses); } + + public estimateSize() { + const notesSize = this.noteSpendingInfoTable.reduce((sum, note) => sum + getNoteSpendingInfoDaoSize(note), 0); + const treeRootsSize = this.treeRoots ? Object.entries(this.treeRoots).length * Fr.SIZE_IN_BYTES : 0; + const authWits = Object.entries(this.authWitnesses); + const authWitsSize = authWits.reduce((sum, [key, value]) => sum + key.length + value.length * Fr.SIZE_IN_BYTES, 0); + return notesSize + treeRootsSize + authWitsSize + this.addresses.length * CompleteAddress.SIZE_IN_BYTES; + } } diff --git a/yarn-project/pxe/src/database/note_spending_info_dao.ts b/yarn-project/pxe/src/database/note_spending_info_dao.ts index 91936a4d6f1..003dcf45c37 100644 --- a/yarn-project/pxe/src/database/note_spending_info_dao.ts +++ b/yarn-project/pxe/src/database/note_spending_info_dao.ts @@ -62,3 +62,14 @@ export const createRandomNoteSpendingInfoDao = ({ index, publicKey, }); + +/** + * Returns the size in bytes of a note spending info dao. + * @param note - The note. + * @returns - Its size in bytes. + */ +export function getNoteSpendingInfoDaoSize(note: NoteSpendingInfoDao) { + // 7 fields + 1 bigint + 1 buffer size (4 bytes) + 1 buffer + const indexSize = Math.ceil(Math.log2(Number(note.index))); + return 7 * Fr.SIZE_IN_BYTES + indexSize + 4 + note.notePreimage.items.length * Fr.SIZE_IN_BYTES; +} diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 9aeb1c38bb8..5e2cda267b3 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -110,6 +110,11 @@ export class PXEService implements PXE { this.log.info('Stopped'); } + /** Returns an estimate of the db size in bytes. */ + public estimateDbSize() { + return this.db.estimateSize(); + } + public addAuthWitness(witness: AuthWitness) { return this.db.addAuthWitness(witness.requestHash, witness.witness); } diff --git a/yarn-project/pxe/src/synchronizer/synchronizer.ts b/yarn-project/pxe/src/synchronizer/synchronizer.ts index 092d2d69ba9..87fd155d85b 100644 --- a/yarn-project/pxe/src/synchronizer/synchronizer.ts +++ b/yarn-project/pxe/src/synchronizer/synchronizer.ts @@ -182,6 +182,7 @@ export class Synchronizer { eventName: 'note-processor-caught-up', publicKey: noteProcessor.publicKey.toString(), duration: noteProcessor.timer.ms(), + dbSize: this.db.estimateSize(), ...noteProcessor.stats, }); this.noteProcessorsToCatchUp.shift(); diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index 6efd2976c7a..605dcd7c10a 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -391,6 +391,7 @@ __metadata: "@types/memdown": ^3.0.3 "@types/node": ^18.7.23 concurrently: ^7.6.0 + glob: ^10.3.10 jest: ^29.5.0 koa: ^2.14.2 koa-static: ^5.0.0 @@ -10516,6 +10517,21 @@ __metadata: languageName: node linkType: hard +"glob@npm:^10.3.10": + version: 10.3.10 + resolution: "glob@npm:10.3.10" + dependencies: + foreground-child: ^3.1.0 + jackspeak: ^2.3.5 + minimatch: ^9.0.1 + minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 + path-scurry: ^1.10.1 + bin: + glob: dist/esm/bin.mjs + checksum: 4f2fe2511e157b5a3f525a54092169a5f92405f24d2aed3142f4411df328baca13059f4182f1db1bf933e2c69c0bd89e57ae87edd8950cba8c7ccbe84f721cf3 + languageName: node + linkType: hard + "glob@npm:^7.0.0, glob@npm:^7.0.3, glob@npm:^7.1.3, glob@npm:^7.1.4": version: 7.2.3 resolution: "glob@npm:7.2.3" @@ -11980,6 +11996,19 @@ __metadata: languageName: node linkType: hard +"jackspeak@npm:^2.3.5": + version: 2.3.6 + resolution: "jackspeak@npm:2.3.6" + dependencies: + "@isaacs/cliui": ^8.0.2 + "@pkgjs/parseargs": ^0.11.0 + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 57d43ad11eadc98cdfe7496612f6bbb5255ea69fe51ea431162db302c2a11011642f50cfad57288bd0aea78384a0612b16e131944ad8ecd09d619041c8531b54 + languageName: node + linkType: hard + "javascript-natural-sort@npm:0.7.1": version: 0.7.1 resolution: "javascript-natural-sort@npm:0.7.1" From f913b5d863a82904ac81f90f926a817272e30b76 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Mon, 9 Oct 2023 15:11:46 -0300 Subject: [PATCH 4/7] More conservative bench history size --- scripts/ci/benchmark_shared.js | 2 +- .../benchmarks/bench_process_history.test.ts | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/scripts/ci/benchmark_shared.js b/scripts/ci/benchmark_shared.js index 34c2d87ca1c..fe3735b4035 100644 --- a/scripts/ci/benchmark_shared.js +++ b/scripts/ci/benchmark_shared.js @@ -4,7 +4,7 @@ const ROLLUP_SIZES = process.env.ROLLUP_SIZES : [8, 32, 128]; // Block size to use for building chains of multiple length (duplicated from yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts) -const BLOCK_SIZE = process.env.BLOCK_SIZE ? +process.env.BLOCK_SIZE : 32; +const BLOCK_SIZE = process.env.BLOCK_SIZE ? +process.env.BLOCK_SIZE : 16; // Chain lengths to test (duplicated from yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts) const CHAIN_LENGTHS = process.env.CHAIN_LENGTHS diff --git a/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts index 94975e30ed9..e18b4356ac0 100644 --- a/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts +++ b/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts @@ -6,17 +6,13 @@ import { BenchmarkingContract } from '@aztec/noir-contracts/types'; import { SequencerClient } from '@aztec/sequencer-client'; import { INITIAL_L2_BLOCK_NUM } from '@aztec/types'; + + import { EndToEndContext } from '../fixtures/utils.js'; -import { - benchmarkSetup, - getFolderSize, - makeDataDirectory, - sendTxs, - waitNewPXESynced, - waitRegisteredAccountSynced, -} from './utils.js'; - -const BLOCK_SIZE = process.env.BLOCK_SIZE ? +process.env.BLOCK_SIZE : 32; +import { benchmarkSetup, getFolderSize, makeDataDirectory, sendTxs, waitNewPXESynced, waitRegisteredAccountSynced } from './utils.js'; + + +const BLOCK_SIZE = process.env.BLOCK_SIZE ? +process.env.BLOCK_SIZE : 16; const CHAIN_LENGTHS = process.env.CHAIN_LENGTHS ? process.env.CHAIN_LENGTHS.split(',').map(Number) : [10, 20, 30]; const MAX_CHAIN_LENGTH = CHAIN_LENGTHS[CHAIN_LENGTHS.length - 1]; const SETUP_BLOCK_COUNT = 2; // deploy account + deploy contract @@ -93,4 +89,4 @@ describe('benchmarks/process_history', () => { }, 60 * 60_000, ); -}); +}); \ No newline at end of file From bd2f800a10e6298c002517f245914ec45b5943b3 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Mon, 9 Oct 2023 15:11:57 -0300 Subject: [PATCH 5/7] Get all metrics into comments --- scripts/ci/comment_e2e_benchmark.js | 132 ++++++++++++++++++++++++---- 1 file changed, 117 insertions(+), 15 deletions(-) diff --git a/scripts/ci/comment_e2e_benchmark.js b/scripts/ci/comment_e2e_benchmark.js index 16f6541a048..b55413c794a 100644 --- a/scripts/ci/comment_e2e_benchmark.js +++ b/scripts/ci/comment_e2e_benchmark.js @@ -10,29 +10,131 @@ const OWNER = "AztecProtocol"; const REPO = "aztec3-packages"; const COMMENT_MARK = ""; -const { ROLLUP_SIZES, BENCHMARK_FILE_JSON } = require("./benchmark_shared.js"); +const { + ROLLUP_SIZES, + BLOCK_SIZE, + BENCHMARK_FILE_JSON, + L1_ROLLUP_CALLDATA_SIZE_IN_BYTES, + L1_ROLLUP_CALLDATA_GAS, + L1_ROLLUP_EXECUTION_GAS, + L2_BLOCK_PROCESSING_TIME, + CIRCUIT_SIMULATION_TIME, + CIRCUIT_INPUT_SIZE, + CIRCUIT_OUTPUT_SIZE, + NOTE_SUCCESSFUL_DECRYPTING_TIME, + NOTE_TRIAL_DECRYPTING_TIME, + L2_BLOCK_BUILD_TIME, + L2_BLOCK_ROLLUP_SIMULATION_TIME, + L2_BLOCK_PUBLIC_TX_PROCESS_TIME, + NODE_HISTORY_SYNC_TIME, + NOTE_HISTORY_SUCCESSFUL_DECRYPTING_TIME, + NOTE_HISTORY_TRIAL_DECRYPTING_TIME, + NODE_DB_SIZE, + PXE_DB_SIZE, +} = require("./benchmark_shared.js"); + +const METRICS_GROUPED_BY_ROLLUP_SIZE = [ + L1_ROLLUP_CALLDATA_SIZE_IN_BYTES, + L1_ROLLUP_CALLDATA_GAS, + L1_ROLLUP_EXECUTION_GAS, + L2_BLOCK_PROCESSING_TIME, + NOTE_SUCCESSFUL_DECRYPTING_TIME, + NOTE_TRIAL_DECRYPTING_TIME, + L2_BLOCK_BUILD_TIME, + L2_BLOCK_ROLLUP_SIMULATION_TIME, + L2_BLOCK_PUBLIC_TX_PROCESS_TIME, +]; + +const METRICS_GROUPED_BY_CHAIN_LENGTH = [ + NODE_HISTORY_SYNC_TIME, + NOTE_HISTORY_SUCCESSFUL_DECRYPTING_TIME, + NOTE_HISTORY_TRIAL_DECRYPTING_TIME, + NODE_DB_SIZE, + PXE_DB_SIZE, +]; + +const METRICS_GROUPED_BY_CIRCUIT_NAME = [ + CIRCUIT_SIMULATION_TIME, + CIRCUIT_INPUT_SIZE, + CIRCUIT_OUTPUT_SIZE, +]; + +function formatValue(value) { + return value; +} -// Returns the md content to post -function getContent() { - const benchmark = JSON.parse(fs.readFileSync(BENCHMARK_FILE_JSON, "utf-8")); - delete benchmark.timestamp; +function transpose(obj) { + const transposed = {}; + for (const outerKey in obj) { + const innerObj = obj[outerKey]; + for (const innerKey in innerObj) { + if (!transposed[innerKey]) transposed[innerKey] = {}; + transposed[innerKey][outerKey] = innerObj[innerKey]; + } + } + return transposed; +} + +function pick(benchmark, keys) { + const result = {}; + for (const key of keys) { + result[key] = benchmark[key]; + } + return result; +} - const sizes = ROLLUP_SIZES; - const header = `| Metric | ${sizes.map((i) => `${i} txs`).join(" | ")} |`; - const separator = `| - | ${sizes.map(() => "-").join(" | ")} |`; - const rows = Object.keys(benchmark).map((key) => { +function getTableContent(benchmark, groupUnit = "", col1Title = "Metric") { + const rowKeys = Object.keys(benchmark); + const groups = [ + ...new Set(rowKeys.flatMap((key) => Object.keys(benchmark[key]))), + ]; + console.log(groups); + const header = `| ${col1Title} | ${groups + .map((i) => `${i} ${groupUnit}`) + .join(" | ")} |`; + const separator = `| - | ${groups.map(() => "-").join(" | ")} |`; + const rows = rowKeys.map((key) => { const metric = benchmark[key]; - return `${key} | ${sizes.map((i) => metric[i]).join(" | ")} |`; + return `${key} | ${groups + .map((i) => formatValue(metric[i])) + .join(" | ")} |`; }); return ` -## Benchmark results - -### Rollup published to L1 - ${header} ${separator} ${rows.join("\n")} + `; +} + +// Returns the md content to post +function getPostContent() { + const benchmark = JSON.parse(fs.readFileSync(BENCHMARK_FILE_JSON, "utf-8")); + delete benchmark.timestamp; + + return ` +## Benchmark results + +All benchmarks are run on txs on the \`Benchmarking\` contract on the repository. Each tx consists of a batch call to \`create_note\` and \`increment_balance\`, which guarantees that each tx has a private call, a nested private call, a public call, and a nested public call, as well as an emitted private note, an unencrypted log, and public storage read and write. + +### L2 block published to L1 + +Each column represents the number of txs on an L2 block published to L1. +${getTableContent(pick(benchmark, METRICS_GROUPED_BY_ROLLUP_SIZE), "txs")} + +### L2 chain processing + +Each column represents the number of blocks on the L2 chain where each block has ${BLOCK_SIZE} txs. +${getTableContent(pick(benchmark, METRICS_GROUPED_BY_CHAIN_LENGTH), "blocks")} + +### Circuits stats + +Stats on running time and I/O sizes collected for every circuit run across all benchmarks. +${getTableContent( + transpose(pick(benchmark, METRICS_GROUPED_BY_CIRCUIT_NAME)), + "", + "Circuit" +)} ${COMMENT_MARK} `; @@ -61,7 +163,7 @@ async function getExistingComment() { // Function to create or update a comment async function upsertComment(existingCommentId) { try { - const commentContent = getContent(); + const commentContent = getPostContent(); const commentData = { body: commentContent }; const requestMethod = existingCommentId ? "PATCH" : "POST"; From e7471e683e7bb098d4b516c69ac7c28daedaa38d Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Mon, 9 Oct 2023 15:20:38 -0300 Subject: [PATCH 6/7] Format --- .../src/benchmarks/bench_process_history.test.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts index e18b4356ac0..ce78602059a 100644 --- a/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts +++ b/yarn-project/end-to-end/src/benchmarks/bench_process_history.test.ts @@ -6,11 +6,15 @@ import { BenchmarkingContract } from '@aztec/noir-contracts/types'; import { SequencerClient } from '@aztec/sequencer-client'; import { INITIAL_L2_BLOCK_NUM } from '@aztec/types'; - - import { EndToEndContext } from '../fixtures/utils.js'; -import { benchmarkSetup, getFolderSize, makeDataDirectory, sendTxs, waitNewPXESynced, waitRegisteredAccountSynced } from './utils.js'; - +import { + benchmarkSetup, + getFolderSize, + makeDataDirectory, + sendTxs, + waitNewPXESynced, + waitRegisteredAccountSynced, +} from './utils.js'; const BLOCK_SIZE = process.env.BLOCK_SIZE ? +process.env.BLOCK_SIZE : 16; const CHAIN_LENGTHS = process.env.CHAIN_LENGTHS ? process.env.CHAIN_LENGTHS.split(',').map(Number) : [10, 20, 30]; @@ -89,4 +93,4 @@ describe('benchmarks/process_history', () => { }, 60 * 60_000, ); -}); \ No newline at end of file +}); From 3e06ff907d6154206a7e63cec282c6c3280cd1ee Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Tue, 10 Oct 2023 11:28:48 -0300 Subject: [PATCH 7/7] Fix env var --- scripts/ci/comment_e2e_benchmark.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci/comment_e2e_benchmark.js b/scripts/ci/comment_e2e_benchmark.js index b55413c794a..38c8aea4c06 100644 --- a/scripts/ci/comment_e2e_benchmark.js +++ b/scripts/ci/comment_e2e_benchmark.js @@ -5,7 +5,7 @@ const https = require("https"); const fs = require("fs"); -const GITHUB_TOKEN = process.env.GITHUB_TOKEN; +const GITHUB_TOKEN = process.env.AZTEC_BOT_COMMENTER_GITHUB_TOKEN; const OWNER = "AztecProtocol"; const REPO = "aztec3-packages"; const COMMENT_MARK = "";