Skip to content

Commit 92e1432

Browse files
author
AztecBot
committed
Merge branch 'next' into merge-train/avm
2 parents 778e569 + 08cc68b commit 92e1432

File tree

16 files changed

+427
-84
lines changed

16 files changed

+427
-84
lines changed

yarn-project/archiver/README.md

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,37 @@
11
# Archiver
22

33
Archiver is a service which is used to fetch data on-chain data and present them in a nice-to-consume form.
4+
45
The on-chain data specifically are the following events:
56

67
1. `L2BlockProposed` event emitted on Rollup contract,
78
2. `MessageAdded` event emitted on Inbox contract,
89

910
The interfaces defining how the data can be consumed from the archiver are `L2BlockSource`, `L2LogsSource` and `ContractDataSource`.
1011

11-
## Usage
12+
## Sync process
13+
14+
The archiver sync process periodically checks its current state against the Rollup contract on L1 and updates its local state.
15+
16+
### Handling invalid blocks
17+
18+
After the implementation of [delayed attestation verification](https://github.com/AztecProtocol/engineering-designs/pull/69), the Rollup contract on L1 no longer validates committee attestations. Instead, these are posted in calldata, and L2 nodes are expected to verify them as they download blocks. The archiver handles this validation during its sync process.
19+
20+
Whenever the archiver detects a block with invalid attestations, it skips it. These blocks are not meant to be part of the chain, so the archiver ignores them and continues processing the next blocks. It is expected that an honest proposer will eventually invalidate these blocks, removing them from the chain on L1, and then resume the sequence of valid blocks.
21+
22+
> [!WARNING]
23+
> If the committee for the epoch is also malicious and attests to a descendant of an invalid block, nodes should also ignore these descendants, unless they become proven. This is currently not implemented. Nodes assume that the majority of the committee is honest.
24+
25+
When the current node is elected as proposer, the `sequencer` needs to know whether there is an invalid block in L1 that needs to be purged before posting their own block. To support this, the archiver exposes a `pendingChainValidationStatus`, which is the state of the tip of the pending chain. This status can be valid in the happy path, or invalid if the tip of the pending chain has invalid attestations. If invalid, this status also contains all the data needed for purging the block from L1 via an `invalidate` call to the Rollup contract. Note that, if the head of the chain has more than one invalid consecutive block, this status will reference the earliest one that needs to be purged, since a call to purge an invalid block will automatically purge all descendants. Refer to the [InvalidateLib.sol](`l1-contracts/src/core/libraries/rollup/InvalidateLib.sol`) for more info.
26+
27+
> [!TIP]
28+
> The archiver can be configured to `skipValidateBlockAttestations`, which will make it skip this validation. This cannot be set via environment variables, only via a call to `nodeAdmin_setConfig`. This setting is only meant for testing purposes.
1229
13-
To install dependencies and build the package run `yarn install` followed by `yarn build`.
14-
To run test execute `yarn test`.
30+
As an example, let's say the chain has been progressing normally up until block 10, and then:
31+
1. Block 11 is posted with invalid attestations. The archiver will report 10 as the latest block, but the `pendingChainValidationStatus` will point to block 11.
32+
2. Block 11 is purged, but another block 11 with invalid attestations is posted in its place. The archiver will still report 10 as latest, and the `pendingChainValidationStatus` will point to the new block 11 that needs to be purged.
33+
3. Block 12 with invalid attestations is posted. No changes in the archiver.
34+
4. Block 13 is posted with valid attestations, due to a malicious committee. The archiver will try to sync it and fail, since 13 does not follow 10. This scenario is not gracefully handled yet.
35+
5. Blocks 11 to 13 are purged. The archiver status will not yet be changed: 10 will still be the latest block, and the `pendingChainValidationStatus` will point to 11. This is because the archiver does **not** follow `BlockInvalidated` events.
36+
6. Block 11 with valid attestations is posted. The archiver pending chain now reports 11 as latest, and its status is valid.
1537

16-
To start the service export `ETHEREUM_HOSTS` (defaults to `http://127.0.0.1:8545/`), `ARCHIVER_POLLING_INTERVAL_MS` (defaults to `1000 ms`), `ROLLUP_CONTRACT_ADDRESS`, `INBOX_CONTRACT_ADDRESS` environmental variables and start the service with `yarn start`.

yarn-project/archiver/src/archiver/archiver.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
} from '@aztec/ethereum';
1111
import { maxBigint } from '@aztec/foundation/bigint';
1212
import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
13-
import { pick } from '@aztec/foundation/collection';
13+
import { merge, pick } from '@aztec/foundation/collection';
1414
import type { EthAddress } from '@aztec/foundation/eth-address';
1515
import { Fr } from '@aztec/foundation/fields';
1616
import { type Logger, createLogger } from '@aztec/foundation/log';
@@ -102,6 +102,14 @@ export type ArchiverDeps = {
102102
dateProvider?: DateProvider;
103103
};
104104

