@aztec/archiver 3.0.0-canary.a9708bd → 3.0.0-devnet.2-patch.1

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 (127) hide show
  1. package/README.md +27 -6
  2. package/dest/archiver/archiver.d.ts +87 -64
  3. package/dest/archiver/archiver.d.ts.map +1 -1
  4. package/dest/archiver/archiver.js +463 -278
  5. package/dest/archiver/archiver_store.d.ts +46 -28
  6. package/dest/archiver/archiver_store.d.ts.map +1 -1
  7. package/dest/archiver/archiver_store_test_suite.d.ts +1 -1
  8. package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
  9. package/dest/archiver/archiver_store_test_suite.js +316 -143
  10. package/dest/archiver/config.d.ts +6 -23
  11. package/dest/archiver/config.d.ts.map +1 -1
  12. package/dest/archiver/config.js +19 -12
  13. package/dest/archiver/errors.d.ts +1 -1
  14. package/dest/archiver/errors.d.ts.map +1 -1
  15. package/dest/archiver/index.d.ts +1 -1
  16. package/dest/archiver/instrumentation.d.ts +5 -3
  17. package/dest/archiver/instrumentation.d.ts.map +1 -1
  18. package/dest/archiver/instrumentation.js +14 -0
  19. package/dest/archiver/kv_archiver_store/block_store.d.ts +45 -9
  20. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
  21. package/dest/archiver/kv_archiver_store/block_store.js +99 -12
  22. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +2 -2
  23. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
  24. package/dest/archiver/kv_archiver_store/contract_class_store.js +1 -1
  25. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +2 -2
  26. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
  27. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +30 -30
  28. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
  29. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +26 -15
  30. package/dest/archiver/kv_archiver_store/log_store.d.ts +3 -10
  31. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
  32. package/dest/archiver/kv_archiver_store/log_store.js +4 -26
  33. package/dest/archiver/kv_archiver_store/message_store.d.ts +6 -5
  34. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
  35. package/dest/archiver/kv_archiver_store/message_store.js +15 -14
  36. package/dest/archiver/l1/bin/retrieve-calldata.d.ts +3 -0
  37. package/dest/archiver/l1/bin/retrieve-calldata.d.ts.map +1 -0
  38. package/dest/archiver/l1/bin/retrieve-calldata.js +147 -0
  39. package/dest/archiver/l1/calldata_retriever.d.ts +98 -0
  40. package/dest/archiver/l1/calldata_retriever.d.ts.map +1 -0
  41. package/dest/archiver/l1/calldata_retriever.js +403 -0
  42. package/dest/archiver/l1/data_retrieval.d.ts +87 -0
  43. package/dest/archiver/l1/data_retrieval.d.ts.map +1 -0
  44. package/dest/archiver/{data_retrieval.js → l1/data_retrieval.js} +118 -154
  45. package/dest/archiver/l1/debug_tx.d.ts +19 -0
  46. package/dest/archiver/l1/debug_tx.d.ts.map +1 -0
  47. package/dest/archiver/l1/debug_tx.js +73 -0
  48. package/dest/archiver/l1/spire_proposer.d.ts +70 -0
  49. package/dest/archiver/l1/spire_proposer.d.ts.map +1 -0
  50. package/dest/archiver/l1/spire_proposer.js +157 -0
  51. package/dest/archiver/l1/trace_tx.d.ts +97 -0
  52. package/dest/archiver/l1/trace_tx.d.ts.map +1 -0
  53. package/dest/archiver/l1/trace_tx.js +91 -0
  54. package/dest/archiver/l1/types.d.ts +12 -0
  55. package/dest/archiver/l1/types.d.ts.map +1 -0
  56. package/dest/archiver/l1/types.js +3 -0
  57. package/dest/archiver/l1/validate_trace.d.ts +29 -0
  58. package/dest/archiver/l1/validate_trace.d.ts.map +1 -0
  59. package/dest/archiver/l1/validate_trace.js +150 -0
  60. package/dest/archiver/structs/data_retrieval.d.ts +1 -1
  61. package/dest/archiver/structs/inbox_message.d.ts +4 -4
  62. package/dest/archiver/structs/inbox_message.d.ts.map +1 -1
  63. package/dest/archiver/structs/inbox_message.js +6 -5
  64. package/dest/archiver/structs/published.d.ts +3 -2
  65. package/dest/archiver/structs/published.d.ts.map +1 -1
  66. package/dest/archiver/validation.d.ts +10 -4
  67. package/dest/archiver/validation.d.ts.map +1 -1
  68. package/dest/archiver/validation.js +66 -44
  69. package/dest/factory.d.ts +3 -11
  70. package/dest/factory.d.ts.map +1 -1
  71. package/dest/factory.js +5 -17
  72. package/dest/index.d.ts +2 -2
  73. package/dest/index.d.ts.map +1 -1
  74. package/dest/index.js +1 -1
  75. package/dest/rpc/index.d.ts +2 -2
  76. package/dest/test/index.d.ts +1 -1
  77. package/dest/test/mock_archiver.d.ts +16 -8
  78. package/dest/test/mock_archiver.d.ts.map +1 -1
  79. package/dest/test/mock_archiver.js +19 -14
  80. package/dest/test/mock_l1_to_l2_message_source.d.ts +7 -6
  81. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  82. package/dest/test/mock_l1_to_l2_message_source.js +10 -9
  83. package/dest/test/mock_l2_block_source.d.ts +24 -20
  84. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  85. package/dest/test/mock_l2_block_source.js +79 -13
  86. package/dest/test/mock_structs.d.ts +3 -2
  87. package/dest/test/mock_structs.d.ts.map +1 -1
  88. package/dest/test/mock_structs.js +9 -8
  89. package/package.json +18 -17
  90. package/src/archiver/archiver.ts +610 -363
  91. package/src/archiver/archiver_store.ts +55 -28
  92. package/src/archiver/archiver_store_test_suite.ts +369 -143
  93. package/src/archiver/config.ts +26 -51
  94. package/src/archiver/instrumentation.ts +19 -2
  95. package/src/archiver/kv_archiver_store/block_store.ts +139 -21
  96. package/src/archiver/kv_archiver_store/contract_class_store.ts +1 -1
  97. package/src/archiver/kv_archiver_store/contract_instance_store.ts +1 -1
  98. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +48 -33
  99. package/src/archiver/kv_archiver_store/log_store.ts +4 -30
  100. package/src/archiver/kv_archiver_store/message_store.ts +21 -18
  101. package/src/archiver/l1/README.md +98 -0
  102. package/src/archiver/l1/bin/retrieve-calldata.ts +182 -0
  103. package/src/archiver/l1/calldata_retriever.ts +531 -0
  104. package/src/archiver/{data_retrieval.ts → l1/data_retrieval.ts} +198 -242
  105. package/src/archiver/l1/debug_tx.ts +99 -0
  106. package/src/archiver/l1/spire_proposer.ts +160 -0
  107. package/src/archiver/l1/trace_tx.ts +128 -0
  108. package/src/archiver/l1/types.ts +13 -0
  109. package/src/archiver/l1/validate_trace.ts +211 -0
  110. package/src/archiver/structs/inbox_message.ts +8 -8
  111. package/src/archiver/structs/published.ts +2 -1
  112. package/src/archiver/validation.ts +86 -32
  113. package/src/factory.ts +6 -26
  114. package/src/index.ts +1 -1
  115. package/src/test/fixtures/debug_traceTransaction-multicall3.json +88 -0
  116. package/src/test/fixtures/debug_traceTransaction-multiplePropose.json +153 -0
  117. package/src/test/fixtures/debug_traceTransaction-proxied.json +122 -0
  118. package/src/test/fixtures/trace_transaction-multicall3.json +65 -0
  119. package/src/test/fixtures/trace_transaction-multiplePropose.json +319 -0
  120. package/src/test/fixtures/trace_transaction-proxied.json +128 -0
  121. package/src/test/fixtures/trace_transaction-randomRevert.json +216 -0
  122. package/src/test/mock_archiver.ts +22 -16
  123. package/src/test/mock_l1_to_l2_message_source.ts +10 -9
  124. package/src/test/mock_l2_block_source.ts +110 -27
  125. package/src/test/mock_structs.ts +10 -9
  126. package/dest/archiver/data_retrieval.d.ts +0 -78
  127. package/dest/archiver/data_retrieval.d.ts.map +0 -1
