@aztec/archiver 0.71.0 → 0.73.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/dest/archiver/archiver.d.ts +6 -6
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +35 -20
- package/dest/archiver/archiver_store.d.ts +6 -6
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +103 -65
- package/dest/archiver/config.d.ts +2 -2
- package/dest/archiver/config.d.ts.map +1 -1
- package/dest/archiver/config.js +5 -5
- package/dest/archiver/data_retrieval.d.ts +3 -2
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +69 -16
- package/dest/archiver/errors.d.ts +4 -0
- package/dest/archiver/errors.d.ts.map +1 -0
- package/dest/archiver/errors.js +6 -0
- package/dest/archiver/kv_archiver_store/block_store.d.ts +16 -16
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +53 -53
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +5 -5
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.js +13 -12
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +3 -3
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.js +3 -3
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +7 -11
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +41 -63
- package/dest/archiver/kv_archiver_store/log_store.d.ts +8 -8
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +122 -89
- package/dest/archiver/kv_archiver_store/message_store.d.ts +6 -6
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +16 -16
- package/dest/archiver/kv_archiver_store/nullifier_store.d.ts +2 -2
- package/dest/archiver/kv_archiver_store/nullifier_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/nullifier_store.js +31 -22
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +9 -9
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +72 -71
- package/dest/factory.js +8 -8
- package/dest/rpc/index.d.ts +1 -1
- package/dest/rpc/index.d.ts.map +1 -1
- package/dest/rpc/index.js +5 -5
- package/dest/test/mock_archiver.d.ts +1 -1
- package/dest/test/mock_archiver.d.ts.map +1 -1
- package/dest/test/mock_archiver.js +2 -1
- package/dest/test/mock_l2_block_source.d.ts +3 -3
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +14 -11
- package/package.json +13 -13
- package/src/archiver/archiver.ts +46 -25
- package/src/archiver/archiver_store.ts +6 -5
- package/src/archiver/archiver_store_test_suite.ts +113 -77
- package/src/archiver/config.ts +6 -6
- package/src/archiver/data_retrieval.ts +94 -12
- package/src/archiver/errors.ts +5 -0
- package/src/archiver/kv_archiver_store/block_store.ts +66 -67
- package/src/archiver/kv_archiver_store/contract_class_store.ts +17 -15
- package/src/archiver/kv_archiver_store/contract_instance_store.ts +5 -5
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +48 -66
- package/src/archiver/kv_archiver_store/log_store.ts +167 -112
- package/src/archiver/kv_archiver_store/message_store.ts +22 -22
- package/src/archiver/kv_archiver_store/nullifier_store.ts +48 -30
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +100 -96
- package/src/factory.ts +11 -9
- package/src/rpc/index.ts +4 -4
- package/src/test/mock_archiver.ts +1 -0
- package/src/test/mock_l2_block_source.ts +20 -18
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
InboxLeaf,
|
|
3
|
-
L2Block,
|
|
4
|
-
LogId,
|
|
5
|
-
TxEffect,
|
|
6
|
-
TxHash,
|
|
7
|
-
UnencryptedFunctionL2Logs,
|
|
8
|
-
UnencryptedL2Log,
|
|
9
|
-
UnencryptedTxL2Logs,
|
|
10
|
-
wrapInBlock,
|
|
11
|
-
} from '@aztec/circuit-types';
|
|
1
|
+
import { InboxLeaf, L2Block, LogId, TxEffect, TxHash, wrapInBlock } from '@aztec/circuit-types';
|
|
12
2
|
import '@aztec/circuit-types/jest';
|
|
13
3
|
import {
|
|
14
4
|
AztecAddress,
|
|
@@ -19,7 +9,9 @@ import {
|
|
|
19
9
|
L1_TO_L2_MSG_SUBTREE_HEIGHT,
|
|
20
10
|
MAX_NULLIFIERS_PER_TX,
|
|
21
11
|
PRIVATE_LOG_SIZE_IN_FIELDS,
|
|
12
|
+
PUBLIC_LOG_DATA_SIZE_IN_FIELDS,
|
|
22
13
|
PrivateLog,
|
|
14
|
+
PublicLog,
|
|
23
15
|
SerializableContractInstance,
|
|
24
16
|
computePublicBytecodeCommitment,
|
|
25
17
|
} from '@aztec/circuits.js';
|
|
@@ -28,7 +20,7 @@ import {
|
|
|
28
20
|
makeExecutablePrivateFunctionWithMembershipProof,
|
|
29
21
|
makeUnconstrainedFunctionWithMembershipProof,
|
|
30
22
|
} from '@aztec/circuits.js/testing';
|
|
31
|
-
import { times } from '@aztec/foundation/collection';
|
|
23
|
+
import { times, timesParallel } from '@aztec/foundation/collection';
|
|
32
24
|
import { randomInt } from '@aztec/foundation/crypto';
|
|
33
25
|
|
|
34
26
|
import { type ArchiverDataStore, type ArchiverL1SynchPoint } from './archiver_store.js';
|
|
@@ -38,7 +30,10 @@ import { type L1Published } from './structs/published.js';
|
|
|
38
30
|
* @param testName - The name of the test suite.
|
|
39
31
|
* @param getStore - Returns an instance of a store that's already been initialized.
|
|
40
32
|
*/
|
|
41
|
-
export function describeArchiverDataStore(
|
|
33
|
+
export function describeArchiverDataStore(
|
|
34
|
+
testName: string,
|
|
35
|
+
getStore: () => ArchiverDataStore | Promise<ArchiverDataStore>,
|
|
36
|
+
) {
|
|
42
37
|
describe(testName, () => {
|
|
43
38
|
let store: ArchiverDataStore;
|
|
44
39
|
let blocks: L1Published<L2Block>[];
|
|
@@ -59,9 +54,9 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
59
54
|
},
|
|
60
55
|
});
|
|
61
56
|
|
|
62
|
-
beforeEach(() => {
|
|
63
|
-
store = getStore();
|
|
64
|
-
blocks =
|
|
57
|
+
beforeEach(async () => {
|
|
58
|
+
store = await getStore();
|
|
59
|
+
blocks = await timesParallel(10, async i => makeL1Published(await L2Block.random(i + 1), i + 10));
|
|
65
60
|
});
|
|
66
61
|
|
|
67
62
|
describe('addBlocks', () => {
|
|
@@ -89,7 +84,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
89
84
|
});
|
|
90
85
|
|
|
91
86
|
it('can unwind multiple empty blocks', async () => {
|
|
92
|
-
const emptyBlocks =
|
|
87
|
+
const emptyBlocks = await timesParallel(10, async i => makeL1Published(await L2Block.random(i + 1, 0), i + 10));
|
|
93
88
|
await store.addBlocks(emptyBlocks);
|
|
94
89
|
expect(await store.getSynchedL2BlockNumber()).toBe(10);
|
|
95
90
|
|
|
@@ -166,14 +161,14 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
166
161
|
});
|
|
167
162
|
|
|
168
163
|
describe('addLogs', () => {
|
|
169
|
-
it('adds private &
|
|
164
|
+
it('adds private & public logs', async () => {
|
|
170
165
|
const block = blocks[0].data;
|
|
171
166
|
await expect(store.addLogs([block])).resolves.toEqual(true);
|
|
172
167
|
});
|
|
173
168
|
});
|
|
174
169
|
|
|
175
170
|
describe('deleteLogs', () => {
|
|
176
|
-
it('deletes private &
|
|
171
|
+
it('deletes private & public logs', async () => {
|
|
177
172
|
const block = blocks[0].data;
|
|
178
173
|
await store.addBlocks([blocks[0]]);
|
|
179
174
|
await expect(store.addLogs([block])).resolves.toEqual(true);
|
|
@@ -181,15 +176,15 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
181
176
|
expect((await store.getPrivateLogs(1, 1)).length).toEqual(
|
|
182
177
|
block.body.txEffects.map(txEffect => txEffect.privateLogs).flat().length,
|
|
183
178
|
);
|
|
184
|
-
expect((await store.
|
|
185
|
-
block.body.
|
|
179
|
+
expect((await store.getPublicLogs({ fromBlock: 1 })).logs.length).toEqual(
|
|
180
|
+
block.body.txEffects.map(txEffect => txEffect.publicLogs).flat().length,
|
|
186
181
|
);
|
|
187
182
|
|
|
188
183
|
// This one is a pain for memory as we would never want to just delete memory in the middle.
|
|
189
184
|
await store.deleteLogs([block]);
|
|
190
185
|
|
|
191
186
|
expect((await store.getPrivateLogs(1, 1)).length).toEqual(0);
|
|
192
|
-
expect((await store.
|
|
187
|
+
expect((await store.getPublicLogs({ fromBlock: 1 })).logs.length).toEqual(0);
|
|
193
188
|
});
|
|
194
189
|
});
|
|
195
190
|
|
|
@@ -217,7 +212,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
217
212
|
() => wrapInBlock(blocks[5].data.body.txEffects[2], blocks[5].data),
|
|
218
213
|
() => wrapInBlock(blocks[1].data.body.txEffects[0], blocks[1].data),
|
|
219
214
|
])('retrieves a previously stored transaction', async getExpectedTx => {
|
|
220
|
-
const expectedTx = getExpectedTx();
|
|
215
|
+
const expectedTx = await getExpectedTx();
|
|
221
216
|
const actualTx = await store.getTxEffect(expectedTx.data.txHash);
|
|
222
217
|
expect(actualTx).toEqual(expectedTx);
|
|
223
218
|
});
|
|
@@ -235,7 +230,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
235
230
|
])('tries to retrieves a previously stored transaction after deleted', async getExpectedTx => {
|
|
236
231
|
await store.unwindBlocks(blocks.length, blocks.length);
|
|
237
232
|
|
|
238
|
-
const expectedTx = getExpectedTx();
|
|
233
|
+
const expectedTx = await getExpectedTx();
|
|
239
234
|
const actualTx = await store.getTxEffect(expectedTx.data.txHash);
|
|
240
235
|
expect(actualTx).toEqual(undefined);
|
|
241
236
|
});
|
|
@@ -284,7 +279,8 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
284
279
|
const blockNum = 10;
|
|
285
280
|
|
|
286
281
|
beforeEach(async () => {
|
|
287
|
-
|
|
282
|
+
const randomInstance = await SerializableContractInstance.random();
|
|
283
|
+
contractInstance = { ...randomInstance, address: await AztecAddress.random() };
|
|
288
284
|
await store.addContractInstances([contractInstance], blockNum);
|
|
289
285
|
});
|
|
290
286
|
|
|
@@ -293,7 +289,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
293
289
|
});
|
|
294
290
|
|
|
295
291
|
it('returns undefined if contract instance is not found', async () => {
|
|
296
|
-
await expect(store.getContractInstance(AztecAddress.random())).resolves.toBeUndefined();
|
|
292
|
+
await expect(store.getContractInstance(await AztecAddress.random())).resolves.toBeUndefined();
|
|
297
293
|
});
|
|
298
294
|
|
|
299
295
|
it('returns undefined if previously stored contract instances was deleted', async () => {
|
|
@@ -307,10 +303,10 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
307
303
|
const blockNum = 10;
|
|
308
304
|
|
|
309
305
|
beforeEach(async () => {
|
|
310
|
-
contractClass = makeContractClassPublic();
|
|
306
|
+
contractClass = await makeContractClassPublic();
|
|
311
307
|
await store.addContractClasses(
|
|
312
308
|
[contractClass],
|
|
313
|
-
[computePublicBytecodeCommitment(contractClass.packedBytecode)],
|
|
309
|
+
[await computePublicBytecodeCommitment(contractClass.packedBytecode)],
|
|
314
310
|
blockNum,
|
|
315
311
|
);
|
|
316
312
|
});
|
|
@@ -327,7 +323,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
327
323
|
it('returns contract class if later "deployment" class was deleted', async () => {
|
|
328
324
|
await store.addContractClasses(
|
|
329
325
|
[contractClass],
|
|
330
|
-
[computePublicBytecodeCommitment(contractClass.packedBytecode)],
|
|
326
|
+
[await computePublicBytecodeCommitment(contractClass.packedBytecode)],
|
|
331
327
|
blockNum + 1,
|
|
332
328
|
);
|
|
333
329
|
await store.deleteContractClasses([contractClass], blockNum + 1);
|
|
@@ -373,18 +369,34 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
373
369
|
const numBlocks = 3;
|
|
374
370
|
const numTxsPerBlock = 4;
|
|
375
371
|
const numPrivateLogsPerTx = 3;
|
|
376
|
-
const
|
|
372
|
+
const numPublicLogsPerTx = 2;
|
|
377
373
|
|
|
378
374
|
let blocks: L1Published<L2Block>[];
|
|
379
375
|
|
|
380
376
|
const makeTag = (blockNumber: number, txIndex: number, logIndex: number, isPublic = false) =>
|
|
381
377
|
new Fr((blockNumber * 100 + txIndex * 10 + logIndex) * (isPublic ? 123 : 1));
|
|
382
378
|
|
|
379
|
+
// See parseLogFromPublic
|
|
380
|
+
// Search the codebase for "disgusting encoding" to see other hardcoded instances of this encoding, that you might need to change if you ever find yourself here.
|
|
381
|
+
const makeLengthsField = (publicValuesLen: number, privateValuesLen: number) => {
|
|
382
|
+
const buf = Buffer.alloc(32);
|
|
383
|
+
buf.writeUint16BE(publicValuesLen, 27);
|
|
384
|
+
buf.writeUint16BE(privateValuesLen, 30);
|
|
385
|
+
return Fr.fromBuffer(buf);
|
|
386
|
+
};
|
|
387
|
+
|
|
383
388
|
const makePrivateLog = (tag: Fr) =>
|
|
384
389
|
PrivateLog.fromFields([tag, ...times(PRIVATE_LOG_SIZE_IN_FIELDS - 1, i => new Fr(tag.toNumber() + i))]);
|
|
385
390
|
|
|
391
|
+
// The tag lives in field 1, not 0, of a public log
|
|
392
|
+
// See extractTaggedLogsFromPublic and noir-projects/aztec-nr/aztec/src/macros/notes/mod.nr -> emit_log
|
|
386
393
|
const makePublicLog = (tag: Fr) =>
|
|
387
|
-
|
|
394
|
+
PublicLog.fromFields([
|
|
395
|
+
AztecAddress.fromNumber(1).toField(), // log address
|
|
396
|
+
makeLengthsField(2, PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 3), // field 0
|
|
397
|
+
tag, // field 1
|
|
398
|
+
...times(PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 1, i => new Fr(tag.toNumber() + i)), // fields 2 to end
|
|
399
|
+
]);
|
|
388
400
|
|
|
389
401
|
const mockPrivateLogs = (blockNumber: number, txIndex: number) => {
|
|
390
402
|
return times(numPrivateLogsPerTx, (logIndex: number) => {
|
|
@@ -393,23 +405,21 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
393
405
|
});
|
|
394
406
|
};
|
|
395
407
|
|
|
396
|
-
const
|
|
397
|
-
|
|
408
|
+
const mockPublicLogs = (blockNumber: number, txIndex: number) => {
|
|
409
|
+
return times(numPublicLogsPerTx, (logIndex: number) => {
|
|
398
410
|
const tag = makeTag(blockNumber, txIndex, logIndex, /* isPublic */ true);
|
|
399
|
-
|
|
400
|
-
return new UnencryptedL2Log(AztecAddress.fromNumber(txIndex), log);
|
|
411
|
+
return makePublicLog(tag);
|
|
401
412
|
});
|
|
402
|
-
return new UnencryptedTxL2Logs([new UnencryptedFunctionL2Logs(logs)]);
|
|
403
413
|
};
|
|
404
414
|
|
|
405
|
-
const mockBlockWithLogs = (blockNumber: number): L1Published<L2Block
|
|
406
|
-
const block = L2Block.random(blockNumber);
|
|
415
|
+
const mockBlockWithLogs = async (blockNumber: number): Promise<L1Published<L2Block>> => {
|
|
416
|
+
const block = await L2Block.random(blockNumber);
|
|
407
417
|
block.header.globalVariables.blockNumber = new Fr(blockNumber);
|
|
408
418
|
|
|
409
|
-
block.body.txEffects =
|
|
410
|
-
const txEffect = TxEffect.random();
|
|
419
|
+
block.body.txEffects = await timesParallel(numTxsPerBlock, async (txIndex: number) => {
|
|
420
|
+
const txEffect = await TxEffect.random();
|
|
411
421
|
txEffect.privateLogs = mockPrivateLogs(blockNumber, txIndex);
|
|
412
|
-
txEffect.
|
|
422
|
+
txEffect.publicLogs = mockPublicLogs(blockNumber, txIndex);
|
|
413
423
|
return txEffect;
|
|
414
424
|
});
|
|
415
425
|
|
|
@@ -420,7 +430,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
420
430
|
};
|
|
421
431
|
|
|
422
432
|
beforeEach(async () => {
|
|
423
|
-
blocks =
|
|
433
|
+
blocks = await timesParallel(numBlocks, (index: number) => mockBlockWithLogs(index));
|
|
424
434
|
|
|
425
435
|
await store.addBlocks(blocks);
|
|
426
436
|
await store.addLogs(blocks.map(b => b.data));
|
|
@@ -449,9 +459,8 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
449
459
|
]);
|
|
450
460
|
});
|
|
451
461
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
// Tag(0, 0, 0) is shared with the first private log and the first unencrypted log.
|
|
462
|
+
it('is possible to batch request all logs (private and public) via tags', async () => {
|
|
463
|
+
// Tag(0, 0, 0) is shared with the first private log and the first public log.
|
|
455
464
|
const tags = [makeTag(0, 0, 0)];
|
|
456
465
|
|
|
457
466
|
const logsByTags = await store.getLogsByTags(tags);
|
|
@@ -465,7 +474,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
465
474
|
}),
|
|
466
475
|
expect.objectContaining({
|
|
467
476
|
blockNumber: 0,
|
|
468
|
-
logData: makePublicLog(tags[0]),
|
|
477
|
+
logData: makePublicLog(tags[0]).toBuffer(),
|
|
469
478
|
isFromPublic: true,
|
|
470
479
|
}),
|
|
471
480
|
],
|
|
@@ -477,7 +486,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
477
486
|
|
|
478
487
|
// Create a block containing logs that have the same tag as the blocks before.
|
|
479
488
|
const newBlockNumber = numBlocks;
|
|
480
|
-
const newBlock = mockBlockWithLogs(newBlockNumber);
|
|
489
|
+
const newBlock = await mockBlockWithLogs(newBlockNumber);
|
|
481
490
|
const newLog = newBlock.data.body.txEffects[1].privateLogs[1];
|
|
482
491
|
newLog.fields[0] = tags[0];
|
|
483
492
|
newBlock.data.body.txEffects[1].privateLogs[1] = newLog;
|
|
@@ -520,18 +529,48 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
520
529
|
],
|
|
521
530
|
]);
|
|
522
531
|
});
|
|
532
|
+
|
|
533
|
+
it('is not possible to add public logs by tag if they are invalid', async () => {
|
|
534
|
+
const tag = makeTag(99, 88, 77);
|
|
535
|
+
const invalidLogs = [
|
|
536
|
+
PublicLog.fromFields([
|
|
537
|
+
AztecAddress.fromNumber(1).toField(),
|
|
538
|
+
makeLengthsField(2, 3), // This field claims we have 5 items, but we actually have more
|
|
539
|
+
tag,
|
|
540
|
+
...times(PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 1, i => new Fr(tag.toNumber() + i)),
|
|
541
|
+
]),
|
|
542
|
+
PublicLog.fromFields([
|
|
543
|
+
AztecAddress.fromNumber(1).toField(),
|
|
544
|
+
makeLengthsField(2, PUBLIC_LOG_DATA_SIZE_IN_FIELDS), // This field claims we have more than the max items
|
|
545
|
+
tag,
|
|
546
|
+
...times(PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 1, i => new Fr(tag.toNumber() + i)),
|
|
547
|
+
]),
|
|
548
|
+
];
|
|
549
|
+
|
|
550
|
+
// Create a block containing these invalid logs
|
|
551
|
+
const newBlockNumber = numBlocks;
|
|
552
|
+
const newBlock = await mockBlockWithLogs(newBlockNumber);
|
|
553
|
+
newBlock.data.body.txEffects[0].publicLogs = invalidLogs;
|
|
554
|
+
await store.addBlocks([newBlock]);
|
|
555
|
+
await store.addLogs([newBlock.data]);
|
|
556
|
+
|
|
557
|
+
const logsByTags = await store.getLogsByTags([tag]);
|
|
558
|
+
|
|
559
|
+
// Neither of the logs should have been added:
|
|
560
|
+
expect(logsByTags).toEqual([[]]);
|
|
561
|
+
});
|
|
523
562
|
});
|
|
524
563
|
|
|
525
|
-
describe('
|
|
564
|
+
describe('getPublicLogs', () => {
|
|
526
565
|
const txsPerBlock = 4;
|
|
527
566
|
const numPublicFunctionCalls = 3;
|
|
528
|
-
const
|
|
567
|
+
const numPublicLogs = 2;
|
|
529
568
|
const numBlocks = 10;
|
|
530
569
|
let blocks: L1Published<L2Block>[];
|
|
531
570
|
|
|
532
571
|
beforeEach(async () => {
|
|
533
|
-
blocks =
|
|
534
|
-
data: L2Block.random(index + 1, txsPerBlock, numPublicFunctionCalls,
|
|
572
|
+
blocks = await timesParallel(numBlocks, async (index: number) => ({
|
|
573
|
+
data: await L2Block.random(index + 1, txsPerBlock, numPublicFunctionCalls, numPublicLogs),
|
|
535
574
|
l1: { blockNumber: BigInt(index), blockHash: `0x${index}`, timestamp: BigInt(index) },
|
|
536
575
|
}));
|
|
537
576
|
|
|
@@ -550,7 +589,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
550
589
|
store.deleteLogs(blocks.map(b => b.data)),
|
|
551
590
|
]);
|
|
552
591
|
|
|
553
|
-
const response = await store.
|
|
592
|
+
const response = await store.getPublicLogs({ txHash: targetTxHash });
|
|
554
593
|
const logs = response.logs;
|
|
555
594
|
|
|
556
595
|
expect(response.maxLogsHit).toBeFalsy();
|
|
@@ -563,12 +602,12 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
563
602
|
const targetTxIndex = randomInt(txsPerBlock);
|
|
564
603
|
const targetTxHash = blocks[targetBlockIndex].data.body.txEffects[targetTxIndex].txHash;
|
|
565
604
|
|
|
566
|
-
const response = await store.
|
|
605
|
+
const response = await store.getPublicLogs({ txHash: targetTxHash });
|
|
567
606
|
const logs = response.logs;
|
|
568
607
|
|
|
569
608
|
expect(response.maxLogsHit).toBeFalsy();
|
|
570
609
|
|
|
571
|
-
const expectedNumLogs = numPublicFunctionCalls *
|
|
610
|
+
const expectedNumLogs = numPublicFunctionCalls * numPublicLogs;
|
|
572
611
|
expect(logs.length).toEqual(expectedNumLogs);
|
|
573
612
|
|
|
574
613
|
const targeBlockNumber = targetBlockIndex + INITIAL_L2_BLOCK_NUM;
|
|
@@ -583,12 +622,12 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
583
622
|
const fromBlock = 3;
|
|
584
623
|
const toBlock = 7;
|
|
585
624
|
|
|
586
|
-
const response = await store.
|
|
625
|
+
const response = await store.getPublicLogs({ fromBlock, toBlock });
|
|
587
626
|
const logs = response.logs;
|
|
588
627
|
|
|
589
628
|
expect(response.maxLogsHit).toBeFalsy();
|
|
590
629
|
|
|
591
|
-
const expectedNumLogs = txsPerBlock * numPublicFunctionCalls *
|
|
630
|
+
const expectedNumLogs = txsPerBlock * numPublicFunctionCalls * numPublicLogs * (toBlock - fromBlock);
|
|
592
631
|
expect(logs.length).toEqual(expectedNumLogs);
|
|
593
632
|
|
|
594
633
|
for (const log of logs) {
|
|
@@ -602,14 +641,11 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
602
641
|
// Get a random contract address from the logs
|
|
603
642
|
const targetBlockIndex = randomInt(numBlocks);
|
|
604
643
|
const targetTxIndex = randomInt(txsPerBlock);
|
|
605
|
-
const
|
|
606
|
-
const targetLogIndex = randomInt(numUnencryptedLogs);
|
|
644
|
+
const targetLogIndex = randomInt(numPublicLogs * numPublicFunctionCalls);
|
|
607
645
|
const targetContractAddress =
|
|
608
|
-
blocks[targetBlockIndex].data.body.txEffects[targetTxIndex].
|
|
609
|
-
targetFunctionLogIndex
|
|
610
|
-
].logs[targetLogIndex].contractAddress;
|
|
646
|
+
blocks[targetBlockIndex].data.body.txEffects[targetTxIndex].publicLogs[targetLogIndex].contractAddress;
|
|
611
647
|
|
|
612
|
-
const response = await store.
|
|
648
|
+
const response = await store.getPublicLogs({ contractAddress: targetContractAddress });
|
|
613
649
|
|
|
614
650
|
expect(response.maxLogsHit).toBeFalsy();
|
|
615
651
|
|
|
@@ -622,11 +658,11 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
622
658
|
// Get a random log as reference
|
|
623
659
|
const targetBlockIndex = randomInt(numBlocks);
|
|
624
660
|
const targetTxIndex = randomInt(txsPerBlock);
|
|
625
|
-
const targetLogIndex = randomInt(
|
|
661
|
+
const targetLogIndex = randomInt(numPublicLogs);
|
|
626
662
|
|
|
627
663
|
const afterLog = new LogId(targetBlockIndex + INITIAL_L2_BLOCK_NUM, targetTxIndex, targetLogIndex);
|
|
628
664
|
|
|
629
|
-
const response = await store.
|
|
665
|
+
const response = await store.getPublicLogs({ afterLog });
|
|
630
666
|
const logs = response.logs;
|
|
631
667
|
|
|
632
668
|
expect(response.maxLogsHit).toBeFalsy();
|
|
@@ -648,40 +684,40 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
648
684
|
const txHash = TxHash.random();
|
|
649
685
|
const afterLog = new LogId(1, 0, 0);
|
|
650
686
|
|
|
651
|
-
const response = await store.
|
|
687
|
+
const response = await store.getPublicLogs({ txHash, afterLog });
|
|
652
688
|
expect(response.logs.length).toBeGreaterThan(1);
|
|
653
689
|
});
|
|
654
690
|
|
|
655
691
|
it('intersecting works', async () => {
|
|
656
|
-
let logs = (await store.
|
|
692
|
+
let logs = (await store.getPublicLogs({ fromBlock: -10, toBlock: -5 })).logs;
|
|
657
693
|
expect(logs.length).toBe(0);
|
|
658
694
|
|
|
659
695
|
// "fromBlock" gets correctly trimmed to range and "toBlock" is exclusive
|
|
660
|
-
logs = (await store.
|
|
696
|
+
logs = (await store.getPublicLogs({ fromBlock: -10, toBlock: 5 })).logs;
|
|
661
697
|
let blockNumbers = new Set(logs.map(log => log.id.blockNumber));
|
|
662
698
|
expect(blockNumbers).toEqual(new Set([1, 2, 3, 4]));
|
|
663
699
|
|
|
664
700
|
// "toBlock" should be exclusive
|
|
665
|
-
logs = (await store.
|
|
701
|
+
logs = (await store.getPublicLogs({ fromBlock: 1, toBlock: 1 })).logs;
|
|
666
702
|
expect(logs.length).toBe(0);
|
|
667
703
|
|
|
668
|
-
logs = (await store.
|
|
704
|
+
logs = (await store.getPublicLogs({ fromBlock: 10, toBlock: 5 })).logs;
|
|
669
705
|
expect(logs.length).toBe(0);
|
|
670
706
|
|
|
671
707
|
// both "fromBlock" and "toBlock" get correctly capped to range and logs from all blocks are returned
|
|
672
|
-
logs = (await store.
|
|
708
|
+
logs = (await store.getPublicLogs({ fromBlock: -100, toBlock: +100 })).logs;
|
|
673
709
|
blockNumbers = new Set(logs.map(log => log.id.blockNumber));
|
|
674
710
|
expect(blockNumbers.size).toBe(numBlocks);
|
|
675
711
|
|
|
676
712
|
// intersecting with "afterLog" works
|
|
677
|
-
logs = (await store.
|
|
713
|
+
logs = (await store.getPublicLogs({ fromBlock: 2, toBlock: 5, afterLog: new LogId(4, 0, 0) })).logs;
|
|
678
714
|
blockNumbers = new Set(logs.map(log => log.id.blockNumber));
|
|
679
715
|
expect(blockNumbers).toEqual(new Set([4]));
|
|
680
716
|
|
|
681
|
-
logs = (await store.
|
|
717
|
+
logs = (await store.getPublicLogs({ toBlock: 5, afterLog: new LogId(5, 1, 0) })).logs;
|
|
682
718
|
expect(logs.length).toBe(0);
|
|
683
719
|
|
|
684
|
-
logs = (await store.
|
|
720
|
+
logs = (await store.getPublicLogs({ fromBlock: 2, toBlock: 5, afterLog: new LogId(100, 0, 0) })).logs;
|
|
685
721
|
expect(logs.length).toBe(0);
|
|
686
722
|
});
|
|
687
723
|
|
|
@@ -689,11 +725,11 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
689
725
|
// Get a random log as reference
|
|
690
726
|
const targetBlockIndex = randomInt(numBlocks);
|
|
691
727
|
const targetTxIndex = randomInt(txsPerBlock);
|
|
692
|
-
const targetLogIndex = randomInt(
|
|
728
|
+
const targetLogIndex = randomInt(numPublicLogs);
|
|
693
729
|
|
|
694
730
|
const afterLog = new LogId(targetBlockIndex + INITIAL_L2_BLOCK_NUM, targetTxIndex, targetLogIndex);
|
|
695
731
|
|
|
696
|
-
const response = await store.
|
|
732
|
+
const response = await store.getPublicLogs({ afterLog, fromBlock: afterLog.blockNumber });
|
|
697
733
|
const logs = response.logs;
|
|
698
734
|
|
|
699
735
|
expect(response.maxLogsHit).toBeFalsy();
|
|
@@ -716,8 +752,8 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
716
752
|
const numBlocks = 10;
|
|
717
753
|
const nullifiersPerBlock = new Map<number, Fr[]>();
|
|
718
754
|
|
|
719
|
-
beforeEach(() => {
|
|
720
|
-
blocks =
|
|
755
|
+
beforeEach(async () => {
|
|
756
|
+
blocks = await timesParallel(numBlocks, (index: number) => L2Block.random(index + 1, 1));
|
|
721
757
|
|
|
722
758
|
blocks.forEach((block, blockIndex) => {
|
|
723
759
|
nullifiersPerBlock.set(
|
package/src/archiver/config.ts
CHANGED
|
@@ -22,7 +22,7 @@ export type ArchiverConfig = {
|
|
|
22
22
|
archiverUrl?: string;
|
|
23
23
|
|
|
24
24
|
/** URL for an L1 consensus client */
|
|
25
|
-
|
|
25
|
+
l1ConsensusHostUrl?: string;
|
|
26
26
|
|
|
27
27
|
/** The polling interval in ms for retrieving new L2 blocks and encrypted logs. */
|
|
28
28
|
archiverPollingIntervalMS?: number;
|
|
@@ -36,7 +36,7 @@ export type ArchiverConfig = {
|
|
|
36
36
|
/** The deployed L1 contract addresses */
|
|
37
37
|
l1Contracts: L1ContractAddresses;
|
|
38
38
|
|
|
39
|
-
/** The max number of logs that can be obtained in 1 "
|
|
39
|
+
/** The max number of logs that can be obtained in 1 "getPublicLogs" call. */
|
|
40
40
|
maxLogs?: number;
|
|
41
41
|
} & L1ReaderConfig &
|
|
42
42
|
L1ContractsConfig;
|
|
@@ -47,10 +47,10 @@ export const archiverConfigMappings: ConfigMappingsType<ArchiverConfig> = {
|
|
|
47
47
|
description:
|
|
48
48
|
'URL for an archiver service. If set, will return an archiver client as opposed to starting a new one.',
|
|
49
49
|
},
|
|
50
|
-
|
|
51
|
-
env: '
|
|
50
|
+
l1ConsensusHostUrl: {
|
|
51
|
+
env: 'L1_CONSENSUS_HOST_URL',
|
|
52
52
|
description: 'URL for an L1 consensus client.',
|
|
53
|
-
parseEnv: (val: string) =>
|
|
53
|
+
parseEnv: (val: string) => val,
|
|
54
54
|
},
|
|
55
55
|
archiverPollingIntervalMS: {
|
|
56
56
|
env: 'ARCHIVER_POLLING_INTERVAL_MS',
|
|
@@ -64,7 +64,7 @@ export const archiverConfigMappings: ConfigMappingsType<ArchiverConfig> = {
|
|
|
64
64
|
},
|
|
65
65
|
maxLogs: {
|
|
66
66
|
env: 'ARCHIVER_MAX_LOGS',
|
|
67
|
-
description: 'The max number of logs that can be obtained in 1 "
|
|
67
|
+
description: 'The max number of logs that can be obtained in 1 "getPublicLogs" call.',
|
|
68
68
|
...numberConfigHelper(1_000),
|
|
69
69
|
},
|
|
70
70
|
...l1ReaderConfigMappings,
|