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
2 changes: 1 addition & 1 deletion spartan/environments/devnet.env
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,4 @@ RPC_INGRESS_HOSTS="[\"$NAMESPACE.aztec-labs.com\"]"
RPC_INGRESS_STATIC_IP_NAME=$NAMESPACE-rpc-ip
RPC_INGRESS_SSL_CERT_NAMES="[\"$NAMESPACE-rpc-cert\"]"

WS_NUM_HISTORIC_BLOCKS=300
WS_NUM_HISTORIC_CHECKPOINTS=300
2 changes: 1 addition & 1 deletion spartan/scripts/deploy_network.sh
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ FULL_NODE_INCLUDE_METRICS = "${FULL_NODE_INCLUDE_METRICS-null}"
LOG_LEVEL = "${LOG_LEVEL}"
FISHERMAN_LOG_LEVEL = "${FISHERMAN_LOG_LEVEL}"

WS_NUM_HISTORIC_BLOCKS = ${WS_NUM_HISTORIC_BLOCKS:-null}
WS_NUM_HISTORIC_CHECKPOINTS = ${WS_NUM_HISTORIC_CHECKPOINTS:-null}

P2P_PUBLIC_IP = ${P2P_PUBLIC_IP}
P2P_NODEPORT_ENABLED = ${P2P_NODEPORT_ENABLED}
Expand Down
12 changes: 6 additions & 6 deletions spartan/terraform/deploy-aztec-infra/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ locals {
"validator.node.env.P2P_GOSSIPSUB_DHI" = var.P2P_GOSSIPSUB_DHI
"validator.node.env.P2P_DROP_TX" = var.P2P_DROP_TX
"validator.node.env.P2P_DROP_TX_CHANCE" = var.P2P_DROP_TX_CHANCE
"validator.node.env.WS_NUM_HISTORIC_BLOCKS" = var.WS_NUM_HISTORIC_BLOCKS
"validator.node.env.WS_NUM_HISTORIC_CHECKPOINTS" = var.WS_NUM_HISTORIC_CHECKPOINTS
"validator.node.env.TX_COLLECTION_FILE_STORE_URLS" = var.TX_COLLECTION_FILE_STORE_URLS
"validator.node.env.SEQ_SKIP_CHECKPOINT_PUBLISH_PERCENT" = var.SEQ_SKIP_CHECKPOINT_PUBLISH_PERCENT
}
Expand Down Expand Up @@ -358,7 +358,7 @@ locals {
"node.node.env.P2P_GOSSIPSUB_DHI" = var.P2P_GOSSIPSUB_DHI
"node.node.env.P2P_DROP_TX" = var.P2P_DROP_TX
"node.node.env.P2P_DROP_TX_CHANCE" = var.P2P_DROP_TX_CHANCE
"node.node.env.WS_NUM_HISTORIC_BLOCKS" = var.WS_NUM_HISTORIC_BLOCKS
"node.node.env.WS_NUM_HISTORIC_CHECKPOINTS" = var.WS_NUM_HISTORIC_CHECKPOINTS
"node.node.env.TX_COLLECTION_FILE_STORE_URLS" = var.TX_COLLECTION_FILE_STORE_URLS
"node.service.p2p.nodePortEnabled" = var.P2P_NODEPORT_ENABLED
"node.service.p2p.announcePort" = local.p2p_port_prover
Expand Down Expand Up @@ -438,7 +438,7 @@ locals {
"node.env.P2P_GOSSIPSUB_DHI" = var.P2P_GOSSIPSUB_DHI
"node.env.P2P_DROP_TX" = var.P2P_DROP_TX
"node.env.P2P_DROP_TX_CHANCE" = var.P2P_DROP_TX_CHANCE
"node.env.WS_NUM_HISTORIC_BLOCKS" = var.WS_NUM_HISTORIC_BLOCKS
"node.env.WS_NUM_HISTORIC_CHECKPOINTS" = var.WS_NUM_HISTORIC_CHECKPOINTS
"node.env.TX_FILE_STORE_ENABLED" = var.TX_FILE_STORE_ENABLED
"node.env.TX_FILE_STORE_URL" = var.TX_FILE_STORE_URL
"node.env.TX_COLLECTION_FILE_STORE_URLS" = var.TX_COLLECTION_FILE_STORE_URLS
Expand Down Expand Up @@ -495,7 +495,7 @@ locals {
"node.env.P2P_GOSSIPSUB_DHI" = var.P2P_GOSSIPSUB_DHI
"node.env.P2P_DROP_TX" = var.P2P_DROP_TX
"node.env.P2P_DROP_TX_CHANCE" = var.P2P_DROP_TX_CHANCE
"node.env.WS_NUM_HISTORIC_BLOCKS" = var.WS_NUM_HISTORIC_BLOCKS
"node.env.WS_NUM_HISTORIC_CHECKPOINTS" = var.WS_NUM_HISTORIC_CHECKPOINTS
"node.env.TX_COLLECTION_FILE_STORE_URLS" = var.TX_COLLECTION_FILE_STORE_URLS
}
boot_node_host_path = "node.env.BOOT_NODE_HOST"
Expand Down Expand Up @@ -535,7 +535,7 @@ locals {
"node.env.P2P_GOSSIPSUB_DHI" = var.P2P_GOSSIPSUB_DHI
"node.env.P2P_DROP_TX" = var.P2P_DROP_TX
"node.env.P2P_DROP_TX_CHANCE" = var.P2P_DROP_TX_CHANCE
"node.env.WS_NUM_HISTORIC_BLOCKS" = var.WS_NUM_HISTORIC_BLOCKS
"node.env.WS_NUM_HISTORIC_CHECKPOINTS" = var.WS_NUM_HISTORIC_CHECKPOINTS
"node.env.TX_COLLECTION_FILE_STORE_URLS" = var.TX_COLLECTION_FILE_STORE_URLS
}
boot_node_host_path = "node.env.BOOT_NODE_HOST"
Expand Down Expand Up @@ -572,7 +572,7 @@ locals {
"node.env.P2P_GOSSIPSUB_DHI" = var.P2P_GOSSIPSUB_DHI
"node.env.P2P_DROP_TX" = var.P2P_DROP_TX
"node.env.P2P_DROP_TX_CHANCE" = var.P2P_DROP_TX_CHANCE
"node.env.WS_NUM_HISTORIC_BLOCKS" = var.WS_NUM_HISTORIC_BLOCKS
"node.env.WS_NUM_HISTORIC_CHECKPOINTS" = var.WS_NUM_HISTORIC_CHECKPOINTS
}
boot_node_host_path = "node.env.BOOT_NODE_HOST"
bootstrap_nodes_path = "node.env.BOOTSTRAP_NODES"
Expand Down
4 changes: 2 additions & 2 deletions spartan/terraform/deploy-aztec-infra/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -772,8 +772,8 @@ variable "P2P_DROP_TX_CHANCE" {
default = 0
}

variable "WS_NUM_HISTORIC_BLOCKS" {
description = "Number of historic blocks for world state"
variable "WS_NUM_HISTORIC_CHECKPOINTS" {
description = "Number of historic checkpoints for world state"
type = string
nullable = true
default = null
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec/src/cli/aztec_start_options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export const aztecStartOptions: { [key: string]: AztecStartOption[] } = {
'WORLD STATE': [
configToFlag('--world-state-data-directory', worldStateConfigMappings.worldStateDataDirectory),
configToFlag('--world-state-db-map-size-kb', worldStateConfigMappings.worldStateDbMapSizeKb),
configToFlag('--world-state-block-history', worldStateConfigMappings.worldStateBlockHistory),
configToFlag('--world-state-checkpoint-history', worldStateConfigMappings.worldStateCheckpointHistory),
],
// We can't easily auto-generate node options as they're parts of modules defined below
'AZTEC NODE': [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { BlockNumber } from '@aztec/foundation/branded-types';
import { jest } from '@jest/globals';

import type { EndToEndContext } from '../fixtures/utils.js';
import { EpochsTestContext, WORLD_STATE_BLOCK_HISTORY } from './epochs_test.js';
import { EpochsTestContext, WORLD_STATE_CHECKPOINT_HISTORY } from './epochs_test.js';

jest.setTimeout(1000 * 60 * 15);

Expand Down Expand Up @@ -50,9 +50,10 @@ describe('e2e_epochs/epochs_multiple', () => {

// Check that finalized blocks are purged from world state
// Right now finalization means a checkpoint is two L2 epochs deep. If this rule changes then this test needs to be updated.
// This test is setup as 1 block per checkpoint
const provenBlockNumber = epochEndBlockNumber;
const finalizedBlockNumber = Math.max(provenBlockNumber - context.config.aztecEpochDuration * 2, 0);
const expectedOldestHistoricBlock = Math.max(finalizedBlockNumber - WORLD_STATE_BLOCK_HISTORY + 1, 1);
const expectedOldestHistoricBlock = Math.max(finalizedBlockNumber - WORLD_STATE_CHECKPOINT_HISTORY + 1, 1);
const expectedBlockRemoved = expectedOldestHistoricBlock - 1;
await test.waitForNodeToSync(BlockNumber(expectedOldestHistoricBlock), 'historic');
await test.verifyHistoricBlock(BlockNumber(expectedOldestHistoricBlock), true);
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/end-to-end/src/e2e_epochs/epochs_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import {
setup,
} from '../fixtures/utils.js';

export const WORLD_STATE_BLOCK_HISTORY = 2;
export const WORLD_STATE_CHECKPOINT_HISTORY = 2;
export const WORLD_STATE_BLOCK_CHECK_INTERVAL = 50;
export const ARCHIVER_POLL_INTERVAL = 50;
export const DEFAULT_L1_BLOCK_TIME = process.env.CI ? 12 : 8;
Expand Down Expand Up @@ -142,7 +142,7 @@ export class EpochsTestContext {
// using the prover's eth address if the proverId is used for something in the rollup contract
// Use numeric EthAddress for deterministic prover id
proverId: EthAddress.fromNumber(1),
worldStateBlockHistory: WORLD_STATE_BLOCK_HISTORY,
worldStateCheckpointHistory: WORLD_STATE_CHECKPOINT_HISTORY,
exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
slasherFlavor: 'none',
l1PublishingTime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ describe('L1Publisher integration', () => {
const worldStateConfig: WorldStateConfig = {
worldStateBlockCheckIntervalMS: 10000,
worldStateDbMapSizeKb: 10 * 1024 * 1024,
worldStateBlockHistory: 0,
worldStateCheckpointHistory: 0,
};
worldStateSynchronizer = new ServerWorldStateSynchronizer(builderDb, blockSource, worldStateConfig);
await worldStateSynchronizer.start();
Expand Down
7 changes: 4 additions & 3 deletions yarn-project/end-to-end/src/e2e_pruned_blocks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('e2e_pruned_blocks', () => {
const MINT_AMOUNT = 1000n;

// Don't make this value too high since we need to mine this number of empty blocks, which is relatively slow.
const WORLD_STATE_BLOCK_HISTORY = 2;
const WORLD_STATE_CHECKPOINT_HISTORY = 2;
const EPOCH_LENGTH = 2;
const WORLD_STATE_CHECK_INTERVAL_MS = 300;
const ARCHIVER_POLLING_INTERVAL_MS = 300;
Expand All @@ -47,7 +47,7 @@ describe('e2e_pruned_blocks', () => {
accounts: [admin, sender, recipient],
} = await setup(3, {
aztecEpochDuration: EPOCH_LENGTH,
worldStateBlockHistory: WORLD_STATE_BLOCK_HISTORY,
worldStateCheckpointHistory: WORLD_STATE_CHECKPOINT_HISTORY,
worldStateBlockCheckIntervalMS: WORLD_STATE_CHECK_INTERVAL_MS,
archiverPollingIntervalMS: ARCHIVER_POLLING_INTERVAL_MS,
aztecProofSubmissionEpochs: 1024, // effectively do not reorg
Expand Down Expand Up @@ -93,8 +93,9 @@ describe('e2e_pruned_blocks', () => {
// We now mine dummy blocks, mark them as proven and wait for the node to process them, which should result in older
// blocks (notably the one with the minted note) being pruned. Given world state prunes based on the finalized tip,
// and we are defining the finalized tip as two epochs behind the proven one, we need to mine two extra epochs.
// This test assumes 1 block per checkpoint
await aztecNodeAdmin!.setConfig({ minTxsPerBlock: 0 });
await waitBlocks(WORLD_STATE_BLOCK_HISTORY + EPOCH_LENGTH * 2 + 1);
await waitBlocks(WORLD_STATE_CHECKPOINT_HISTORY + EPOCH_LENGTH * 2 + 1);
await cheatCodes.rollup.markAsProven();

// The same historical query we performed before should now fail since this block is not available anymore. We poll
Expand Down
1 change: 1 addition & 0 deletions yarn-project/foundation/src/config/env_var.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ export type EnvVar =
| 'WS_BLOCK_REQUEST_BATCH_SIZE'
| 'L1_READER_VIEM_POLLING_INTERVAL_MS'
| 'WS_DATA_DIRECTORY'
| 'WS_NUM_HISTORIC_CHECKPOINTS'
| 'WS_NUM_HISTORIC_BLOCKS'
| 'ETHEREUM_SLOT_DURATION'
| 'AZTEC_SLOT_DURATION'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ describe('ValidatorClient Integration', () => {
worldStateBlockCheckIntervalMS: 20,
worldStateBlockRequestBatchSize: 10,
worldStateDbMapSizeKb: 1024 * 1024,
worldStateBlockHistory: 0,
worldStateCheckpointHistory: 0,
};
const worldStateDb = await NativeWorldStateService.tmp(rollupAddress, true, prefilledPublicData);
const synchronizer = new ServerWorldStateSynchronizer(worldStateDb, archiver, wsConfig);
Expand Down
12 changes: 7 additions & 5 deletions yarn-project/world-state/src/synchronizer/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export interface WorldStateConfig {
/** Optional directory for the world state DB, if unspecified will default to the general data directory */
worldStateDataDirectory?: string;

/** The number of historic blocks to maintain */
worldStateBlockHistory: number;
/** The number of historic checkpoints worth of blocks to maintain */
worldStateCheckpointHistory: number;
}

export const worldStateConfigMappings: ConfigMappingsType<WorldStateConfig> = {
Expand Down Expand Up @@ -84,9 +84,11 @@ export const worldStateConfigMappings: ConfigMappingsType<WorldStateConfig> = {
env: 'WS_DATA_DIRECTORY',
description: 'Optional directory for the world state database',
},
worldStateBlockHistory: {
env: 'WS_NUM_HISTORIC_BLOCKS',
description: 'The number of historic blocks to maintain. Values less than 1 mean all history is maintained',
worldStateCheckpointHistory: {
env: 'WS_NUM_HISTORIC_CHECKPOINTS',
description:
'The number of historic checkpoints worth of blocks to maintain. Values less than 1 mean all history is maintained',
fallback: ['WS_NUM_HISTORIC_BLOCKS'],
...numberConfigHelper(64),
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ describe('ServerWorldStateSynchronizer', () => {
const config: WorldStateConfig = {
worldStateBlockCheckIntervalMS: 100,
worldStateDbMapSizeKb: 1024 * 1024,
worldStateBlockHistory: 0,
worldStateCheckpointHistory: 0,
};

server = new TestWorldStateSynchronizer(merkleTreeDb, blockAndMessagesSource, config, l2BlockStream);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GENESIS_BLOCK_HEADER_HASH, INITIAL_L2_BLOCK_NUM, INITIAL_L2_CHECKPOINT_NUM } from '@aztec/constants';
import { BlockNumber } from '@aztec/foundation/branded-types';
import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
import type { Fr } from '@aztec/foundation/curves/bn254';
import { type Logger, createLogger } from '@aztec/foundation/log';
import { promiseWithResolvers } from '@aztec/foundation/promise';
Expand Down Expand Up @@ -64,7 +64,7 @@ export class ServerWorldStateSynchronizer
private readonly log: Logger = createLogger('world_state'),
) {
this.merkleTreeCommitted = this.merkleTreeDb.getCommitted();
this.historyToKeep = config.worldStateBlockHistory < 1 ? undefined : config.worldStateBlockHistory;
this.historyToKeep = config.worldStateCheckpointHistory < 1 ? undefined : config.worldStateCheckpointHistory;
this.log.info(
`Created world state synchroniser with block history of ${
this.historyToKeep === undefined ? 'infinity' : this.historyToKeep
Expand Down Expand Up @@ -364,12 +364,37 @@ export class ServerWorldStateSynchronizer
if (this.historyToKeep === undefined) {
return;
}
const newHistoricBlock = summary.finalizedBlockNumber - this.historyToKeep + 1;
if (newHistoricBlock <= 1) {
// Get the checkpointed block for the finalized block number
const finalisedCheckpoint = await this.l2BlockSource.getCheckpointedBlock(summary.finalizedBlockNumber);
if (finalisedCheckpoint === undefined) {
this.log.warn(
`Failed to retrieve checkpointed block for finalized block number: ${summary.finalizedBlockNumber}`,
);
return;
}
// Compute the required historic checkpoint number
const newHistoricCheckpointNumber = finalisedCheckpoint.checkpointNumber - this.historyToKeep + 1;
if (newHistoricCheckpointNumber <= 1) {
return;
}
// Retrieve the historic checkpoint
const historicCheckpoints = await this.l2BlockSource.getCheckpoints(
CheckpointNumber(newHistoricCheckpointNumber),
1,
);
if (historicCheckpoints.length === 0 || historicCheckpoints[0] === undefined) {
this.log.warn(`Failed to retrieve checkpoint number ${newHistoricCheckpointNumber} from Archiver`);
return;
}
const historicCheckpoint = historicCheckpoints[0];
if (historicCheckpoint.checkpoint.blocks.length === 0 || historicCheckpoint.checkpoint.blocks[0] === undefined) {
this.log.warn(`Retrieved checkpoint number ${newHistoricCheckpointNumber} has no blocks!`);
return;
}
this.log.verbose(`Pruning historic blocks to ${newHistoricBlock}`);
const status = await this.merkleTreeDb.removeHistoricalBlocks(BlockNumber(newHistoricBlock));
// Find the block at the start of the checkpoint and remove blocks up to this one
const newHistoricBlock = historicCheckpoint.checkpoint.blocks[0];
this.log.verbose(`Pruning historic blocks to ${newHistoricBlock.number}`);
const status = await this.merkleTreeDb.removeHistoricalBlocks(BlockNumber(newHistoricBlock.number));
this.log.debug(`World state summary `, status.summary);
}

Expand Down
2 changes: 1 addition & 1 deletion yarn-project/world-state/src/test/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ describe('world-state integration', () => {
worldStateBlockCheckIntervalMS: 20,
worldStateBlockRequestBatchSize: 5,
worldStateDbMapSizeKb: 1024 * 1024,
worldStateBlockHistory: 0,
worldStateCheckpointHistory: 0,
};

archiver = new MockPrefilledArchiver(checkpoints);
Expand Down
Loading