@@ -1,13 +1,14 @@
1
- import { INITIAL_L2_BLOCK_NUM, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, PRIVATE_LOG_SIZE_IN_FIELDS, PUBLIC_LOG_SIZE_IN_FIELDS } from '@aztec/constants';
1
+ import { INITIAL_L2_BLOCK_NUM, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, PRIVATE_LOG_SIZE_IN_FIELDS } from '@aztec/constants';
2
2
  import { makeTuple } from '@aztec/foundation/array';
3
+ import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
3
4
  import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
4
5
  import { times, timesParallel } from '@aztec/foundation/collection';
5
- import { randomInt } from '@aztec/foundation/crypto';
6
- import { Fr } from '@aztec/foundation/fields';
6
+ import { randomInt } from '@aztec/foundation/crypto/random';
7
+ import { Fr } from '@aztec/foundation/curves/bn254';
7
8
  import { toArray } from '@aztec/foundation/iterable';
8
9
  import { sleep } from '@aztec/foundation/sleep';
9
10
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
10
- import { CommitteeAttestation, L2Block, L2BlockHash, wrapInBlock } from '@aztec/stdlib/block';
11
+ import { CommitteeAttestation, EthAddress, L2Block, L2BlockHash, PublishedL2Block, randomBlockInfo, wrapDataInBlock } from '@aztec/stdlib/block';
11
12
  import { SerializableContractInstance, computePublicBytecodeCommitment } from '@aztec/stdlib/contract';
12
13
  import { LogId, PrivateLog, PublicLog } from '@aztec/stdlib/logs';
13
14
  import { InboxLeaf } from '@aztec/stdlib/messaging';
@@ -52,7 +53,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
52
53
  ]
53
54
  ];
54
55
  const makeBlockHash = (blockNumber)=>`0x${blockNumber.toString(16).padStart(64, '0')}`;
