@aztec/archiver 0.8.9 → 0.8.11
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/dest/archiver/archiver.d.ts +12 -6
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +48 -31
- package/dest/archiver/archiver_store.d.ts +27 -19
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store.js +102 -31
- package/dest/archiver/config.d.ts +2 -4
- package/dest/archiver/config.d.ts.map +1 -1
- package/dest/archiver/config.js +3 -4
- package/dest/index.js +5 -4
- package/package.json +6 -6
- package/src/archiver/archiver.ts +54 -33
- package/src/archiver/archiver_store.ts +129 -38
- package/src/archiver/config.ts +5 -8
- package/src/index.ts +3 -3
|
@@ -3,13 +3,19 @@ import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
|
3
3
|
import {
|
|
4
4
|
ContractData,
|
|
5
5
|
ExtendedContractData,
|
|
6
|
+
ExtendedUnencryptedL2Log,
|
|
7
|
+
GetUnencryptedLogsResponse,
|
|
6
8
|
INITIAL_L2_BLOCK_NUM,
|
|
7
9
|
L1ToL2Message,
|
|
8
10
|
L2Block,
|
|
11
|
+
L2BlockContext,
|
|
9
12
|
L2BlockL2Logs,
|
|
10
13
|
L2Tx,
|
|
14
|
+
LogFilter,
|
|
15
|
+
LogId,
|
|
11
16
|
LogType,
|
|
12
17
|
TxHash,
|
|
18
|
+
UnencryptedL2Log,
|
|
13
19
|
} from '@aztec/types';
|
|
14
20
|
|
|
15
21
|
import { L1ToL2MessageStore, PendingL1ToL2MessageStore } from './l1_to_l2_message_store.js';
|
|
@@ -24,7 +30,7 @@ export interface ArchiverDataStore {
|
|
|
24
30
|
* @param blocks - The L2 blocks to be added to the store.
|
|
25
31
|
* @returns True if the operation is successful.
|
|
26
32
|
*/
|
|
27
|
-
|
|
33
|
+
addBlocks(blocks: L2Block[]): Promise<boolean>;
|
|
28
34
|
|
|
29
35
|
/**
|
|
30
36
|
* Gets up to `limit` amount of L2 blocks starting from `from`.
|
|
@@ -32,7 +38,7 @@ export interface ArchiverDataStore {
|
|
|
32
38
|
* @param limit - The number of blocks to return.
|
|
33
39
|
* @returns The requested L2 blocks.
|
|
34
40
|
*/
|
|
35
|
-
|
|
41
|
+
getBlocks(from: number, limit: number): Promise<L2Block[]>;
|
|
36
42
|
|
|
37
43
|
/**
|
|
38
44
|
* Gets an l2 tx.
|
|
@@ -94,6 +100,13 @@ export interface ArchiverDataStore {
|
|
|
94
100
|
*/
|
|
95
101
|
getLogs(from: number, limit: number, logType: LogType): Promise<L2BlockL2Logs[]>;
|
|
96
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Gets unencrypted logs based on the provided filter.
|
|
105
|
+
* @param filter - The filter to apply to the logs.
|
|
106
|
+
* @returns The requested logs.
|
|
107
|
+
*/
|
|
108
|
+
getUnencryptedLogs(filter: LogFilter): Promise<GetUnencryptedLogsResponse>;
|
|
109
|
+
|
|
97
110
|
/**
|
|
98
111
|
* Add new extended contract data from an L2 block to the store's list.
|
|
99
112
|
* @param data - List of contracts' data to be added.
|
|
@@ -137,12 +150,6 @@ export interface ArchiverDataStore {
|
|
|
137
150
|
* @returns The number of the latest L2 block processed.
|
|
138
151
|
*/
|
|
139
152
|
getBlockNumber(): Promise<number>;
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Gets the length of L2 blocks in store.
|
|
143
|
-
* @returns The length of L2 Blocks stored.
|
|
144
|
-
*/
|
|
145
|
-
getBlocksLength(): number;
|
|
146
153
|
}
|
|
147
154
|
|
|
148
155
|
/**
|
|
@@ -152,7 +159,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
152
159
|
/**
|
|
153
160
|
* An array containing all the L2 blocks that have been fetched so far.
|
|
154
161
|
*/
|
|
155
|
-
private
|
|
162
|
+
private l2BlockContexts: L2BlockContext[] = [];
|
|
156
163
|
|
|
157
164
|
/**
|
|
158
165
|
* An array containing all the L2 Txs in the L2 blocks that have been fetched so far.
|
|
@@ -163,13 +170,13 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
163
170
|
* An array containing all the encrypted logs that have been fetched so far.
|
|
164
171
|
* Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM).
|
|
165
172
|
*/
|
|
166
|
-
private
|
|
173
|
+
private encryptedLogsPerBlock: L2BlockL2Logs[] = [];
|
|
167
174
|
|
|
168
175
|
/**
|
|
169
176
|
* An array containing all the unencrypted logs that have been fetched so far.
|
|
170
177
|
* Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM).
|
|
171
178
|
*/
|
|
172
|
-
private
|
|
179
|
+
private unencryptedLogsPerBlock: L2BlockL2Logs[] = [];
|
|
173
180
|
|
|
174
181
|
/**
|
|
175
182
|
* A sparse array containing all the extended contract data that have been fetched so far.
|
|
@@ -192,15 +199,18 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
192
199
|
*/
|
|
193
200
|
private pendingL1ToL2Messages: PendingL1ToL2MessageStore = new PendingL1ToL2MessageStore();
|
|
194
201
|
|
|
195
|
-
constructor(
|
|
202
|
+
constructor(
|
|
203
|
+
/** The max number of logs that can be obtained in 1 "getUnencryptedLogs" call. */
|
|
204
|
+
public readonly maxLogs: number,
|
|
205
|
+
) {}
|
|
196
206
|
|
|
197
207
|
/**
|
|
198
208
|
* Append new blocks to the store's list.
|
|
199
209
|
* @param blocks - The L2 blocks to be added to the store.
|
|
200
210
|
* @returns True if the operation is successful (always in this implementation).
|
|
201
211
|
*/
|
|
202
|
-
public
|
|
203
|
-
this.
|
|
212
|
+
public addBlocks(blocks: L2Block[]): Promise<boolean> {
|
|
213
|
+
this.l2BlockContexts.push(...blocks.map(block => new L2BlockContext(block)));
|
|
204
214
|
this.l2Txs.push(...blocks.flatMap(b => b.getTxs()));
|
|
205
215
|
return Promise.resolve(true);
|
|
206
216
|
}
|
|
@@ -212,7 +222,9 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
212
222
|
* @returns True if the operation is successful.
|
|
213
223
|
*/
|
|
214
224
|
addLogs(data: L2BlockL2Logs[], logType: LogType): Promise<boolean> {
|
|
215
|
-
logType === LogType.ENCRYPTED
|
|
225
|
+
logType === LogType.ENCRYPTED
|
|
226
|
+
? this.encryptedLogsPerBlock.push(...data)
|
|
227
|
+
: this.unencryptedLogsPerBlock.push(...data);
|
|
216
228
|
return Promise.resolve(true);
|
|
217
229
|
}
|
|
218
230
|
|
|
@@ -281,18 +293,21 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
281
293
|
* @param from - Number of the first block to return (inclusive).
|
|
282
294
|
* @param limit - The number of blocks to return.
|
|
283
295
|
* @returns The requested L2 blocks.
|
|
296
|
+
* @remarks When "from" is smaller than genesis block number, blocks from the beginning are returned.
|
|
284
297
|
*/
|
|
285
|
-
public
|
|
298
|
+
public getBlocks(from: number, limit: number): Promise<L2Block[]> {
|
|
286
299
|
// Return an empty array if we are outside of range
|
|
287
300
|
if (limit < 1) {
|
|
288
|
-
throw new Error(`Invalid
|
|
301
|
+
throw new Error(`Invalid limit: ${limit}`);
|
|
289
302
|
}
|
|
290
|
-
|
|
303
|
+
|
|
304
|
+
const fromIndex = Math.max(from - INITIAL_L2_BLOCK_NUM, 0);
|
|
305
|
+
if (fromIndex >= this.l2BlockContexts.length) {
|
|
291
306
|
return Promise.resolve([]);
|
|
292
307
|
}
|
|
293
|
-
|
|
294
|
-
const
|
|
295
|
-
return Promise.resolve(this.
|
|
308
|
+
|
|
309
|
+
const toIndex = fromIndex + limit;
|
|
310
|
+
return Promise.resolve(this.l2BlockContexts.slice(fromIndex, toIndex).map(blockContext => blockContext.block));
|
|
296
311
|
}
|
|
297
312
|
|
|
298
313
|
/**
|
|
@@ -336,9 +351,9 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
336
351
|
*/
|
|
337
352
|
getLogs(from: number, limit: number, logType: LogType): Promise<L2BlockL2Logs[]> {
|
|
338
353
|
if (from < INITIAL_L2_BLOCK_NUM || limit < 1) {
|
|
339
|
-
throw new Error(`Invalid
|
|
354
|
+
throw new Error(`Invalid limit: ${limit}`);
|
|
340
355
|
}
|
|
341
|
-
const logs = logType === LogType.ENCRYPTED ? this.
|
|
356
|
+
const logs = logType === LogType.ENCRYPTED ? this.encryptedLogsPerBlock : this.unencryptedLogsPerBlock;
|
|
342
357
|
if (from > logs.length) {
|
|
343
358
|
return Promise.resolve([]);
|
|
344
359
|
}
|
|
@@ -347,6 +362,90 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
347
362
|
return Promise.resolve(logs.slice(startIndex, endIndex));
|
|
348
363
|
}
|
|
349
364
|
|
|
365
|
+
/**
|
|
366
|
+
* Gets unencrypted logs based on the provided filter.
|
|
367
|
+
* @param filter - The filter to apply to the logs.
|
|
368
|
+
* @returns The requested logs.
|
|
369
|
+
* @remarks Works by doing an intersection of all params in the filter.
|
|
370
|
+
*/
|
|
371
|
+
getUnencryptedLogs(filter: LogFilter): Promise<GetUnencryptedLogsResponse> {
|
|
372
|
+
let txHash: TxHash | undefined;
|
|
373
|
+
let fromBlockIndex = 0;
|
|
374
|
+
let toBlockIndex = this.unencryptedLogsPerBlock.length;
|
|
375
|
+
let txIndexInBlock = 0;
|
|
376
|
+
let logIndexInTx = 0;
|
|
377
|
+
|
|
378
|
+
if (filter.afterLog) {
|
|
379
|
+
// Continuation parameter is set --> tx hash is ignored
|
|
380
|
+
if (filter.fromBlock == undefined || filter.fromBlock <= filter.afterLog.blockNumber) {
|
|
381
|
+
fromBlockIndex = filter.afterLog.blockNumber - INITIAL_L2_BLOCK_NUM;
|
|
382
|
+
txIndexInBlock = filter.afterLog.txIndex;
|
|
383
|
+
logIndexInTx = filter.afterLog.logIndex + 1; // We want to start from the next log
|
|
384
|
+
} else {
|
|
385
|
+
fromBlockIndex = filter.fromBlock - INITIAL_L2_BLOCK_NUM;
|
|
386
|
+
}
|
|
387
|
+
} else {
|
|
388
|
+
txHash = filter.txHash;
|
|
389
|
+
|
|
390
|
+
if (filter.fromBlock !== undefined) {
|
|
391
|
+
fromBlockIndex = filter.fromBlock - INITIAL_L2_BLOCK_NUM;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (filter.toBlock !== undefined) {
|
|
396
|
+
toBlockIndex = filter.toBlock - INITIAL_L2_BLOCK_NUM;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Ensure the indices are within block array bounds
|
|
400
|
+
fromBlockIndex = Math.max(fromBlockIndex, 0);
|
|
401
|
+
toBlockIndex = Math.min(toBlockIndex, this.unencryptedLogsPerBlock.length);
|
|
402
|
+
|
|
403
|
+
if (fromBlockIndex > this.unencryptedLogsPerBlock.length || toBlockIndex < fromBlockIndex || toBlockIndex <= 0) {
|
|
404
|
+
return Promise.resolve({
|
|
405
|
+
logs: [],
|
|
406
|
+
maxLogsHit: false,
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const contractAddress = filter.contractAddress;
|
|
411
|
+
const selector = filter.selector;
|
|
412
|
+
|
|
413
|
+
const logs: ExtendedUnencryptedL2Log[] = [];
|
|
414
|
+
|
|
415
|
+
for (; fromBlockIndex < toBlockIndex; fromBlockIndex++) {
|
|
416
|
+
const blockContext = this.l2BlockContexts[fromBlockIndex];
|
|
417
|
+
const blockLogs = this.unencryptedLogsPerBlock[fromBlockIndex];
|
|
418
|
+
for (; txIndexInBlock < blockLogs.txLogs.length; txIndexInBlock++) {
|
|
419
|
+
const txLogs = blockLogs.txLogs[txIndexInBlock].unrollLogs().map(log => UnencryptedL2Log.fromBuffer(log));
|
|
420
|
+
for (; logIndexInTx < txLogs.length; logIndexInTx++) {
|
|
421
|
+
const log = txLogs[logIndexInTx];
|
|
422
|
+
if (
|
|
423
|
+
(!txHash || blockContext.getTxHash(txIndexInBlock).equals(txHash)) &&
|
|
424
|
+
(!contractAddress || log.contractAddress.equals(contractAddress)) &&
|
|
425
|
+
(!selector || log.selector.equals(selector))
|
|
426
|
+
) {
|
|
427
|
+
logs.push(
|
|
428
|
+
new ExtendedUnencryptedL2Log(new LogId(blockContext.block.number, txIndexInBlock, logIndexInTx), log),
|
|
429
|
+
);
|
|
430
|
+
if (logs.length === this.maxLogs) {
|
|
431
|
+
return Promise.resolve({
|
|
432
|
+
logs,
|
|
433
|
+
maxLogsHit: true,
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
logIndexInTx = 0;
|
|
439
|
+
}
|
|
440
|
+
txIndexInBlock = 0;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
return Promise.resolve({
|
|
444
|
+
logs,
|
|
445
|
+
maxLogsHit: false,
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
|
|
350
449
|
/**
|
|
351
450
|
* Get the extended contract data for this contract.
|
|
352
451
|
* @param contractAddress - The contract data address.
|
|
@@ -363,7 +462,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
363
462
|
* @returns All extended contract data in the block (if found).
|
|
364
463
|
*/
|
|
365
464
|
public getExtendedContractDataInBlock(blockNum: number): Promise<ExtendedContractData[]> {
|
|
366
|
-
if (blockNum > this.
|
|
465
|
+
if (blockNum > this.l2BlockContexts.length) {
|
|
367
466
|
return Promise.resolve([]);
|
|
368
467
|
}
|
|
369
468
|
return Promise.resolve(this.extendedContractDataByBlock[blockNum] || []);
|
|
@@ -379,8 +478,8 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
379
478
|
if (contractAddress.isZero()) {
|
|
380
479
|
return Promise.resolve(undefined);
|
|
381
480
|
}
|
|
382
|
-
for (const
|
|
383
|
-
for (const contractData of block.newContractData) {
|
|
481
|
+
for (const blockContext of this.l2BlockContexts) {
|
|
482
|
+
for (const contractData of blockContext.block.newContractData) {
|
|
384
483
|
if (contractData.contractAddress.equals(contractAddress)) {
|
|
385
484
|
return Promise.resolve(contractData);
|
|
386
485
|
}
|
|
@@ -396,10 +495,10 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
396
495
|
* @returns ContractData with the portal address (if we didn't throw an error).
|
|
397
496
|
*/
|
|
398
497
|
public getContractDataInBlock(l2BlockNum: number): Promise<ContractData[] | undefined> {
|
|
399
|
-
if (l2BlockNum > this.
|
|
498
|
+
if (l2BlockNum > this.l2BlockContexts.length) {
|
|
400
499
|
return Promise.resolve([]);
|
|
401
500
|
}
|
|
402
|
-
const block = this.
|
|
501
|
+
const block = this.l2BlockContexts[l2BlockNum].block;
|
|
403
502
|
return Promise.resolve(block.newContractData);
|
|
404
503
|
}
|
|
405
504
|
|
|
@@ -408,15 +507,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
408
507
|
* @returns The number of the latest L2 block processed.
|
|
409
508
|
*/
|
|
410
509
|
public getBlockNumber(): Promise<number> {
|
|
411
|
-
if (this.
|
|
412
|
-
return Promise.resolve(this.
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
/**
|
|
416
|
-
* Gets the length of L2 blocks in store.
|
|
417
|
-
* @returns The length of L2 Blocks array.
|
|
418
|
-
*/
|
|
419
|
-
public getBlocksLength(): number {
|
|
420
|
-
return this.l2Blocks.length;
|
|
510
|
+
if (this.l2BlockContexts.length === 0) return Promise.resolve(INITIAL_L2_BLOCK_NUM - 1);
|
|
511
|
+
return Promise.resolve(this.l2BlockContexts[this.l2BlockContexts.length - 1].block.number);
|
|
421
512
|
}
|
|
422
513
|
}
|
package/src/archiver/config.ts
CHANGED
|
@@ -32,11 +32,6 @@ export interface ArchiverConfig {
|
|
|
32
32
|
*/
|
|
33
33
|
viemPollingIntervalMS?: number;
|
|
34
34
|
|
|
35
|
-
/**
|
|
36
|
-
* Eth block from which we start scanning for L2Blocks.
|
|
37
|
-
*/
|
|
38
|
-
searchStartBlock: number;
|
|
39
|
-
|
|
40
35
|
/**
|
|
41
36
|
* The deployed L1 contract addresses
|
|
42
37
|
*/
|
|
@@ -46,6 +41,9 @@ export interface ArchiverConfig {
|
|
|
46
41
|
* Optional dir to store data. If omitted will store in memory.
|
|
47
42
|
*/
|
|
48
43
|
dataDirectory?: string;
|
|
44
|
+
|
|
45
|
+
/** The max number of logs that can be obtained in 1 "getUnencryptedLogs" call. */
|
|
46
|
+
maxLogs?: number;
|
|
49
47
|
}
|
|
50
48
|
|
|
51
49
|
/**
|
|
@@ -60,9 +58,9 @@ export function getConfigEnvVars(): ArchiverConfig {
|
|
|
60
58
|
ARCHIVER_VIEM_POLLING_INTERVAL_MS,
|
|
61
59
|
ROLLUP_CONTRACT_ADDRESS,
|
|
62
60
|
CONTRACT_DEPLOYMENT_EMITTER_ADDRESS,
|
|
63
|
-
SEARCH_START_BLOCK,
|
|
64
61
|
API_KEY,
|
|
65
62
|
INBOX_CONTRACT_ADDRESS,
|
|
63
|
+
OUTBOX_CONTRACT_ADDRESS,
|
|
66
64
|
REGISTRY_CONTRACT_ADDRESS,
|
|
67
65
|
DATA_DIRECTORY,
|
|
68
66
|
} = process.env;
|
|
@@ -71,7 +69,7 @@ export function getConfigEnvVars(): ArchiverConfig {
|
|
|
71
69
|
rollupAddress: ROLLUP_CONTRACT_ADDRESS ? EthAddress.fromString(ROLLUP_CONTRACT_ADDRESS) : EthAddress.ZERO,
|
|
72
70
|
registryAddress: REGISTRY_CONTRACT_ADDRESS ? EthAddress.fromString(REGISTRY_CONTRACT_ADDRESS) : EthAddress.ZERO,
|
|
73
71
|
inboxAddress: INBOX_CONTRACT_ADDRESS ? EthAddress.fromString(INBOX_CONTRACT_ADDRESS) : EthAddress.ZERO,
|
|
74
|
-
outboxAddress: EthAddress.ZERO,
|
|
72
|
+
outboxAddress: OUTBOX_CONTRACT_ADDRESS ? EthAddress.fromString(OUTBOX_CONTRACT_ADDRESS) : EthAddress.ZERO,
|
|
75
73
|
contractDeploymentEmitterAddress: CONTRACT_DEPLOYMENT_EMITTER_ADDRESS
|
|
76
74
|
? EthAddress.fromString(CONTRACT_DEPLOYMENT_EMITTER_ADDRESS)
|
|
77
75
|
: EthAddress.ZERO,
|
|
@@ -81,7 +79,6 @@ export function getConfigEnvVars(): ArchiverConfig {
|
|
|
81
79
|
rpcUrl: ETHEREUM_HOST || 'http://127.0.0.1:8545/',
|
|
82
80
|
archiverPollingIntervalMS: ARCHIVER_POLLING_INTERVAL_MS ? +ARCHIVER_POLLING_INTERVAL_MS : 1_000,
|
|
83
81
|
viemPollingIntervalMS: ARCHIVER_VIEM_POLLING_INTERVAL_MS ? +ARCHIVER_VIEM_POLLING_INTERVAL_MS : 1_000,
|
|
84
|
-
searchStartBlock: SEARCH_START_BLOCK ? +SEARCH_START_BLOCK : 0,
|
|
85
82
|
apiKey: API_KEY,
|
|
86
83
|
l1Contracts: addresses,
|
|
87
84
|
dataDirectory: DATA_DIRECTORY,
|
package/src/index.ts
CHANGED
|
@@ -17,14 +17,14 @@ const log = createDebugLogger('aztec:archiver');
|
|
|
17
17
|
// eslint-disable-next-line require-await
|
|
18
18
|
async function main() {
|
|
19
19
|
const config = getConfigEnvVars();
|
|
20
|
-
const { rpcUrl, l1Contracts
|
|
20
|
+
const { rpcUrl, l1Contracts } = config;
|
|
21
21
|
|
|
22
22
|
const publicClient = createPublicClient({
|
|
23
23
|
chain: localhost,
|
|
24
24
|
transport: http(rpcUrl),
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
const archiverStore = new MemoryArchiverStore();
|
|
27
|
+
const archiverStore = new MemoryArchiverStore(1000);
|
|
28
28
|
|
|
29
29
|
const archiver = new Archiver(
|
|
30
30
|
publicClient,
|
|
@@ -32,7 +32,7 @@ async function main() {
|
|
|
32
32
|
l1Contracts.inboxAddress,
|
|
33
33
|
l1Contracts.registryAddress,
|
|
34
34
|
l1Contracts.contractDeploymentEmitterAddress,
|
|
35
|
-
searchStartBlock
|
|
35
|
+
0, // searchStartBlock
|
|
36
36
|
archiverStore,
|
|
37
37
|
);
|
|
38
38
|
|