105+
function mapArchiverConfig(config: Partial<ArchiverConfig>) {
106+
return {
107+
pollingIntervalMs: config.archiverPollingIntervalMS,
108+
batchSize: config.archiverBatchSize,
109+
skipValidateBlockAttestations: config.skipValidateBlockAttestations,
110+
};
111+
}
112+
105113
/**
106114
* Pulls L2 blocks in a non-blocking manner and provides interface for their retrieval.
107115
* Responsible for handling robust L1 polling so that other components do not need to
@@ -138,7 +146,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
138146
private readonly publicClient: ViemPublicClient,
139147
private readonly l1Addresses: { rollupAddress: EthAddress; inboxAddress: EthAddress; registryAddress: EthAddress },
140148
readonly dataStore: ArchiverDataStore,
141-
private readonly config: { pollingIntervalMs: number; batchSize: number },
149+
private config: { pollingIntervalMs: number; batchSize: number; skipValidateBlockAttestations?: boolean },
142150
private readonly blobSinkClient: BlobSinkClientInterface,
143151
private readonly epochCache: EpochCache,
144152
private readonly instrumentation: ArchiverInstrumentation,
@@ -198,10 +206,7 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
198206
proofSubmissionEpochs: Number(proofSubmissionEpochs),
199207
};
200208

201-
const opts = {
202-
pollingIntervalMs: config.archiverPollingIntervalMS ?? 10_000,
203-
batchSize: config.archiverBatchSize ?? 100,
204-
};
209+
const opts = merge({ pollingIntervalMs: 10_000, batchSize: 100 }, mapArchiverConfig(config));
205210

206211
const epochCache = deps.epochCache ?? (await EpochCache.create(config.l1Contracts.rollupAddress, config, deps));
207212
const telemetry = deps.telemetry ?? getTelemetryClient();
@@ -220,6 +225,11 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
220225
return archiver;
221226
}
222227

228+
/** Updates archiver config */
229+
public updateConfig(newConfig: Partial<ArchiverConfig>) {
230+
this.config = merge(this.config, mapArchiverConfig(newConfig));
231+
}
232+
223233
/**
224234
* Starts sync process.
225235
* @param blockUntilSynced - If true, blocks until the archiver has fully synced.
@@ -796,7 +806,9 @@ export class Archiver extends (EventEmitter as new () => ArchiverEmitter) implem
796806
const validBlocks: PublishedL2Block[] = [];
797807

798808
for (const block of publishedBlocks) {
799-
const validationResult = await validateBlockAttestations(block, this.epochCache, this.l1constants, this.log);
809+
const validationResult = this.config.skipValidateBlockAttestations
810+
? { valid: true as const }
811+
: await validateBlockAttestations(block, this.epochCache, this.l1constants, this.log);
800812

801813
// Only update the validation result if it has changed, so we can keep track of the first invalid block
802814
// in case there is a sequence of more than one invalid block, as we need to invalidate the first one.

yarn-project/archiver/src/archiver/config.ts

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,28 @@
11
import { type BlobSinkConfig, blobSinkConfigMapping } from '@aztec/blob-sink/client';
22
import {
3-
type L1ContractAddresses,
43
type L1ContractsConfig,
54
type L1ReaderConfig,
65
l1ContractAddressesMapping,
76
l1ContractsConfigMappings,
87
l1ReaderConfigMappings,
98
} from '@aztec/ethereum';
10-
import { type ConfigMappingsType, getConfigFromMappings, numberConfigHelper } from '@aztec/foundation/config';
9+
import {
10+
type ConfigMappingsType,
11+
booleanConfigHelper,
12+
getConfigFromMappings,
13+
numberConfigHelper,
14+
} from '@aztec/foundation/config';
1115
import { type ChainConfig, chainConfigMappings } from '@aztec/stdlib/config';
16+
import type { ArchiverSpecificConfig } from '@aztec/stdlib/interfaces/server';
1217

1318
/**
19+
* The archiver configuration.
1420
* There are 2 polling intervals used in this configuration. The first is the archiver polling interval, archiverPollingIntervalMS.
1521
* This is the interval between successive calls to eth_blockNumber via viem.
1622
* Results of calls to eth_blockNumber are cached by viem with this cache being updated periodically at the interval specified by viemPollingIntervalMS.
1723
* As a result the maximum observed polling time for new blocks will be viemPollingIntervalMS + archiverPollingIntervalMS.
1824
*/
19-
20-
/**
21-
* The archiver configuration.
22-
*/
23-
export type ArchiverConfig = {
24-
/** The polling interval in ms for retrieving new L2 blocks and encrypted logs. */
25-
archiverPollingIntervalMS?: number;
26-
27-
/** The number of L2 blocks the archiver will attempt to download at a time. */
28-
archiverBatchSize?: number;
29-
30-
/** The polling interval viem uses in ms */
31-
viemPollingIntervalMS?: number;
32-
33-
/** The deployed L1 contract addresses */
34-
l1Contracts: L1ContractAddresses;
35-
36-
/** The max number of logs that can be obtained in 1 "getPublicLogs" call. */
37-
maxLogs?: number;
38-
39-
/** The maximum possible size of the archiver DB in KB. Overwrites the general dataStoreMapSizeKB. */
40-
archiverStoreMapSizeKb?: number;
41-
} & L1ReaderConfig &
42-
L1ContractsConfig &
43-
BlobSinkConfig &
44-
ChainConfig;
25+
export type ArchiverConfig = ArchiverSpecificConfig & L1ReaderConfig & L1ContractsConfig & BlobSinkConfig & ChainConfig;
4526

