@aztec/archiver 0.55.1 → 0.57.0
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 +27 -25
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +391 -169
- package/dest/archiver/archiver_store.d.ts +47 -23
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +75 -42
- package/dest/archiver/config.js +6 -6
- package/dest/archiver/data_retrieval.d.ts +32 -5
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +126 -16
- package/dest/archiver/epoch_helpers.d.ts +15 -0
- package/dest/archiver/epoch_helpers.d.ts.map +1 -0
- package/dest/archiver/epoch_helpers.js +23 -0
- package/dest/archiver/kv_archiver_store/block_store.d.ts +22 -3
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +75 -12
- 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 +11 -4
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +1 -0
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.js +4 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +31 -23
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +65 -38
- package/dest/archiver/kv_archiver_store/log_store.d.ts +4 -5
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +18 -14
- package/dest/archiver/kv_archiver_store/message_store.d.ts +2 -0
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +18 -8
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +1 -0
- 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 +4 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +23 -39
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +132 -91
- package/dest/index.d.ts +0 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -2
- package/dest/test/index.d.ts +2 -0
- package/dest/test/index.d.ts.map +1 -0
- package/dest/test/index.js +2 -0
- package/dest/test/mock_l2_block_source.d.ts +73 -0
- package/dest/test/mock_l2_block_source.d.ts.map +1 -0
- package/dest/test/mock_l2_block_source.js +134 -0
- package/package.json +15 -11
- package/src/archiver/archiver.ts +531 -248
- package/src/archiver/archiver_store.ts +53 -31
- package/src/archiver/archiver_store_test_suite.ts +93 -81
- package/src/archiver/config.ts +5 -5
- package/src/archiver/data_retrieval.ts +189 -30
- package/src/archiver/epoch_helpers.ts +26 -0
- package/src/archiver/kv_archiver_store/block_store.ts +87 -12
- package/src/archiver/kv_archiver_store/contract_class_store.ts +18 -5
- package/src/archiver/kv_archiver_store/contract_instance_store.ts +4 -0
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +74 -47
- package/src/archiver/kv_archiver_store/log_store.ts +18 -18
- package/src/archiver/kv_archiver_store/message_store.ts +18 -5
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +4 -0
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +155 -108
- package/src/index.ts +1 -2
- package/src/test/index.ts +1 -0
- package/src/test/mock_l2_block_source.ts +165 -0
- package/dest/archiver/eth_log_handlers.d.ts +0 -59
- package/dest/archiver/eth_log_handlers.d.ts.map +0 -1
- package/dest/archiver/eth_log_handlers.js +0 -155
- package/dest/archiver/kv_archiver_store/block_body_store.d.ts +0 -34
- package/dest/archiver/kv_archiver_store/block_body_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/block_body_store.js +0 -65
- package/dest/archiver/kv_archiver_store/proven_store.d.ts +0 -14
- package/dest/archiver/kv_archiver_store/proven_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/proven_store.js +0 -30
- package/src/archiver/eth_log_handlers.ts +0 -213
- package/src/archiver/kv_archiver_store/block_body_store.ts +0 -74
- package/src/archiver/kv_archiver_store/proven_store.ts +0 -34
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type Body,
|
|
3
2
|
type EncryptedL2BlockL2Logs,
|
|
4
3
|
type EncryptedNoteL2BlockL2Logs,
|
|
5
4
|
ExtendedUnencryptedL2Log,
|
|
@@ -16,18 +15,19 @@ import {
|
|
|
16
15
|
TxReceipt,
|
|
17
16
|
type UnencryptedL2BlockL2Logs,
|
|
18
17
|
} from '@aztec/circuit-types';
|
|
19
|
-
import { Fr, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
|
|
18
|
+
import { Fr, type Header, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
|
|
20
19
|
import { type ContractArtifact } from '@aztec/foundation/abi';
|
|
21
20
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
22
21
|
import {
|
|
23
22
|
type ContractClassPublic,
|
|
23
|
+
type ContractClassPublicWithBlockNumber,
|
|
24
24
|
type ContractInstanceWithAddress,
|
|
25
25
|
type ExecutablePrivateFunctionWithMembershipProof,
|
|
26
26
|
type UnconstrainedFunctionWithMembershipProof,
|
|
27
27
|
} from '@aztec/types/contracts';
|
|
28
28
|
|
|
29
29
|
import { type ArchiverDataStore, type ArchiverL1SynchPoint } from '../archiver_store.js';
|
|
30
|
-
import { type DataRetrieval
|
|
30
|
+
import { type DataRetrieval } from '../structs/data_retrieval.js';
|
|
31
31
|
import { type L1Published } from '../structs/published.js';
|
|
32
32
|
import { L1ToL2MessageStore } from './l1_to_l2_message_store.js';
|
|
33
33
|
|
|
@@ -40,33 +40,16 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
40
40
|
*/
|
|
41
41
|
private l2Blocks: L1Published<L2Block>[] = [];
|
|
42
42
|
|
|
43
|
-
/**
|
|
44
|
-
* A mapping of body hash to body
|
|
45
|
-
*/
|
|
46
|
-
private l2BlockBodies: Map<string, Body> = new Map();
|
|
47
|
-
|
|
48
43
|
/**
|
|
49
44
|
* An array containing all the tx effects in the L2 blocks that have been fetched so far.
|
|
50
45
|
*/
|
|
51
46
|
private txEffects: TxEffect[] = [];
|
|
52
47
|
|
|
53
|
-
|
|
54
|
-
* An array containing all the encrypted logs that have been fetched so far.
|
|
55
|
-
* Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM).
|
|
56
|
-
*/
|
|
57
|
-
private noteEncryptedLogsPerBlock: EncryptedNoteL2BlockL2Logs[] = [];
|
|
48
|
+
private noteEncryptedLogsPerBlock: Map<number, EncryptedNoteL2BlockL2Logs> = new Map();
|
|
58
49
|
|
|
59
|
-
|
|
60
|
-
* An array containing all the encrypted logs that have been fetched so far.
|
|
61
|
-
* Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM).
|
|
62
|
-
*/
|
|
63
|
-
private encryptedLogsPerBlock: EncryptedL2BlockL2Logs[] = [];
|
|
50
|
+
private encryptedLogsPerBlock: Map<number, EncryptedL2BlockL2Logs> = new Map();
|
|
64
51
|
|
|
65
|
-
|
|
66
|
-
* An array containing all the unencrypted logs that have been fetched so far.
|
|
67
|
-
* Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM).
|
|
68
|
-
*/
|
|
69
|
-
private unencryptedLogsPerBlock: UnencryptedL2BlockL2Logs[] = [];
|
|
52
|
+
private unencryptedLogsPerBlock: Map<number, UnencryptedL2BlockL2Logs> = new Map();
|
|
70
53
|
|
|
71
54
|
/**
|
|
72
55
|
* Contains all L1 to L2 messages.
|
|
@@ -75,7 +58,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
75
58
|
|
|
76
59
|
private contractArtifacts: Map<string, ContractArtifact> = new Map();
|
|
77
60
|
|
|
78
|
-
private contractClasses: Map<string,
|
|
61
|
+
private contractClasses: Map<string, ContractClassPublicWithBlockNumber> = new Map();
|
|
79
62
|
|
|
80
63
|
private privateFunctions: Map<string, ExecutablePrivateFunctionWithMembershipProof[]> = new Map();
|
|
81
64
|
|
|
@@ -84,11 +67,10 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
84
67
|
private contractInstances: Map<string, ContractInstanceWithAddress> = new Map();
|
|
85
68
|
|
|
86
69
|
private lastL1BlockNewBlocks: bigint | undefined = undefined;
|
|
87
|
-
private lastL1BlockNewBlockBodies: bigint | undefined = undefined;
|
|
88
70
|
private lastL1BlockNewMessages: bigint | undefined = undefined;
|
|
89
|
-
private lastL1BlockNewProvenLogs: bigint | undefined = undefined;
|
|
90
71
|
|
|
91
72
|
private lastProvenL2BlockNumber: number = 0;
|
|
73
|
+
private lastProvenL2EpochNumber: number = 0;
|
|
92
74
|
|
|
93
75
|
constructor(
|
|
94
76
|
/** The max number of logs that can be obtained in 1 "getUnencryptedLogs" call. */
|
|
@@ -136,9 +118,24 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
136
118
|
return Promise.resolve(true);
|
|
137
119
|
}
|
|
138
120
|
|
|
139
|
-
public addContractClasses(data: ContractClassPublic[],
|
|
121
|
+
public addContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
|
|
140
122
|
for (const contractClass of data) {
|
|
141
|
-
this.contractClasses.
|
|
123
|
+
if (!this.contractClasses.has(contractClass.id.toString())) {
|
|
124
|
+
this.contractClasses.set(contractClass.id.toString(), {
|
|
125
|
+
...contractClass,
|
|
126
|
+
l2BlockNumber: blockNumber,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return Promise.resolve(true);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public deleteContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
|
|
134
|
+
for (const contractClass of data) {
|
|
135
|
+
const restored = this.contractClasses.get(contractClass.id.toString());
|
|
136
|
+
if (restored && restored.l2BlockNumber >= blockNumber) {
|
|
137
|
+
this.contractClasses.delete(contractClass.id.toString());
|
|
138
|
+
}
|
|
142
139
|
}
|
|
143
140
|
return Promise.resolve(true);
|
|
144
141
|
}
|
|
@@ -150,6 +147,13 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
150
147
|
return Promise.resolve(true);
|
|
151
148
|
}
|
|
152
149
|
|
|
150
|
+
public deleteContractInstances(data: ContractInstanceWithAddress[], _blockNumber: number): Promise<boolean> {
|
|
151
|
+
for (const contractInstance of data) {
|
|
152
|
+
this.contractInstances.delete(contractInstance.address.toString());
|
|
153
|
+
}
|
|
154
|
+
return Promise.resolve(true);
|
|
155
|
+
}
|
|
156
|
+
|
|
153
157
|
/**
|
|
154
158
|
* Append new blocks to the store's list.
|
|
155
159
|
* @param blocks - The L2 blocks to be added to the store and the last processed L1 block.
|
|
@@ -163,62 +167,63 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
163
167
|
this.lastL1BlockNewBlocks = blocks[blocks.length - 1].l1.blockNumber;
|
|
164
168
|
this.l2Blocks.push(...blocks);
|
|
165
169
|
this.txEffects.push(...blocks.flatMap(b => b.data.body.txEffects));
|
|
170
|
+
|
|
166
171
|
return Promise.resolve(true);
|
|
167
172
|
}
|
|
168
173
|
|
|
169
174
|
/**
|
|
170
|
-
*
|
|
171
|
-
* @param
|
|
172
|
-
*
|
|
175
|
+
* Unwinds blocks from the database
|
|
176
|
+
* @param from - The tip of the chain, passed for verification purposes,
|
|
177
|
+
* ensuring that we don't end up deleting something we did not intend
|
|
178
|
+
* @param blocksToUnwind - The number of blocks we are to unwind
|
|
179
|
+
* @returns True if the operation is successful
|
|
173
180
|
*/
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
181
|
+
public async unwindBlocks(from: number, blocksToUnwind: number): Promise<boolean> {
|
|
182
|
+
const last = await this.getSynchedL2BlockNumber();
|
|
183
|
+
if (from != last) {
|
|
184
|
+
throw new Error(`Can only remove the tip`);
|
|
177
185
|
}
|
|
178
|
-
this.lastL1BlockNewBlockBodies = blockBodies.lastProcessedL1BlockNumber;
|
|
179
|
-
return Promise.resolve(true);
|
|
180
|
-
}
|
|
181
186
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
);
|
|
187
|
+
const stopAt = from - blocksToUnwind;
|
|
188
|
+
while ((await this.getSynchedL2BlockNumber()) > stopAt) {
|
|
189
|
+
const block = this.l2Blocks.pop();
|
|
190
|
+
if (block == undefined) {
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
block.data.body.txEffects.forEach(() => this.txEffects.pop());
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return Promise.resolve(true);
|
|
192
197
|
}
|
|
193
198
|
|
|
194
199
|
/**
|
|
195
200
|
* Append new logs to the store's list.
|
|
196
|
-
* @param
|
|
197
|
-
* @param unencryptedLogs - The unencrypted logs to be added to the store.
|
|
198
|
-
* @param blockNumber - The block for which to add the logs.
|
|
201
|
+
* @param block - The block for which to add the logs.
|
|
199
202
|
* @returns True if the operation is successful.
|
|
200
203
|
*/
|
|
201
|
-
addLogs(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
if (encryptedLogs) {
|
|
212
|
-
this.encryptedLogsPerBlock[blockNumber - INITIAL_L2_BLOCK_NUM] = encryptedLogs;
|
|
213
|
-
}
|
|
204
|
+
addLogs(blocks: L2Block[]): Promise<boolean> {
|
|
205
|
+
blocks.forEach(block => {
|
|
206
|
+
this.noteEncryptedLogsPerBlock.set(block.number, block.body.noteEncryptedLogs);
|
|
207
|
+
this.encryptedLogsPerBlock.set(block.number, block.body.encryptedLogs);
|
|
208
|
+
this.unencryptedLogsPerBlock.set(block.number, block.body.unencryptedLogs);
|
|
209
|
+
});
|
|
210
|
+
return Promise.resolve(true);
|
|
211
|
+
}
|
|
214
212
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
213
|
+
deleteLogs(blocks: L2Block[]): Promise<boolean> {
|
|
214
|
+
blocks.forEach(block => {
|
|
215
|
+
this.encryptedLogsPerBlock.delete(block.number);
|
|
216
|
+
this.noteEncryptedLogsPerBlock.delete(block.number);
|
|
217
|
+
this.unencryptedLogsPerBlock.delete(block.number);
|
|
218
|
+
});
|
|
218
219
|
|
|
219
220
|
return Promise.resolve(true);
|
|
220
221
|
}
|
|
221
222
|
|
|
223
|
+
getTotalL1ToL2MessageCount(): Promise<bigint> {
|
|
224
|
+
return Promise.resolve(this.l1ToL2Messages.getTotalL1ToL2MessageCount());
|
|
225
|
+
}
|
|
226
|
+
|
|
222
227
|
/**
|
|
223
228
|
* Append L1 to L2 messages to the store.
|
|
224
229
|
* @param messages - The L1 to L2 messages to be added to the store and the last processed L1 block.
|
|
@@ -257,12 +262,15 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
257
262
|
* @remarks When "from" is smaller than genesis block number, blocks from the beginning are returned.
|
|
258
263
|
*/
|
|
259
264
|
public getBlocks(from: number, limit: number): Promise<L1Published<L2Block>[]> {
|
|
260
|
-
// Return an empty array if we are outside of range
|
|
261
265
|
if (limit < 1) {
|
|
262
266
|
return Promise.reject(new Error(`Invalid limit: ${limit}`));
|
|
263
267
|
}
|
|
264
268
|
|
|
265
|
-
|
|
269
|
+
if (from < INITIAL_L2_BLOCK_NUM) {
|
|
270
|
+
return Promise.reject(new Error(`Invalid start: ${from}`));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const fromIndex = from - INITIAL_L2_BLOCK_NUM;
|
|
266
274
|
if (fromIndex >= this.l2Blocks.length) {
|
|
267
275
|
return Promise.resolve([]);
|
|
268
276
|
}
|
|
@@ -271,6 +279,11 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
271
279
|
return Promise.resolve(this.l2Blocks.slice(fromIndex, toIndex));
|
|
272
280
|
}
|
|
273
281
|
|
|
282
|
+
public async getBlockHeaders(from: number, limit: number): Promise<Header[]> {
|
|
283
|
+
const blocks = await this.getBlocks(from, limit);
|
|
284
|
+
return blocks.map(block => block.data.header);
|
|
285
|
+
}
|
|
286
|
+
|
|
274
287
|
/**
|
|
275
288
|
* Gets a tx effect.
|
|
276
289
|
* @param txHash - The txHash of the tx effect.
|
|
@@ -328,9 +341,14 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
328
341
|
logType: TLogType,
|
|
329
342
|
): Promise<L2BlockL2Logs<FromLogType<TLogType>>[]> {
|
|
330
343
|
if (from < INITIAL_L2_BLOCK_NUM || limit < 1) {
|
|
331
|
-
|
|
344
|
+
return Promise.resolve([]);
|
|
332
345
|
}
|
|
333
|
-
|
|
346
|
+
|
|
347
|
+
if (from > this.l2Blocks.length) {
|
|
348
|
+
return Promise.resolve([]);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const logMap = (() => {
|
|
334
352
|
switch (logType) {
|
|
335
353
|
case LogType.ENCRYPTED:
|
|
336
354
|
return this.encryptedLogsPerBlock;
|
|
@@ -340,14 +358,24 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
340
358
|
default:
|
|
341
359
|
return this.unencryptedLogsPerBlock;
|
|
342
360
|
}
|
|
343
|
-
})() as L2BlockL2Logs<FromLogType<TLogType
|
|
361
|
+
})() as Map<number, L2BlockL2Logs<FromLogType<TLogType>>>;
|
|
344
362
|
|
|
345
|
-
|
|
346
|
-
return Promise.resolve([]);
|
|
347
|
-
}
|
|
348
|
-
const startIndex = from - INITIAL_L2_BLOCK_NUM;
|
|
363
|
+
const startIndex = from;
|
|
349
364
|
const endIndex = startIndex + limit;
|
|
350
|
-
|
|
365
|
+
const upper = Math.min(endIndex, this.l2Blocks.length + INITIAL_L2_BLOCK_NUM);
|
|
366
|
+
|
|
367
|
+
const l = [];
|
|
368
|
+
for (let i = startIndex; i < upper; i++) {
|
|
369
|
+
const log = logMap.get(i);
|
|
370
|
+
if (log) {
|
|
371
|
+
l.push(log);
|
|
372
|
+
} else {
|
|
373
|
+
// I hate typescript sometimes
|
|
374
|
+
l.push(undefined as unknown as L2BlockL2Logs<FromLogType<TLogType>>);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return Promise.resolve(l);
|
|
351
379
|
}
|
|
352
380
|
|
|
353
381
|
/**
|
|
@@ -358,37 +386,37 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
358
386
|
*/
|
|
359
387
|
getUnencryptedLogs(filter: LogFilter): Promise<GetUnencryptedLogsResponse> {
|
|
360
388
|
let txHash: TxHash | undefined;
|
|
361
|
-
let
|
|
362
|
-
let
|
|
389
|
+
let fromBlock = 0;
|
|
390
|
+
let toBlock = this.l2Blocks.length + INITIAL_L2_BLOCK_NUM;
|
|
363
391
|
let txIndexInBlock = 0;
|
|
364
392
|
let logIndexInTx = 0;
|
|
365
393
|
|
|
366
394
|
if (filter.afterLog) {
|
|
367
395
|
// Continuation parameter is set --> tx hash is ignored
|
|
368
396
|
if (filter.fromBlock == undefined || filter.fromBlock <= filter.afterLog.blockNumber) {
|
|
369
|
-
|
|
397
|
+
fromBlock = filter.afterLog.blockNumber;
|
|
370
398
|
txIndexInBlock = filter.afterLog.txIndex;
|
|
371
399
|
logIndexInTx = filter.afterLog.logIndex + 1; // We want to start from the next log
|
|
372
400
|
} else {
|
|
373
|
-
|
|
401
|
+
fromBlock = filter.fromBlock;
|
|
374
402
|
}
|
|
375
403
|
} else {
|
|
376
404
|
txHash = filter.txHash;
|
|
377
405
|
|
|
378
406
|
if (filter.fromBlock !== undefined) {
|
|
379
|
-
|
|
407
|
+
fromBlock = filter.fromBlock;
|
|
380
408
|
}
|
|
381
409
|
}
|
|
382
410
|
|
|
383
411
|
if (filter.toBlock !== undefined) {
|
|
384
|
-
|
|
412
|
+
toBlock = filter.toBlock;
|
|
385
413
|
}
|
|
386
414
|
|
|
387
415
|
// Ensure the indices are within block array bounds
|
|
388
|
-
|
|
389
|
-
|
|
416
|
+
fromBlock = Math.max(fromBlock, INITIAL_L2_BLOCK_NUM);
|
|
417
|
+
toBlock = Math.min(toBlock, this.l2Blocks.length + INITIAL_L2_BLOCK_NUM);
|
|
390
418
|
|
|
391
|
-
if (
|
|
419
|
+
if (fromBlock > this.l2Blocks.length || toBlock < fromBlock || toBlock <= 0) {
|
|
392
420
|
return Promise.resolve({
|
|
393
421
|
logs: [],
|
|
394
422
|
maxLogsHit: false,
|
|
@@ -399,27 +427,30 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
399
427
|
|
|
400
428
|
const logs: ExtendedUnencryptedL2Log[] = [];
|
|
401
429
|
|
|
402
|
-
for (;
|
|
403
|
-
const block = this.l2Blocks[
|
|
404
|
-
const blockLogs = this.unencryptedLogsPerBlock
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
for (;
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
430
|
+
for (; fromBlock < toBlock; fromBlock++) {
|
|
431
|
+
const block = this.l2Blocks[fromBlock - INITIAL_L2_BLOCK_NUM];
|
|
432
|
+
const blockLogs = this.unencryptedLogsPerBlock.get(fromBlock);
|
|
433
|
+
|
|
434
|
+
if (blockLogs) {
|
|
435
|
+
for (; txIndexInBlock < blockLogs.txLogs.length; txIndexInBlock++) {
|
|
436
|
+
const txLogs = blockLogs.txLogs[txIndexInBlock].unrollLogs();
|
|
437
|
+
for (; logIndexInTx < txLogs.length; logIndexInTx++) {
|
|
438
|
+
const log = txLogs[logIndexInTx];
|
|
439
|
+
if (
|
|
440
|
+
(!txHash || block.data.body.txEffects[txIndexInBlock].txHash.equals(txHash)) &&
|
|
441
|
+
(!contractAddress || log.contractAddress.equals(contractAddress))
|
|
442
|
+
) {
|
|
443
|
+
logs.push(new ExtendedUnencryptedL2Log(new LogId(block.data.number, txIndexInBlock, logIndexInTx), log));
|
|
444
|
+
if (logs.length === this.maxLogs) {
|
|
445
|
+
return Promise.resolve({
|
|
446
|
+
logs,
|
|
447
|
+
maxLogsHit: true,
|
|
448
|
+
});
|
|
449
|
+
}
|
|
419
450
|
}
|
|
420
451
|
}
|
|
452
|
+
logIndexInTx = 0;
|
|
421
453
|
}
|
|
422
|
-
logIndexInTx = 0;
|
|
423
454
|
}
|
|
424
455
|
txIndexInBlock = 0;
|
|
425
456
|
}
|
|
@@ -445,9 +476,27 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
445
476
|
return Promise.resolve(this.lastProvenL2BlockNumber);
|
|
446
477
|
}
|
|
447
478
|
|
|
448
|
-
public
|
|
449
|
-
this.
|
|
450
|
-
|
|
479
|
+
public getProvenL2EpochNumber(): Promise<number | undefined> {
|
|
480
|
+
return Promise.resolve(this.lastProvenL2EpochNumber);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
public setProvenL2BlockNumber(l2BlockNumber: number): Promise<void> {
|
|
484
|
+
this.lastProvenL2BlockNumber = l2BlockNumber;
|
|
485
|
+
return Promise.resolve();
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
public setProvenL2EpochNumber(l2EpochNumber: number): Promise<void> {
|
|
489
|
+
this.lastProvenL2EpochNumber = l2EpochNumber;
|
|
490
|
+
return Promise.resolve();
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
setBlockSynchedL1BlockNumber(l1BlockNumber: bigint) {
|
|
494
|
+
this.lastL1BlockNewBlocks = l1BlockNumber;
|
|
495
|
+
return Promise.resolve();
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
setMessageSynchedL1BlockNumber(l1BlockNumber: bigint) {
|
|
499
|
+
this.lastL1BlockNewMessages = l1BlockNumber;
|
|
451
500
|
return Promise.resolve();
|
|
452
501
|
}
|
|
453
502
|
|
|
@@ -455,8 +504,6 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
455
504
|
return Promise.resolve({
|
|
456
505
|
blocksSynchedTo: this.lastL1BlockNewBlocks,
|
|
457
506
|
messagesSynchedTo: this.lastL1BlockNewMessages,
|
|
458
|
-
blockBodiesSynchedTo: this.lastL1BlockNewBlockBodies,
|
|
459
|
-
provenLogsSynchedTo: this.lastL1BlockNewProvenLogs,
|
|
460
507
|
});
|
|
461
508
|
}
|
|
462
509
|
|
package/src/index.ts
CHANGED
|
@@ -15,8 +15,6 @@ export * from './factory.js';
|
|
|
15
15
|
|
|
16
16
|
export { retrieveL2ProofVerifiedEvents, retrieveBlockFromRollup } from './archiver/data_retrieval.js';
|
|
17
17
|
|
|
18
|
-
export { getL2BlockProposedLogs } from './archiver/eth_log_handlers.js';
|
|
19
|
-
|
|
20
18
|
const log = createDebugLogger('aztec:archiver');
|
|
21
19
|
|
|
22
20
|
/**
|
|
@@ -27,6 +25,7 @@ async function main() {
|
|
|
27
25
|
const config = getArchiverConfigFromEnv();
|
|
28
26
|
const { l1RpcUrl: rpcUrl, l1Contracts } = config;
|
|
29
27
|
|
|
28
|
+
log.info(`Starting archiver in main(): ${JSON.stringify(config)}`);
|
|
30
29
|
const publicClient = createPublicClient({
|
|
31
30
|
chain: localhost,
|
|
32
31
|
transport: http(rpcUrl),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './mock_l2_block_source.js';
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { L2Block, type L2BlockSource, type TxEffect, type TxHash, TxReceipt, TxStatus } from '@aztec/circuit-types';
|
|
2
|
+
import { EthAddress, type Header } from '@aztec/circuits.js';
|
|
3
|
+
|
|
4
|
+
import { getSlotRangeForEpoch } from '../archiver/epoch_helpers.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A mocked implementation of L2BlockSource to be used in p2p tests.
|
|
8
|
+
*/
|
|
9
|
+
export class MockBlockSource implements L2BlockSource {
|
|
10
|
+
private l2Blocks: L2Block[] = [];
|
|
11
|
+
private txEffects: TxEffect[] = [];
|
|
12
|
+
private provenEpochNumber: number = 0;
|
|
13
|
+
|
|
14
|
+
constructor(numBlocks = 100, private provenBlockNumber?: number) {
|
|
15
|
+
this.addBlocks(numBlocks);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public addBlocks(numBlocks: number) {
|
|
19
|
+
for (let i = 0; i < numBlocks; i++) {
|
|
20
|
+
const blockNum = this.l2Blocks.length;
|
|
21
|
+
const block = L2Block.random(blockNum, blockNum);
|
|
22
|
+
this.l2Blocks.push(block);
|
|
23
|
+
this.txEffects.push(...block.body.txEffects);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public setProvenBlockNumber(provenBlockNumber: number) {
|
|
28
|
+
this.provenBlockNumber = provenBlockNumber;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public setProvenEpochNumber(provenEpochNumber: number) {
|
|
32
|
+
this.provenEpochNumber = provenEpochNumber;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Method to fetch the rollup contract address at the base-layer.
|
|
37
|
+
* @returns The rollup address.
|
|
38
|
+
*/
|
|
39
|
+
getRollupAddress(): Promise<EthAddress> {
|
|
40
|
+
return Promise.resolve(EthAddress.random());
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Method to fetch the registry contract address at the base-layer.
|
|
45
|
+
* @returns The registry address.
|
|
46
|
+
*/
|
|
47
|
+
getRegistryAddress(): Promise<EthAddress> {
|
|
48
|
+
return Promise.resolve(EthAddress.random());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Gets the number of the latest L2 block processed by the block source implementation.
|
|
53
|
+
* @returns In this mock instance, returns the number of L2 blocks that we've mocked.
|
|
54
|
+
*/
|
|
55
|
+
public getBlockNumber() {
|
|
56
|
+
return Promise.resolve(this.l2Blocks.length - 1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public async getProvenBlockNumber(): Promise<number> {
|
|
60
|
+
return this.provenBlockNumber ?? (await this.getBlockNumber());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public getProvenL2EpochNumber(): Promise<number | undefined> {
|
|
64
|
+
return Promise.resolve(this.provenEpochNumber);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Gets an l2 block.
|
|
69
|
+
* @param number - The block number to return (inclusive).
|
|
70
|
+
* @returns The requested L2 block.
|
|
71
|
+
*/
|
|
72
|
+
public getBlock(number: number) {
|
|
73
|
+
return Promise.resolve(this.l2Blocks[number]);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Gets up to `limit` amount of L2 blocks starting from `from`.
|
|
78
|
+
* @param from - Number of the first block to return (inclusive).
|
|
79
|
+
* @param limit - The maximum number of blocks to return.
|
|
80
|
+
* @returns The requested mocked L2 blocks.
|
|
81
|
+
*/
|
|
82
|
+
public getBlocks(from: number, limit: number, proven?: boolean) {
|
|
83
|
+
return Promise.resolve(
|
|
84
|
+
this.l2Blocks
|
|
85
|
+
.slice(from, from + limit)
|
|
86
|
+
.filter(b => !proven || this.provenBlockNumber === undefined || b.number <= this.provenBlockNumber),
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
getBlockHeader(number: number | 'latest'): Promise<Header | undefined> {
|
|
91
|
+
return Promise.resolve(this.l2Blocks.at(typeof number === 'number' ? number : -1)?.header);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
getBlocksForEpoch(epochNumber: bigint): Promise<L2Block[]> {
|
|
95
|
+
const [start, end] = getSlotRangeForEpoch(epochNumber);
|
|
96
|
+
const blocks = this.l2Blocks.filter(b => {
|
|
97
|
+
const slot = b.header.globalVariables.slotNumber.toBigInt();
|
|
98
|
+
return slot >= start && slot <= end;
|
|
99
|
+
});
|
|
100
|
+
return Promise.resolve(blocks);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Gets a tx effect.
|
|
105
|
+
* @param txHash - The hash of a transaction which resulted in the returned tx effect.
|
|
106
|
+
* @returns The requested tx effect.
|
|
107
|
+
*/
|
|
108
|
+
public getTxEffect(txHash: TxHash) {
|
|
109
|
+
const txEffect = this.txEffects.find(tx => tx.txHash.equals(txHash));
|
|
110
|
+
return Promise.resolve(txEffect);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Gets a receipt of a settled tx.
|
|
115
|
+
* @param txHash - The hash of a tx we try to get the receipt for.
|
|
116
|
+
* @returns The requested tx receipt (or undefined if not found).
|
|
117
|
+
*/
|
|
118
|
+
public getSettledTxReceipt(txHash: TxHash): Promise<TxReceipt | undefined> {
|
|
119
|
+
for (const block of this.l2Blocks) {
|
|
120
|
+
for (const txEffect of block.body.txEffects) {
|
|
121
|
+
if (txEffect.txHash.equals(txHash)) {
|
|
122
|
+
return Promise.resolve(
|
|
123
|
+
new TxReceipt(
|
|
124
|
+
txHash,
|
|
125
|
+
TxStatus.SUCCESS,
|
|
126
|
+
'',
|
|
127
|
+
txEffect.transactionFee.toBigInt(),
|
|
128
|
+
block.hash().toBuffer(),
|
|
129
|
+
block.number,
|
|
130
|
+
),
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return Promise.resolve(undefined);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
getL2EpochNumber(): Promise<bigint> {
|
|
139
|
+
throw new Error('Method not implemented.');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
getL2SlotNumber(): Promise<bigint> {
|
|
143
|
+
throw new Error('Method not implemented.');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
isEpochComplete(_epochNumber: bigint): Promise<boolean> {
|
|
147
|
+
throw new Error('Method not implemented.');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Starts the block source. In this mock implementation, this is a noop.
|
|
152
|
+
* @returns A promise that signals the initialization of the l2 block source on completion.
|
|
153
|
+
*/
|
|
154
|
+
public start(): Promise<void> {
|
|
155
|
+
return Promise.resolve();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Stops the block source. In this mock implementation, this is a noop.
|
|
160
|
+
* @returns A promise that signals the l2 block source is now stopped.
|
|
161
|
+
*/
|
|
162
|
+
public stop(): Promise<void> {
|
|
163
|
+
return Promise.resolve();
|
|
164
|
+
}
|
|
165
|
+
}
|