55
- const makePublished = (block, l1BlockNumber)=>({
56
+ const makePublished = (block, l1BlockNumber)=>PublishedL2Block.fromFields({
56
57
  block: block,
57
58
  l1: {
58
59
  blockNumber: BigInt(l1BlockNumber),
@@ -73,7 +74,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
73
74
  };
74
75
  beforeEach(async ()=>{
75
76
  store = await getStore();
76
- blocks = await timesParallel(10, async (i)=>makePublished(await L2Block.random(i + 1), i + 10));
77
+ blocks = await timesParallel(10, async (i)=>makePublished(await L2Block.random(BlockNumber(i + 1)), i + 10));
77
78
  });
78
79
  describe('addBlocks', ()=>{
79
80
  it('returns success when adding blocks', async ()=>{
@@ -84,19 +85,19 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
84
85
  await expect(store.addBlocks(blocks)).resolves.toBe(true);
85
86
  });
86
87
  it('throws an error if the previous block does not exist in the store', async ()=>{
87
- const block = makePublished(await L2Block.random(2), 2);
88
+ const block = makePublished(await L2Block.random(BlockNumber(2)), 2);
88
89
  await expect(store.addBlocks([
89
90
  block
90
91
  ])).rejects.toThrow(InitialBlockNumberNotSequentialError);
91
- await expect(store.getPublishedBlocks(1, 10)).resolves.toEqual([]);
92
+ await expect(store.getPublishedBlocks(BlockNumber(1), 10)).resolves.toEqual([]);
92
93
  });
93
94
  it('throws an error if there is a gap in the blocks being added', async ()=>{
94
95
  const blocks = [
95
- makePublished(await L2Block.random(1), 1),
96
- makePublished(await L2Block.random(3), 3)
96
+ makePublished(await L2Block.random(BlockNumber(1)), 1),
97
+ makePublished(await L2Block.random(BlockNumber(3)), 3)
97
98
  ];
98
99
  await expect(store.addBlocks(blocks)).rejects.toThrow(BlockNumberNotSequentialError);
99
- await expect(store.getPublishedBlocks(1, 10)).resolves.toEqual([]);
100
+ await expect(store.getPublishedBlocks(BlockNumber(1), 10)).resolves.toEqual([]);
100
101
  });
101
102
  });
102
103
  describe('unwindBlocks', ()=>{
@@ -111,12 +112,12 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
111
112
  expect(await store.getPublishedBlocks(blockNumber, 1)).toEqual([]);
112
113
  });
113
114
  it('can unwind multiple empty blocks', async ()=>{
114
- const emptyBlocks = await timesParallel(10, async (i)=>makePublished(await L2Block.random(i + 1, 0), i + 10));
115
+ const emptyBlocks = await timesParallel(10, async (i)=>makePublished(await L2Block.random(BlockNumber(i + 1), 0), i + 10));
115
116
  await store.addBlocks(emptyBlocks);
116
117
  expect(await store.getSynchedL2BlockNumber()).toBe(10);
117
- await store.unwindBlocks(10, 3);
118
+ await store.unwindBlocks(BlockNumber(10), 3);
118
119
  expect(await store.getSynchedL2BlockNumber()).toBe(7);
119
- expect((await store.getPublishedBlocks(1, 10)).map((b)=>b.block.number)).toEqual([
120
+ expect((await store.getPublishedBlocks(BlockNumber(1), 10)).map((b)=>b.block.number)).toEqual([
120
121
  1,
121
122
  2,
122
123
  3,
@@ -128,7 +129,25 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
128
129
  });
129
130
  it('refuses to unwind blocks if the tip is not the last block', async ()=>{
130
131
  await store.addBlocks(blocks);
131
- await expect(store.unwindBlocks(5, 1)).rejects.toThrow(/can only unwind blocks from the tip/i);
132
+ await expect(store.unwindBlocks(BlockNumber(5), 1)).rejects.toThrow(/can only unwind blocks from the tip/i);
133
+ });
134
+ it('unwound blocks and headers cannot be retrieved by hash or archive', async ()=>{
135
+ await store.addBlocks(blocks);
136
+ const lastBlock = blocks[blocks.length - 1];
137
+ const blockHash = await lastBlock.block.hash();
138
+ const archive = lastBlock.block.archive.root;
139
+ // Verify block and header exist before unwinding
140
+ expect(await store.getPublishedBlockByHash(blockHash)).toBeDefined();
141
+ expect(await store.getPublishedBlockByArchive(archive)).toBeDefined();
142
+ expect(await store.getBlockHeaderByHash(blockHash)).toBeDefined();
143
+ expect(await store.getBlockHeaderByArchive(archive)).toBeDefined();
144
+ // Unwind the block
145
+ await store.unwindBlocks(lastBlock.block.number, 1);
146
+ // Verify neither block nor header can be retrieved after unwinding
147
+ expect(await store.getPublishedBlockByHash(blockHash)).toBeUndefined();
148
+ expect(await store.getPublishedBlockByArchive(archive)).toBeUndefined();
149
+ expect(await store.getBlockHeaderByHash(blockHash)).toBeUndefined();
150
+ expect(await store.getBlockHeaderByArchive(archive)).toBeUndefined();
132
151
  });
133
152
  });
134
153
  describe('getBlocks', ()=>{
@@ -136,33 +155,105 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
136
155
  await store.addBlocks(blocks);
137
156
  });
138
157
  it.each(blockTests)('retrieves previously stored blocks', async (start, limit, getExpectedBlocks)=>{
139
- expectBlocksEqual(await store.getPublishedBlocks(start, limit), getExpectedBlocks());
158
+ expectBlocksEqual(await store.getPublishedBlocks(BlockNumber(start), limit), getExpectedBlocks());
140
159
  });
141
160
  it('returns an empty array if no blocks are found', async ()=>{
142
- await expect(store.getPublishedBlocks(12, 1)).resolves.toEqual([]);
161
+ await expect(store.getPublishedBlocks(BlockNumber(12), 1)).resolves.toEqual([]);
143
162
  });
144
163
  it('throws an error if limit is invalid', async ()=>{
145
- await expect(store.getPublishedBlocks(1, 0)).rejects.toThrow('Invalid limit: 0');
164
+ await expect(store.getPublishedBlocks(BlockNumber(1), 0)).rejects.toThrow('Invalid limit: 0');
146
165
  });
147
166
  it('throws an error if `from` it is out of range', async ()=>{
148
167
  await expect(store.getPublishedBlocks(INITIAL_L2_BLOCK_NUM - 100, 1)).rejects.toThrow('Invalid start: -99');
149
168
  });
150
169
  it('throws an error if unexpected initial block number is found', async ()=>{
151
170
  await store.addBlocks([
152
- makePublished(await L2Block.random(21), 31)
171
+ makePublished(await L2Block.random(BlockNumber(21)), 31)
153
172
  ], {
154
173
  force: true
155
174
  });
156
- await expect(store.getPublishedBlocks(20, 1)).rejects.toThrow(`mismatch`);
175
+ await expect(store.getPublishedBlocks(BlockNumber(20), 1)).rejects.toThrow(`mismatch`);
157
176
  });
158
177
  it('throws an error if a gap is found', async ()=>{
159
178
  await store.addBlocks([
160
- makePublished(await L2Block.random(20), 30),
161
- makePublished(await L2Block.random(22), 32)
179
+ makePublished(await L2Block.random(BlockNumber(20)), 30),
180
+ makePublished(await L2Block.random(BlockNumber(22)), 32)
162
181
  ], {
163
182
  force: true
164
183
  });
165
- await expect(store.getPublishedBlocks(20, 2)).rejects.toThrow(`mismatch`);
184
+ await expect(store.getPublishedBlocks(BlockNumber(20), 2)).rejects.toThrow(`mismatch`);
185
+ });
186
+ });
187
+ describe('getPublishedBlockByHash', ()=>{
188
+ beforeEach(async ()=>{
189
+ await store.addBlocks(blocks);
190
+ });
191
+ it('retrieves a block by its hash', async ()=>{
192
+ const expectedBlock = blocks[5];
193
+ const blockHash = await expectedBlock.block.hash();
194
+ const retrievedBlock = await store.getPublishedBlockByHash(blockHash);
195
+ expect(retrievedBlock).toBeDefined();
196
+ expectBlocksEqual([
197
+ retrievedBlock
198
+ ], [
199
+ expectedBlock
200
+ ]);
201
+ });
202
+ it('returns undefined for non-existent block hash', async ()=>{
203
+ const nonExistentHash = Fr.random();
204
+ await expect(store.getPublishedBlockByHash(nonExistentHash)).resolves.toBeUndefined();
205
+ });
206
+ });
207
+ describe('getPublishedBlockByArchive', ()=>{
208
+ beforeEach(async ()=>{
209
+ await store.addBlocks(blocks);
210
+ });
211
+ it('retrieves a block by its archive root', async ()=>{
212
+ const expectedBlock = blocks[3];
213
+ const archive = expectedBlock.block.archive.root;
214
+ const retrievedBlock = await store.getPublishedBlockByArchive(archive);
215
+ expect(retrievedBlock).toBeDefined();
216
+ expectBlocksEqual([
217
+ retrievedBlock
218
+ ], [
219
+ expectedBlock
220
+ ]);
221
+ });
222
+ it('returns undefined for non-existent archive root', async ()=>{
223
+ const nonExistentArchive = Fr.random();
224
+ await expect(store.getPublishedBlockByArchive(nonExistentArchive)).resolves.toBeUndefined();
225
+ });
226
+ });
227
+ describe('getBlockHeaderByHash', ()=>{
228
+ beforeEach(async ()=>{
229
+ await store.addBlocks(blocks);
230
+ });
231
+ it('retrieves a block header by its hash', async ()=>{
232
+ const expectedBlock = blocks[7];
233
+ const blockHash = await expectedBlock.block.hash();
234
+ const retrievedHeader = await store.getBlockHeaderByHash(blockHash);
235
+ expect(retrievedHeader).toBeDefined();
236
+ expect(retrievedHeader.equals(expectedBlock.block.getBlockHeader())).toBe(true);
237
+ });
238
+ it('returns undefined for non-existent block hash', async ()=>{
239
+ const nonExistentHash = Fr.random();
240
+ await expect(store.getBlockHeaderByHash(nonExistentHash)).resolves.toBeUndefined();
241
+ });
242
+ });
243
+ describe('getBlockHeaderByArchive', ()=>{
244
+ beforeEach(async ()=>{
245
+ await store.addBlocks(blocks);
246
+ });
247
+ it('retrieves a block header by its archive root', async ()=>{
248
+ const expectedBlock = blocks[2];
249
+ const archive = expectedBlock.block.archive.root;
250
+ const retrievedHeader = await store.getBlockHeaderByArchive(archive);
251
+ expect(retrievedHeader).toBeDefined();
252
+ expect(retrievedHeader.equals(expectedBlock.block.getBlockHeader())).toBe(true);
253
+ });
254
+ it('returns undefined for non-existent archive root', async ()=>{
255
+ const nonExistentArchive = Fr.random();
256
+ await expect(store.getBlockHeaderByArchive(nonExistentArchive)).resolves.toBeUndefined();
166
257
  });
167
258
  });
168
259
  describe('getSyncedL2BlockNumber', ()=>{
@@ -240,41 +331,24 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
240
331
  ])).resolves.toEqual(true);
241
332
  });
242
333
  });
