@aztec/archiver 0.56.0 → 0.58.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 -22
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +421 -115
- package/dest/archiver/archiver_store.d.ts +39 -10
- 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 +84 -31
- package/dest/archiver/config.js +6 -6
- package/dest/archiver/data_retrieval.d.ts +2 -3
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +23 -22
- 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 +20 -1
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +62 -5
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +3 -3
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.js +12 -5
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +2 -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 +5 -2
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +29 -10
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +57 -17
- 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 -1
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +17 -13
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +3 -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 +12 -14
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +23 -23
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +130 -70
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +17 -1
- package/dest/index.js +2 -1
- package/dest/test/index.d.ts +4 -0
- package/dest/test/index.d.ts.map +1 -0
- package/dest/test/index.js +4 -0
- package/dest/test/mock_archiver.d.ts +22 -0
- package/dest/test/mock_archiver.d.ts.map +1 -0
- package/dest/test/mock_archiver.js +44 -0
- package/dest/test/mock_l1_to_l2_message_source.d.ts +16 -0
- package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -0
- package/dest/test/mock_l1_to_l2_message_source.js +25 -0
- package/dest/test/mock_l2_block_source.d.ts +75 -0
- package/dest/test/mock_l2_block_source.d.ts.map +1 -0
- package/dest/test/mock_l2_block_source.js +154 -0
- package/package.json +15 -11
- package/src/archiver/archiver.ts +553 -170
- package/src/archiver/archiver_store.ts +48 -19
- package/src/archiver/archiver_store_test_suite.ts +111 -73
- package/src/archiver/config.ts +5 -5
- package/src/archiver/data_retrieval.ts +25 -26
- package/src/archiver/epoch_helpers.ts +26 -0
- package/src/archiver/kv_archiver_store/block_store.ts +70 -2
- package/src/archiver/kv_archiver_store/contract_class_store.ts +24 -9
- package/src/archiver/kv_archiver_store/contract_instance_store.ts +5 -2
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +71 -29
- package/src/archiver/kv_archiver_store/log_store.ts +18 -18
- package/src/archiver/kv_archiver_store/message_store.ts +16 -18
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +13 -19
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +154 -83
- package/src/factory.ts +18 -0
- package/src/index.ts +1 -0
- package/src/test/index.ts +3 -0
- package/src/test/mock_archiver.ts +55 -0
- package/src/test/mock_l1_to_l2_message_source.ts +31 -0
- package/src/test/mock_l2_block_source.ts +190 -0
- 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/kv_archiver_store/proven_store.ts +0 -34
|
@@ -15,18 +15,21 @@ import {
|
|
|
15
15
|
TxReceipt,
|
|
16
16
|
type UnencryptedL2BlockL2Logs,
|
|
17
17
|
} from '@aztec/circuit-types';
|
|
18
|
-
import { Fr, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
|
|
19
|
-
import { type ContractArtifact } from '@aztec/foundation/abi';
|
|
20
|
-
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
21
18
|
import {
|
|
22
19
|
type ContractClassPublic,
|
|
20
|
+
type ContractClassPublicWithBlockNumber,
|
|
23
21
|
type ContractInstanceWithAddress,
|
|
24
22
|
type ExecutablePrivateFunctionWithMembershipProof,
|
|
23
|
+
Fr,
|
|
24
|
+
type Header,
|
|
25
|
+
INITIAL_L2_BLOCK_NUM,
|
|
25
26
|
type UnconstrainedFunctionWithMembershipProof,
|
|
26
|
-
} from '@aztec/
|
|
27
|
+
} from '@aztec/circuits.js';
|
|
28
|
+
import { type ContractArtifact } from '@aztec/foundation/abi';
|
|
29
|
+
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
27
30
|
|
|
28
31
|
import { type ArchiverDataStore, type ArchiverL1SynchPoint } from '../archiver_store.js';
|
|
29
|
-
import { type DataRetrieval
|
|
32
|
+
import { type DataRetrieval } from '../structs/data_retrieval.js';
|
|
30
33
|
import { type L1Published } from '../structs/published.js';
|
|
31
34
|
import { L1ToL2MessageStore } from './l1_to_l2_message_store.js';
|
|
32
35
|
|
|
@@ -44,23 +47,11 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
44
47
|
*/
|
|
45
48
|
private txEffects: TxEffect[] = [];
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
* An array containing all the encrypted logs that have been fetched so far.
|
|
49
|
-
* Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM).
|
|
50
|
-
*/
|
|
51
|
-
private noteEncryptedLogsPerBlock: EncryptedNoteL2BlockL2Logs[] = [];
|
|
50
|
+
private noteEncryptedLogsPerBlock: Map<number, EncryptedNoteL2BlockL2Logs> = new Map();
|
|
52
51
|
|
|
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 encryptedLogsPerBlock: EncryptedL2BlockL2Logs[] = [];
|
|
52
|
+
private encryptedLogsPerBlock: Map<number, EncryptedL2BlockL2Logs> = new Map();
|
|
58
53
|
|
|
59
|
-
|
|
60
|
-
* An array containing all the unencrypted 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 unencryptedLogsPerBlock: UnencryptedL2BlockL2Logs[] = [];
|
|
54
|
+
private unencryptedLogsPerBlock: Map<number, UnencryptedL2BlockL2Logs> = new Map();
|
|
64
55
|
|
|
65
56
|
/**
|
|
66
57
|
* Contains all L1 to L2 messages.
|
|
@@ -69,7 +60,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
69
60
|
|
|
70
61
|
private contractArtifacts: Map<string, ContractArtifact> = new Map();
|
|
71
62
|
|
|
72
|
-
private contractClasses: Map<string,
|
|
63
|
+
private contractClasses: Map<string, ContractClassPublicWithBlockNumber> = new Map();
|
|
73
64
|
|
|
74
65
|
private privateFunctions: Map<string, ExecutablePrivateFunctionWithMembershipProof[]> = new Map();
|
|
75
66
|
|
|
@@ -79,9 +70,9 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
79
70
|
|
|
80
71
|
private lastL1BlockNewBlocks: bigint | undefined = undefined;
|
|
81
72
|
private lastL1BlockNewMessages: bigint | undefined = undefined;
|
|
82
|
-
private lastL1BlockNewProvenLogs: bigint | undefined = undefined;
|
|
83
73
|
|
|
84
74
|
private lastProvenL2BlockNumber: number = 0;
|
|
75
|
+
private lastProvenL2EpochNumber: number = 0;
|
|
85
76
|
|
|
86
77
|
constructor(
|
|
87
78
|
/** The max number of logs that can be obtained in 1 "getUnencryptedLogs" call. */
|
|
@@ -129,9 +120,24 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
129
120
|
return Promise.resolve(true);
|
|
130
121
|
}
|
|
131
122
|
|
|
132
|
-
public addContractClasses(data: ContractClassPublic[],
|
|
123
|
+
public addContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
|
|
133
124
|
for (const contractClass of data) {
|
|
134
|
-
this.contractClasses.
|
|
125
|
+
if (!this.contractClasses.has(contractClass.id.toString())) {
|
|
126
|
+
this.contractClasses.set(contractClass.id.toString(), {
|
|
127
|
+
...contractClass,
|
|
128
|
+
l2BlockNumber: blockNumber,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return Promise.resolve(true);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
public deleteContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
|
|
136
|
+
for (const contractClass of data) {
|
|
137
|
+
const restored = this.contractClasses.get(contractClass.id.toString());
|
|
138
|
+
if (restored && restored.l2BlockNumber >= blockNumber) {
|
|
139
|
+
this.contractClasses.delete(contractClass.id.toString());
|
|
140
|
+
}
|
|
135
141
|
}
|
|
136
142
|
return Promise.resolve(true);
|
|
137
143
|
}
|
|
@@ -143,6 +149,13 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
143
149
|
return Promise.resolve(true);
|
|
144
150
|
}
|
|
145
151
|
|
|
152
|
+
public deleteContractInstances(data: ContractInstanceWithAddress[], _blockNumber: number): Promise<boolean> {
|
|
153
|
+
for (const contractInstance of data) {
|
|
154
|
+
this.contractInstances.delete(contractInstance.address.toString());
|
|
155
|
+
}
|
|
156
|
+
return Promise.resolve(true);
|
|
157
|
+
}
|
|
158
|
+
|
|
146
159
|
/**
|
|
147
160
|
* Append new blocks to the store's list.
|
|
148
161
|
* @param blocks - The L2 blocks to be added to the store and the last processed L1 block.
|
|
@@ -161,33 +174,58 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
161
174
|
}
|
|
162
175
|
|
|
163
176
|
/**
|
|
164
|
-
*
|
|
165
|
-
* @param
|
|
166
|
-
*
|
|
167
|
-
* @param
|
|
168
|
-
* @returns True if the operation is successful
|
|
177
|
+
* Unwinds blocks from the database
|
|
178
|
+
* @param from - The tip of the chain, passed for verification purposes,
|
|
179
|
+
* ensuring that we don't end up deleting something we did not intend
|
|
180
|
+
* @param blocksToUnwind - The number of blocks we are to unwind
|
|
181
|
+
* @returns True if the operation is successful
|
|
169
182
|
*/
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
blockNumber: number,
|
|
175
|
-
): Promise<boolean> {
|
|
176
|
-
if (noteEncryptedLogs) {
|
|
177
|
-
this.noteEncryptedLogsPerBlock[blockNumber - INITIAL_L2_BLOCK_NUM] = noteEncryptedLogs;
|
|
183
|
+
public async unwindBlocks(from: number, blocksToUnwind: number): Promise<boolean> {
|
|
184
|
+
const last = await this.getSynchedL2BlockNumber();
|
|
185
|
+
if (from != last) {
|
|
186
|
+
throw new Error(`Can only remove the tip`);
|
|
178
187
|
}
|
|
179
188
|
|
|
180
|
-
|
|
181
|
-
|
|
189
|
+
const stopAt = from - blocksToUnwind;
|
|
190
|
+
while ((await this.getSynchedL2BlockNumber()) > stopAt) {
|
|
191
|
+
const block = this.l2Blocks.pop();
|
|
192
|
+
if (block == undefined) {
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
block.data.body.txEffects.forEach(() => this.txEffects.pop());
|
|
182
196
|
}
|
|
183
197
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
198
|
+
return Promise.resolve(true);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Append new logs to the store's list.
|
|
203
|
+
* @param block - The block for which to add the logs.
|
|
204
|
+
* @returns True if the operation is successful.
|
|
205
|
+
*/
|
|
206
|
+
addLogs(blocks: L2Block[]): Promise<boolean> {
|
|
207
|
+
blocks.forEach(block => {
|
|
208
|
+
this.noteEncryptedLogsPerBlock.set(block.number, block.body.noteEncryptedLogs);
|
|
209
|
+
this.encryptedLogsPerBlock.set(block.number, block.body.encryptedLogs);
|
|
210
|
+
this.unencryptedLogsPerBlock.set(block.number, block.body.unencryptedLogs);
|
|
211
|
+
});
|
|
212
|
+
return Promise.resolve(true);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
deleteLogs(blocks: L2Block[]): Promise<boolean> {
|
|
216
|
+
blocks.forEach(block => {
|
|
217
|
+
this.encryptedLogsPerBlock.delete(block.number);
|
|
218
|
+
this.noteEncryptedLogsPerBlock.delete(block.number);
|
|
219
|
+
this.unencryptedLogsPerBlock.delete(block.number);
|
|
220
|
+
});
|
|
187
221
|
|
|
188
222
|
return Promise.resolve(true);
|
|
189
223
|
}
|
|
190
224
|
|
|
225
|
+
getTotalL1ToL2MessageCount(): Promise<bigint> {
|
|
226
|
+
return Promise.resolve(this.l1ToL2Messages.getTotalL1ToL2MessageCount());
|
|
227
|
+
}
|
|
228
|
+
|
|
191
229
|
/**
|
|
192
230
|
* Append L1 to L2 messages to the store.
|
|
193
231
|
* @param messages - The L1 to L2 messages to be added to the store and the last processed L1 block.
|
|
@@ -226,12 +264,15 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
226
264
|
* @remarks When "from" is smaller than genesis block number, blocks from the beginning are returned.
|
|
227
265
|
*/
|
|
228
266
|
public getBlocks(from: number, limit: number): Promise<L1Published<L2Block>[]> {
|
|
229
|
-
// Return an empty array if we are outside of range
|
|
230
267
|
if (limit < 1) {
|
|
231
268
|
return Promise.reject(new Error(`Invalid limit: ${limit}`));
|
|
232
269
|
}
|
|
233
270
|
|
|
234
|
-
|
|
271
|
+
if (from < INITIAL_L2_BLOCK_NUM) {
|
|
272
|
+
return Promise.reject(new Error(`Invalid start: ${from}`));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const fromIndex = from - INITIAL_L2_BLOCK_NUM;
|
|
235
276
|
if (fromIndex >= this.l2Blocks.length) {
|
|
236
277
|
return Promise.resolve([]);
|
|
237
278
|
}
|
|
@@ -240,6 +281,11 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
240
281
|
return Promise.resolve(this.l2Blocks.slice(fromIndex, toIndex));
|
|
241
282
|
}
|
|
242
283
|
|
|
284
|
+
public async getBlockHeaders(from: number, limit: number): Promise<Header[]> {
|
|
285
|
+
const blocks = await this.getBlocks(from, limit);
|
|
286
|
+
return blocks.map(block => block.data.header);
|
|
287
|
+
}
|
|
288
|
+
|
|
243
289
|
/**
|
|
244
290
|
* Gets a tx effect.
|
|
245
291
|
* @param txHash - The txHash of the tx effect.
|
|
@@ -297,9 +343,14 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
297
343
|
logType: TLogType,
|
|
298
344
|
): Promise<L2BlockL2Logs<FromLogType<TLogType>>[]> {
|
|
299
345
|
if (from < INITIAL_L2_BLOCK_NUM || limit < 1) {
|
|
300
|
-
|
|
346
|
+
return Promise.resolve([]);
|
|
301
347
|
}
|
|
302
|
-
|
|
348
|
+
|
|
349
|
+
if (from > this.l2Blocks.length) {
|
|
350
|
+
return Promise.resolve([]);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const logMap = (() => {
|
|
303
354
|
switch (logType) {
|
|
304
355
|
case LogType.ENCRYPTED:
|
|
305
356
|
return this.encryptedLogsPerBlock;
|
|
@@ -309,14 +360,24 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
309
360
|
default:
|
|
310
361
|
return this.unencryptedLogsPerBlock;
|
|
311
362
|
}
|
|
312
|
-
})() as L2BlockL2Logs<FromLogType<TLogType
|
|
363
|
+
})() as Map<number, L2BlockL2Logs<FromLogType<TLogType>>>;
|
|
313
364
|
|
|
314
|
-
|
|
315
|
-
return Promise.resolve([]);
|
|
316
|
-
}
|
|
317
|
-
const startIndex = from - INITIAL_L2_BLOCK_NUM;
|
|
365
|
+
const startIndex = from;
|
|
318
366
|
const endIndex = startIndex + limit;
|
|
319
|
-
|
|
367
|
+
const upper = Math.min(endIndex, this.l2Blocks.length + INITIAL_L2_BLOCK_NUM);
|
|
368
|
+
|
|
369
|
+
const l = [];
|
|
370
|
+
for (let i = startIndex; i < upper; i++) {
|
|
371
|
+
const log = logMap.get(i);
|
|
372
|
+
if (log) {
|
|
373
|
+
l.push(log);
|
|
374
|
+
} else {
|
|
375
|
+
// I hate typescript sometimes
|
|
376
|
+
l.push(undefined as unknown as L2BlockL2Logs<FromLogType<TLogType>>);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return Promise.resolve(l);
|
|
320
381
|
}
|
|
321
382
|
|
|
322
383
|
/**
|
|
@@ -327,37 +388,37 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
327
388
|
*/
|
|
328
389
|
getUnencryptedLogs(filter: LogFilter): Promise<GetUnencryptedLogsResponse> {
|
|
329
390
|
let txHash: TxHash | undefined;
|
|
330
|
-
let
|
|
331
|
-
let
|
|
391
|
+
let fromBlock = 0;
|
|
392
|
+
let toBlock = this.l2Blocks.length + INITIAL_L2_BLOCK_NUM;
|
|
332
393
|
let txIndexInBlock = 0;
|
|
333
394
|
let logIndexInTx = 0;
|
|
334
395
|
|
|
335
396
|
if (filter.afterLog) {
|
|
336
397
|
// Continuation parameter is set --> tx hash is ignored
|
|
337
398
|
if (filter.fromBlock == undefined || filter.fromBlock <= filter.afterLog.blockNumber) {
|
|
338
|
-
|
|
399
|
+
fromBlock = filter.afterLog.blockNumber;
|
|
339
400
|
txIndexInBlock = filter.afterLog.txIndex;
|
|
340
401
|
logIndexInTx = filter.afterLog.logIndex + 1; // We want to start from the next log
|
|
341
402
|
} else {
|
|
342
|
-
|
|
403
|
+
fromBlock = filter.fromBlock;
|
|
343
404
|
}
|
|
344
405
|
} else {
|
|
345
406
|
txHash = filter.txHash;
|
|
346
407
|
|
|
347
408
|
if (filter.fromBlock !== undefined) {
|
|
348
|
-
|
|
409
|
+
fromBlock = filter.fromBlock;
|
|
349
410
|
}
|
|
350
411
|
}
|
|
351
412
|
|
|
352
413
|
if (filter.toBlock !== undefined) {
|
|
353
|
-
|
|
414
|
+
toBlock = filter.toBlock;
|
|
354
415
|
}
|
|
355
416
|
|
|
356
417
|
// Ensure the indices are within block array bounds
|
|
357
|
-
|
|
358
|
-
|
|
418
|
+
fromBlock = Math.max(fromBlock, INITIAL_L2_BLOCK_NUM);
|
|
419
|
+
toBlock = Math.min(toBlock, this.l2Blocks.length + INITIAL_L2_BLOCK_NUM);
|
|
359
420
|
|
|
360
|
-
if (
|
|
421
|
+
if (fromBlock > this.l2Blocks.length || toBlock < fromBlock || toBlock <= 0) {
|
|
361
422
|
return Promise.resolve({
|
|
362
423
|
logs: [],
|
|
363
424
|
maxLogsHit: false,
|
|
@@ -368,27 +429,30 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
368
429
|
|
|
369
430
|
const logs: ExtendedUnencryptedL2Log[] = [];
|
|
370
431
|
|
|
371
|
-
for (;
|
|
372
|
-
const block = this.l2Blocks[
|
|
373
|
-
const blockLogs = this.unencryptedLogsPerBlock
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
for (;
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
432
|
+
for (; fromBlock < toBlock; fromBlock++) {
|
|
433
|
+
const block = this.l2Blocks[fromBlock - INITIAL_L2_BLOCK_NUM];
|
|
434
|
+
const blockLogs = this.unencryptedLogsPerBlock.get(fromBlock);
|
|
435
|
+
|
|
436
|
+
if (blockLogs) {
|
|
437
|
+
for (; txIndexInBlock < blockLogs.txLogs.length; txIndexInBlock++) {
|
|
438
|
+
const txLogs = blockLogs.txLogs[txIndexInBlock].unrollLogs();
|
|
439
|
+
for (; logIndexInTx < txLogs.length; logIndexInTx++) {
|
|
440
|
+
const log = txLogs[logIndexInTx];
|
|
441
|
+
if (
|
|
442
|
+
(!txHash || block.data.body.txEffects[txIndexInBlock].txHash.equals(txHash)) &&
|
|
443
|
+
(!contractAddress || log.contractAddress.equals(contractAddress))
|
|
444
|
+
) {
|
|
445
|
+
logs.push(new ExtendedUnencryptedL2Log(new LogId(block.data.number, txIndexInBlock, logIndexInTx), log));
|
|
446
|
+
if (logs.length === this.maxLogs) {
|
|
447
|
+
return Promise.resolve({
|
|
448
|
+
logs,
|
|
449
|
+
maxLogsHit: true,
|
|
450
|
+
});
|
|
451
|
+
}
|
|
388
452
|
}
|
|
389
453
|
}
|
|
454
|
+
logIndexInTx = 0;
|
|
390
455
|
}
|
|
391
|
-
logIndexInTx = 0;
|
|
392
456
|
}
|
|
393
457
|
txIndexInBlock = 0;
|
|
394
458
|
}
|
|
@@ -414,9 +478,17 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
414
478
|
return Promise.resolve(this.lastProvenL2BlockNumber);
|
|
415
479
|
}
|
|
416
480
|
|
|
417
|
-
public
|
|
418
|
-
this.
|
|
419
|
-
|
|
481
|
+
public getProvenL2EpochNumber(): Promise<number | undefined> {
|
|
482
|
+
return Promise.resolve(this.lastProvenL2EpochNumber);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
public setProvenL2BlockNumber(l2BlockNumber: number): Promise<void> {
|
|
486
|
+
this.lastProvenL2BlockNumber = l2BlockNumber;
|
|
487
|
+
return Promise.resolve();
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
public setProvenL2EpochNumber(l2EpochNumber: number): Promise<void> {
|
|
491
|
+
this.lastProvenL2EpochNumber = l2EpochNumber;
|
|
420
492
|
return Promise.resolve();
|
|
421
493
|
}
|
|
422
494
|
|
|
@@ -434,7 +506,6 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
434
506
|
return Promise.resolve({
|
|
435
507
|
blocksSynchedTo: this.lastL1BlockNewBlocks,
|
|
436
508
|
messagesSynchedTo: this.lastL1BlockNewMessages,
|
|
437
|
-
provenLogsSynchedTo: this.lastL1BlockNewProvenLogs,
|
|
438
509
|
});
|
|
439
510
|
}
|
|
440
511
|
|
package/src/factory.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { type ContractClassPublic } from '@aztec/circuits.js';
|
|
1
2
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
2
3
|
import { createStore } from '@aztec/kv-store/utils';
|
|
4
|
+
import { getCanonicalProtocolContract, protocolContractNames } from '@aztec/protocol-contracts';
|
|
3
5
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
4
6
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
5
7
|
|
|
@@ -16,8 +18,24 @@ export async function createArchiver(
|
|
|
16
18
|
if (!config.archiverUrl) {
|
|
17
19
|
const store = await createStore('archiver', config, createDebugLogger('aztec:archiver:lmdb'));
|
|
18
20
|
const archiverStore = new KVArchiverDataStore(store, config.maxLogs);
|
|
21
|
+
await initWithProtocolContracts(archiverStore);
|
|
19
22
|
return Archiver.createAndSync(config, archiverStore, telemetry, opts.blockUntilSync);
|
|
20
23
|
} else {
|
|
21
24
|
return createArchiverClient(config.archiverUrl);
|
|
22
25
|
}
|
|
23
26
|
}
|
|
27
|
+
|
|
28
|
+
async function initWithProtocolContracts(store: KVArchiverDataStore) {
|
|
29
|
+
const blockNumber = 0;
|
|
30
|
+
for (const name of protocolContractNames) {
|
|
31
|
+
const contract = getCanonicalProtocolContract(name);
|
|
32
|
+
const contractClassPublic: ContractClassPublic = {
|
|
33
|
+
...contract.contractClass,
|
|
34
|
+
privateFunctions: [],
|
|
35
|
+
unconstrainedFunctions: [],
|
|
36
|
+
};
|
|
37
|
+
await store.addContractArtifact(contract.address, contract.artifact);
|
|
38
|
+
await store.addContractClasses([contractClassPublic], blockNumber);
|
|
39
|
+
await store.addContractInstances([contract.instance], blockNumber);
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -25,6 +25,7 @@ async function main() {
|
|
|
25
25
|
const config = getArchiverConfigFromEnv();
|
|
26
26
|
const { l1RpcUrl: rpcUrl, l1Contracts } = config;
|
|
27
27
|
|
|
28
|
+
log.info(`Starting archiver in main(): ${JSON.stringify(config)}`);
|
|
28
29
|
const publicClient = createPublicClient({
|
|
29
30
|
chain: localhost,
|
|
30
31
|
transport: http(rpcUrl),
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type L1ToL2MessageSource, type L2Block, type L2BlockSource } from '@aztec/circuit-types';
|
|
2
|
+
import { type Fr } from '@aztec/circuits.js';
|
|
3
|
+
|
|
4
|
+
import { MockL1ToL2MessageSource } from './mock_l1_to_l2_message_source.js';
|
|
5
|
+
import { MockL2BlockSource } from './mock_l2_block_source.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A mocked implementation of the archiver that implements L2BlockSource and L1ToL2MessageSource.
|
|
9
|
+
*/
|
|
10
|
+
export class MockArchiver extends MockL2BlockSource implements L2BlockSource, L1ToL2MessageSource {
|
|
11
|
+
private messageSource = new MockL1ToL2MessageSource(0);
|
|
12
|
+
|
|
13
|
+
public setL1ToL2Messages(blockNumber: number, msgs: Fr[]) {
|
|
14
|
+
this.messageSource.setL1ToL2Messages(blockNumber, msgs);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
getL1ToL2Messages(blockNumber: bigint): Promise<Fr[]> {
|
|
18
|
+
return this.messageSource.getL1ToL2Messages(blockNumber);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
getL1ToL2MessageIndex(_l1ToL2Message: Fr, _startIndex: bigint): Promise<bigint | undefined> {
|
|
22
|
+
return this.messageSource.getL1ToL2MessageIndex(_l1ToL2Message, _startIndex);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A mocked implementation of the archiver with a set of precomputed blocks and messages.
|
|
28
|
+
*/
|
|
29
|
+
export class MockPrefilledArchiver extends MockArchiver {
|
|
30
|
+
private precomputed: L2Block[];
|
|
31
|
+
|
|
32
|
+
constructor(precomputed: L2Block[], messages: Fr[][]) {
|
|
33
|
+
super();
|
|
34
|
+
this.precomputed = precomputed.slice();
|
|
35
|
+
messages.forEach((msgs, i) => this.setL1ToL2Messages(i + 1, msgs));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public setPrefilledBlocks(blocks: L2Block[], messages: Fr[][]) {
|
|
39
|
+
for (const block of blocks) {
|
|
40
|
+
this.precomputed[block.number - 1] = block;
|
|
41
|
+
}
|
|
42
|
+
messages.forEach((msgs, i) => this.setL1ToL2Messages(blocks[i].number, msgs));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public override createBlocks(numBlocks: number) {
|
|
46
|
+
if (this.l2Blocks.length + numBlocks > this.precomputed.length) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`Not enough precomputed blocks to create ${numBlocks} more blocks (already at ${this.l2Blocks.length})`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const fromBlock = this.l2Blocks.length;
|
|
53
|
+
this.addBlocks(this.precomputed.slice(fromBlock, fromBlock + numBlocks));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type L1ToL2MessageSource } from '@aztec/circuit-types';
|
|
2
|
+
import { type Fr } from '@aztec/circuits.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A mocked implementation of L1ToL2MessageSource to be used in tests.
|
|
6
|
+
*/
|
|
7
|
+
export class MockL1ToL2MessageSource implements L1ToL2MessageSource {
|
|
8
|
+
private messagesPerBlock = new Map<number, Fr[]>();
|
|
9
|
+
|
|
10
|
+
constructor(private blockNumber: number) {}
|
|
11
|
+
|
|
12
|
+
public setL1ToL2Messages(blockNumber: number, msgs: Fr[]) {
|
|
13
|
+
this.messagesPerBlock.set(blockNumber, msgs);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public setBlockNumber(blockNumber: number) {
|
|
17
|
+
this.blockNumber = blockNumber;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getL1ToL2Messages(blockNumber: bigint): Promise<Fr[]> {
|
|
21
|
+
return Promise.resolve(this.messagesPerBlock.get(Number(blockNumber)) ?? []);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getL1ToL2MessageIndex(_l1ToL2Message: Fr, _startIndex: bigint): Promise<bigint | undefined> {
|
|
25
|
+
throw new Error('Method not implemented.');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getBlockNumber(): Promise<number> {
|
|
29
|
+
return Promise.resolve(this.blockNumber);
|
|
30
|
+
}
|
|
31
|
+
}
|