@aztec/archiver 0.74.0 → 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2

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.
Files changed (81) hide show
  1. package/dest/archiver/archiver.js +729 -711
  2. package/dest/archiver/archiver_store.js +4 -2
  3. package/dest/archiver/archiver_store_test_suite.js +385 -224
  4. package/dest/archiver/config.js +9 -11
  5. package/dest/archiver/data_retrieval.js +78 -68
  6. package/dest/archiver/errors.js +1 -2
  7. package/dest/archiver/index.js +0 -1
  8. package/dest/archiver/instrumentation.js +29 -17
  9. package/dest/archiver/kv_archiver_store/block_store.js +118 -127
  10. package/dest/archiver/kv_archiver_store/contract_class_store.js +43 -37
  11. package/dest/archiver/kv_archiver_store/contract_instance_store.js +7 -12
  12. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +135 -158
  13. package/dest/archiver/kv_archiver_store/log_store.js +271 -256
  14. package/dest/archiver/kv_archiver_store/message_store.js +42 -48
  15. package/dest/archiver/kv_archiver_store/nullifier_store.js +35 -42
  16. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +15 -24
  17. package/dest/archiver/memory_archiver_store/memory_archiver_store.js +227 -231
  18. package/dest/archiver/structs/data_retrieval.js +5 -2
  19. package/dest/archiver/structs/published.js +1 -2
  20. package/dest/factory.js +30 -20
  21. package/dest/index.js +0 -1
  22. package/dest/rpc/index.js +5 -2
  23. package/dest/test/index.js +0 -1
  24. package/dest/test/mock_archiver.js +8 -13
  25. package/dest/test/mock_l1_to_l2_message_source.js +4 -4
  26. package/dest/test/mock_l2_block_source.js +68 -67
  27. package/package.json +14 -13
  28. package/src/archiver/data_retrieval.ts +1 -1
  29. package/src/archiver/index.ts +1 -1
  30. package/dest/archiver/archiver.d.ts +0 -186
  31. package/dest/archiver/archiver.d.ts.map +0 -1
  32. package/dest/archiver/archiver_store.d.ts +0 -217
  33. package/dest/archiver/archiver_store.d.ts.map +0 -1
  34. package/dest/archiver/archiver_store_test_suite.d.ts +0 -8
  35. package/dest/archiver/archiver_store_test_suite.d.ts.map +0 -1
  36. package/dest/archiver/config.d.ts +0 -35
  37. package/dest/archiver/config.d.ts.map +0 -1
  38. package/dest/archiver/data_retrieval.d.ts +0 -71
  39. package/dest/archiver/data_retrieval.d.ts.map +0 -1
  40. package/dest/archiver/errors.d.ts +0 -4
  41. package/dest/archiver/errors.d.ts.map +0 -1
  42. package/dest/archiver/index.d.ts +0 -8
  43. package/dest/archiver/index.d.ts.map +0 -1
  44. package/dest/archiver/instrumentation.d.ts +0 -27
  45. package/dest/archiver/instrumentation.d.ts.map +0 -1
  46. package/dest/archiver/kv_archiver_store/block_store.d.ts +0 -87
  47. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +0 -1
  48. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +0 -17
  49. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +0 -1
  50. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +0 -13
  51. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +0 -1
  52. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +0 -147
  53. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +0 -1
  54. package/dest/archiver/kv_archiver_store/log_store.d.ts +0 -47
  55. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +0 -1
  56. package/dest/archiver/kv_archiver_store/message_store.d.ts +0 -33
  57. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +0 -1
  58. package/dest/archiver/kv_archiver_store/nullifier_store.d.ts +0 -12
  59. package/dest/archiver/kv_archiver_store/nullifier_store.d.ts.map +0 -1
  60. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +0 -23
  61. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +0 -1
  62. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +0 -168
  63. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +0 -1
  64. package/dest/archiver/structs/data_retrieval.d.ts +0 -27
  65. package/dest/archiver/structs/data_retrieval.d.ts.map +0 -1
  66. package/dest/archiver/structs/published.d.ts +0 -11
  67. package/dest/archiver/structs/published.d.ts.map +0 -1
  68. package/dest/factory.d.ts +0 -10
  69. package/dest/factory.d.ts.map +0 -1
  70. package/dest/index.d.ts +0 -5
  71. package/dest/index.d.ts.map +0 -1
  72. package/dest/rpc/index.d.ts +0 -4
  73. package/dest/rpc/index.d.ts.map +0 -1
  74. package/dest/test/index.d.ts +0 -4
  75. package/dest/test/index.d.ts.map +0 -1
  76. package/dest/test/mock_archiver.d.ts +0 -22
  77. package/dest/test/mock_archiver.d.ts.map +0 -1
  78. package/dest/test/mock_l1_to_l2_message_source.d.ts +0 -16
  79. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +0 -1
  80. package/dest/test/mock_l2_block_source.d.ts +0 -80
  81. package/dest/test/mock_l2_block_source.d.ts.map +0 -1
@@ -1,266 +1,340 @@
1
1
  import { InboxLeaf, L2Block, LogId, TxEffect, TxHash, wrapInBlock } from '@aztec/circuit-types';
2
2
  import '@aztec/circuit-types/jest';
3
- import { AztecAddress, Fr, INITIAL_L2_BLOCK_NUM, L1_TO_L2_MSG_SUBTREE_HEIGHT, MAX_NULLIFIERS_PER_TX, PRIVATE_LOG_SIZE_IN_FIELDS, PUBLIC_LOG_DATA_SIZE_IN_FIELDS, PrivateLog, PublicLog, SerializableContractInstance, computePublicBytecodeCommitment, } from '@aztec/circuits.js';
4
- import { makeContractClassPublic, makeExecutablePrivateFunctionWithMembershipProof, makeUnconstrainedFunctionWithMembershipProof, } from '@aztec/circuits.js/testing';
3
+ import { AztecAddress, Fr, INITIAL_L2_BLOCK_NUM, L1_TO_L2_MSG_SUBTREE_HEIGHT, MAX_NULLIFIERS_PER_TX, PRIVATE_LOG_SIZE_IN_FIELDS, PUBLIC_LOG_DATA_SIZE_IN_FIELDS, PrivateLog, PublicLog, SerializableContractInstance, computePublicBytecodeCommitment } from '@aztec/circuits.js';
4
+ import { makeContractClassPublic, makeExecutablePrivateFunctionWithMembershipProof, makeUnconstrainedFunctionWithMembershipProof } from '@aztec/circuits.js/testing';
5
5
  import { times, timesParallel } from '@aztec/foundation/collection';
6
6
  import { randomInt } from '@aztec/foundation/crypto';