243
- describe('deleteLogs', ()=>{
244
- it('deletes private & public logs', async ()=>{
245
- const block = blocks[0].block;
246
- await store.addBlocks([
247
- blocks[0]
248
- ]);
249
- await expect(store.addLogs([
250
- block
251
- ])).resolves.toEqual(true);
252
- expect((await store.getPrivateLogs(1, 1)).length).toEqual(block.body.txEffects.map((txEffect)=>txEffect.privateLogs).flat().length);
253
- expect((await store.getPublicLogs({
254
- fromBlock: 1
255
- })).logs.length).toEqual(block.body.txEffects.map((txEffect)=>txEffect.publicLogs).flat().length);
256
- // This one is a pain for memory as we would never want to just delete memory in the middle.
257
- await store.deleteLogs([
258
- block
259
- ]);
260
- expect((await store.getPrivateLogs(1, 1)).length).toEqual(0);
261
- expect((await store.getPublicLogs({
262
- fromBlock: 1
263
- })).logs.length).toEqual(0);
264
- });
265
- });
266
- describe('getPrivateLogs', ()=>{
267
- it('gets added private logs', async ()=>{
268
- const block = blocks[0].block;
269
- await store.addBlocks([
270
- blocks[0]
271
- ]);
272
- await store.addLogs([
273
- block
274
- ]);
275
- const privateLogs = await store.getPrivateLogs(1, 1);
276
- expect(privateLogs).toEqual(block.body.txEffects.map((txEffect)=>txEffect.privateLogs).flat());
277
- });
334
+ it('deleteLogs', async ()=>{
335
+ const block = blocks[0].block;
336
+ await store.addBlocks([
337
+ blocks[0]
338
+ ]);
339
+ await expect(store.addLogs([
340
+ block
341
+ ])).resolves.toEqual(true);
342
+ expect((await store.getPublicLogs({
343
+ fromBlock: BlockNumber(1)
344
+ })).logs.length).toEqual(block.body.txEffects.map((txEffect)=>txEffect.publicLogs).flat().length);
345
+ // This one is a pain for memory as we would never want to just delete memory in the middle.
346
+ await store.deleteLogs([
347
+ block
348
+ ]);
349
+ expect((await store.getPublicLogs({
350
+ fromBlock: BlockNumber(1)
351
+ })).logs.length).toEqual(0);
278
352
  });
279
353
  describe('getTxEffect', ()=>{
280
354
  beforeEach(async ()=>{
@@ -322,13 +396,13 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
322
396
  await expect(store.getTxEffect(TxHash.random())).resolves.toBeUndefined();
323
397
  });
324
398
  it.each([
325
- ()=>wrapInBlock(blocks[0].block.body.txEffects[0], blocks[0].block),
326
- ()=>wrapInBlock(blocks[9].block.body.txEffects[3], blocks[9].block),
327
- ()=>wrapInBlock(blocks[3].block.body.txEffects[1], blocks[3].block),
328
- ()=>wrapInBlock(blocks[5].block.body.txEffects[2], blocks[5].block),
329
- ()=>wrapInBlock(blocks[1].block.body.txEffects[0], blocks[1].block)
399
+ ()=>wrapDataInBlock(blocks[0].block.body.txEffects[0], blocks[0].block),
400
+ ()=>wrapDataInBlock(blocks[9].block.body.txEffects[3], blocks[9].block),
401
+ ()=>wrapDataInBlock(blocks[3].block.body.txEffects[1], blocks[3].block),
402
+ ()=>wrapDataInBlock(blocks[5].block.body.txEffects[2], blocks[5].block),
403
+ ()=>wrapDataInBlock(blocks[1].block.body.txEffects[0], blocks[1].block)
330
404
  ])('tries to retrieves a previously stored transaction after deleted', async (getExpectedTx)=>{
331
- await store.unwindBlocks(blocks.length, blocks.length);
405
+ await store.unwindBlocks(BlockNumber(blocks.length), blocks.length);
332
406
  const expectedTx = await getExpectedTx();
333
407
  const actualTx = await store.getTxEffect(expectedTx.data.txHash);
334
408
  expect(actualTx).toEqual(undefined);
@@ -337,7 +411,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
337
411
  await expect(store.getTxEffect(TxHash.random())).resolves.toBeUndefined();
338
412
  });
339
413
  it('does not fail if the block is unwound while requesting a tx', async ()=>{
340
- const expectedTx = await wrapInBlock(blocks[1].block.body.txEffects[0], blocks[1].block);
414
+ const expectedTx = await wrapDataInBlock(blocks[1].block.body.txEffects[0], blocks[1].block);
341
415
  let done = false;
342
416
  void (async ()=>{
343
417
  while(!done){
@@ -345,13 +419,13 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
345
419
  await sleep(1);
346
420
  }
347
421
  })();
348
- await store.unwindBlocks(blocks.length, blocks.length);
422
+ await store.unwindBlocks(BlockNumber(blocks.length), blocks.length);
349
423
  done = true;
350
424
  expect(await store.getTxEffect(expectedTx.data.txHash)).toEqual(undefined);
351
425
  });
352
426
  });
353
427
  describe('L1 to L2 Messages', ()=>{
354
- const initialL2BlockNumber = 13;
428
+ const initialCheckpointNumber = CheckpointNumber(13);
355
429
  const checkMessages = async (msgs)=>{
356
430
  expect(await store.getLastL1ToL2Message()).toEqual(msgs.at(-1));
357
431
  expect(await toArray(store.iterateL1ToL2Messages())).toEqual(msgs);
@@ -359,11 +433,11 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
359
433
  };
360
434
  const makeInboxMessagesWithFullBlocks = (blockCount, opts = {})=>makeInboxMessages(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * blockCount, {
361
435
  overrideFn: (msg, i)=>{
362
- const l2BlockNumber = (opts.initialL2BlockNumber ?? initialL2BlockNumber) + Math.floor(i / NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
363
- const index = InboxLeaf.smallestIndexFromL2Block(l2BlockNumber) + BigInt(i % NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
436
+ const checkpointNumber = CheckpointNumber((opts.initialCheckpointNumber ?? initialCheckpointNumber) + Math.floor(i / NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP));
437
+ const index = InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) + BigInt(i % NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
364
438
  return {
365
439
  ...msg,
366
- l2BlockNumber,
440
+ checkpointNumber,
367
441
  index
368
442
  };
369
443
  }
@@ -371,7 +445,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
371
445
  it('stores first message ever', async ()=>{
372
446
  const msg = makeInboxMessage(Buffer16.ZERO, {
373
447
  index: 0n,
374
- l2BlockNumber: 1
448
+ checkpointNumber: CheckpointNumber(1)
375
449
  });
376
450
  await store.addL1ToL2Messages([
377
451
  msg
@@ -379,13 +453,13 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
379
453
  await checkMessages([
380
454
  msg
381
455
  ]);
382
- expect(await store.getL1ToL2Messages(1)).toEqual([
456
+ expect(await store.getL1ToL2Messages(CheckpointNumber(1))).toEqual([
383
457
  msg.leaf
384
458
  ]);
385
459
  });
386
460
  it('stores single message', async ()=>{
387
461
  const msg = makeInboxMessage(Buffer16.ZERO, {
388
- l2BlockNumber: 2
462
+ checkpointNumber: CheckpointNumber(2)
389
463
  });
390
464
  await store.addL1ToL2Messages([
391
465
  msg
@@ -393,23 +467,23 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
393
467
  await checkMessages([
394
468
  msg
395
469
  ]);
396
- expect(await store.getL1ToL2Messages(2)).toEqual([
470
+ expect(await store.getL1ToL2Messages(CheckpointNumber(2))).toEqual([
397
471
  msg.leaf
398
472
  ]);
399
473
  });
400
474
  it('stores and returns messages across different blocks', async ()=>{
401
475
  const msgs = makeInboxMessages(5, {
402
- initialL2BlockNumber
476
+ initialCheckpointNumber
403
477
  });
404
478
  await store.addL1ToL2Messages(msgs);
405
479
  await checkMessages(msgs);
406
- expect(await store.getL1ToL2Messages(initialL2BlockNumber + 2)).toEqual([
480
+ expect(await store.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 2))).toEqual([
407
481
  msgs[2]
408
482
  ].map((m)=>m.leaf));
409
483
  });
410
484
  it('stores the same messages again', async ()=>{
411
485
  const msgs = makeInboxMessages(5, {
412
- initialL2BlockNumber
486
+ initialCheckpointNumber
413
487
  });
414
488
  await store.addL1ToL2Messages(msgs);
415
489
  await store.addL1ToL2Messages(msgs.slice(2));
@@ -417,10 +491,10 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
417
491
  });
418
492
  it('stores and returns messages across different blocks with gaps', async ()=>{
419
493
  const msgs1 = makeInboxMessages(3, {
420
- initialL2BlockNumber: 1
494
+ initialCheckpointNumber: CheckpointNumber(1)
421
495
  });
422
496
  const msgs2 = makeInboxMessages(3, {
423
- initialL2BlockNumber: 20,
497
+ initialCheckpointNumber: CheckpointNumber(20),
424
498
  initialHash: msgs1.at(-1).rollingHash
425
499
  });
426
500
  await store.addL1ToL2Messages(msgs1);
@@ -429,22 +503,22 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
429
503
  ...msgs1,
430
504
  ...msgs2
431
505
  ]);
432
- expect(await store.getL1ToL2Messages(1)).toEqual([
506
+ expect(await store.getL1ToL2Messages(CheckpointNumber(1))).toEqual([
433
507
  msgs1[0].leaf
434
508
  ]);
435
- expect(await store.getL1ToL2Messages(4)).toEqual([]);
436
- expect(await store.getL1ToL2Messages(20)).toEqual([
509
+ expect(await store.getL1ToL2Messages(CheckpointNumber(4))).toEqual([]);
510
+ expect(await store.getL1ToL2Messages(CheckpointNumber(20))).toEqual([
437
511
  msgs2[0].leaf
438
512
  ]);
439
- expect(await store.getL1ToL2Messages(24)).toEqual([]);
513
+ expect(await store.getL1ToL2Messages(CheckpointNumber(24))).toEqual([]);
440
514
  });
441
515
  it('stores and returns messages with block numbers larger than a byte', async ()=>{
442
516
  const msgs = makeInboxMessages(5, {
443
- initialL2BlockNumber: 1000
517
+ initialCheckpointNumber: CheckpointNumber(1000)
444
518
  });
445
519
  await store.addL1ToL2Messages(msgs);
446
520
  await checkMessages(msgs);
447
- expect(await store.getL1ToL2Messages(1002)).toEqual([
521
+ expect(await store.getL1ToL2Messages(CheckpointNumber(1002))).toEqual([
448
522
  msgs[2]
449
523
  ].map((m)=>m.leaf));
450
524
  });
@@ -452,27 +526,27 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
452
526
  const msgs = makeInboxMessagesWithFullBlocks(4);
453
527
  await store.addL1ToL2Messages(msgs);
454
528
  await checkMessages(msgs);
455
- const blockMessages = await store.getL1ToL2Messages(initialL2BlockNumber + 1);
529
+ const blockMessages = await store.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 1));
456
530
  expect(blockMessages).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
457
531
  expect(blockMessages).toEqual(msgs.slice(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2).map((m)=>m.leaf));
458
532
  });
459
533
  it('stores messages in multiple operations', async ()=>{
460
534
  const msgs = makeInboxMessages(20, {
461
- initialL2BlockNumber
535
+ initialCheckpointNumber
462
536
  });
463
537
  await store.addL1ToL2Messages(msgs.slice(0, 10));
464
538
  await store.addL1ToL2Messages(msgs.slice(10, 20));
465
- expect(await store.getL1ToL2Messages(initialL2BlockNumber + 2)).toEqual([
539
+ expect(await store.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 2))).toEqual([
466
540
  msgs[2]
467
541
  ].map((m)=>m.leaf));
468
- expect(await store.getL1ToL2Messages(initialL2BlockNumber + 12)).toEqual([
542
+ expect(await store.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 12))).toEqual([
469
543
  msgs[12]
470
544
  ].map((m)=>m.leaf));
471
545
  await checkMessages(msgs);
472
546
  });
473
547
  it('iterates over messages from start index', async ()=>{
474
548
  const msgs = makeInboxMessages(10, {
475
- initialL2BlockNumber
549
+ initialCheckpointNumber
476
550
  });
477
551
  await store.addL1ToL2Messages(msgs);
478
552
  const iterated = await toArray(store.iterateL1ToL2Messages({
@@ -482,9 +556,10 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
482
556
  });
483
557
  it('iterates over messages in reverse', async ()=>{
484
558
  const msgs = makeInboxMessages(10, {
485
- initialL2BlockNumber
559
+ initialCheckpointNumber
486
560
  });
487
561
  await store.addL1ToL2Messages(msgs);
562
+ initialCheckpointNumber;
488
563
  const iterated = await toArray(store.iterateL1ToL2Messages({
489
564
  reverse: true,
490
565
  end: msgs[3].index
@@ -502,9 +577,9 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
502
577
  });
503
578
  it('throws if block number for the first message is out of order', async ()=>{
504
579
  const msgs = makeInboxMessages(4, {
505
- initialL2BlockNumber
580
+ initialCheckpointNumber
506
581
  });
507
- msgs[2].l2BlockNumber = initialL2BlockNumber - 1;
582
+ msgs[2].checkpointNumber = CheckpointNumber(initialCheckpointNumber - 1);
508
583
  await store.addL1ToL2Messages(msgs.slice(0, 2));
509
584
  await expect(store.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError);
510
585
  });
@@ -516,29 +591,29 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
516
591
  it('throws if rolling hash for first message is not correct', async ()=>{
517
592
  const msgs = makeInboxMessages(4);
518
593
  msgs[2].rollingHash = Buffer16.random();
519
- await store.addL1ToL2Messages(msgs.slice(0, 2));
594
+ await store.addL1ToL2Messages(msgs.slice(0, CheckpointNumber(2)));
520
595
  await expect(store.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError);
521
596
  });
522
597
  it('throws if index is not in the correct range', async ()=>{
523
598
  const msgs = makeInboxMessages(5, {
524
- initialL2BlockNumber
599
+ initialCheckpointNumber
525
600
  });
526
601
  msgs.at(-1).index += 100n;
527
602
  await expect(store.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError);
528
603
  });
529
604
  it('throws if first index in block has gaps', async ()=>{
530
605
  const msgs = makeInboxMessages(4, {
531
- initialL2BlockNumber
606
+ initialCheckpointNumber
532
607
  });
533
608
  msgs[2].index++;
534
609
  await expect(store.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError);
535
610
  });
536
611
  it('throws if index does not follow previous one', async ()=>{
537
612
  const msgs = makeInboxMessages(2, {
538
- initialL2BlockNumber,
613
+ initialCheckpointNumber,
539
614
  overrideFn: (msg, i)=>({
540
615
  ...msg,
541
- l2BlockNumber: 2,
616
+ checkpointNumber: CheckpointNumber(2),
542
617
  index: BigInt(i + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2)
543
618
  })
544
619
  });
@@ -547,24 +622,24 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
547
622
  });
548
623
  it('removes messages up to the given block number', async ()=>{
549
624
  const msgs = makeInboxMessagesWithFullBlocks(4, {
550
- initialL2BlockNumber: 1
625
+ initialCheckpointNumber: CheckpointNumber(1)
551
626
  });
552
627
  await store.addL1ToL2Messages(msgs);
553
628
  await checkMessages(msgs);
554
- expect(await store.getL1ToL2Messages(1)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
555
- expect(await store.getL1ToL2Messages(2)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
556
- expect(await store.getL1ToL2Messages(3)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
557
- expect(await store.getL1ToL2Messages(4)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
558
- await store.rollbackL1ToL2MessagesToL2Block(2);
559
- expect(await store.getL1ToL2Messages(1)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
560
- expect(await store.getL1ToL2Messages(2)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
561
- expect(await store.getL1ToL2Messages(3)).toHaveLength(0);
562
- expect(await store.getL1ToL2Messages(4)).toHaveLength(0);
629
+ expect(await store.getL1ToL2Messages(CheckpointNumber(1))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
630
+ expect(await store.getL1ToL2Messages(CheckpointNumber(2))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
631
+ expect(await store.getL1ToL2Messages(CheckpointNumber(3))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
632
+ expect(await store.getL1ToL2Messages(CheckpointNumber(4))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
633
+ await store.rollbackL1ToL2MessagesToCheckpoint(CheckpointNumber(2));
634
+ expect(await store.getL1ToL2Messages(CheckpointNumber(1))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
635
+ expect(await store.getL1ToL2Messages(CheckpointNumber(2))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
636
+ expect(await store.getL1ToL2Messages(CheckpointNumber(3))).toHaveLength(0);
637
+ expect(await store.getL1ToL2Messages(CheckpointNumber(4))).toHaveLength(0);
563
638
  await checkMessages(msgs.slice(0, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2));
564
639
  });
565
640
  it('removes messages starting with the given index', async ()=>{
566
641
  const msgs = makeInboxMessagesWithFullBlocks(4, {
567
- initialL2BlockNumber: 1
642
+ initialCheckpointNumber: CheckpointNumber(1)
568
643
  });
569
644
  await store.addL1ToL2Messages(msgs);
570
645
  await store.removeL1ToL2Messages(msgs[13].index);
@@ -587,7 +662,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
587
662
  };
588
663
  await store.addContractInstances([
589
664
  contractInstance
590
- ], blockNum);
665
+ ], BlockNumber(blockNum));
591
666
  });
592
667
  it('returns previously stored contract instances', async ()=>{
593
668
  await expect(store.getContractInstance(contractInstance.address, timestamp)).resolves.toMatchObject(contractInstance);
@@ -598,7 +673,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
598
673
  it('returns undefined if previously stored contract instances was deleted', async ()=>{
599
674
  await store.deleteContractInstances([
600
675
  contractInstance
601
- ], blockNum);
676
+ ], BlockNumber(blockNum));
602
677
  await expect(store.getContractInstance(contractInstance.address, timestamp)).resolves.toBeUndefined();
603
678
  });
604
679
  });
@@ -620,7 +695,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
620
695
  };
621
696
  await store.addContractInstances([
622
697
  contractInstance
623
- ], 1);
698
+ ], BlockNumber(1));
624
699
  await store.addContractInstanceUpdates([
625
700
  {
626
701
  prevContractClassId: classId,
@@ -657,7 +732,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
657
732
  };
658
733
  await store.addContractInstances([
659
734
  otherContractInstance
660
- ], 1);
735
+ ], BlockNumber(1));
661
736
  const fetchedInstance = await store.getContractInstance(otherContractInstance.address, timestampOfChange + 1n);
662
737
  expect(fetchedInstance?.originalContractClassId).toEqual(otherClassId);
663
738
  expect(fetchedInstance?.currentContractClassId).toEqual(otherClassId);
@@ -675,7 +750,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
675
750
  };
676
751
  await store.addContractInstances([
677
752
  otherContractInstance
678
- ], 1);
753
+ ], BlockNumber(1));
679
754
  await store.addContractInstanceUpdates([
680
755
  {
681
756
  prevContractClassId: otherClassId,
@@ -698,7 +773,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
698
773
  contractClass
699
774
  ], [
700
775
  await computePublicBytecodeCommitment(contractClass.packedBytecode)
701
- ], blockNum);
776
+ ], BlockNumber(blockNum));
702
777
  });
703
778
  it('returns previously stored contract class', async ()=>{
704
779
  await expect(store.getContractClass(contractClass.id)).resolves.toMatchObject(contractClass);
@@ -706,7 +781,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
706
781
  it('returns undefined if the initial deployed contract class was deleted', async ()=>{
707
782
  await store.deleteContractClasses([
708
783
  contractClass
709
- ], blockNum);
784
+ ], BlockNumber(blockNum));
710
785
  await expect(store.getContractClass(contractClass.id)).resolves.toBeUndefined();
711
786
  });
712
787
  it('returns contract class if later "deployment" class was deleted', async ()=>{
@@ -714,10 +789,10 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
714
789
  contractClass
715
790
  ], [
716
791
  await computePublicBytecodeCommitment(contractClass.packedBytecode)
717
- ], blockNum + 1);
792
+ ], BlockNumber(blockNum + 1));
718
793
  await store.deleteContractClasses([
719
794
  contractClass
720
- ], blockNum + 1);
795
+ ], BlockNumber(blockNum + 1));
721
796
  await expect(store.getContractClass(contractClass.id)).resolves.toMatchObject(contractClass);
722
797
  });
723
798
  it('returns undefined if contract class is not found', async ()=>{
@@ -764,8 +839,8 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
764
839
  });
765
840
  const makePublicLog = (tag)=>PublicLog.from({
766
841
  contractAddress: AztecAddress.fromNumber(1),
767
- fields: makeTuple(PUBLIC_LOG_SIZE_IN_FIELDS, (i)=>!i ? tag : new Fr(tag.toNumber() + i)),
768
- emittedLength: PUBLIC_LOG_SIZE_IN_FIELDS
842
+ // Arbitrary length
843
+ fields: new Array(10).fill(null).map((_, i)=>!i ? tag : new Fr(tag.toNumber() + i))
769
844
  });
770
845
  const mockPrivateLogs = (blockNumber, txIndex)=>{
771
846
  return times(numPrivateLogsPerTx, (logIndex)=>{
@@ -780,15 +855,15 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
780
855
  });
781
856
  };
782
857
  const mockBlockWithLogs = async (blockNumber)=>{
783
- const block = await L2Block.random(blockNumber);
784
- block.header.globalVariables.blockNumber = blockNumber;
858
+ const block = await L2Block.random(BlockNumber(blockNumber));
859
+ block.header.globalVariables.blockNumber = BlockNumber(blockNumber);
785
860
  block.body.txEffects = await timesParallel(numTxsPerBlock, async (txIndex)=>{
786
861
  const txEffect = await TxEffect.random();
787
862
  txEffect.privateLogs = mockPrivateLogs(blockNumber, txIndex);
788
863
  txEffect.publicLogs = mockPublicLogs(blockNumber, txIndex);
789
864
  return txEffect;
790
865
  });
791
- return {
866
+ return PublishedL2Block.fromFields({
792
867
  block: block,
793
868
  attestations: times(3, CommitteeAttestation.random),
794
869
  l1: {
@@ -796,7 +871,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
796
871
  blockHash: makeBlockHash(blockNumber),
797
872
  timestamp: BigInt(blockNumber)
798
873
  }
799
- };
874
+ });
800
875
  };
801
876
  beforeEach(async ()=>{
802
877
  blocks = await timesParallel(numBlocks, (index)=>mockBlockWithLogs(index + 1));
@@ -904,8 +979,8 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
904
979
  const numBlocks = 10;
905
980
  let blocks;
906
981
  beforeEach(async ()=>{
907
- blocks = await timesParallel(numBlocks, async (index)=>({
908
- block: await L2Block.random(index + 1, txsPerBlock, numPublicFunctionCalls, numPublicLogs),
982
+ blocks = await timesParallel(numBlocks, async (index)=>PublishedL2Block.fromFields({
983
+ block: await L2Block.random(BlockNumber(index + 1), txsPerBlock, numPublicFunctionCalls, numPublicLogs),
909
984
  l1: {
910
985
  blockNumber: BigInt(index),
911
986
  blockHash: makeBlockHash(index),
@@ -922,7 +997,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
922
997
  const targetTxIndex = randomInt(txsPerBlock);
923
998
  const targetTxHash = blocks[targetBlockIndex].block.body.txEffects[targetTxIndex].txHash;
924
999
  await Promise.all([
925
- store.unwindBlocks(blocks.length, blocks.length),
1000
+ store.unwindBlocks(BlockNumber(blocks.length), blocks.length),
926
1001
  store.deleteLogs(blocks.map((b)=>b.block))
927
1002
  ]);
928
1003
  const response = await store.getPublicLogs({
@@ -987,7 +1062,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
987
1062
  const targetBlockIndex = randomInt(numBlocks);
988
1063
  const targetTxIndex = randomInt(txsPerBlock);
989
1064
  const targetLogIndex = randomInt(numPublicLogs);
990
- const afterLog = new LogId(targetBlockIndex + INITIAL_L2_BLOCK_NUM, targetTxIndex, targetLogIndex);
1065
+ const afterLog = new LogId(BlockNumber(targetBlockIndex + INITIAL_L2_BLOCK_NUM), targetTxIndex, targetLogIndex);
991
1066
  const response = await store.getPublicLogs({
992
1067
  afterLog
993
1068
  });
@@ -1007,7 +1082,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
1007
1082
  it('"txHash" filter param is ignored when "afterLog" is set', async ()=>{
1008
1083
  // Get random txHash
1009
1084
  const txHash = TxHash.random();
1010
- const afterLog = new LogId(1, 0, 0);
1085
+ const afterLog = new LogId(BlockNumber(1), 0, 0);
1011
1086
  const response = await store.getPublicLogs({
1012
1087
  txHash,
1013
1088
  afterLog
@@ -1023,7 +1098,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
1023
1098
  // "fromBlock" gets correctly trimmed to range and "toBlock" is exclusive
1024
1099
  logs = (await store.getPublicLogs({
1025
1100
  fromBlock: -10,
1026
- toBlock: 5
1101
+ toBlock: BlockNumber(5)
1027
1102
  })).logs;
1028
1103
  let blockNumbers = new Set(logs.map((log)=>log.id.blockNumber));
1029
1104
  expect(blockNumbers).toEqual(new Set([
@@ -1034,13 +1109,13 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
1034
1109
  ]));
1035
1110
  // "toBlock" should be exclusive
1036
1111
  logs = (await store.getPublicLogs({
1037
- fromBlock: 1,
1038
- toBlock: 1
1112
+ fromBlock: BlockNumber(1),
1113
+ toBlock: BlockNumber(1)
1039
1114
  })).logs;
1040
1115
  expect(logs.length).toBe(0);
1041
1116
  logs = (await store.getPublicLogs({
1042
- fromBlock: 10,
1043
- toBlock: 5
1117
+ fromBlock: BlockNumber(10),
1118
+ toBlock: BlockNumber(5)
1044
1119
  })).logs;
1045
1120
  expect(logs.length).toBe(0);
1046
1121
  // both "fromBlock" and "toBlock" get correctly capped to range and logs from all blocks are returned
@@ -1052,23 +1127,23 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
1052
1127
  expect(blockNumbers.size).toBe(numBlocks);
1053
1128
  // intersecting with "afterLog" works
1054
1129
  logs = (await store.getPublicLogs({
1055
- fromBlock: 2,
1056
- toBlock: 5,
1057
- afterLog: new LogId(4, 0, 0)
1130
+ fromBlock: BlockNumber(2),
1131
+ toBlock: BlockNumber(5),
1132
+ afterLog: new LogId(BlockNumber(4), 0, 0)
1058
1133
  })).logs;
1059
1134
  blockNumbers = new Set(logs.map((log)=>log.id.blockNumber));
1060
1135
  expect(blockNumbers).toEqual(new Set([
1061
1136
  4
1062
1137
  ]));
1063
1138
  logs = (await store.getPublicLogs({
1064
- toBlock: 5,
1065
- afterLog: new LogId(5, 1, 0)
1139
+ toBlock: BlockNumber(5),
1140
+ afterLog: new LogId(BlockNumber(5), 1, 0)
1066
1141
  })).logs;
1067
1142
  expect(logs.length).toBe(0);
1068
1143
  logs = (await store.getPublicLogs({
1069
- fromBlock: 2,
1070
- toBlock: 5,
1071
- afterLog: new LogId(100, 0, 0)
1144
+ fromBlock: BlockNumber(2),
1145
+ toBlock: BlockNumber(5),
1146
+ afterLog: new LogId(BlockNumber(100), 0, 0)
1072
1147
  })).logs;
1073
1148
  expect(logs.length).toBe(0);
1074
1149
  });
@@ -1077,7 +1152,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
1077
1152
  const targetBlockIndex = randomInt(numBlocks);
1078
1153
  const targetTxIndex = randomInt(txsPerBlock);
1079
1154
  const targetLogIndex = randomInt(numPublicLogs);
1080
- const afterLog = new LogId(targetBlockIndex + INITIAL_L2_BLOCK_NUM, targetTxIndex, targetLogIndex);
1155
+ const afterLog = new LogId(BlockNumber(targetBlockIndex + INITIAL_L2_BLOCK_NUM), targetTxIndex, targetLogIndex);
1081
1156
  const response = await store.getPublicLogs({
1082
1157
  afterLog,
1083
1158
  fromBlock: afterLog.blockNumber
@@ -1096,5 +1171,103 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
1096
1171
  }
1097
1172
  });
1098
1173
  });
1174
+ describe('pendingChainValidationStatus', ()=>{
1175
+ it('should return undefined when no status is set', async ()=>{
1176
+ const status = await store.getPendingChainValidationStatus();
1177
+ expect(status).toBeUndefined();
1178
+ });
1179
+ it('should store and retrieve a valid validation status', async ()=>{
1180
+ const validStatus = {
1181
+ valid: true
1182
+ };
1183
+ await store.setPendingChainValidationStatus(validStatus);
1184
+ const retrievedStatus = await store.getPendingChainValidationStatus();
1185
+ expect(retrievedStatus).toEqual(validStatus);
1186
+ });
1187
+ it('should store and retrieve an invalid validation status with insufficient attestations', async ()=>{
1188
+ const invalidStatus = {
1189
+ valid: false,
1190
+ block: randomBlockInfo(1),
1191
+ committee: [
1192
+ EthAddress.random(),
1193
+ EthAddress.random()
1194
+ ],
1195
+ epoch: EpochNumber(123),
1196
+ seed: 456n,
1197
+ attestors: [
1198
+ EthAddress.random()
1199
+ ],
1200
+ attestations: [
1201
+ CommitteeAttestation.random()
1202
+ ],
1203
+ reason: 'insufficient-attestations'
1204
+ };
1205
+ await store.setPendingChainValidationStatus(invalidStatus);
1206
+ const retrievedStatus = await store.getPendingChainValidationStatus();
1207
+ expect(retrievedStatus).toEqual(invalidStatus);
1208
+ });
1209
+ it('should store and retrieve an invalid validation status with invalid attestation', async ()=>{
1210
+ const invalidStatus = {
1211
+ valid: false,
1212
+ block: randomBlockInfo(2),
1213
+ committee: [
1214
+ EthAddress.random()
1215
+ ],
1216
+ attestors: [
1217
+ EthAddress.random()
1218
+ ],
1219
+ epoch: EpochNumber(789),
1220
+ seed: 101n,
1221
+ attestations: [
1222
+ CommitteeAttestation.random()
1223
+ ],
1224
+ reason: 'invalid-attestation',
1225
+ invalidIndex: 5
1226
+ };
1227
+ await store.setPendingChainValidationStatus(invalidStatus);
1228
+ const retrievedStatus = await store.getPendingChainValidationStatus();
1229
+ expect(retrievedStatus).toEqual(invalidStatus);
1230
+ });
1231
+ it('should overwrite existing status when setting a new one', async ()=>{
1232
+ const firstStatus = {
1233
+ valid: true
1234
+ };
1235
+ const secondStatus = {
1236
+ valid: false,
1237
+ block: randomBlockInfo(3),
1238
+ committee: [
1239
+ EthAddress.random()
1240
+ ],
1241
+ epoch: EpochNumber(999),
1242
+ seed: 888n,
1243
+ attestors: [
1244
+ EthAddress.random()
1245
+ ],
1246
+ attestations: [
1247
+ CommitteeAttestation.random()
1248
+ ],
1249
+ reason: 'insufficient-attestations'
1250
+ };
1251
+ await store.setPendingChainValidationStatus(firstStatus);
1252
+ await store.setPendingChainValidationStatus(secondStatus);
1253
+ const retrievedStatus = await store.getPendingChainValidationStatus();
1254
+ expect(retrievedStatus).toEqual(secondStatus);
1255
+ });
1256
+ it('should handle empty committee and attestations arrays', async ()=>{
1257
+ const statusWithEmptyArrays = {
1258
+ valid: false,
1259
+ block: randomBlockInfo(4),
1260
+ committee: [],
1261
+ epoch: EpochNumber(0),
1262
+ seed: 0n,
1263
+ attestors: [],
1264
+ attestations: [],
1265
+ reason: 'insufficient-attestations'
1266
+ };
1267
+ await store.setPendingChainValidationStatus(statusWithEmptyArrays);
1268
+ const retrievedStatus = await store.getPendingChainValidationStatus();
1269
+ expect(retrievedStatus).toEqual(statusWithEmptyArrays);
1270
+ });
1271
+ });
1099
1272
  });
1100
1273
  }