@aztec/archiver 4.0.0-nightly.20260122 → 4.0.0-nightly.20260124
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 +9 -0
- package/dest/archiver.d.ts +3 -3
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +9 -6
- package/dest/l1/bin/retrieve-calldata.js +2 -2
- package/dest/l1/data_retrieval.d.ts +1 -1
- package/dest/l1/data_retrieval.d.ts.map +1 -1
- package/dest/l1/data_retrieval.js +2 -2
- package/dest/modules/data_source_base.d.ts +14 -16
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +17 -51
- package/dest/modules/data_store_updater.d.ts +5 -5
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/instrumentation.d.ts +3 -3
- package/dest/modules/instrumentation.d.ts.map +1 -1
- package/dest/store/block_store.d.ts +10 -10
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +2 -2
- package/dest/store/kv_archiver_store.d.ts +12 -12
- package/dest/store/kv_archiver_store.d.ts.map +1 -1
- package/dest/store/log_store.d.ts +4 -4
- package/dest/store/log_store.d.ts.map +1 -1
- package/dest/test/fake_l1_state.d.ts +4 -4
- package/dest/test/fake_l1_state.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.d.ts +16 -18
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +28 -36
- package/dest/test/mock_structs.js +4 -4
- package/package.json +13 -13
- package/src/archiver.ts +12 -11
- package/src/l1/bin/retrieve-calldata.ts +7 -2
- package/src/l1/data_retrieval.ts +3 -3
- package/src/modules/data_source_base.ts +20 -75
- package/src/modules/data_store_updater.ts +7 -7
- package/src/modules/instrumentation.ts +2 -2
- package/src/store/block_store.ts +17 -17
- package/src/store/kv_archiver_store.ts +11 -11
- package/src/store/log_store.ts +8 -8
- package/src/test/fake_l1_state.ts +2 -2
- package/src/test/mock_l2_block_source.ts +36 -56
- package/src/test/mock_structs.ts +4 -4
|
@@ -5,7 +5,7 @@ import { Buffer32 } from '@aztec/foundation/buffer';
|
|
|
5
5
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
6
6
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
7
7
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
|
-
import { CheckpointedL2Block,
|
|
8
|
+
import { CheckpointedL2Block, L2Block, L2BlockHash } from '@aztec/stdlib/block';
|
|
9
9
|
import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
10
10
|
import { EmptyL1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
11
11
|
import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
@@ -20,7 +20,7 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
|
20
20
|
async createBlocks(numBlocks) {
|
|
21
21
|
for(let i = 0; i < numBlocks; i++){
|
|
22
22
|
const blockNum = this.l2Blocks.length + 1;
|
|
23
|
-
const block = await
|
|
23
|
+
const block = await L2Block.random(BlockNumber(blockNum), {
|
|
24
24
|
slotNumber: SlotNumber(blockNum)
|
|
25
25
|
});
|
|
26
26
|
this.l2Blocks.push(block);
|
|
@@ -82,10 +82,10 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
|
82
82
|
if (!block) {
|
|
83
83
|
return Promise.resolve(undefined);
|
|
84
84
|
}
|
|
85
|
-
const checkpointedBlock = new CheckpointedL2Block(CheckpointNumber(number), block, new L1PublishedData(BigInt(number), BigInt(number), `0x${number.toString(16).padStart(64, '0')}`), []);
|
|
85
|
+
const checkpointedBlock = new CheckpointedL2Block(CheckpointNumber.fromBlockNumber(number), block, new L1PublishedData(BigInt(number), BigInt(number), `0x${number.toString(16).padStart(64, '0')}`), []);
|
|
86
86
|
return Promise.resolve(checkpointedBlock);
|
|
87
87
|
}
|
|
88
|
-
async getCheckpointedBlocks(from, limit
|
|
88
|
+
async getCheckpointedBlocks(from, limit) {
|
|
89
89
|
const result = [];
|
|
90
90
|
for(let i = 0; i < limit; i++){
|
|
91
91
|
const blockNum = from + i;
|
|
@@ -111,7 +111,7 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
|
111
111
|
* Gets an L2 block (new format).
|
|
112
112
|
* @param number - The block number to return.
|
|
113
113
|
* @returns The requested L2 block.
|
|
114
|
-
*/
|
|
114
|
+
*/ getL2Block(number) {
|
|
115
115
|
const block = this.l2Blocks[number - 1];
|
|
116
116
|
return Promise.resolve(block);
|
|
117
117
|
}
|
|
@@ -120,14 +120,14 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
|
120
120
|
* @param from - Number of the first block to return (inclusive).
|
|
121
121
|
* @param limit - The maximum number of blocks to return.
|
|
122
122
|
* @returns The requested mocked L2 blocks.
|
|
123
|
-
*/ getBlocks(from, limit
|
|
124
|
-
return Promise.resolve(this.l2Blocks.slice(from - 1, from - 1 + limit)
|
|
123
|
+
*/ getBlocks(from, limit) {
|
|
124
|
+
return Promise.resolve(this.l2Blocks.slice(from - 1, from - 1 + limit));
|
|
125
125
|
}
|
|
126
|
-
|
|
126
|
+
getCheckpoints(from, limit) {
|
|
127
127
|
// TODO(mbps): Implement this properly. This only works when we have one block per checkpoint.
|
|
128
128
|
const blocks = this.l2Blocks.slice(from - 1, from - 1 + limit);
|
|
129
129
|
return Promise.all(blocks.map(async (block)=>{
|
|
130
|
-
// Create a checkpoint from the block - manually construct since
|
|
130
|
+
// Create a checkpoint from the block - manually construct since L2Block doesn't have toCheckpoint()
|
|
131
131
|
const checkpoint = await Checkpoint.random(block.checkpointNumber, {
|
|
132
132
|
numBlocks: 1
|
|
133
133
|
});
|
|
@@ -143,7 +143,7 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
|
143
143
|
if (!block) {
|
|
144
144
|
return undefined;
|
|
145
145
|
}
|
|
146
|
-
// Create a checkpoint from the block - manually construct since
|
|
146
|
+
// Create a checkpoint from the block - manually construct since L2Block doesn't have toCheckpoint()
|
|
147
147
|
const checkpoint = await Checkpoint.random(block.checkpointNumber, {
|
|
148
148
|
numBlocks: 1
|
|
149
149
|
});
|
|
@@ -152,25 +152,12 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
|
152
152
|
];
|
|
153
153
|
return checkpoint;
|
|
154
154
|
}
|
|
155
|
-
|
|
156
|
-
const blocks = this.l2Blocks.slice(from - 1, from - 1 + limit).filter((b)=>!proven || this.provenBlockNumber === undefined || b.number <= this.provenBlockNumber);
|
|
157
|
-
return Promise.resolve(blocks.map((block)=>CheckpointedL2Block.fromFields({
|
|
158
|
-
checkpointNumber: CheckpointNumber(block.number),
|
|
159
|
-
block,
|
|
160
|
-
l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
|
|
161
|
-
attestations: []
|
|
162
|
-
})));
|
|
163
|
-
}
|
|
164
|
-
getL2BlocksNew(from, limit, proven) {
|
|
165
|
-
// getBlocks already returns L2BlockNew[], so just return directly
|
|
166
|
-
return this.getBlocks(from, limit, proven);
|
|
167
|
-
}
|
|
168
|
-
async getPublishedBlockByHash(blockHash) {
|
|
155
|
+
async getCheckpointedBlockByHash(blockHash) {
|
|
169
156
|
for (const block of this.l2Blocks){
|
|
170
157
|
const hash = await block.hash();
|
|
171
158
|
if (hash.equals(blockHash)) {
|
|
172
159
|
return CheckpointedL2Block.fromFields({
|
|
173
|
-
checkpointNumber: CheckpointNumber(block.number),
|
|
160
|
+
checkpointNumber: CheckpointNumber.fromBlockNumber(block.number),
|
|
174
161
|
block,
|
|
175
162
|
l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
|
|
176
163
|
attestations: []
|
|
@@ -179,19 +166,19 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
|
179
166
|
}
|
|
180
167
|
return undefined;
|
|
181
168
|
}
|
|
182
|
-
|
|
169
|
+
getCheckpointedBlockByArchive(archive) {
|
|
183
170
|
const block = this.l2Blocks.find((b)=>b.archive.root.equals(archive));
|
|
184
171
|
if (!block) {
|
|
185
172
|
return Promise.resolve(undefined);
|
|
186
173
|
}
|
|
187
174
|
return Promise.resolve(CheckpointedL2Block.fromFields({
|
|
188
|
-
checkpointNumber: CheckpointNumber(block.number),
|
|
175
|
+
checkpointNumber: CheckpointNumber.fromBlockNumber(block.number),
|
|
189
176
|
block,
|
|
190
177
|
l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
|
|
191
178
|
attestations: []
|
|
192
179
|
}));
|
|
193
180
|
}
|
|
194
|
-
async
|
|
181
|
+
async getL2BlockByHash(blockHash) {
|
|
195
182
|
for (const block of this.l2Blocks){
|
|
196
183
|
const hash = await block.hash();
|
|
197
184
|
if (hash.equals(blockHash)) {
|
|
@@ -200,7 +187,7 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
|
200
187
|
}
|
|
201
188
|
return undefined;
|
|
202
189
|
}
|
|
203
|
-
|
|
190
|
+
getL2BlockByArchive(archive) {
|
|
204
191
|
const block = this.l2Blocks.find((b)=>b.archive.root.equals(archive));
|
|
205
192
|
return Promise.resolve(block);
|
|
206
193
|
}
|
|
@@ -230,7 +217,7 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
|
230
217
|
const slot = b.header.globalVariables.slotNumber;
|
|
231
218
|
return slot >= start && slot <= end;
|
|
232
219
|
});
|
|
233
|
-
// Create checkpoints from blocks - manually construct since
|
|
220
|
+
// Create checkpoints from blocks - manually construct since L2Block doesn't have toCheckpoint()
|
|
234
221
|
return Promise.all(blocks.map(async (block)=>{
|
|
235
222
|
const checkpoint = await Checkpoint.random(block.checkpointNumber, {
|
|
236
223
|
numBlocks: 1
|
|
@@ -241,7 +228,7 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
|
241
228
|
return checkpoint;
|
|
242
229
|
}));
|
|
243
230
|
}
|
|
244
|
-
|
|
231
|
+
getCheckpointedBlocksForEpoch(epochNumber) {
|
|
245
232
|
const epochDuration = DefaultL1ContractsConfig.aztecEpochDuration;
|
|
246
233
|
const [start, end] = getSlotRangeForEpoch(epochNumber, {
|
|
247
234
|
epochDuration
|
|
@@ -250,15 +237,20 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
|
250
237
|
const slot = b.header.globalVariables.slotNumber;
|
|
251
238
|
return slot >= start && slot <= end;
|
|
252
239
|
});
|
|
253
|
-
return Promise.resolve(blocks)
|
|
240
|
+
return Promise.resolve(blocks.map((block)=>CheckpointedL2Block.fromFields({
|
|
241
|
+
checkpointNumber: CheckpointNumber.fromBlockNumber(block.number),
|
|
242
|
+
block,
|
|
243
|
+
l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
|
|
244
|
+
attestations: []
|
|
245
|
+
})));
|
|
254
246
|
}
|
|
255
247
|
getBlocksForSlot(slotNumber) {
|
|
256
248
|
const blocks = this.l2Blocks.filter((b)=>b.header.globalVariables.slotNumber === slotNumber);
|
|
257
249
|
return Promise.resolve(blocks);
|
|
258
250
|
}
|
|
259
|
-
async
|
|
260
|
-
const
|
|
261
|
-
return
|
|
251
|
+
async getCheckpointedBlockHeadersForEpoch(epochNumber) {
|
|
252
|
+
const checkpointedBlocks = await this.getCheckpointedBlocksForEpoch(epochNumber);
|
|
253
|
+
return checkpointedBlocks.map((b)=>b.block.header);
|
|
262
254
|
}
|
|
263
255
|
/**
|
|
264
256
|
* Gets a tx effect.
|
|
@@ -325,7 +317,7 @@ import { TxExecutionResult, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
|
325
317
|
const makeTipId = (blockId)=>({
|
|
326
318
|
block: blockId,
|
|
327
319
|
checkpoint: {
|
|
328
|
-
number: CheckpointNumber(blockId.number),
|
|
320
|
+
number: CheckpointNumber.fromBlockNumber(blockId.number),
|
|
329
321
|
hash: blockId.hash
|
|
330
322
|
}
|
|
331
323
|
});
|
|
@@ -6,7 +6,7 @@ import { times, timesParallel } from '@aztec/foundation/collection';
|
|
|
6
6
|
import { randomBigInt, randomInt } from '@aztec/foundation/crypto/random';
|
|
7
7
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
8
8
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
9
|
-
import { CommitteeAttestation,
|
|
9
|
+
import { CommitteeAttestation, L2Block } from '@aztec/stdlib/block';
|
|
10
10
|
import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
11
11
|
import { PrivateLog, PublicLog, SiloedTag, Tag } from '@aztec/stdlib/logs';
|
|
12
12
|
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
@@ -147,8 +147,8 @@ export function makeInboxMessages(count, opts = {}) {
|
|
|
147
147
|
}
|
|
148
148
|
/** Creates a checkpoint with specified logs on each tx effect. */ export async function makeCheckpointWithLogs(blockNumber, options = {}) {
|
|
149
149
|
const { previousArchive, numTxsPerBlock = 4, privateLogs, publicLogs } = options;
|
|
150
|
-
const block = await
|
|
151
|
-
checkpointNumber: CheckpointNumber(blockNumber),
|
|
150
|
+
const block = await L2Block.random(BlockNumber(blockNumber), {
|
|
151
|
+
checkpointNumber: CheckpointNumber.fromBlockNumber(BlockNumber(blockNumber)),
|
|
152
152
|
indexWithinCheckpoint: IndexWithinCheckpoint(0),
|
|
153
153
|
state: makeStateForBlock(blockNumber, numTxsPerBlock),
|
|
154
154
|
...previousArchive ? {
|
|
@@ -164,6 +164,6 @@ export function makeInboxMessages(count, opts = {}) {
|
|
|
164
164
|
});
|
|
165
165
|
const checkpoint = new Checkpoint(AppendOnlyTreeSnapshot.random(), CheckpointHeader.random(), [
|
|
166
166
|
block
|
|
167
|
-
], CheckpointNumber(blockNumber));
|
|
167
|
+
], CheckpointNumber.fromBlockNumber(BlockNumber(blockNumber)));
|
|
168
168
|
return makePublishedCheckpoint(checkpoint, blockNumber);
|
|
169
169
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/archiver",
|
|
3
|
-
"version": "4.0.0-nightly.
|
|
3
|
+
"version": "4.0.0-nightly.20260124",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -64,18 +64,18 @@
|
|
|
64
64
|
]
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@aztec/blob-client": "4.0.0-nightly.
|
|
68
|
-
"@aztec/blob-lib": "4.0.0-nightly.
|
|
69
|
-
"@aztec/constants": "4.0.0-nightly.
|
|
70
|
-
"@aztec/epoch-cache": "4.0.0-nightly.
|
|
71
|
-
"@aztec/ethereum": "4.0.0-nightly.
|
|
72
|
-
"@aztec/foundation": "4.0.0-nightly.
|
|
73
|
-
"@aztec/kv-store": "4.0.0-nightly.
|
|
74
|
-
"@aztec/l1-artifacts": "4.0.0-nightly.
|
|
75
|
-
"@aztec/noir-protocol-circuits-types": "4.0.0-nightly.
|
|
76
|
-
"@aztec/protocol-contracts": "4.0.0-nightly.
|
|
77
|
-
"@aztec/stdlib": "4.0.0-nightly.
|
|
78
|
-
"@aztec/telemetry-client": "4.0.0-nightly.
|
|
67
|
+
"@aztec/blob-client": "4.0.0-nightly.20260124",
|
|
68
|
+
"@aztec/blob-lib": "4.0.0-nightly.20260124",
|
|
69
|
+
"@aztec/constants": "4.0.0-nightly.20260124",
|
|
70
|
+
"@aztec/epoch-cache": "4.0.0-nightly.20260124",
|
|
71
|
+
"@aztec/ethereum": "4.0.0-nightly.20260124",
|
|
72
|
+
"@aztec/foundation": "4.0.0-nightly.20260124",
|
|
73
|
+
"@aztec/kv-store": "4.0.0-nightly.20260124",
|
|
74
|
+
"@aztec/l1-artifacts": "4.0.0-nightly.20260124",
|
|
75
|
+
"@aztec/noir-protocol-circuits-types": "4.0.0-nightly.20260124",
|
|
76
|
+
"@aztec/protocol-contracts": "4.0.0-nightly.20260124",
|
|
77
|
+
"@aztec/stdlib": "4.0.0-nightly.20260124",
|
|
78
|
+
"@aztec/telemetry-client": "4.0.0-nightly.20260124",
|
|
79
79
|
"lodash.groupby": "^4.6.0",
|
|
80
80
|
"lodash.omit": "^4.5.0",
|
|
81
81
|
"tslib": "^2.5.0",
|
package/src/archiver.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
type ArchiverEmitter,
|
|
18
18
|
type CheckpointId,
|
|
19
19
|
GENESIS_CHECKPOINT_HEADER_HASH,
|
|
20
|
-
|
|
20
|
+
L2Block,
|
|
21
21
|
type L2BlockSink,
|
|
22
22
|
type L2Tips,
|
|
23
23
|
type ValidateCheckpointResult,
|
|
@@ -46,7 +46,7 @@ export type { ArchiverEmitter };
|
|
|
46
46
|
|
|
47
47
|
/** Request to add a block to the archiver, queued for processing by the sync loop. */
|
|
48
48
|
type AddBlockRequest = {
|
|
49
|
-
block:
|
|
49
|
+
block: L2Block;
|
|
50
50
|
resolve: () => void;
|
|
51
51
|
reject: (err: Error) => void;
|
|
52
52
|
};
|
|
@@ -187,7 +187,7 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
187
187
|
* @param block - The L2 block to add.
|
|
188
188
|
* @returns A promise that resolves when the block has been added to the store, or rejects on error.
|
|
189
189
|
*/
|
|
190
|
-
public addBlock(block:
|
|
190
|
+
public addBlock(block: L2Block): Promise<void> {
|
|
191
191
|
return new Promise<void>((resolve, reject) => {
|
|
192
192
|
this.blockQueue.push({ block, resolve, reject });
|
|
193
193
|
this.log.debug(`Queued block ${block.number} for processing`);
|
|
@@ -323,8 +323,11 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
323
323
|
}
|
|
324
324
|
|
|
325
325
|
public async isEpochComplete(epochNumber: EpochNumber): Promise<boolean> {
|
|
326
|
-
// The epoch is complete if the current L2 block is the last one in the epoch (or later)
|
|
327
|
-
|
|
326
|
+
// The epoch is complete if the current checkpointed L2 block is the last one in the epoch (or later).
|
|
327
|
+
// We use the checkpointed block number (synced from L1) instead of 'latest' to avoid returning true
|
|
328
|
+
// prematurely when proposed blocks have been pushed to the archiver but not yet checkpointed on L1.
|
|
329
|
+
const checkpointedBlockNumber = await this.getCheckpointedL2BlockNumber();
|
|
330
|
+
const header = checkpointedBlockNumber > 0 ? await this.getBlockHeader(checkpointedBlockNumber) : undefined;
|
|
328
331
|
const slot = header ? header.globalVariables.slotNumber : undefined;
|
|
329
332
|
const [_startSlot, endSlot] = getSlotRangeForEpoch(epochNumber, this.l1Constants);
|
|
330
333
|
if (slot && slot >= endSlot) {
|
|
@@ -421,14 +424,12 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
421
424
|
// Now attempt to retrieve checkpoints for proven, finalised and checkpointed blocks
|
|
422
425
|
const [[provenBlockCheckpoint], [finalizedBlockCheckpoint], [checkpointedBlockCheckpoint]] = await Promise.all([
|
|
423
426
|
provenCheckpointedBlock !== undefined
|
|
424
|
-
? await this.
|
|
427
|
+
? await this.getCheckpoints(provenCheckpointedBlock?.checkpointNumber, 1)
|
|
425
428
|
: [undefined],
|
|
426
429
|
finalizedCheckpointedBlock !== undefined
|
|
427
|
-
? await this.
|
|
428
|
-
: [undefined],
|
|
429
|
-
checkpointedBlock !== undefined
|
|
430
|
-
? await this.getPublishedCheckpoints(checkpointedBlock?.checkpointNumber, 1)
|
|
430
|
+
? await this.getCheckpoints(finalizedCheckpointedBlock?.checkpointNumber, 1)
|
|
431
431
|
: [undefined],
|
|
432
|
+
checkpointedBlock !== undefined ? await this.getCheckpoints(checkpointedBlock?.checkpointNumber, 1) : [undefined],
|
|
432
433
|
]);
|
|
433
434
|
|
|
434
435
|
const initialcheckpointId: CheckpointId = {
|
|
@@ -502,7 +503,7 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
502
503
|
}
|
|
503
504
|
const targetL1BlockHash = Buffer32.fromString(targetL1Block.hash);
|
|
504
505
|
this.log.info(`Unwinding ${blocksToUnwind} checkpoints from L2 block ${currentL2Block}`);
|
|
505
|
-
await this.updater.unwindCheckpoints(CheckpointNumber(currentL2Block), blocksToUnwind);
|
|
506
|
+
await this.updater.unwindCheckpoints(CheckpointNumber.fromBlockNumber(currentL2Block), blocksToUnwind);
|
|
506
507
|
this.log.info(`Unwinding L1 to L2 messages to checkpoint ${targetCheckpointNumber}`);
|
|
507
508
|
await this.store.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
|
|
508
509
|
this.log.info(`Setting L1 syncpoints to ${targetL1BlockNumber}`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import type { ViemPublicClient, ViemPublicDebugClient } from '@aztec/ethereum/types';
|
|
3
|
-
import { CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
4
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
6
|
|
|
@@ -142,7 +142,12 @@ async function main() {
|
|
|
142
142
|
logger.info('');
|
|
143
143
|
|
|
144
144
|
// For this script, we don't have blob hashes or expected hashes, so pass empty arrays/objects
|
|
145
|
-
const result = await retriever.getCheckpointFromRollupTx(
|
|
145
|
+
const result = await retriever.getCheckpointFromRollupTx(
|
|
146
|
+
txHash,
|
|
147
|
+
[],
|
|
148
|
+
CheckpointNumber.fromBlockNumber(BlockNumber(l2BlockNumber)),
|
|
149
|
+
{},
|
|
150
|
+
);
|
|
146
151
|
|
|
147
152
|
logger.info(' Successfully retrieved block header!');
|
|
148
153
|
logger.info('');
|
package/src/l1/data_retrieval.ts
CHANGED
|
@@ -20,7 +20,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
|
|
|
20
20
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
21
21
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
22
22
|
import { RollupAbi } from '@aztec/l1-artifacts';
|
|
23
|
-
import { Body, CommitteeAttestation,
|
|
23
|
+
import { Body, CommitteeAttestation, L2Block } from '@aztec/stdlib/block';
|
|
24
24
|
import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
25
25
|
import { Proof } from '@aztec/stdlib/proofs';
|
|
26
26
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
@@ -69,7 +69,7 @@ export async function retrievedToPublishedCheckpoint({
|
|
|
69
69
|
const l1toL2MessageTreeRoot = blocksBlobData[0].l1ToL2MessageRoot!;
|
|
70
70
|
|
|
71
71
|
const spongeBlob = SpongeBlob.init();
|
|
72
|
-
const l2Blocks:
|
|
72
|
+
const l2Blocks: L2Block[] = [];
|
|
73
73
|
for (let i = 0; i < blocksBlobData.length; i++) {
|
|
74
74
|
const blockBlobData = blocksBlobData[i];
|
|
75
75
|
const { blockEndMarker, blockEndStateField, lastArchiveRoot, noteHashRoot, nullifierRoot, publicDataRoot } =
|
|
@@ -119,7 +119,7 @@ export async function retrievedToPublishedCheckpoint({
|
|
|
119
119
|
|
|
120
120
|
const newArchive = new AppendOnlyTreeSnapshot(newArchiveRoots[i], l2BlockNumber + 1);
|
|
121
121
|
|
|
122
|
-
l2Blocks.push(new
|
|
122
|
+
l2Blocks.push(new L2Block(newArchive, header, body, checkpointNumber, IndexWithinCheckpoint(i)));
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
const lastBlock = l2Blocks.at(-1)!;
|
|
@@ -4,7 +4,7 @@ import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
4
4
|
import { isDefined } from '@aztec/foundation/types';
|
|
5
5
|
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
6
6
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
7
|
-
import { CheckpointedL2Block, CommitteeAttestation,
|
|
7
|
+
import { CheckpointedL2Block, CommitteeAttestation, L2Block, type L2Tips } from '@aztec/stdlib/block';
|
|
8
8
|
import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
9
9
|
import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
10
10
|
import { type L1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
@@ -117,18 +117,8 @@ export abstract class ArchiverDataSourceBase
|
|
|
117
117
|
return BlockNumber(checkpointData.startBlock + checkpointData.numBlocks - 1);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
public
|
|
121
|
-
from
|
|
122
|
-
limit: number,
|
|
123
|
-
proven?: boolean,
|
|
124
|
-
): Promise<CheckpointedL2Block[]> {
|
|
125
|
-
const blocks = await this.store.getCheckpointedBlocks(from, limit);
|
|
126
|
-
|
|
127
|
-
if (proven === true) {
|
|
128
|
-
const provenBlockNumber = await this.store.getProvenBlockNumber();
|
|
129
|
-
return blocks.filter(b => b.block.number <= provenBlockNumber);
|
|
130
|
-
}
|
|
131
|
-
return blocks;
|
|
120
|
+
public getCheckpointedBlocks(from: BlockNumber, limit: number): Promise<CheckpointedL2Block[]> {
|
|
121
|
+
return this.store.getCheckpointedBlocks(from, limit);
|
|
132
122
|
}
|
|
133
123
|
|
|
134
124
|
public getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
|
|
@@ -139,7 +129,7 @@ export abstract class ArchiverDataSourceBase
|
|
|
139
129
|
return this.store.getBlockHeaderByArchive(archive);
|
|
140
130
|
}
|
|
141
131
|
|
|
142
|
-
public async
|
|
132
|
+
public async getL2Block(number: BlockNumber): Promise<L2Block | undefined> {
|
|
143
133
|
// If the number provided is -ve, then return the latest block.
|
|
144
134
|
if (number < 0) {
|
|
145
135
|
number = await this.store.getLatestBlockNumber();
|
|
@@ -167,16 +157,6 @@ export abstract class ArchiverDataSourceBase
|
|
|
167
157
|
return (await this.store.getPendingChainValidationStatus()) ?? { valid: true };
|
|
168
158
|
}
|
|
169
159
|
|
|
170
|
-
public async getL2BlocksNew(from: BlockNumber, limit: number, proven?: boolean): Promise<L2BlockNew[]> {
|
|
171
|
-
const blocks = await this.store.getBlocks(from, limit);
|
|
172
|
-
|
|
173
|
-
if (proven === true) {
|
|
174
|
-
const provenBlockNumber = await this.store.getProvenBlockNumber();
|
|
175
|
-
return blocks.filter(b => b.number <= provenBlockNumber);
|
|
176
|
-
}
|
|
177
|
-
return blocks;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
160
|
public getPrivateLogsByTags(tags: SiloedTag[], page?: number): Promise<TxScopedL2Log[][]> {
|
|
181
161
|
return this.store.getPrivateLogsByTags(tags, page);
|
|
182
162
|
}
|
|
@@ -241,10 +221,7 @@ export abstract class ArchiverDataSourceBase
|
|
|
241
221
|
return this.store.getL1ToL2MessageIndex(l1ToL2Message);
|
|
242
222
|
}
|
|
243
223
|
|
|
244
|
-
public async
|
|
245
|
-
checkpointNumber: CheckpointNumber,
|
|
246
|
-
limit: number,
|
|
247
|
-
): Promise<PublishedCheckpoint[]> {
|
|
224
|
+
public async getCheckpoints(checkpointNumber: CheckpointNumber, limit: number): Promise<PublishedCheckpoint[]> {
|
|
248
225
|
const checkpoints = await this.store.getRangeOfCheckpoints(checkpointNumber, limit);
|
|
249
226
|
const blocks = (
|
|
250
227
|
await Promise.all(checkpoints.map(ch => this.store.getBlocksForCheckpoint(ch.checkpointNumber)))
|
|
@@ -270,17 +247,17 @@ export abstract class ArchiverDataSourceBase
|
|
|
270
247
|
return fullCheckpoints;
|
|
271
248
|
}
|
|
272
249
|
|
|
273
|
-
public getBlocksForSlot(slotNumber: SlotNumber): Promise<
|
|
250
|
+
public getBlocksForSlot(slotNumber: SlotNumber): Promise<L2Block[]> {
|
|
274
251
|
return this.store.getBlocksForSlot(slotNumber);
|
|
275
252
|
}
|
|
276
253
|
|
|
277
|
-
public async
|
|
254
|
+
public async getCheckpointedBlocksForEpoch(epochNumber: EpochNumber): Promise<CheckpointedL2Block[]> {
|
|
278
255
|
if (!this.l1Constants) {
|
|
279
256
|
throw new Error('L1 constants not set');
|
|
280
257
|
}
|
|
281
258
|
|
|
282
259
|
const [start, end] = getSlotRangeForEpoch(epochNumber, this.l1Constants);
|
|
283
|
-
const blocks:
|
|
260
|
+
const blocks: CheckpointedL2Block[] = [];
|
|
284
261
|
|
|
285
262
|
// Walk the list of checkpoints backwards and filter by slots matching the requested epoch.
|
|
286
263
|
// We'll typically ask for checkpoints for a very recent epoch, so we shouldn't need an index here.
|
|
@@ -291,9 +268,9 @@ export abstract class ArchiverDataSourceBase
|
|
|
291
268
|
// push the blocks on backwards
|
|
292
269
|
const endBlock = checkpoint.startBlock + checkpoint.numBlocks - 1;
|
|
293
270
|
for (let i = endBlock; i >= checkpoint.startBlock; i--) {
|
|
294
|
-
const
|
|
295
|
-
if (
|
|
296
|
-
blocks.push(
|
|
271
|
+
const checkpointedBlock = await this.getCheckpointedBlock(BlockNumber(i));
|
|
272
|
+
if (checkpointedBlock) {
|
|
273
|
+
blocks.push(checkpointedBlock);
|
|
297
274
|
}
|
|
298
275
|
}
|
|
299
276
|
}
|
|
@@ -303,7 +280,7 @@ export abstract class ArchiverDataSourceBase
|
|
|
303
280
|
return blocks.reverse();
|
|
304
281
|
}
|
|
305
282
|
|
|
306
|
-
public async
|
|
283
|
+
public async getCheckpointedBlockHeadersForEpoch(epochNumber: EpochNumber): Promise<BlockHeader[]> {
|
|
307
284
|
if (!this.l1Constants) {
|
|
308
285
|
throw new Error('L1 constants not set');
|
|
309
286
|
}
|
|
@@ -346,7 +323,7 @@ export abstract class ArchiverDataSourceBase
|
|
|
346
323
|
while (checkpointData && slot(checkpointData) >= start) {
|
|
347
324
|
if (slot(checkpointData) <= end) {
|
|
348
325
|
// push the checkpoints on backwards
|
|
349
|
-
const [checkpoint] = await this.
|
|
326
|
+
const [checkpoint] = await this.getCheckpoints(checkpointData.checkpointNumber, 1);
|
|
350
327
|
checkpoints.push(checkpoint.checkpoint);
|
|
351
328
|
}
|
|
352
329
|
checkpointData = await this.store.getCheckpointData(CheckpointNumber(checkpointData.checkpointNumber - 1));
|
|
@@ -355,33 +332,7 @@ export abstract class ArchiverDataSourceBase
|
|
|
355
332
|
return checkpoints.reverse();
|
|
356
333
|
}
|
|
357
334
|
|
|
358
|
-
public async
|
|
359
|
-
const checkpoints = await this.store.getRangeOfCheckpoints(CheckpointNumber(from), limit);
|
|
360
|
-
const provenCheckpointNumber = await this.store.getProvenCheckpointNumber();
|
|
361
|
-
const blocks = (
|
|
362
|
-
await Promise.all(checkpoints.map(ch => this.store.getBlocksForCheckpoint(ch.checkpointNumber)))
|
|
363
|
-
).filter(isDefined);
|
|
364
|
-
|
|
365
|
-
const publishedBlocks: CheckpointedL2Block[] = [];
|
|
366
|
-
for (let i = 0; i < checkpoints.length; i++) {
|
|
367
|
-
const blockForCheckpoint = blocks[i][0];
|
|
368
|
-
const checkpoint = checkpoints[i];
|
|
369
|
-
if (checkpoint.checkpointNumber > provenCheckpointNumber && proven === true) {
|
|
370
|
-
// this checkpoint isn't proven and we only want proven
|
|
371
|
-
continue;
|
|
372
|
-
}
|
|
373
|
-
const publishedBlock = new CheckpointedL2Block(
|
|
374
|
-
checkpoint.checkpointNumber,
|
|
375
|
-
blockForCheckpoint,
|
|
376
|
-
checkpoint.l1,
|
|
377
|
-
checkpoint.attestations.map(x => CommitteeAttestation.fromBuffer(x)),
|
|
378
|
-
);
|
|
379
|
-
publishedBlocks.push(publishedBlock);
|
|
380
|
-
}
|
|
381
|
-
return publishedBlocks;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
public async getBlock(number: BlockNumber): Promise<L2BlockNew | undefined> {
|
|
335
|
+
public async getBlock(number: BlockNumber): Promise<L2Block | undefined> {
|
|
385
336
|
// If the number provided is -ve, then return the latest block.
|
|
386
337
|
if (number < 0) {
|
|
387
338
|
number = await this.store.getLatestBlockNumber();
|
|
@@ -392,30 +343,24 @@ export abstract class ArchiverDataSourceBase
|
|
|
392
343
|
return this.store.getBlock(number);
|
|
393
344
|
}
|
|
394
345
|
|
|
395
|
-
public
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
if (proven === true) {
|
|
399
|
-
const provenBlockNumber = await this.store.getProvenBlockNumber();
|
|
400
|
-
return blocks.filter(b => b.number <= provenBlockNumber);
|
|
401
|
-
}
|
|
402
|
-
return blocks;
|
|
346
|
+
public getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
|
|
347
|
+
return this.store.getBlocks(from, limit);
|
|
403
348
|
}
|
|
404
349
|
|
|
405
|
-
public
|
|
350
|
+
public getCheckpointedBlockByHash(blockHash: Fr): Promise<CheckpointedL2Block | undefined> {
|
|
406
351
|
return this.store.getCheckpointedBlockByHash(blockHash);
|
|
407
352
|
}
|
|
408
353
|
|
|
409
|
-
public
|
|
354
|
+
public getCheckpointedBlockByArchive(archive: Fr): Promise<CheckpointedL2Block | undefined> {
|
|
410
355
|
return this.store.getCheckpointedBlockByArchive(archive);
|
|
411
356
|
}
|
|
412
357
|
|
|
413
|
-
public async
|
|
358
|
+
public async getL2BlockByHash(blockHash: Fr): Promise<L2Block | undefined> {
|
|
414
359
|
const checkpointedBlock = await this.store.getCheckpointedBlockByHash(blockHash);
|
|
415
360
|
return checkpointedBlock?.block;
|
|
416
361
|
}
|
|
417
362
|
|
|
418
|
-
public async
|
|
363
|
+
public async getL2BlockByArchive(archive: Fr): Promise<L2Block | undefined> {
|
|
419
364
|
const checkpointedBlock = await this.store.getCheckpointedBlockByArchive(archive);
|
|
420
365
|
return checkpointedBlock?.block;
|
|
421
366
|
}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
ContractInstancePublishedEvent,
|
|
11
11
|
ContractInstanceUpdatedEvent,
|
|
12
12
|
} from '@aztec/protocol-contracts/instance-registry';
|
|
13
|
-
import type {
|
|
13
|
+
import type { L2Block, ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
14
14
|
import type { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
15
15
|
import {
|
|
16
16
|
type ExecutablePrivateFunctionWithMembershipProof,
|
|
@@ -35,7 +35,7 @@ enum Operation {
|
|
|
35
35
|
/** Result of adding checkpoints with information about any pruned blocks. */
|
|
36
36
|
type ReconcileCheckpointsResult = {
|
|
37
37
|
/** Blocks that were pruned due to conflict with L1 checkpoints. */
|
|
38
|
-
prunedBlocks:
|
|
38
|
+
prunedBlocks: L2Block[] | undefined;
|
|
39
39
|
/** Last block number that was already inserted locally, or undefined if none. */
|
|
40
40
|
lastAlreadyInsertedBlockNumber: BlockNumber | undefined;
|
|
41
41
|
};
|
|
@@ -55,7 +55,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
55
55
|
* @param pendingChainValidationStatus - Optional validation status to set.
|
|
56
56
|
* @returns True if the operation is successful.
|
|
57
57
|
*/
|
|
58
|
-
public addBlocks(blocks:
|
|
58
|
+
public addBlocks(blocks: L2Block[], pendingChainValidationStatus?: ValidateCheckpointResult): Promise<boolean> {
|
|
59
59
|
return this.store.transactionAsync(async () => {
|
|
60
60
|
await this.store.addBlocks(blocks);
|
|
61
61
|
|
|
@@ -191,7 +191,7 @@ export class ArchiverDataStoreUpdater {
|
|
|
191
191
|
* @param blockNumber - Remove all blocks with number greater than this.
|
|
192
192
|
* @returns The removed blocks.
|
|
193
193
|
*/
|
|
194
|
-
public removeBlocksAfter(blockNumber: BlockNumber): Promise<
|
|
194
|
+
public removeBlocksAfter(blockNumber: BlockNumber): Promise<L2Block[]> {
|
|
195
195
|
return this.store.transactionAsync(async () => {
|
|
196
196
|
// First get the blocks to be removed so we can clean up contract data
|
|
197
197
|
const removedBlocks = await this.store.removeBlocksAfter(blockNumber);
|
|
@@ -248,17 +248,17 @@ export class ArchiverDataStoreUpdater {
|
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
/** Extracts and stores contract data from a single block. */
|
|
251
|
-
private addBlockDataToDB(block:
|
|
251
|
+
private addBlockDataToDB(block: L2Block): Promise<boolean> {
|
|
252
252
|
return this.editContractBlockData(block, Operation.Store);
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
/** Removes contract data associated with a block. */
|
|
256
|
-
private removeBlockDataFromDB(block:
|
|
256
|
+
private removeBlockDataFromDB(block: L2Block): Promise<boolean> {
|
|
257
257
|
return this.editContractBlockData(block, Operation.Delete);
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
/** Adds or remove contract data associated with a block. */
|
|
261
|
-
private async editContractBlockData(block:
|
|
261
|
+
private async editContractBlockData(block: L2Block, operation: Operation): Promise<boolean> {
|
|
262
262
|
const contractClassLogs = block.body.txEffects.flatMap(txEffect => txEffect.contractClassLogs);
|
|
263
263
|
const privateLogs = block.body.txEffects.flatMap(txEffect => txEffect.privateLogs);
|
|
264
264
|
const publicLogs = block.body.txEffects.flatMap(txEffect => txEffect.publicLogs);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
-
import type {
|
|
2
|
+
import type { L2Block } from '@aztec/stdlib/block';
|
|
3
3
|
import {
|
|
4
4
|
Attributes,
|
|
5
5
|
type Gauge,
|
|
@@ -97,7 +97,7 @@ export class ArchiverInstrumentation {
|
|
|
97
97
|
return this.telemetry.isEnabled();
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
public processNewBlocks(syncTimePerBlock: number, blocks:
|
|
100
|
+
public processNewBlocks(syncTimePerBlock: number, blocks: L2Block[]) {
|
|
101
101
|
this.syncDurationPerBlock.record(Math.ceil(syncTimePerBlock));
|
|
102
102
|
this.blockHeight.record(Math.max(...blocks.map(b => b.number)));
|
|
103
103
|
this.syncBlockCount.add(blocks.length);
|