7
7
  /**
8
8
  * @param testName - The name of the test suite.
9
9
  * @param getStore - Returns an instance of a store that's already been initialized.
10
- */
11
- export function describeArchiverDataStore(testName, getStore) {
12
- describe(testName, () => {
10
+ */ export function describeArchiverDataStore(testName, getStore) {
11
+ describe(testName, ()=>{
13
12
  let store;
14
13
  let blocks;
15
14
  const blockTests = [
16
- [1, 1, () => blocks.slice(0, 1)],
17
- [10, 1, () => blocks.slice(9, 10)],
18
- [1, 10, () => blocks.slice(0, 10)],
19
- [2, 5, () => blocks.slice(1, 6)],
20
- [5, 2, () => blocks.slice(4, 6)],
15
+ [
16
+ 1,
17
+ 1,
18
+ ()=>blocks.slice(0, 1)
19
+ ],
20
+ [
21
+ 10,
22
+ 1,
23
+ ()=>blocks.slice(9, 10)
24
+ ],
25
+ [
26
+ 1,
27
+ 10,
28
+ ()=>blocks.slice(0, 10)
29
+ ],
30
+ [
31
+ 2,
32
+ 5,
33
+ ()=>blocks.slice(1, 6)
34
+ ],
35
+ [
36
+ 5,
37
+ 2,
38
+ ()=>blocks.slice(4, 6)
39
+ ]
21
40
  ];
22
- const makeL1Published = (block, l1BlockNumber) => ({
23
- data: block,
24
- l1: {
25
- blockNumber: BigInt(l1BlockNumber),
26
- blockHash: `0x${l1BlockNumber}`,
27
- timestamp: BigInt(l1BlockNumber * 1000),
28
- },
29
- });
30
- beforeEach(async () => {
41
+ const makeL1Published = (block, l1BlockNumber)=>({
42
+ data: block,
43
+ l1: {
44
+ blockNumber: BigInt(l1BlockNumber),
45
+ blockHash: `0x${l1BlockNumber}`,
46
+ timestamp: BigInt(l1BlockNumber * 1000)
47
+ }
48
+ });
49
+ beforeEach(async ()=>{
31
50
  store = await getStore();
32
- blocks = await timesParallel(10, async (i) => makeL1Published(await L2Block.random(i + 1), i + 10));
51
+ blocks = await timesParallel(10, async (i)=>makeL1Published(await L2Block.random(i + 1), i + 10));
33
52
  });
34
- describe('addBlocks', () => {
35
- it('returns success when adding blocks', async () => {
53
+ describe('addBlocks', ()=>{
54
+ it('returns success when adding blocks', async ()=>{
36
55
  await expect(store.addBlocks(blocks)).resolves.toBe(true);
37
56
  });
38
- it('allows duplicate blocks', async () => {
57
+ it('allows duplicate blocks', async ()=>{
39
58
  await store.addBlocks(blocks);
40
59
  await expect(store.addBlocks(blocks)).resolves.toBe(true);
41
60
  });
42
61
  });
43
- describe('unwindBlocks', () => {
44
- it('unwinding blocks will remove blocks from the chain', async () => {
62
+ describe('unwindBlocks', ()=>{
63
+ it('unwinding blocks will remove blocks from the chain', async ()=>{
45
64
  await store.addBlocks(blocks);
46
65
  const blockNumber = await store.getSynchedL2BlockNumber();
47
- expect(await store.getBlocks(blockNumber, 1)).toEqual([blocks[blocks.length - 1]]);
66
+ expect(await store.getBlocks(blockNumber, 1)).toEqual([
67
+ blocks[blocks.length - 1]
68
+ ]);
48
69
  await store.unwindBlocks(blockNumber, 1);
49
70
  expect(await store.getSynchedL2BlockNumber()).toBe(blockNumber - 1);
50
71
  expect(await store.getBlocks(blockNumber, 1)).toEqual([]);
51
72
  });
52
- it('can unwind multiple empty blocks', async () => {
53
- const emptyBlocks = await timesParallel(10, async (i) => makeL1Published(await L2Block.random(i + 1, 0), i + 10));
73
+ it('can unwind multiple empty blocks', async ()=>{
74
+ const emptyBlocks = await timesParallel(10, async (i)=>makeL1Published(await L2Block.random(i + 1, 0), i + 10));
54
75
  await store.addBlocks(emptyBlocks);
55
76
  expect(await store.getSynchedL2BlockNumber()).toBe(10);
56
77
  await store.unwindBlocks(10, 3);
57
78
  expect(await store.getSynchedL2BlockNumber()).toBe(7);
58
- expect((await store.getBlocks(1, 10)).map(b => b.data.number)).toEqual([1, 2, 3, 4, 5, 6, 7]);
79
+ expect((await store.getBlocks(1, 10)).map((b)=>b.data.number)).toEqual([
80
+ 1,
81
+ 2,
82
+ 3,
83
+ 4,
84
+ 5,
85
+ 6,
86
+ 7
87
+ ]);
59
88
  });
60
- it('refuses to unwind blocks if the tip is not the last block', async () => {
89
+ it('refuses to unwind blocks if the tip is not the last block', async ()=>{
61
90
  await store.addBlocks(blocks);
62
91
  await expect(store.unwindBlocks(5, 1)).rejects.toThrow(/can only unwind blocks from the tip/i);
63
92
  });
64
93
  });
65
- describe('getBlocks', () => {
66
- beforeEach(async () => {
94
+ describe('getBlocks', ()=>{
95
+ beforeEach(async ()=>{
67
96
  await store.addBlocks(blocks);
68
97
  });
69
- it.each(blockTests)('retrieves previously stored blocks', async (start, limit, getExpectedBlocks) => {
98
+ it.each(blockTests)('retrieves previously stored blocks', async (start, limit, getExpectedBlocks)=>{
70
99
  await expect(store.getBlocks(start, limit)).resolves.toEqual(getExpectedBlocks());
71
100
  });
72
- it('returns an empty array if no blocks are found', async () => {
101
+ it('returns an empty array if no blocks are found', async ()=>{
73
102
  await expect(store.getBlocks(12, 1)).resolves.toEqual([]);
74
103
  });
75
- it('throws an error if limit is invalid', async () => {
104
+ it('throws an error if limit is invalid', async ()=>{
76
105
  await expect(store.getBlocks(1, 0)).rejects.toThrow('Invalid limit: 0');
77
106
  });
78
- it('throws an error if `from` it is out of range', async () => {
107
+ it('throws an error if `from` it is out of range', async ()=>{
79
108
  await expect(store.getBlocks(INITIAL_L2_BLOCK_NUM - 100, 1)).rejects.toThrow('Invalid start: -99');
80
109
  });
81
110
  });
82
- describe('getSyncedL2BlockNumber', () => {
83
- it('returns the block number before INITIAL_L2_BLOCK_NUM if no blocks have been added', async () => {
111
+ describe('getSyncedL2BlockNumber', ()=>{
112
+ it('returns the block number before INITIAL_L2_BLOCK_NUM if no blocks have been added', async ()=>{
84
113
  await expect(store.getSynchedL2BlockNumber()).resolves.toEqual(INITIAL_L2_BLOCK_NUM - 1);
85
114
  });
86
- it("returns the most recently added block's number", async () => {
115
+ it("returns the most recently added block's number", async ()=>{
87
116
  await store.addBlocks(blocks);
88
117
  await expect(store.getSynchedL2BlockNumber()).resolves.toEqual(blocks.at(-1).data.number);
89
118
  });
90
119
  });
91
- describe('getSynchPoint', () => {
92
- it('returns undefined if no blocks have been added', async () => {
120
+ describe('getSynchPoint', ()=>{
121
+ it('returns undefined if no blocks have been added', async ()=>{
93
122
  await expect(store.getSynchPoint()).resolves.toEqual({
94
123
  blocksSynchedTo: undefined,
95
- messagesSynchedTo: undefined,
124
+ messagesSynchedTo: undefined
96
125
  });
97
126
  });
98
- it('returns the L1 block number in which the most recent L2 block was published', async () => {
127
+ it('returns the L1 block number in which the most recent L2 block was published', async ()=>{
99
128
  await store.addBlocks(blocks);
100
129
  await expect(store.getSynchPoint()).resolves.toEqual({
101
130
  blocksSynchedTo: 19n,
102
- messagesSynchedTo: undefined,
131
+ messagesSynchedTo: undefined
103
132
  });
104
133
  });
105
- it('returns the L1 block number that most recently added messages from inbox', async () => {
134
+ it('returns the L1 block number that most recently added messages from inbox', async ()=>{
106
135
  await store.addL1ToL2Messages({
107
136
  lastProcessedL1BlockNumber: 1n,
108
- retrievedData: [new InboxLeaf(1n, Fr.ZERO)],
137
+ retrievedData: [
138
+ new InboxLeaf(1n, Fr.ZERO)
139
+ ]
109
140
  });
110
141
  await expect(store.getSynchPoint()).resolves.toEqual({
111
142
  blocksSynchedTo: undefined,
112
- messagesSynchedTo: 1n,
143
+ messagesSynchedTo: 1n
113
144
  });
114
145
  });
115
146
  });
116
- describe('addLogs', () => {
117
- it('adds private & public logs', async () => {
147
+ describe('addLogs', ()=>{
148
+ it('adds private & public logs', async ()=>{
118
149
  const block = blocks[0].data;
119
- await expect(store.addLogs([block])).resolves.toEqual(true);
150
+ await expect(store.addLogs([
151
+ block
152
+ ])).resolves.toEqual(true);
120
153
  });
121
154
  });
122
- describe('deleteLogs', () => {
123
- it('deletes private & public logs', async () => {
155
+ describe('deleteLogs', ()=>{
156
+ it('deletes private & public logs', async ()=>{
124
157
  const block = blocks[0].data;
125
- await store.addBlocks([blocks[0]]);
126
- await expect(store.addLogs([block])).resolves.toEqual(true);
127
- expect((await store.getPrivateLogs(1, 1)).length).toEqual(block.body.txEffects.map(txEffect => txEffect.privateLogs).flat().length);
128
- expect((await store.getPublicLogs({ fromBlock: 1 })).logs.length).toEqual(block.body.txEffects.map(txEffect => txEffect.publicLogs).flat().length);
158
+ await store.addBlocks([
159
+ blocks[0]
160
+ ]);
161
+ await expect(store.addLogs([
162
+ block
163
+ ])).resolves.toEqual(true);
164
+ expect((await store.getPrivateLogs(1, 1)).length).toEqual(block.body.txEffects.map((txEffect)=>txEffect.privateLogs).flat().length);
165
+ expect((await store.getPublicLogs({
166
+ fromBlock: 1
167
+ })).logs.length).toEqual(block.body.txEffects.map((txEffect)=>txEffect.publicLogs).flat().length);
129
168
  // This one is a pain for memory as we would never want to just delete memory in the middle.
130
- await store.deleteLogs([block]);
169
+ await store.deleteLogs([
170
+ block
171
+ ]);
131
172
  expect((await store.getPrivateLogs(1, 1)).length).toEqual(0);
132
- expect((await store.getPublicLogs({ fromBlock: 1 })).logs.length).toEqual(0);
173
+ expect((await store.getPublicLogs({
174
+ fromBlock: 1
175
+ })).logs.length).toEqual(0);
133
176
  });
134
177
  });
135
- describe('getPrivateLogs', () => {
136
- it('gets added private logs', async () => {
178
+ describe('getPrivateLogs', ()=>{
179
+ it('gets added private logs', async ()=>{
137
180
  const block = blocks[0].data;
138
- await store.addBlocks([blocks[0]]);
139
- await store.addLogs([block]);
181
+ await store.addBlocks([
182
+ blocks[0]
183
+ ]);
184
+ await store.addLogs([
185
+ block
186
+ ]);
140
187
  const privateLogs = await store.getPrivateLogs(1, 1);
141
- expect(privateLogs).toEqual(block.body.txEffects.map(txEffect => txEffect.privateLogs).flat());
188
+ expect(privateLogs).toEqual(block.body.txEffects.map((txEffect)=>txEffect.privateLogs).flat());
142
189
  });
143
190
  });
144
- describe('getTxEffect', () => {
145
- beforeEach(async () => {
146
- await store.addLogs(blocks.map(b => b.data));
191
+ describe('getTxEffect', ()=>{
192
+ beforeEach(async ()=>{
193
+ await store.addLogs(blocks.map((b)=>b.data));
147
194
  await store.addBlocks(blocks);
148
195
  });
149
196
  it.each([
150
- () => wrapInBlock(blocks[0].data.body.txEffects[0], blocks[0].data),
151
- () => wrapInBlock(blocks[9].data.body.txEffects[3], blocks[9].data),
152
- () => wrapInBlock(blocks[3].data.body.txEffects[1], blocks[3].data),
153
- () => wrapInBlock(blocks[5].data.body.txEffects[2], blocks[5].data),
154
- () => wrapInBlock(blocks[1].data.body.txEffects[0], blocks[1].data),
155
- ])('retrieves a previously stored transaction', async (getExpectedTx) => {
197
+ ()=>wrapInBlock(blocks[0].data.body.txEffects[0], blocks[0].data),
198
+ ()=>wrapInBlock(blocks[9].data.body.txEffects[3], blocks[9].data),
199
+ ()=>wrapInBlock(blocks[3].data.body.txEffects[1], blocks[3].data),
200
+ ()=>wrapInBlock(blocks[5].data.body.txEffects[2], blocks[5].data),
201
+ ()=>wrapInBlock(blocks[1].data.body.txEffects[0], blocks[1].data)
202
+ ])('retrieves a previously stored transaction', async (getExpectedTx)=>{
156
203
  const expectedTx = await getExpectedTx();
157
204
  const actualTx = await store.getTxEffect(expectedTx.data.txHash);
158
205
  expect(actualTx).toEqual(expectedTx);
159
206
  });
160
- it('returns undefined if tx is not found', async () => {
207
+ it('returns undefined if tx is not found', async ()=>{
161
208
  await expect(store.getTxEffect(TxHash.random())).resolves.toBeUndefined();
162
209
  });
163
210
  it.each([
164
- () => wrapInBlock(blocks[0].data.body.txEffects[0], blocks[0].data),
165
- () => wrapInBlock(blocks[9].data.body.txEffects[3], blocks[9].data),
166
- () => wrapInBlock(blocks[3].data.body.txEffects[1], blocks[3].data),
167
- () => wrapInBlock(blocks[5].data.body.txEffects[2], blocks[5].data),
168
- () => wrapInBlock(blocks[1].data.body.txEffects[0], blocks[1].data),
169
- ])('tries to retrieves a previously stored transaction after deleted', async (getExpectedTx) => {
211
+ ()=>wrapInBlock(blocks[0].data.body.txEffects[0], blocks[0].data),
212
+ ()=>wrapInBlock(blocks[9].data.body.txEffects[3], blocks[9].data),
213
+ ()=>wrapInBlock(blocks[3].data.body.txEffects[1], blocks[3].data),
214
+ ()=>wrapInBlock(blocks[5].data.body.txEffects[2], blocks[5].data),
215
+ ()=>wrapInBlock(blocks[1].data.body.txEffects[0], blocks[1].data)
216
+ ])('tries to retrieves a previously stored transaction after deleted', async (getExpectedTx)=>{
170
217
  await store.unwindBlocks(blocks.length, blocks.length);
171
218
  const expectedTx = await getExpectedTx();
172
219
  const actualTx = await store.getTxEffect(expectedTx.data.txHash);
173
220
  expect(actualTx).toEqual(undefined);
174
221
  });
175
- it('returns undefined if tx is not found', async () => {
222
+ it('returns undefined if tx is not found', async ()=>{
176
223
  await expect(store.getTxEffect(TxHash.random())).resolves.toBeUndefined();
177
224
  });
178
225
  });
179
- describe('L1 to L2 Messages', () => {
226
+ describe('L1 to L2 Messages', ()=>{
180
227
  const l2BlockNumber = 13n;
181
228
  const l1ToL2MessageSubtreeSize = 2 ** L1_TO_L2_MSG_SUBTREE_HEIGHT;
182
- const generateBlockMessages = (blockNumber, numMessages) => Array.from({ length: numMessages }, (_, i) => new InboxLeaf(InboxLeaf.smallestIndexFromL2Block(blockNumber) + BigInt(i), Fr.random()));
183
- it('returns messages in correct order', async () => {
229
+ const generateBlockMessages = (blockNumber, numMessages)=>Array.from({
230
+ length: numMessages
231
+ }, (_, i)=>new InboxLeaf(InboxLeaf.smallestIndexFromL2Block(blockNumber) + BigInt(i), Fr.random()));
232
+ it('returns messages in correct order', async ()=>{
184
233
  const msgs = generateBlockMessages(l2BlockNumber, l1ToL2MessageSubtreeSize);
185
- const shuffledMessages = msgs.slice().sort(() => randomInt(1) - 0.5);
186
- await store.addL1ToL2Messages({ lastProcessedL1BlockNumber: 100n, retrievedData: shuffledMessages });
234
+ const shuffledMessages = msgs.slice().sort(()=>randomInt(1) - 0.5);
235
+ await store.addL1ToL2Messages({
236
+ lastProcessedL1BlockNumber: 100n,
237
+ retrievedData: shuffledMessages
238
+ });
187
239
  const retrievedMessages = await store.getL1ToL2Messages(l2BlockNumber);
188
- const expectedLeavesOrder = msgs.map(msg => msg.leaf);
240
+ const expectedLeavesOrder = msgs.map((msg)=>msg.leaf);
189
241
  expect(expectedLeavesOrder).toEqual(retrievedMessages);
190
242
  });
191
- it('throws if it is impossible to sequence messages correctly', async () => {
243
+ it('throws if it is impossible to sequence messages correctly', async ()=>{
192
244
  const msgs = generateBlockMessages(l2BlockNumber, l1ToL2MessageSubtreeSize - 1);
193
245
  // We replace a message with index 4 with a message with index at the end of the tree
194
246
  // --> with that there will be a gap and it will be impossible to sequence the
195
247
  // end of tree = start of next tree/block - 1
196
248
  msgs[4] = new InboxLeaf(InboxLeaf.smallestIndexFromL2Block(l2BlockNumber + 1n) - 1n, Fr.random());
197
- await store.addL1ToL2Messages({ lastProcessedL1BlockNumber: 100n, retrievedData: msgs });
198
- await expect(async () => {
249
+ await store.addL1ToL2Messages({
250
+ lastProcessedL1BlockNumber: 100n,
251
+ retrievedData: msgs
252
+ });
253
+ await expect(async ()=>{
199
254
  await store.getL1ToL2Messages(l2BlockNumber);
200
255
  }).rejects.toThrow(`L1 to L2 message gap found in block ${l2BlockNumber}`);
201
256
  });
202
257
  });
203
- describe('contractInstances', () => {
258
+ describe('contractInstances', ()=>{
204
259
  let contractInstance;
205
260
  const blockNum = 10;
206
- beforeEach(async () => {
261
+ beforeEach(async ()=>{
207
262
  const randomInstance = await SerializableContractInstance.random();
208
- contractInstance = { ...randomInstance, address: await AztecAddress.random() };
209
- await store.addContractInstances([contractInstance], blockNum);
263
+ contractInstance = {
264
+ ...randomInstance,
265
+ address: await AztecAddress.random()
266
+ };
267
+ await store.addContractInstances([
268
+ contractInstance
269
+ ], blockNum);
210
270
  });
211
- it('returns previously stored contract instances', async () => {
271
+ it('returns previously stored contract instances', async ()=>{
212
272
  await expect(store.getContractInstance(contractInstance.address)).resolves.toMatchObject(contractInstance);
213
273
  });
214
- it('returns undefined if contract instance is not found', async () => {
274
+ it('returns undefined if contract instance is not found', async ()=>{
215
275
  await expect(store.getContractInstance(await AztecAddress.random())).resolves.toBeUndefined();
216
276
  });
217
- it('returns undefined if previously stored contract instances was deleted', async () => {
218
- await store.deleteContractInstances([contractInstance], blockNum);
277
+ it('returns undefined if previously stored contract instances was deleted', async ()=>{
278
+ await store.deleteContractInstances([
279
+ contractInstance
280
+ ], blockNum);
219
281
  await expect(store.getContractInstance(contractInstance.address)).resolves.toBeUndefined();
220
282
  });
221
283
  });
222
- describe('contractClasses', () => {
284
+ describe('contractClasses', ()=>{
223
285
  let contractClass;
224
286
  const blockNum = 10;
225
- beforeEach(async () => {
287
+ beforeEach(async ()=>{
226
288
  contractClass = await makeContractClassPublic();
227
- await store.addContractClasses([contractClass], [await computePublicBytecodeCommitment(contractClass.packedBytecode)], blockNum);
289
+ await store.addContractClasses([
290
+ contractClass
291
+ ], [
292
+ await computePublicBytecodeCommitment(contractClass.packedBytecode)
293
+ ], blockNum);
228
294
  });
229
- it('returns previously stored contract class', async () => {
295
+ it('returns previously stored contract class', async ()=>{
230
296
  await expect(store.getContractClass(contractClass.id)).resolves.toMatchObject(contractClass);
231
297
  });
232
- it('returns undefined if the initial deployed contract class was deleted', async () => {
233
- await store.deleteContractClasses([contractClass], blockNum);
298
+ it('returns undefined if the initial deployed contract class was deleted', async ()=>{
299
+ await store.deleteContractClasses([
300
+ contractClass
301
+ ], blockNum);
234
302
  await expect(store.getContractClass(contractClass.id)).resolves.toBeUndefined();
235
303
  });
236
- it('returns contract class if later "deployment" class was deleted', async () => {
237
- await store.addContractClasses([contractClass], [await computePublicBytecodeCommitment(contractClass.packedBytecode)], blockNum + 1);
238
- await store.deleteContractClasses([contractClass], blockNum + 1);
304
+ it('returns contract class if later "deployment" class was deleted', async ()=>{
305
+ await store.addContractClasses([
306
+ contractClass
307
+ ], [
308
+ await computePublicBytecodeCommitment(contractClass.packedBytecode)
309
+ ], blockNum + 1);
310
+ await store.deleteContractClasses([
311
+ contractClass
312
+ ], blockNum + 1);
239
313
  await expect(store.getContractClass(contractClass.id)).resolves.toMatchObject(contractClass);
240
314
  });
241
- it('returns undefined if contract class is not found', async () => {
315
+ it('returns undefined if contract class is not found', async ()=>{
242
316
  await expect(store.getContractClass(Fr.random())).resolves.toBeUndefined();
243
317
  });
244
- it('adds new private functions', async () => {
318
+ it('adds new private functions', async ()=>{
245
319
  const fns = times(3, makeExecutablePrivateFunctionWithMembershipProof);
246
320
  await store.addFunctions(contractClass.id, fns, []);
247
321
  const stored = await store.getContractClass(contractClass.id);
248
322
  expect(stored?.privateFunctions).toEqual(fns);
249
323
  });
250
- it('does not duplicate private functions', async () => {
324
+ it('does not duplicate private functions', async ()=>{
251
325
  const fns = times(3, makeExecutablePrivateFunctionWithMembershipProof);
252
326
  await store.addFunctions(contractClass.id, fns.slice(0, 1), []);
253
327
  await store.addFunctions(contractClass.id, fns, []);
254
328
  const stored = await store.getContractClass(contractClass.id);
255
329
  expect(stored?.privateFunctions).toEqual(fns);
256
330
  });
257
- it('adds new unconstrained functions', async () => {
331
+ it('adds new unconstrained functions', async ()=>{
258
332
  const fns = times(3, makeUnconstrainedFunctionWithMembershipProof);
259
333
  await store.addFunctions(contractClass.id, [], fns);
260
334
  const stored = await store.getContractClass(contractClass.id);
261
335
  expect(stored?.unconstrainedFunctions).toEqual(fns);
262
336
  });
263
- it('does not duplicate unconstrained functions', async () => {
337
+ it('does not duplicate unconstrained functions', async ()=>{
264
338
  const fns = times(3, makeUnconstrainedFunctionWithMembershipProof);
265
339
  await store.addFunctions(contractClass.id, [], fns.slice(0, 1));
266
340
  await store.addFunctions(contractClass.id, [], fns);
@@ -268,46 +342,49 @@ export function describeArchiverDataStore(testName, getStore) {
268
342
  expect(stored?.unconstrainedFunctions).toEqual(fns);
269
343
  });
270
344
  });
271
- describe('getLogsByTags', () => {
345
+ describe('getLogsByTags', ()=>{
272
346
  const numBlocks = 3;
273
347
  const numTxsPerBlock = 4;
274
348
  const numPrivateLogsPerTx = 3;
275
349
  const numPublicLogsPerTx = 2;
276
350
  let blocks;
277
- const makeTag = (blockNumber, txIndex, logIndex, isPublic = false) => new Fr((blockNumber * 100 + txIndex * 10 + logIndex) * (isPublic ? 123 : 1));
351
+ const makeTag = (blockNumber, txIndex, logIndex, isPublic = false)=>new Fr((blockNumber * 100 + txIndex * 10 + logIndex) * (isPublic ? 123 : 1));
278
352
  // See parseLogFromPublic
279
353
  // 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.
280
- const makeLengthsField = (publicValuesLen, privateValuesLen) => {
354
+ const makeLengthsField = (publicValuesLen, privateValuesLen)=>{
281
355
  const buf = Buffer.alloc(32);
282
356
  buf.writeUint16BE(publicValuesLen, 27);
283
357
  buf.writeUint16BE(privateValuesLen, 30);
284
358
  return Fr.fromBuffer(buf);
285
359
  };
286
- const makePrivateLog = (tag) => PrivateLog.fromFields([tag, ...times(PRIVATE_LOG_SIZE_IN_FIELDS - 1, i => new Fr(tag.toNumber() + i))]);
360
+ const makePrivateLog = (tag)=>PrivateLog.fromFields([
361
+ tag,
362
+ ...times(PRIVATE_LOG_SIZE_IN_FIELDS - 1, (i)=>new Fr(tag.toNumber() + i))
363
+ ]);
287
364
  // The tag lives in field 1, not 0, of a public log
288
365
  // See extractTaggedLogsFromPublic and noir-projects/aztec-nr/aztec/src/macros/notes/mod.nr -> emit_log
289
- const makePublicLog = (tag) => PublicLog.fromFields([
290
- AztecAddress.fromNumber(1).toField(), // log address
291
- makeLengthsField(2, PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 3), // field 0
292
- tag, // field 1
293
- ...times(PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 1, i => new Fr(tag.toNumber() + i)), // fields 2 to end
294
- ]);
295
- const mockPrivateLogs = (blockNumber, txIndex) => {
296
- return times(numPrivateLogsPerTx, (logIndex) => {
366
+ const makePublicLog = (tag)=>PublicLog.fromFields([
367
+ AztecAddress.fromNumber(1).toField(),
368
+ makeLengthsField(2, PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 3),
369
+ tag,
370
+ ...times(PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 1, (i)=>new Fr(tag.toNumber() + i))
371
+ ]);
372
+ const mockPrivateLogs = (blockNumber, txIndex)=>{
373
+ return times(numPrivateLogsPerTx, (logIndex)=>{
297
374
  const tag = makeTag(blockNumber, txIndex, logIndex);
298
375
  return makePrivateLog(tag);
299
376
  });
300
377
  };
301
- const mockPublicLogs = (blockNumber, txIndex) => {
302
- return times(numPublicLogsPerTx, (logIndex) => {
378
+ const mockPublicLogs = (blockNumber, txIndex)=>{
379
+ return times(numPublicLogsPerTx, (logIndex)=>{
303
380
  const tag = makeTag(blockNumber, txIndex, logIndex, /* isPublic */ true);
304
381
  return makePublicLog(tag);
305
382
  });
306
383
  };
307
- const mockBlockWithLogs = async (blockNumber) => {
384
+ const mockBlockWithLogs = async (blockNumber)=>{
308
385
  const block = await L2Block.random(blockNumber);
309
386
  block.header.globalVariables.blockNumber = new Fr(blockNumber);
310
- block.body.txEffects = await timesParallel(numTxsPerBlock, async (txIndex) => {
387
+ block.body.txEffects = await timesParallel(numTxsPerBlock, async (txIndex)=>{
311
388
  const txEffect = await TxEffect.random();
312
389
  txEffect.privateLogs = mockPrivateLogs(blockNumber, txIndex);
313
390
  txEffect.publicLogs = mockPublicLogs(blockNumber, txIndex);
@@ -315,203 +392,242 @@ export function describeArchiverDataStore(testName, getStore) {
315
392
  });
316
393
  return {
317
394
  data: block,
318
- l1: { blockNumber: BigInt(blockNumber), blockHash: `0x${blockNumber}`, timestamp: BigInt(blockNumber) },
395
+ l1: {
396
+ blockNumber: BigInt(blockNumber),
397
+ blockHash: `0x${blockNumber}`,
398
+ timestamp: BigInt(blockNumber)
399
+ }
319
400
  };
320
401
  };
321
- beforeEach(async () => {
322
- blocks = await timesParallel(numBlocks, (index) => mockBlockWithLogs(index));
402
+ beforeEach(async ()=>{
403
+ blocks = await timesParallel(numBlocks, (index)=>mockBlockWithLogs(index));
323
404
  await store.addBlocks(blocks);
324
- await store.addLogs(blocks.map(b => b.data));
405
+ await store.addLogs(blocks.map((b)=>b.data));
325
406
  });
326
- it('is possible to batch request private logs via tags', async () => {
327
- const tags = [makeTag(1, 1, 2), makeTag(0, 2, 0)];
407
+ it('is possible to batch request private logs via tags', async ()=>{
408
+ const tags = [
409
+ makeTag(1, 1, 2),
410
+ makeTag(0, 2, 0)
411
+ ];
328
412
  const logsByTags = await store.getLogsByTags(tags);
329
413
  expect(logsByTags).toEqual([
330
414
  [
331
415
  expect.objectContaining({
332
416
  blockNumber: 1,
333
417
  logData: makePrivateLog(tags[0]).toBuffer(),
334
- isFromPublic: false,
335
- }),
418
+ isFromPublic: false
419
+ })
336
420
  ],
337
421
  [
338
422
  expect.objectContaining({
339
423
  blockNumber: 0,
340
424
  logData: makePrivateLog(tags[1]).toBuffer(),
341
- isFromPublic: false,
342
- }),
343
- ],
425
+ isFromPublic: false
426
+ })
427
+ ]
344
428
  ]);
345
429
  });
346
- it('is possible to batch request all logs (private and public) via tags', async () => {
430
+ it('is possible to batch request all logs (private and public) via tags', async ()=>{
347
431
  // Tag(0, 0, 0) is shared with the first private log and the first public log.
348
- const tags = [makeTag(0, 0, 0)];
432
+ const tags = [
433
+ makeTag(0, 0, 0)
434
+ ];
349
435
  const logsByTags = await store.getLogsByTags(tags);
350
436
  expect(logsByTags).toEqual([
351
437
  [
352
438
  expect.objectContaining({
353
439
  blockNumber: 0,
354
440
  logData: makePrivateLog(tags[0]).toBuffer(),
355
- isFromPublic: false,
441
+ isFromPublic: false
356
442
  }),
357
443
  expect.objectContaining({
358
444
  blockNumber: 0,
359
445
  logData: makePublicLog(tags[0]).toBuffer(),
360
- isFromPublic: true,
361
- }),
362
- ],
446
+ isFromPublic: true
447
+ })
448
+ ]
363
449
  ]);
364
450
  });
365
- it('is possible to batch request logs that have the same tag but different content', async () => {
366
- const tags = [makeTag(1, 2, 1)];
451
+ it('is possible to batch request logs that have the same tag but different content', async ()=>{
452
+ const tags = [
453
+ makeTag(1, 2, 1)
454
+ ];
367
455
  // Create a block containing logs that have the same tag as the blocks before.
368
456
  const newBlockNumber = numBlocks;
369
457
  const newBlock = await mockBlockWithLogs(newBlockNumber);
370
458
  const newLog = newBlock.data.body.txEffects[1].privateLogs[1];
371
459
  newLog.fields[0] = tags[0];
372
460
  newBlock.data.body.txEffects[1].privateLogs[1] = newLog;
373
- await store.addBlocks([newBlock]);
374
- await store.addLogs([newBlock.data]);
461
+ await store.addBlocks([
462
+ newBlock
463
+ ]);
464
+ await store.addLogs([
465
+ newBlock.data
466
+ ]);
375
467
  const logsByTags = await store.getLogsByTags(tags);
376
468
  expect(logsByTags).toEqual([
377
469
  [
378
470
  expect.objectContaining({
379
471
  blockNumber: 1,
380
472
  logData: makePrivateLog(tags[0]).toBuffer(),
381
- isFromPublic: false,
473
+ isFromPublic: false
382
474
  }),
383
475
  expect.objectContaining({
384
476
  blockNumber: newBlockNumber,
385
477
  logData: newLog.toBuffer(),
386
- isFromPublic: false,
387
- }),
388
- ],
478
+ isFromPublic: false
479
+ })
480
+ ]
389
481
  ]);
390
482
  });
391
- it('is possible to request logs for non-existing tags and determine their position', async () => {
392
- const tags = [makeTag(99, 88, 77), makeTag(1, 1, 1)];
483
+ it('is possible to request logs for non-existing tags and determine their position', async ()=>{
484
+ const tags = [
485
+ makeTag(99, 88, 77),
486
+ makeTag(1, 1, 1)
487
+ ];
393
488
  const logsByTags = await store.getLogsByTags(tags);
394
489
  expect(logsByTags).toEqual([
395
- [
396
- // No logs for the first tag.
397
- ],
490
+ [],
398
491
  [
399
492
  expect.objectContaining({
400
493
  blockNumber: 1,
401
494
  logData: makePrivateLog(tags[1]).toBuffer(),
402
- isFromPublic: false,
403
- }),
404
- ],
495
+ isFromPublic: false
496
+ })
497
+ ]
405
498
  ]);
406
499
  });
407
- it('is not possible to add public logs by tag if they are invalid', async () => {
500
+ it('is not possible to add public logs by tag if they are invalid', async ()=>{
408
501
  const tag = makeTag(99, 88, 77);
409
502
  const invalidLogs = [
410
503
  PublicLog.fromFields([
411
504
  AztecAddress.fromNumber(1).toField(),
412
- makeLengthsField(2, 3), // This field claims we have 5 items, but we actually have more
505
+ makeLengthsField(2, 3),
413
506
  tag,
414
- ...times(PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 1, i => new Fr(tag.toNumber() + i)),
507
+ ...times(PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 1, (i)=>new Fr(tag.toNumber() + i))
415
508
  ]),
416
509
  PublicLog.fromFields([
417
510
  AztecAddress.fromNumber(1).toField(),
418
- makeLengthsField(2, PUBLIC_LOG_DATA_SIZE_IN_FIELDS), // This field claims we have more than the max items
511
+ makeLengthsField(2, PUBLIC_LOG_DATA_SIZE_IN_FIELDS),
419
512
  tag,
420
- ...times(PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 1, i => new Fr(tag.toNumber() + i)),
421
- ]),
513
+ ...times(PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 1, (i)=>new Fr(tag.toNumber() + i))
514
+ ])
422
515
  ];
423
516
  // Create a block containing these invalid logs
424
517
  const newBlockNumber = numBlocks;
425
518
  const newBlock = await mockBlockWithLogs(newBlockNumber);
426
519
  newBlock.data.body.txEffects[0].publicLogs = invalidLogs;
427
- await store.addBlocks([newBlock]);
428
- await store.addLogs([newBlock.data]);
429
- const logsByTags = await store.getLogsByTags([tag]);
520
+ await store.addBlocks([
521
+ newBlock
522
+ ]);
523
+ await store.addLogs([
524
+ newBlock.data
525
+ ]);
526
+ const logsByTags = await store.getLogsByTags([
527
+ tag
528
+ ]);
430
529
  // Neither of the logs should have been added:
431
- expect(logsByTags).toEqual([[]]);
530
+ expect(logsByTags).toEqual([
531
+ []
532
+ ]);
432
533
  });
433
534
  });
434
- describe('getPublicLogs', () => {
535
+ describe('getPublicLogs', ()=>{
435
536
  const txsPerBlock = 4;
436
537
  const numPublicFunctionCalls = 3;
437
538
  const numPublicLogs = 2;
438
539
  const numBlocks = 10;
439
540
  let blocks;
440
- beforeEach(async () => {
441
- blocks = await timesParallel(numBlocks, async (index) => ({
442
- data: await L2Block.random(index + 1, txsPerBlock, numPublicFunctionCalls, numPublicLogs),
443
- l1: { blockNumber: BigInt(index), blockHash: `0x${index}`, timestamp: BigInt(index) },
444
- }));
541
+ beforeEach(async ()=>{
542
+ blocks = await timesParallel(numBlocks, async (index)=>({
543
+ data: await L2Block.random(index + 1, txsPerBlock, numPublicFunctionCalls, numPublicLogs),
544
+ l1: {
545
+ blockNumber: BigInt(index),
546
+ blockHash: `0x${index}`,
547
+ timestamp: BigInt(index)
548
+ }
549
+ }));
445
550
  await store.addBlocks(blocks);
446
- await store.addLogs(blocks.map(b => b.data));
551
+ await store.addLogs(blocks.map((b)=>b.data));
447
552
  });
448
- it('no logs returned if deleted ("txHash" filter param is respected variant)', async () => {
553
+ it('no logs returned if deleted ("txHash" filter param is respected variant)', async ()=>{
449
554
  // get random tx
450
555
  const targetBlockIndex = randomInt(numBlocks);
451
556
  const targetTxIndex = randomInt(txsPerBlock);
452
557
  const targetTxHash = blocks[targetBlockIndex].data.body.txEffects[targetTxIndex].txHash;
453
558
  await Promise.all([
454
559
  store.unwindBlocks(blocks.length, blocks.length),
455
- store.deleteLogs(blocks.map(b => b.data)),
560
+ store.deleteLogs(blocks.map((b)=>b.data))
456
561
  ]);
457
- const response = await store.getPublicLogs({ txHash: targetTxHash });
562
+ const response = await store.getPublicLogs({
563
+ txHash: targetTxHash
564
+ });
458
565
  const logs = response.logs;
459
566
  expect(response.maxLogsHit).toBeFalsy();
460
567
  expect(logs.length).toEqual(0);
461
568
  });
462
- it('"txHash" filter param is respected', async () => {
569
+ it('"txHash" filter param is respected', async ()=>{
463
570
  // get random tx
464
571
  const targetBlockIndex = randomInt(numBlocks);
465
572
  const targetTxIndex = randomInt(txsPerBlock);
466
573
  const targetTxHash = blocks[targetBlockIndex].data.body.txEffects[targetTxIndex].txHash;
467
- const response = await store.getPublicLogs({ txHash: targetTxHash });
574
+ const response = await store.getPublicLogs({
575
+ txHash: targetTxHash
576
+ });
468
577
  const logs = response.logs;
469
578
  expect(response.maxLogsHit).toBeFalsy();
470
579
  const expectedNumLogs = numPublicFunctionCalls * numPublicLogs;
471
580
  expect(logs.length).toEqual(expectedNumLogs);
472
581
  const targeBlockNumber = targetBlockIndex + INITIAL_L2_BLOCK_NUM;
473
- for (const log of logs) {
582
+ for (const log of logs){
474
583
  expect(log.id.blockNumber).toEqual(targeBlockNumber);
475
584
  expect(log.id.txIndex).toEqual(targetTxIndex);
476
585
  }
477
586
  });
478
- it('"fromBlock" and "toBlock" filter params are respected', async () => {
587
+ it('"fromBlock" and "toBlock" filter params are respected', async ()=>{
479
588
  // Set "fromBlock" and "toBlock"
480
589
  const fromBlock = 3;
481
590
  const toBlock = 7;
482
- const response = await store.getPublicLogs({ fromBlock, toBlock });
591
+ const response = await store.getPublicLogs({
592
+ fromBlock,
593
+ toBlock
594
+ });
483
595
  const logs = response.logs;
484
596
  expect(response.maxLogsHit).toBeFalsy();
485
597
  const expectedNumLogs = txsPerBlock * numPublicFunctionCalls * numPublicLogs * (toBlock - fromBlock);
486
598
  expect(logs.length).toEqual(expectedNumLogs);
487
- for (const log of logs) {
599
+ for (const log of logs){
488
600
  const blockNumber = log.id.blockNumber;
489
601
  expect(blockNumber).toBeGreaterThanOrEqual(fromBlock);
490
602
  expect(blockNumber).toBeLessThan(toBlock);
491
603
  }
492
604
  });
493
- it('"contractAddress" filter param is respected', async () => {
605
+ it('"contractAddress" filter param is respected', async ()=>{
494
606
  // Get a random contract address from the logs
495
607
  const targetBlockIndex = randomInt(numBlocks);
496
608
  const targetTxIndex = randomInt(txsPerBlock);
497
609
  const targetLogIndex = randomInt(numPublicLogs * numPublicFunctionCalls);
498
610
  const targetContractAddress = blocks[targetBlockIndex].data.body.txEffects[targetTxIndex].publicLogs[targetLogIndex].contractAddress;
499
- const response = await store.getPublicLogs({ contractAddress: targetContractAddress });
611
+ const response = await store.getPublicLogs({
612
+ contractAddress: targetContractAddress
613
+ });
500
614
  expect(response.maxLogsHit).toBeFalsy();
501
- for (const extendedLog of response.logs) {
615
+ for (const extendedLog of response.logs){
502
616
  expect(extendedLog.log.contractAddress.equals(targetContractAddress)).toBeTruthy();
503
617
  }
504
618
  });
505
- it('"afterLog" filter param is respected', async () => {
619
+ it('"afterLog" filter param is respected', async ()=>{
506
620
  // Get a random log as reference
507
621
  const targetBlockIndex = randomInt(numBlocks);
508
622
  const targetTxIndex = randomInt(txsPerBlock);
509
623
  const targetLogIndex = randomInt(numPublicLogs);
510
624
  const afterLog = new LogId(targetBlockIndex + INITIAL_L2_BLOCK_NUM, targetTxIndex, targetLogIndex);
511
- const response = await store.getPublicLogs({ afterLog });
625
+ const response = await store.getPublicLogs({
626
+ afterLog
627
+ });
512
628
  const logs = response.logs;
513
629
  expect(response.maxLogsHit).toBeFalsy();
514
- for (const log of logs) {
630
+ for (const log of logs){
515
631
  const logId = log.id;
516
632
  expect(logId.blockNumber).toBeGreaterThanOrEqual(afterLog.blockNumber);
517
633
  if (logId.blockNumber === afterLog.blockNumber) {
@@ -522,48 +638,87 @@ export function describeArchiverDataStore(testName, getStore) {
522
638
  }
523
639
  }
524
640
  });
525
- it('"txHash" filter param is ignored when "afterLog" is set', async () => {
641
+ it('"txHash" filter param is ignored when "afterLog" is set', async ()=>{
526
642
  // Get random txHash
527
643
  const txHash = TxHash.random();
528
644
  const afterLog = new LogId(1, 0, 0);
529
- const response = await store.getPublicLogs({ txHash, afterLog });
645
+ const response = await store.getPublicLogs({
646
+ txHash,
647
+ afterLog
648
+ });
530
649
  expect(response.logs.length).toBeGreaterThan(1);
531
650
  });
532
- it('intersecting works', async () => {
533
- let logs = (await store.getPublicLogs({ fromBlock: -10, toBlock: -5 })).logs;
651
+ it('intersecting works', async ()=>{
652
+ let logs = (await store.getPublicLogs({
653
+ fromBlock: -10,
654
+ toBlock: -5
655
+ })).logs;
534
656
  expect(logs.length).toBe(0);
535
657
  // "fromBlock" gets correctly trimmed to range and "toBlock" is exclusive
536
- logs = (await store.getPublicLogs({ fromBlock: -10, toBlock: 5 })).logs;
537
- let blockNumbers = new Set(logs.map(log => log.id.blockNumber));
538
- expect(blockNumbers).toEqual(new Set([1, 2, 3, 4]));
658
+ logs = (await store.getPublicLogs({
659
+ fromBlock: -10,
660
+ toBlock: 5
661
+ })).logs;
662
+ let blockNumbers = new Set(logs.map((log)=>log.id.blockNumber));
663
+ expect(blockNumbers).toEqual(new Set([
664
+ 1,
665
+ 2,
666
+ 3,
667
+ 4
668
+ ]));
539
669
  // "toBlock" should be exclusive
540
- logs = (await store.getPublicLogs({ fromBlock: 1, toBlock: 1 })).logs;
670
+ logs = (await store.getPublicLogs({
671
+ fromBlock: 1,
672
+ toBlock: 1
673
+ })).logs;
541
674
  expect(logs.length).toBe(0);
542
- logs = (await store.getPublicLogs({ fromBlock: 10, toBlock: 5 })).logs;
675
+ logs = (await store.getPublicLogs({
676
+ fromBlock: 10,
677
+ toBlock: 5
678
+ })).logs;
543
679
  expect(logs.length).toBe(0);
544
680
  // both "fromBlock" and "toBlock" get correctly capped to range and logs from all blocks are returned
545
- logs = (await store.getPublicLogs({ fromBlock: -100, toBlock: +100 })).logs;
546
- blockNumbers = new Set(logs.map(log => log.id.blockNumber));
681
+ logs = (await store.getPublicLogs({
682
+ fromBlock: -100,
683
+ toBlock: +100
684
+ })).logs;
685
+ blockNumbers = new Set(logs.map((log)=>log.id.blockNumber));
547
686
  expect(blockNumbers.size).toBe(numBlocks);
548
687
  // intersecting with "afterLog" works
549
- logs = (await store.getPublicLogs({ fromBlock: 2, toBlock: 5, afterLog: new LogId(4, 0, 0) })).logs;
550
- blockNumbers = new Set(logs.map(log => log.id.blockNumber));
551
- expect(blockNumbers).toEqual(new Set([4]));
552
- logs = (await store.getPublicLogs({ toBlock: 5, afterLog: new LogId(5, 1, 0) })).logs;
688
+ logs = (await store.getPublicLogs({
689
+ fromBlock: 2,
690
+ toBlock: 5,
691
+ afterLog: new LogId(4, 0, 0)
692
+ })).logs;
693
+ blockNumbers = new Set(logs.map((log)=>log.id.blockNumber));
694
+ expect(blockNumbers).toEqual(new Set([
695
+ 4
696
+ ]));
697
+ logs = (await store.getPublicLogs({
698
+ toBlock: 5,
699
+ afterLog: new LogId(5, 1, 0)
700
+ })).logs;
553
701
  expect(logs.length).toBe(0);
554
- logs = (await store.getPublicLogs({ fromBlock: 2, toBlock: 5, afterLog: new LogId(100, 0, 0) })).logs;
702
+ logs = (await store.getPublicLogs({
703
+ fromBlock: 2,
704
+ toBlock: 5,
705
+ afterLog: new LogId(100, 0, 0)
706
+ })).logs;
555
707
  expect(logs.length).toBe(0);
556
708
  });
557
- it('"txIndex" and "logIndex" are respected when "afterLog.blockNumber" is equal to "fromBlock"', async () => {
709
+ it('"txIndex" and "logIndex" are respected when "afterLog.blockNumber" is equal to "fromBlock"', async ()=>{
558
710
  // Get a random log as reference
559
711
  const targetBlockIndex = randomInt(numBlocks);
560
712
  const targetTxIndex = randomInt(txsPerBlock);
561
713
  const targetLogIndex = randomInt(numPublicLogs);
562
714
  const afterLog = new LogId(targetBlockIndex + INITIAL_L2_BLOCK_NUM, targetTxIndex, targetLogIndex);
563
- const response = await store.getPublicLogs({ afterLog, fromBlock: afterLog.blockNumber });
715
+ const response = await store.getPublicLogs({
716
+ afterLog,
717
+ fromBlock: afterLog.blockNumber
718
+ });
564
719
  const logs = response.logs;
565
720
  expect(response.maxLogsHit).toBeFalsy();
566
- for (const log of logs) {
721
+ for (const log of logs){
567
722
  const logId = log.id;
568
723
  expect(logId.blockNumber).toBeGreaterThanOrEqual(afterLog.blockNumber);
569
724
  if (logId.blockNumber === afterLog.blockNumber) {
@@ -575,24 +730,28 @@ export function describeArchiverDataStore(testName, getStore) {
575
730
  }
576
731
  });
577
732
  });
578
- describe('findNullifiersIndexesWithBlock', () => {
733
+ describe('findNullifiersIndexesWithBlock', ()=>{
579
734
  let blocks;
580
735
  const numBlocks = 10;
581
736
  const nullifiersPerBlock = new Map();
582
- beforeEach(async () => {
583
- blocks = await timesParallel(numBlocks, (index) => L2Block.random(index + 1, 1));
584
- blocks.forEach((block, blockIndex) => {
585
- nullifiersPerBlock.set(blockIndex, block.body.txEffects.flatMap(txEffect => txEffect.nullifiers));
737
+ beforeEach(async ()=>{
738
+ blocks = await timesParallel(numBlocks, (index)=>L2Block.random(index + 1, 1));
739
+ blocks.forEach((block, blockIndex)=>{
740
+ nullifiersPerBlock.set(blockIndex, block.body.txEffects.flatMap((txEffect)=>txEffect.nullifiers));
586
741
  });
587
742
  });
588
- it('returns wrapped nullifiers with blocks if they exist', async () => {
743
+ it('returns wrapped nullifiers with blocks if they exist', async ()=>{
589
744
  await store.addNullifiers(blocks);
590
- const nullifiersToRetrieve = [...nullifiersPerBlock.get(0), ...nullifiersPerBlock.get(5), Fr.random()];
745
+ const nullifiersToRetrieve = [
746
+ ...nullifiersPerBlock.get(0),
747
+ ...nullifiersPerBlock.get(5),
748
+ Fr.random()
749
+ ];
591
750
  const blockScopedNullifiers = await store.findNullifiersIndexesWithBlock(10, nullifiersToRetrieve);
592
751
  expect(blockScopedNullifiers).toHaveLength(nullifiersToRetrieve.length);
593
752
  const [undefinedNullifier] = blockScopedNullifiers.slice(-1);
594
753
  const realNullifiers = blockScopedNullifiers.slice(0, -1);
595
- realNullifiers.forEach((blockScopedNullifier, index) => {
754
+ realNullifiers.forEach((blockScopedNullifier, index)=>{
596
755
  expect(blockScopedNullifier).not.toBeUndefined();
597
756
  const { data, l2BlockNumber } = blockScopedNullifier;
598
757
  expect(data).toEqual(expect.any(BigInt));
@@ -600,24 +759,26 @@ export function describeArchiverDataStore(testName, getStore) {
600
759
  });
601
760
  expect(undefinedNullifier).toBeUndefined();
602
761
  });
603
- it('returns wrapped nullifiers filtering by blockNumber', async () => {
762
+ it('returns wrapped nullifiers filtering by blockNumber', async ()=>{
604
763
  await store.addNullifiers(blocks);
605
- const nullifiersToRetrieve = [...nullifiersPerBlock.get(0), ...nullifiersPerBlock.get(5)];
764
+ const nullifiersToRetrieve = [
765
+ ...nullifiersPerBlock.get(0),
766
+ ...nullifiersPerBlock.get(5)
767
+ ];
606
768
  const blockScopedNullifiers = await store.findNullifiersIndexesWithBlock(5, nullifiersToRetrieve);
607
769
  expect(blockScopedNullifiers).toHaveLength(nullifiersToRetrieve.length);
608
770
  const undefinedNullifiers = blockScopedNullifiers.slice(-MAX_NULLIFIERS_PER_TX);
609
771
  const realNullifiers = blockScopedNullifiers.slice(0, -MAX_NULLIFIERS_PER_TX);
610
- realNullifiers.forEach(blockScopedNullifier => {
772
+ realNullifiers.forEach((blockScopedNullifier)=>{
611
773
  expect(blockScopedNullifier).not.toBeUndefined();
612
774
  const { data, l2BlockNumber } = blockScopedNullifier;
613
775
  expect(data).toEqual(expect.any(BigInt));
614
776
  expect(l2BlockNumber).toEqual(1);
615
777
  });
616
- undefinedNullifiers.forEach(undefinedNullifier => {
778
+ undefinedNullifiers.forEach((undefinedNullifier)=>{
617
779
  expect(undefinedNullifier).toBeUndefined();
618
780
  });
619
781
  });
620
782
  });
621
783
  });
622
784
  }
623
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJjaGl2ZXJfc3RvcmVfdGVzdF9zdWl0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcmNoaXZlci9hcmNoaXZlcl9zdG9yZV90ZXN0X3N1aXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2hHLE9BQU8sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUNMLFlBQVksRUFHWixFQUFFLEVBQ0Ysb0JBQW9CLEVBQ3BCLDJCQUEyQixFQUMzQixxQkFBcUIsRUFDckIsMEJBQTBCLEVBQzFCLDhCQUE4QixFQUM5QixVQUFVLEVBQ1YsU0FBUyxFQUNULDRCQUE0QixFQUM1QiwrQkFBK0IsR0FDaEMsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGdEQUFnRCxFQUNoRCw0Q0FBNEMsR0FDN0MsTUFBTSw0QkFBNEIsQ0FBQztBQUNwQyxPQUFPLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3BFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUtyRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUseUJBQXlCLENBQ3ZDLFFBQWdCLEVBQ2hCLFFBQThEO0lBRTlELFFBQVEsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFO1FBQ3RCLElBQUksS0FBd0IsQ0FBQztRQUM3QixJQUFJLE1BQThCLENBQUM7UUFDbkMsTUFBTSxVQUFVLEdBQXFEO1lBQ25FLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNoQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFB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