@aztec/archiver 0.76.4 → 0.77.0-testnet-ignition.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dest/archiver/archiver.d.ts +22 -10
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +762 -713
- package/dest/archiver/archiver_store.d.ts +20 -7
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store.js +4 -2
- package/dest/archiver/archiver_store_test_suite.d.ts +2 -2
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +398 -227
- package/dest/archiver/config.d.ts +1 -1
- package/dest/archiver/config.d.ts.map +1 -1
- package/dest/archiver/config.js +10 -12
- package/dest/archiver/data_retrieval.d.ts +17 -14
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +90 -88
- package/dest/archiver/errors.js +1 -2
- package/dest/archiver/index.d.ts +1 -1
- package/dest/archiver/index.d.ts.map +1 -1
- package/dest/archiver/index.js +0 -1
- package/dest/archiver/instrumentation.d.ts +3 -1
- package/dest/archiver/instrumentation.d.ts.map +1 -1
- package/dest/archiver/instrumentation.js +37 -17
- package/dest/archiver/kv_archiver_store/block_store.d.ts +5 -3
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +125 -130
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +2 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.js +45 -37
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +10 -2
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.js +54 -15
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +16 -9
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +143 -160
- package/dest/archiver/kv_archiver_store/log_store.d.ts +5 -3
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +296 -255
- package/dest/archiver/kv_archiver_store/message_store.d.ts +3 -3
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +45 -50
- package/dest/archiver/kv_archiver_store/nullifier_store.d.ts +2 -2
- package/dest/archiver/kv_archiver_store/nullifier_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/nullifier_store.js +36 -43
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +2 -2
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +17 -26
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +16 -7
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +287 -247
- package/dest/archiver/structs/data_retrieval.js +5 -2
- package/dest/archiver/structs/published.js +1 -2
- package/dest/factory.d.ts +20 -6
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +54 -30
- package/dest/index.js +0 -1
- package/dest/rpc/index.d.ts +2 -1
- package/dest/rpc/index.d.ts.map +1 -1
- package/dest/rpc/index.js +8 -4
- package/dest/test/index.js +0 -1
- package/dest/test/mock_archiver.d.ts +3 -2
- package/dest/test/mock_archiver.d.ts.map +1 -1
- package/dest/test/mock_archiver.js +8 -13
- package/dest/test/mock_l1_to_l2_message_source.d.ts +2 -2
- package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
- package/dest/test/mock_l1_to_l2_message_source.js +4 -4
- package/dest/test/mock_l2_block_source.d.ts +5 -3
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +71 -68
- package/package.json +15 -16
- package/src/archiver/archiver.ts +149 -89
- package/src/archiver/archiver_store.ts +27 -27
- package/src/archiver/archiver_store_test_suite.ts +22 -15
- package/src/archiver/config.ts +1 -1
- package/src/archiver/data_retrieval.ts +32 -44
- package/src/archiver/index.ts +1 -1
- package/src/archiver/instrumentation.ts +11 -1
- package/src/archiver/kv_archiver_store/block_store.ts +10 -4
- package/src/archiver/kv_archiver_store/contract_class_store.ts +9 -9
- package/src/archiver/kv_archiver_store/contract_instance_store.ts +81 -3
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +44 -29
- package/src/archiver/kv_archiver_store/log_store.ts +56 -32
- package/src/archiver/kv_archiver_store/message_store.ts +4 -3
- package/src/archiver/kv_archiver_store/nullifier_store.ts +3 -2
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +3 -3
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +110 -57
- package/src/factory.ts +44 -25
- package/src/rpc/index.ts +2 -6
- package/src/test/mock_archiver.ts +3 -2
- package/src/test/mock_l1_to_l2_message_source.ts +2 -2
- package/src/test/mock_l2_block_source.ts +16 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/archiver",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.77.0-testnet-ignition.21",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"clean": "rm -rf ./dest .tsbuildinfo",
|
|
23
23
|
"formatting": "run -T prettier --check ./src && run -T eslint ./src",
|
|
24
24
|
"formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src",
|
|
25
|
-
"test": "
|
|
25
|
+
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}",
|
|
26
26
|
"test:integration": "concurrently -k -s first -c reset,dim -n test,anvil \"yarn test:integration:run\" \"anvil\"",
|
|
27
27
|
"test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --config jest.integration.config.json"
|
|
28
28
|
},
|
|
@@ -58,25 +58,24 @@
|
|
|
58
58
|
"reporters": [
|
|
59
59
|
"default"
|
|
60
60
|
],
|
|
61
|
-
"testTimeout":
|
|
61
|
+
"testTimeout": 120000,
|
|
62
62
|
"setupFiles": [
|
|
63
63
|
"../../foundation/src/jest/setup.mjs"
|
|
64
64
|
]
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@aztec/blob-lib": "0.
|
|
68
|
-
"@aztec/blob-sink": "0.
|
|
69
|
-
"@aztec/
|
|
70
|
-
"@aztec/
|
|
71
|
-
"@aztec/
|
|
72
|
-
"@aztec/
|
|
73
|
-
"@aztec/
|
|
74
|
-
"@aztec/
|
|
75
|
-
"@aztec/noir-
|
|
76
|
-
"@aztec/
|
|
77
|
-
"@aztec/
|
|
78
|
-
"@aztec/telemetry-client": "0.
|
|
79
|
-
"@aztec/types": "0.76.4",
|
|
67
|
+
"@aztec/blob-lib": "0.77.0-testnet-ignition.21",
|
|
68
|
+
"@aztec/blob-sink": "0.77.0-testnet-ignition.21",
|
|
69
|
+
"@aztec/constants": "0.77.0-testnet-ignition.21",
|
|
70
|
+
"@aztec/ethereum": "0.77.0-testnet-ignition.21",
|
|
71
|
+
"@aztec/foundation": "0.77.0-testnet-ignition.21",
|
|
72
|
+
"@aztec/kv-store": "0.77.0-testnet-ignition.21",
|
|
73
|
+
"@aztec/l1-artifacts": "0.77.0-testnet-ignition.21",
|
|
74
|
+
"@aztec/noir-contracts.js": "0.77.0-testnet-ignition.21",
|
|
75
|
+
"@aztec/noir-protocol-circuits-types": "0.77.0-testnet-ignition.21",
|
|
76
|
+
"@aztec/protocol-contracts": "0.77.0-testnet-ignition.21",
|
|
77
|
+
"@aztec/stdlib": "0.77.0-testnet-ignition.21",
|
|
78
|
+
"@aztec/telemetry-client": "0.77.0-testnet-ignition.21",
|
|
80
79
|
"debug": "^4.3.4",
|
|
81
80
|
"lodash.groupby": "^4.6.0",
|
|
82
81
|
"lodash.omit": "^4.5.0",
|
package/src/archiver/archiver.ts
CHANGED
|
@@ -1,77 +1,69 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
2
|
+
import { type ViemPublicClient, createEthereumChain } from '@aztec/ethereum';
|
|
3
|
+
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
5
|
+
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
6
|
+
import { RunningPromise, makeLoggingErrorHandler } from '@aztec/foundation/running-promise';
|
|
7
|
+
import { count } from '@aztec/foundation/string';
|
|
8
|
+
import { elapsed } from '@aztec/foundation/timer';
|
|
9
|
+
import { InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
10
|
+
import {
|
|
11
|
+
ContractClassRegisteredEvent,
|
|
12
|
+
PrivateFunctionBroadcastedEvent,
|
|
13
|
+
UnconstrainedFunctionBroadcastedEvent,
|
|
14
|
+
} from '@aztec/protocol-contracts/class-registerer';
|
|
15
|
+
import {
|
|
16
|
+
ContractInstanceDeployedEvent,
|
|
17
|
+
ContractInstanceUpdatedEvent,
|
|
18
|
+
} from '@aztec/protocol-contracts/instance-deployer';
|
|
19
|
+
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
20
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
2
21
|
import {
|
|
3
|
-
type GetContractClassLogsResponse,
|
|
4
|
-
type GetPublicLogsResponse,
|
|
5
22
|
type InBlock,
|
|
6
|
-
type InboxLeaf,
|
|
7
|
-
type L1RollupConstants,
|
|
8
|
-
type L1ToL2MessageSource,
|
|
9
23
|
type L2Block,
|
|
10
24
|
type L2BlockId,
|
|
11
25
|
type L2BlockSource,
|
|
12
|
-
|
|
26
|
+
L2BlockSourceEvents,
|
|
13
27
|
type L2Tips,
|
|
14
|
-
type LogFilter,
|
|
15
28
|
type NullifierWithBlockSource,
|
|
16
|
-
|
|
17
|
-
type TxHash,
|
|
18
|
-
type TxReceipt,
|
|
19
|
-
type TxScopedL2Log,
|
|
20
|
-
type UnencryptedL2Log,
|
|
21
|
-
getEpochNumberAtTimestamp,
|
|
22
|
-
getSlotAtTimestamp,
|
|
23
|
-
getSlotRangeForEpoch,
|
|
24
|
-
getTimestampRangeForEpoch,
|
|
25
|
-
} from '@aztec/circuit-types';
|
|
29
|
+
} from '@aztec/stdlib/block';
|
|
26
30
|
import {
|
|
27
|
-
type BlockHeader,
|
|
28
31
|
type ContractClassPublic,
|
|
29
32
|
type ContractDataSource,
|
|
30
33
|
type ContractInstanceWithAddress,
|
|
31
34
|
type ExecutablePrivateFunctionWithMembershipProof,
|
|
32
|
-
type FunctionSelector,
|
|
33
|
-
type PrivateLog,
|
|
34
35
|
type PublicFunction,
|
|
35
36
|
type UnconstrainedFunctionWithMembershipProof,
|
|
36
37
|
computePublicBytecodeCommitment,
|
|
37
38
|
isValidPrivateFunctionMembershipProof,
|
|
38
39
|
isValidUnconstrainedFunctionMembershipProof,
|
|
39
|
-
} from '@aztec/
|
|
40
|
-
import { createEthereumChain } from '@aztec/ethereum';
|
|
41
|
-
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
42
|
-
import { type EthAddress } from '@aztec/foundation/eth-address';
|
|
43
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
44
|
-
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
45
|
-
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
46
|
-
import { count } from '@aztec/foundation/string';
|
|
47
|
-
import { elapsed } from '@aztec/foundation/timer';
|
|
48
|
-
import { InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
40
|
+
} from '@aztec/stdlib/contract';
|
|
49
41
|
import {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
42
|
+
type L1RollupConstants,
|
|
43
|
+
getEpochAtSlot,
|
|
44
|
+
getEpochNumberAtTimestamp,
|
|
45
|
+
getSlotAtTimestamp,
|
|
46
|
+
getSlotRangeForEpoch,
|
|
47
|
+
getTimestampRangeForEpoch,
|
|
48
|
+
} from '@aztec/stdlib/epoch-helpers';
|
|
49
|
+
import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
|
|
50
|
+
import type { L2LogsSource } from '@aztec/stdlib/interfaces/server';
|
|
51
|
+
import { ContractClassLog, type LogFilter, type PrivateLog, type PublicLog, TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
52
|
+
import type { InboxLeaf, L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
53
|
+
import { type BlockHeader, TxEffect, TxHash, TxReceipt } from '@aztec/stdlib/tx';
|
|
55
54
|
import { Attributes, type TelemetryClient, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client';
|
|
56
55
|
|
|
56
|
+
import { EventEmitter } from 'events';
|
|
57
57
|
import groupBy from 'lodash.groupby';
|
|
58
|
-
import {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
type PublicClient,
|
|
63
|
-
createPublicClient,
|
|
64
|
-
getContract,
|
|
65
|
-
http,
|
|
66
|
-
} from 'viem';
|
|
67
|
-
|
|
68
|
-
import { type ArchiverDataStore, type ArchiverL1SynchPoint } from './archiver_store.js';
|
|
69
|
-
import { type ArchiverConfig } from './config.js';
|
|
58
|
+
import { type GetContractReturnType, createPublicClient, fallback, getContract, http } from 'viem';
|
|
59
|
+
|
|
60
|
+
import type { ArchiverDataStore, ArchiverL1SynchPoint } from './archiver_store.js';
|
|
61
|
+
import type { ArchiverConfig } from './config.js';
|
|
70
62
|
import { retrieveBlocksFromRollup, retrieveL1ToL2Messages } from './data_retrieval.js';
|
|
71
63
|
import { NoBlobBodiesFoundError } from './errors.js';
|
|
72
64
|
import { ArchiverInstrumentation } from './instrumentation.js';
|
|
73
|
-
import {
|
|
74
|
-
import {
|
|
65
|
+
import type { DataRetrieval } from './structs/data_retrieval.js';
|
|
66
|
+
import type { L1Published } from './structs/published.js';
|
|
75
67
|
|
|
76
68
|
/**
|
|
77
69
|
* Helper interface to combine all sources this archiver implementation provides.
|
|
@@ -87,14 +79,14 @@ export type ArchiveSource = L2BlockSource &
|
|
|
87
79
|
* Responsible for handling robust L1 polling so that other components do not need to
|
|
88
80
|
* concern themselves with it.
|
|
89
81
|
*/
|
|
90
|
-
export class Archiver implements ArchiveSource, Traceable {
|
|
82
|
+
export class Archiver extends EventEmitter implements ArchiveSource, Traceable {
|
|
91
83
|
/**
|
|
92
84
|
* A promise in which we will be continually fetching new L2 blocks.
|
|
93
85
|
*/
|
|
94
86
|
private runningPromise?: RunningPromise;
|
|
95
87
|
|
|
96
|
-
private rollup: GetContractReturnType<typeof RollupAbi,
|
|
97
|
-
private inbox: GetContractReturnType<typeof InboxAbi,
|
|
88
|
+
private rollup: GetContractReturnType<typeof RollupAbi, ViemPublicClient>;
|
|
89
|
+
private inbox: GetContractReturnType<typeof InboxAbi, ViemPublicClient>;
|
|
98
90
|
|
|
99
91
|
private store: ArchiverStoreHelper;
|
|
100
92
|
|
|
@@ -114,7 +106,7 @@ export class Archiver implements ArchiveSource, Traceable {
|
|
|
114
106
|
* @param log - A logger.
|
|
115
107
|
*/
|
|
116
108
|
constructor(
|
|
117
|
-
private readonly publicClient:
|
|
109
|
+
private readonly publicClient: ViemPublicClient,
|
|
118
110
|
private readonly l1Addresses: { rollupAddress: EthAddress; inboxAddress: EthAddress; registryAddress: EthAddress },
|
|
119
111
|
readonly dataStore: ArchiverDataStore,
|
|
120
112
|
private readonly config: { pollingIntervalMs: number; batchSize: number },
|
|
@@ -123,6 +115,8 @@ export class Archiver implements ArchiveSource, Traceable {
|
|
|
123
115
|
private readonly l1constants: L1RollupConstants,
|
|
124
116
|
private readonly log: Logger = createLogger('archiver'),
|
|
125
117
|
) {
|
|
118
|
+
super();
|
|
119
|
+
|
|
126
120
|
this.tracer = instrumentation.tracer;
|
|
127
121
|
this.store = new ArchiverStoreHelper(dataStore);
|
|
128
122
|
|
|
@@ -152,10 +146,10 @@ export class Archiver implements ArchiveSource, Traceable {
|
|
|
152
146
|
deps: { telemetry: TelemetryClient; blobSinkClient: BlobSinkClientInterface },
|
|
153
147
|
blockUntilSynced = true,
|
|
154
148
|
): Promise<Archiver> {
|
|
155
|
-
const chain = createEthereumChain(config.
|
|
149
|
+
const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
|
|
156
150
|
const publicClient = createPublicClient({
|
|
157
151
|
chain: chain.chainInfo,
|
|
158
|
-
transport: http(
|
|
152
|
+
transport: fallback(config.l1RpcUrls.map(url => http(url))),
|
|
159
153
|
pollingInterval: config.viemPollingIntervalMS,
|
|
160
154
|
});
|
|
161
155
|
|
|
@@ -198,18 +192,32 @@ export class Archiver implements ArchiveSource, Traceable {
|
|
|
198
192
|
}
|
|
199
193
|
|
|
200
194
|
if (blockUntilSynced) {
|
|
201
|
-
await this.
|
|
195
|
+
await this.syncSafe(blockUntilSynced);
|
|
202
196
|
}
|
|
203
197
|
|
|
204
|
-
this.runningPromise = new RunningPromise(
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
198
|
+
this.runningPromise = new RunningPromise(
|
|
199
|
+
() => this.sync(false),
|
|
200
|
+
this.log,
|
|
201
|
+
this.config.pollingIntervalMs,
|
|
202
|
+
makeLoggingErrorHandler(
|
|
203
|
+
this.log,
|
|
204
|
+
// Ignored errors will not log to the console
|
|
205
|
+
// We ignore NoBlobBodiesFound as the message may not have been passed to the blob sink yet
|
|
206
|
+
NoBlobBodiesFoundError,
|
|
207
|
+
),
|
|
208
|
+
);
|
|
209
209
|
|
|
210
210
|
this.runningPromise.start();
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
+
private async syncSafe(initialRun: boolean) {
|
|
214
|
+
try {
|
|
215
|
+
await this.sync(initialRun);
|
|
216
|
+
} catch (error) {
|
|
217
|
+
this.log.error('Error during sync', { error });
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
213
221
|
/**
|
|
214
222
|
* Fetches logs from L1 contracts and processes them.
|
|
215
223
|
*/
|
|
@@ -278,29 +286,46 @@ export class Archiver implements ArchiveSource, Traceable {
|
|
|
278
286
|
// the chain locally before we start unwinding stuff. This can be optimized by figuring out
|
|
279
287
|
// up to which point we're pruning, and then requesting L2 blocks up to that point only.
|
|
280
288
|
await this.handleEpochPrune(provenBlockNumber, currentL1BlockNumber);
|
|
289
|
+
|
|
290
|
+
this.instrumentation.updateL1BlockHeight(currentL1BlockNumber);
|
|
281
291
|
}
|
|
282
292
|
|
|
283
293
|
if (initialRun) {
|
|
284
294
|
this.log.info(`Initial archiver sync to L1 block ${currentL1BlockNumber} complete.`, {
|
|
285
295
|
l1BlockNumber: currentL1BlockNumber,
|
|
296
|
+
syncPoint: await this.store.getSynchPoint(),
|
|
286
297
|
...(await this.getL2Tips()),
|
|
287
298
|
});
|
|
288
299
|
}
|
|
289
300
|
}
|
|
290
301
|
|
|
302
|
+
/** Queries the rollup contract on whether a prune can be executed on the immediatenext L1 block. */
|
|
303
|
+
private async canPrune(currentL1BlockNumber: bigint) {
|
|
304
|
+
const time = (this.l1Timestamp ?? 0n) + BigInt(this.l1constants.ethereumSlotDuration);
|
|
305
|
+
return await this.rollup.read.canPruneAtTime([time], { blockNumber: currentL1BlockNumber });
|
|
306
|
+
}
|
|
307
|
+
|
|
291
308
|
/** Checks if there'd be a reorg for the next block submission and start pruning now. */
|
|
292
309
|
private async handleEpochPrune(provenBlockNumber: bigint, currentL1BlockNumber: bigint) {
|
|
293
310
|
const localPendingBlockNumber = BigInt(await this.getBlockNumber());
|
|
294
|
-
|
|
295
|
-
const time = (this.l1Timestamp ?? 0n) + BigInt(this.l1constants.ethereumSlotDuration);
|
|
296
|
-
|
|
297
|
-
const canPrune =
|
|
298
|
-
localPendingBlockNumber > provenBlockNumber &&
|
|
299
|
-
(await this.rollup.read.canPruneAtTime([time], { blockNumber: currentL1BlockNumber }));
|
|
311
|
+
const canPrune = localPendingBlockNumber > provenBlockNumber && (await this.canPrune(currentL1BlockNumber));
|
|
300
312
|
|
|
301
313
|
if (canPrune) {
|
|
314
|
+
const localPendingSlotNumber = await this.getL2SlotNumber();
|
|
315
|
+
const localPendingEpochNumber = getEpochAtSlot(localPendingSlotNumber, this.l1constants);
|
|
316
|
+
|
|
317
|
+
// Emit an event for listening services to react to the chain prune
|
|
318
|
+
this.emit(L2BlockSourceEvents.L2PruneDetected, {
|
|
319
|
+
type: L2BlockSourceEvents.L2PruneDetected,
|
|
320
|
+
blockNumber: localPendingBlockNumber,
|
|
321
|
+
slotNumber: localPendingSlotNumber,
|
|
322
|
+
epochNumber: localPendingEpochNumber,
|
|
323
|
+
});
|
|
324
|
+
|
|
302
325
|
const blocksToUnwind = localPendingBlockNumber - provenBlockNumber;
|
|
303
|
-
this.log.debug(
|
|
326
|
+
this.log.debug(
|
|
327
|
+
`L2 prune from ${provenBlockNumber + 1n} to ${localPendingBlockNumber} will occur on next block submission.`,
|
|
328
|
+
);
|
|
304
329
|
await this.store.unwindBlocks(Number(localPendingBlockNumber), Number(blocksToUnwind));
|
|
305
330
|
this.log.warn(
|
|
306
331
|
`Unwound ${count(blocksToUnwind, 'block')} from L2 block ${localPendingBlockNumber} ` +
|
|
@@ -688,9 +713,11 @@ export class Archiver implements ArchiveSource, Traceable {
|
|
|
688
713
|
if (!instance) {
|
|
689
714
|
throw new Error(`Contract ${address.toString()} not found`);
|
|
690
715
|
}
|
|
691
|
-
const contractClass = await this.getContractClass(instance.
|
|
716
|
+
const contractClass = await this.getContractClass(instance.currentContractClassId);
|
|
692
717
|
if (!contractClass) {
|
|
693
|
-
throw new Error(
|
|
718
|
+
throw new Error(
|
|
719
|
+
`Contract class ${instance.currentContractClassId.toString()} for ${address.toString()} not found`,
|
|
720
|
+
);
|
|
694
721
|
}
|
|
695
722
|
return contractClass.publicFunctions.find(f => f.selector.equals(selector));
|
|
696
723
|
}
|
|
@@ -842,9 +869,18 @@ export class Archiver implements ArchiveSource, Traceable {
|
|
|
842
869
|
const provenBlockHeaderHash = await provenBlockHeader?.hash();
|
|
843
870
|
const finalizedBlockHeaderHash = await provenBlockHeader?.hash();
|
|
844
871
|
return {
|
|
845
|
-
latest: {
|
|
846
|
-
|
|
847
|
-
|
|
872
|
+
latest: {
|
|
873
|
+
number: latestBlockNumber,
|
|
874
|
+
hash: latestBlockHeaderHash?.toString(),
|
|
875
|
+
} as L2BlockId,
|
|
876
|
+
proven: {
|
|
877
|
+
number: provenBlockNumber,
|
|
878
|
+
hash: provenBlockHeaderHash?.toString(),
|
|
879
|
+
} as L2BlockId,
|
|
880
|
+
finalized: {
|
|
881
|
+
number: provenBlockNumber,
|
|
882
|
+
hash: finalizedBlockHeaderHash?.toString(),
|
|
883
|
+
} as L2BlockId,
|
|
848
884
|
};
|
|
849
885
|
}
|
|
850
886
|
}
|
|
@@ -872,6 +908,8 @@ class ArchiverStoreHelper
|
|
|
872
908
|
| 'deleteContractClasses'
|
|
873
909
|
| 'addContractInstances'
|
|
874
910
|
| 'deleteContractInstances'
|
|
911
|
+
| 'addContractInstanceUpdates'
|
|
912
|
+
| 'deleteContractInstanceUpdates'
|
|
875
913
|
| 'addFunctions'
|
|
876
914
|
>
|
|
877
915
|
{
|
|
@@ -892,10 +930,10 @@ class ArchiverStoreHelper
|
|
|
892
930
|
* Extracts and stores contract classes out of ContractClassRegistered events emitted by the class registerer contract.
|
|
893
931
|
* @param allLogs - All logs emitted in a bunch of blocks.
|
|
894
932
|
*/
|
|
895
|
-
async #updateRegisteredContractClasses(allLogs:
|
|
933
|
+
async #updateRegisteredContractClasses(allLogs: ContractClassLog[], blockNum: number, operation: Operation) {
|
|
896
934
|
const contractClassRegisteredEvents = allLogs
|
|
897
|
-
.filter(log => ContractClassRegisteredEvent.isContractClassRegisteredEvent(log
|
|
898
|
-
.map(log => ContractClassRegisteredEvent.fromLog(log
|
|
935
|
+
.filter(log => ContractClassRegisteredEvent.isContractClassRegisteredEvent(log))
|
|
936
|
+
.map(log => ContractClassRegisteredEvent.fromLog(log));
|
|
899
937
|
|
|
900
938
|
const contractClasses = await Promise.all(contractClassRegisteredEvents.map(e => e.toContractClassPublic()));
|
|
901
939
|
if (contractClasses.length > 0) {
|
|
@@ -935,6 +973,29 @@ class ArchiverStoreHelper
|
|
|
935
973
|
return true;
|
|
936
974
|
}
|
|
937
975
|
|
|
976
|
+
/**
|
|
977
|
+
* Extracts and stores contract instances out of ContractInstanceDeployed events emitted by the canonical deployer contract.
|
|
978
|
+
* @param allLogs - All logs emitted in a bunch of blocks.
|
|
979
|
+
*/
|
|
980
|
+
async #updateUpdatedContractInstances(allLogs: PublicLog[], blockNum: number, operation: Operation) {
|
|
981
|
+
const contractUpdates = allLogs
|
|
982
|
+
.filter(log => ContractInstanceUpdatedEvent.isContractInstanceUpdatedEvent(log))
|
|
983
|
+
.map(log => ContractInstanceUpdatedEvent.fromLog(log))
|
|
984
|
+
.map(e => e.toContractInstanceUpdate());
|
|
985
|
+
|
|
986
|
+
if (contractUpdates.length > 0) {
|
|
987
|
+
contractUpdates.forEach(c =>
|
|
988
|
+
this.#log.verbose(`${Operation[operation]} contract instance update at ${c.address.toString()}`),
|
|
989
|
+
);
|
|
990
|
+
if (operation == Operation.Store) {
|
|
991
|
+
return await this.store.addContractInstanceUpdates(contractUpdates, blockNum);
|
|
992
|
+
} else if (operation == Operation.Delete) {
|
|
993
|
+
return await this.store.deleteContractInstanceUpdates(contractUpdates, blockNum);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
return true;
|
|
997
|
+
}
|
|
998
|
+
|
|
938
999
|
/**
|
|
939
1000
|
* Stores the functions that was broadcasted individually
|
|
940
1001
|
*
|
|
@@ -945,14 +1006,14 @@ class ArchiverStoreHelper
|
|
|
945
1006
|
* @param _blockNum - The block number
|
|
946
1007
|
* @returns
|
|
947
1008
|
*/
|
|
948
|
-
async #storeBroadcastedIndividualFunctions(allLogs:
|
|
1009
|
+
async #storeBroadcastedIndividualFunctions(allLogs: ContractClassLog[], _blockNum: number) {
|
|
949
1010
|
// Filter out private and unconstrained function broadcast events
|
|
950
1011
|
const privateFnEvents = allLogs
|
|
951
|
-
.filter(log => PrivateFunctionBroadcastedEvent.isPrivateFunctionBroadcastedEvent(log
|
|
952
|
-
.map(log => PrivateFunctionBroadcastedEvent.fromLog(log
|
|
1012
|
+
.filter(log => PrivateFunctionBroadcastedEvent.isPrivateFunctionBroadcastedEvent(log))
|
|
1013
|
+
.map(log => PrivateFunctionBroadcastedEvent.fromLog(log));
|
|
953
1014
|
const unconstrainedFnEvents = allLogs
|
|
954
|
-
.filter(log => UnconstrainedFunctionBroadcastedEvent.isUnconstrainedFunctionBroadcastedEvent(log
|
|
955
|
-
.map(log => UnconstrainedFunctionBroadcastedEvent.fromLog(log
|
|
1015
|
+
.filter(log => UnconstrainedFunctionBroadcastedEvent.isUnconstrainedFunctionBroadcastedEvent(log))
|
|
1016
|
+
.map(log => UnconstrainedFunctionBroadcastedEvent.fromLog(log));
|
|
956
1017
|
|
|
957
1018
|
// Group all events by contract class id
|
|
958
1019
|
for (const [classIdString, classEvents] of Object.entries(
|
|
@@ -1004,15 +1065,15 @@ class ArchiverStoreHelper
|
|
|
1004
1065
|
this.store.addLogs(blocks.map(block => block.data)),
|
|
1005
1066
|
// Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them
|
|
1006
1067
|
...blocks.map(async block => {
|
|
1007
|
-
const contractClassLogs = block.data.body.txEffects
|
|
1008
|
-
.flatMap(txEffect => (txEffect ? [txEffect.contractClassLogs] : []))
|
|
1009
|
-
.flatMap(txLog => txLog.unrollLogs());
|
|
1068
|
+
const contractClassLogs = block.data.body.txEffects.flatMap(txEffect => txEffect.contractClassLogs);
|
|
1010
1069
|
// ContractInstanceDeployed event logs are broadcast in privateLogs.
|
|
1011
1070
|
const privateLogs = block.data.body.txEffects.flatMap(txEffect => txEffect.privateLogs);
|
|
1071
|
+
const publicLogs = block.data.body.txEffects.flatMap(txEffect => txEffect.publicLogs);
|
|
1012
1072
|
return (
|
|
1013
1073
|
await Promise.all([
|
|
1014
1074
|
this.#updateRegisteredContractClasses(contractClassLogs, block.data.number, Operation.Store),
|
|
1015
1075
|
this.#updateDeployedContractInstances(privateLogs, block.data.number, Operation.Store),
|
|
1076
|
+
this.#updateUpdatedContractInstances(publicLogs, block.data.number, Operation.Store),
|
|
1016
1077
|
this.#storeBroadcastedIndividualFunctions(contractClassLogs, block.data.number),
|
|
1017
1078
|
])
|
|
1018
1079
|
).every(Boolean);
|
|
@@ -1036,17 +1097,16 @@ class ArchiverStoreHelper
|
|
|
1036
1097
|
const opResults = await Promise.all([
|
|
1037
1098
|
// Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them
|
|
1038
1099
|
...blocks.map(async block => {
|
|
1039
|
-
const contractClassLogs = block.data.body.txEffects
|
|
1040
|
-
.flatMap(txEffect => (txEffect ? [txEffect.contractClassLogs] : []))
|
|
1041
|
-
.flatMap(txLog => txLog.unrollLogs());
|
|
1042
|
-
|
|
1100
|
+
const contractClassLogs = block.data.body.txEffects.flatMap(txEffect => txEffect.contractClassLogs);
|
|
1043
1101
|
// ContractInstanceDeployed event logs are broadcast in privateLogs.
|
|
1044
1102
|
const privateLogs = block.data.body.txEffects.flatMap(txEffect => txEffect.privateLogs);
|
|
1103
|
+
const publicLogs = block.data.body.txEffects.flatMap(txEffect => txEffect.publicLogs);
|
|
1045
1104
|
|
|
1046
1105
|
return (
|
|
1047
1106
|
await Promise.all([
|
|
1048
1107
|
this.#updateRegisteredContractClasses(contractClassLogs, block.data.number, Operation.Delete),
|
|
1049
1108
|
this.#updateDeployedContractInstances(privateLogs, block.data.number, Operation.Delete),
|
|
1109
|
+
this.#updateUpdatedContractInstances(publicLogs, block.data.number, Operation.Delete),
|
|
1050
1110
|
])
|
|
1051
1111
|
).every(Boolean);
|
|
1052
1112
|
}),
|
|
@@ -1,29 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from '@aztec/
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
type PrivateLog,
|
|
20
|
-
type UnconstrainedFunctionWithMembershipProof,
|
|
21
|
-
} from '@aztec/circuits.js';
|
|
22
|
-
import { type FunctionSelector } from '@aztec/foundation/abi';
|
|
23
|
-
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
24
|
-
|
|
25
|
-
import { type DataRetrieval } from './structs/data_retrieval.js';
|
|
26
|
-
import { type L1Published } from './structs/published.js';
|
|
1
|
+
import type { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
3
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
+
import type { InBlock, L2Block } from '@aztec/stdlib/block';
|
|
5
|
+
import type {
|
|
6
|
+
ContractClassPublic,
|
|
7
|
+
ContractInstanceUpdateWithAddress,
|
|
8
|
+
ContractInstanceWithAddress,
|
|
9
|
+
ExecutablePrivateFunctionWithMembershipProof,
|
|
10
|
+
UnconstrainedFunctionWithMembershipProof,
|
|
11
|
+
} from '@aztec/stdlib/contract';
|
|
12
|
+
import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
|
|
13
|
+
import type { LogFilter, PrivateLog, TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
14
|
+
import type { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
15
|
+
import { BlockHeader, type TxEffect, type TxHash, type TxReceipt } from '@aztec/stdlib/tx';
|
|
16
|
+
|
|
17
|
+
import type { DataRetrieval } from './structs/data_retrieval.js';
|
|
18
|
+
import type { L1Published } from './structs/published.js';
|
|
27
19
|
|
|
28
20
|
/**
|
|
29
21
|
* Represents the latest L1 block processed by the archiver for various objects in L2.
|
|
@@ -244,6 +236,14 @@ export interface ArchiverDataStore {
|
|
|
244
236
|
addContractInstances(data: ContractInstanceWithAddress[], blockNumber: number): Promise<boolean>;
|
|
245
237
|
deleteContractInstances(data: ContractInstanceWithAddress[], blockNumber: number): Promise<boolean>;
|
|
246
238
|
|
|
239
|
+
/**
|
|
240
|
+
* Add new contract instance updates
|
|
241
|
+
* @param data - List of contract updates to be added.
|
|
242
|
+
* @param blockNumber - Number of the L2 block the updates were scheduled in.
|
|
243
|
+
* @returns True if the operation is successful.
|
|
244
|
+
*/
|
|
245
|
+
addContractInstanceUpdates(data: ContractInstanceUpdateWithAddress[], blockNumber: number): Promise<boolean>;
|
|
246
|
+
deleteContractInstanceUpdates(data: ContractInstanceUpdateWithAddress[], blockNumber: number): Promise<boolean>;
|
|
247
247
|
/**
|
|
248
248
|
* Adds private functions to a contract class.
|
|
249
249
|
*/
|
|
@@ -254,7 +254,7 @@ export interface ArchiverDataStore {
|
|
|
254
254
|
): Promise<boolean>;
|
|
255
255
|
|
|
256
256
|
/**
|
|
257
|
-
* Returns a contract instance given its address, or undefined if not exists.
|
|
257
|
+
* Returns a contract instance given its address and the given block number, or undefined if not exists.
|
|
258
258
|
* @param address - Address of the contract.
|
|
259
259
|
*/
|
|
260
260
|
getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined>;
|
|
@@ -1,30 +1,33 @@
|
|
|
1
|
-
import { InboxLeaf, L2Block, LogId, TxEffect, TxHash, wrapInBlock } from '@aztec/circuit-types';
|
|
2
|
-
import '@aztec/circuit-types/jest';
|
|
3
1
|
import {
|
|
4
|
-
AztecAddress,
|
|
5
|
-
type ContractClassPublic,
|
|
6
|
-
type ContractInstanceWithAddress,
|
|
7
|
-
Fr,
|
|
8
2
|
INITIAL_L2_BLOCK_NUM,
|
|
9
3
|
L1_TO_L2_MSG_SUBTREE_HEIGHT,
|
|
10
4
|
MAX_NULLIFIERS_PER_TX,
|
|
11
5
|
PRIVATE_LOG_SIZE_IN_FIELDS,
|
|
12
6
|
PUBLIC_LOG_DATA_SIZE_IN_FIELDS,
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
} from '@aztec/constants';
|
|
8
|
+
import { times, timesParallel } from '@aztec/foundation/collection';
|
|
9
|
+
import { randomInt } from '@aztec/foundation/crypto';
|
|
10
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
11
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
12
|
+
import { L2Block, wrapInBlock } from '@aztec/stdlib/block';
|
|
13
|
+
import {
|
|
14
|
+
type ContractClassPublic,
|
|
15
|
+
type ContractInstanceWithAddress,
|
|
15
16
|
SerializableContractInstance,
|
|
16
17
|
computePublicBytecodeCommitment,
|
|
17
|
-
} from '@aztec/
|
|
18
|
+
} from '@aztec/stdlib/contract';
|
|
19
|
+
import { LogId, PrivateLog, PublicLog } from '@aztec/stdlib/logs';
|
|
20
|
+
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
18
21
|
import {
|
|
19
22
|
makeContractClassPublic,
|
|
20
23
|
makeExecutablePrivateFunctionWithMembershipProof,
|
|
21
24
|
makeUnconstrainedFunctionWithMembershipProof,
|
|
22
|
-
} from '@aztec/
|
|
23
|
-
import
|
|
24
|
-
import {
|
|
25
|
+
} from '@aztec/stdlib/testing';
|
|
26
|
+
import '@aztec/stdlib/testing/jest';
|
|
27
|
+
import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
25
28
|
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
29
|
+
import type { ArchiverDataStore, ArchiverL1SynchPoint } from './archiver_store.js';
|
|
30
|
+
import type { L1Published } from './structs/published.js';
|
|
28
31
|
|
|
29
32
|
/**
|
|
30
33
|
* @param testName - The name of the test suite.
|
|
@@ -279,7 +282,11 @@ export function describeArchiverDataStore(
|
|
|
279
282
|
const blockNum = 10;
|
|
280
283
|
|
|
281
284
|
beforeEach(async () => {
|
|
282
|
-
const
|
|
285
|
+
const classId = Fr.random();
|
|
286
|
+
const randomInstance = await SerializableContractInstance.random({
|
|
287
|
+
currentContractClassId: classId,
|
|
288
|
+
originalContractClassId: classId,
|
|
289
|
+
});
|
|
283
290
|
contractInstance = { ...randomInstance, address: await AztecAddress.random() };
|
|
284
291
|
await store.addContractInstances([contractInstance], blockNum);
|
|
285
292
|
});
|
package/src/archiver/config.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type BlobSinkConfig, blobSinkConfigMapping } from '@aztec/blob-sink/client';
|
|
2
|
-
import { type ChainConfig, chainConfigMappings } from '@aztec/circuit-types/config';
|
|
3
2
|
import {
|
|
4
3
|
type L1ContractAddresses,
|
|
5
4
|
type L1ContractsConfig,
|
|
@@ -8,6 +7,7 @@ import {
|
|
|
8
7
|
l1ReaderConfigMappings,
|
|
9
8
|
} from '@aztec/ethereum';
|
|
10
9
|
import { type ConfigMappingsType, getConfigFromMappings, numberConfigHelper } from '@aztec/foundation/config';
|
|
10
|
+
import { type ChainConfig, chainConfigMappings } from '@aztec/stdlib/config';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* There are 2 polling intervals used in this configuration. The first is the archiver polling interval, archiverPollingIntervalMS.
|