4627
export const archiverConfigMappings: ConfigMappingsType<ArchiverConfig> = {
4728
...blobSinkConfigMapping,
@@ -65,6 +46,10 @@ export const archiverConfigMappings: ConfigMappingsType<ArchiverConfig> = {
6546
parseEnv: (val: string | undefined) => (val ? +val : undefined),
6647
description: 'The maximum possible size of the archiver DB in KB. Overwrites the general dataStoreMapSizeKB.',
6748
},
49+
skipValidateBlockAttestations: {
50+
description: 'Whether to skip validating block attestations (use only for testing).',
51+
...booleanConfigHelper(false),
52+
},
6853
...chainConfigMappings,
6954
...l1ReaderConfigMappings,
7055
viemPollingIntervalMS: {

yarn-project/aztec-node/src/aztec-node/server.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1126,7 +1126,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
11261126
this.slasherClient?.updateConfig(config);
11271127
this.validatorsSentinel?.updateConfig(config);
11281128
await this.p2pClient.updateP2PConfig(config);
1129-
1129+
const archiver = this.blockSource as Archiver;
1130+
if ('updateConfig' in archiver) {
1131+
archiver.updateConfig(config);
1132+
}
11301133
if (newConfig.realProofs !== this.config.realProofs) {
11311134
this.proofVerifier = config.realProofs ? await BBCircuitVerifier.new(newConfig) : new TestCircuitVerifier();
11321135
}

0 commit comments

Comments
 (0)