@aztec/archiver 0.24.0 → 0.26.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 (61) hide show
  1. package/dest/archiver/archiver.d.ts +15 -11
  2. package/dest/archiver/archiver.d.ts.map +1 -1
  3. package/dest/archiver/archiver.js +67 -72
  4. package/dest/archiver/archiver_store.d.ts +37 -15
  5. package/dest/archiver/archiver_store.d.ts.map +1 -1
  6. package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
  7. package/dest/archiver/archiver_store_test_suite.js +70 -54
  8. package/dest/archiver/data_retrieval.d.ts +18 -8
  9. package/dest/archiver/data_retrieval.d.ts.map +1 -1
  10. package/dest/archiver/data_retrieval.js +39 -14
  11. package/dest/archiver/eth_log_handlers.d.ts +25 -23
  12. package/dest/archiver/eth_log_handlers.d.ts.map +1 -1
  13. package/dest/archiver/eth_log_handlers.js +98 -57
  14. package/dest/archiver/kv_archiver_store/block_body_store.d.ts +27 -0
  15. package/dest/archiver/kv_archiver_store/block_body_store.d.ts.map +1 -0
  16. package/dest/archiver/kv_archiver_store/block_body_store.js +47 -0
  17. package/dest/archiver/kv_archiver_store/block_store.d.ts +19 -11
  18. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
  19. package/dest/archiver/kv_archiver_store/block_store.js +58 -30
  20. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +1 -0
  21. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
  22. package/dest/archiver/kv_archiver_store/contract_class_store.js +4 -1
  23. package/dest/archiver/kv_archiver_store/contract_store.d.ts.map +1 -1
  24. package/dest/archiver/kv_archiver_store/contract_store.js +6 -3
  25. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +36 -16
  26. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
  27. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +52 -22
  28. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
  29. package/dest/archiver/kv_archiver_store/log_store.js +4 -3
  30. package/dest/archiver/kv_archiver_store/message_store.d.ts +9 -9
  31. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
  32. package/dest/archiver/kv_archiver_store/message_store.js +34 -31
  33. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +6 -6
  34. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +1 -1
  35. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +18 -18
  36. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +41 -16
  37. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
  38. package/dest/archiver/memory_archiver_store/memory_archiver_store.js +78 -29
  39. package/dest/index.js +2 -2
  40. package/dest/rpc/archiver_client.d.ts.map +1 -1
  41. package/dest/rpc/archiver_client.js +3 -3
  42. package/dest/rpc/archiver_server.d.ts.map +1 -1
  43. package/dest/rpc/archiver_server.js +4 -3
  44. package/package.json +10 -10
  45. package/src/archiver/archiver.ts +95 -92
  46. package/src/archiver/archiver_store.ts +42 -15
  47. package/src/archiver/archiver_store_test_suite.ts +73 -58
  48. package/src/archiver/data_retrieval.ts +61 -16
  49. package/src/archiver/eth_log_handlers.ts +142 -68
  50. package/src/archiver/kv_archiver_store/block_body_store.ts +54 -0
  51. package/src/archiver/kv_archiver_store/block_store.ts +71 -36
  52. package/src/archiver/kv_archiver_store/contract_class_store.ts +4 -0
  53. package/src/archiver/kv_archiver_store/contract_store.ts +7 -2
  54. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +56 -20
  55. package/src/archiver/kv_archiver_store/log_store.ts +2 -2
  56. package/src/archiver/kv_archiver_store/message_store.ts +34 -30
  57. package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +17 -17
  58. package/src/archiver/memory_archiver_store/memory_archiver_store.ts +91 -29
  59. package/src/index.ts +1 -0
  60. package/src/rpc/archiver_client.ts +3 -1
  61. package/src/rpc/archiver_server.ts +5 -1
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  ExtendedContractData,
3
- INITIAL_L2_BLOCK_NUM,
4
3
  L1ToL2Message,
5
4
  L2Block,
6
5
  L2BlockContext,
@@ -10,8 +9,8 @@ import {
10
9
  UnencryptedL2Log,
11
10
  } from '@aztec/circuit-types';
12
11
  import '@aztec/circuit-types/jest';
13
- import { AztecAddress, Fr } from '@aztec/circuits.js';
14
- import { makeContractClassPublic } from '@aztec/circuits.js/factories';
12
+ import { AztecAddress, Fr, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
13
+ import { makeContractClassPublic } from '@aztec/circuits.js/testing';
15
14
  import { randomBytes } from '@aztec/foundation/crypto';
16
15
  import { ContractClassPublic, ContractInstanceWithAddress, SerializableContractInstance } from '@aztec/types/contracts';
17
16
 
@@ -43,6 +42,10 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
43
42
  });
44
43
 
45
44
  describe('addBlocks', () => {
45
+ it('returns success when adding block bodies', async () => {
46
+ await expect(store.addBlockBodies(blocks.map(block => block.body))).resolves.toBe(true);
47
+ });
48
+
46
49
  it('returns success when adding blocks', async () => {
47
50
  await expect(store.addBlocks(blocks)).resolves.toBe(true);
48
51
  });
@@ -56,6 +59,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
56
59
  describe('getBlocks', () => {
57
60
  beforeEach(async () => {
58
61
  await store.addBlocks(blocks);
62
+ await store.addBlockBodies(blocks.map(block => block.body));
59
63
  });
60
64
 
61
65
  it.each(blockTests)('retrieves previously stored blocks', async (start, limit, getExpectedBlocks) => {
@@ -115,7 +119,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
115
119
  it('returns the L1 block number that most recently cancelled pending messages', async () => {
116
120
  const message = L1ToL2Message.random(Fr.random());
117
121
  await store.addPendingL1ToL2Messages([message], 1n);
118
- await store.cancelPendingL1ToL2Messages([message.entryKey!], 2n);
122
+ await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 2n);
119
123
  await expect(store.getL1BlockNumber()).resolves.toEqual({
120
124
  addedBlock: 0n,
121
125
  addedMessages: 1n,
@@ -127,7 +131,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
127
131
  describe('addLogs', () => {
128
132
  it('adds encrypted & unencrypted logs', async () => {
129
133
  await expect(
130
- store.addLogs(blocks[0].newEncryptedLogs, blocks[0].newUnencryptedLogs, blocks[0].number),
134
+ store.addLogs(blocks[0].body.encryptedLogs, blocks[0].body.unencryptedLogs, blocks[0].number),
131
135
  ).resolves.toEqual(true);
132
136
  });
133
137
  });
@@ -138,25 +142,26 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
138
142
  ])('getLogs (%s)', (_, logType) => {
139
143
  beforeEach(async () => {
140
144
  await Promise.all(
141
- blocks.map(block => store.addLogs(block.newEncryptedLogs, block.newUnencryptedLogs, block.number)),
145
+ blocks.map(block => store.addLogs(block.body.encryptedLogs, block.body.unencryptedLogs, block.number)),
142
146
  );
143
147
  });
144
148
 
145
149
  it.each(blockTests)('retrieves previously stored logs', async (from, limit, getExpectedBlocks) => {
146
150
  const expectedLogs = getExpectedBlocks().map(block =>
147
- logType === LogType.ENCRYPTED ? block.newEncryptedLogs : block.newUnencryptedLogs,
151
+ logType === LogType.ENCRYPTED ? block.body.encryptedLogs : block.body.unencryptedLogs,
148
152
  );
149
153
  const actualLogs = await store.getLogs(from, limit, logType);
150
154
  expect(actualLogs).toEqual(expectedLogs);
151
155
  });
152
156
  });
153
157
 
154
- describe('getL2Tx', () => {
158
+ describe('getTxEffect', () => {
155
159
  beforeEach(async () => {
156
160
  await Promise.all(
157
- blocks.map(block => store.addLogs(block.newEncryptedLogs, block.newUnencryptedLogs, block.number)),
161
+ blocks.map(block => store.addLogs(block.body.encryptedLogs, block.body.unencryptedLogs, block.number)),
158
162
  );
159
163
  await store.addBlocks(blocks);
164
+ await store.addBlockBodies(blocks.map(block => block.body));
160
165
  });
161
166
 
162
167
  it.each([
@@ -167,12 +172,12 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
167
172
  () => blocks[1].getTx(0),
168
173
  ])('retrieves a previously stored transaction', async getExpectedTx => {
169
174
  const expectedTx = getExpectedTx();
170
- const actualTx = await store.getL2Tx(expectedTx.txHash);
175
+ const actualTx = await store.getTxEffect(expectedTx.txHash);
171
176
  expect(actualTx).toEqual(expectedTx);
172
177
  });
173
178
 
174
179
  it('returns undefined if tx is not found', async () => {
175
- await expect(store.getL2Tx(new TxHash(Fr.random().toBuffer()))).resolves.toBeUndefined();
180
+ await expect(store.getTxEffect(new TxHash(Fr.random().toBuffer()))).resolves.toBeUndefined();
176
181
  });
177
182
  });
178
183
 
@@ -185,7 +190,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
185
190
  const message = L1ToL2Message.random(Fr.random());
186
191
  await expect(store.addPendingL1ToL2Messages([message, message], 1n)).resolves.toEqual(true);
187
192
 
188
- await expect(store.getPendingL1ToL2MessageKeys(2)).resolves.toEqual([message.entryKey!, message.entryKey!]);
193
+ await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([message.entryKey!, message.entryKey!]);
189
194
  });
190
195
 
191
196
  it('allows duplicate pending messages in different blocks', async () => {
@@ -193,25 +198,26 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
193
198
  await expect(store.addPendingL1ToL2Messages([message], 1n)).resolves.toEqual(true);
194
199
  await expect(store.addPendingL1ToL2Messages([message], 2n)).resolves.toEqual(true);
195
200
 
196
- await expect(store.getPendingL1ToL2MessageKeys(2)).resolves.toEqual([message.entryKey!, message.entryKey!]);
201
+ await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([message.entryKey!, message.entryKey!]);
197
202
  });
198
203
 
199
204
  it('is idempotent', async () => {
200
205
  const message = L1ToL2Message.random(Fr.random());
201
206
  await expect(store.addPendingL1ToL2Messages([message], 1n)).resolves.toEqual(true);
202
207
  await expect(store.addPendingL1ToL2Messages([message], 1n)).resolves.toEqual(false);
203
- await expect(store.getPendingL1ToL2MessageKeys(2)).resolves.toEqual([message.entryKey!]);
208
+ await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([message.entryKey!]);
204
209
  });
205
210
  });
206
211
 
207
- describe('getPendingL1ToL2Messages', () => {
212
+ describe('getPendingL1ToL2EntryKeys', () => {
208
213
  it('returns previously stored pending L1 to L2 messages', async () => {
209
214
  const message = L1ToL2Message.random(Fr.random());
210
215
  await store.addPendingL1ToL2Messages([message], 1n);
211
- await expect(store.getPendingL1ToL2MessageKeys(1)).resolves.toEqual([message.entryKey!]);
216
+ await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([message.entryKey!]);
212
217
  });
213
218
 
214
- it('returns messages ordered by fee', async () => {
219
+ // TODO(@spalladino): Fix and re-enable
220
+ it.skip('returns messages ordered by fee', async () => {
215
221
  const messages = Array.from({ length: 3 }, () => L1ToL2Message.random(Fr.random()));
216
222
  // add a duplicate message
217
223
  messages.push(messages[0]);
@@ -219,43 +225,43 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
219
225
  await store.addPendingL1ToL2Messages(messages, 1n);
220
226
 
221
227
  messages.sort((a, b) => b.fee - a.fee);
222
- await expect(store.getPendingL1ToL2MessageKeys(messages.length)).resolves.toEqual(
228
+ await expect(store.getPendingL1ToL2EntryKeys(messages.length)).resolves.toEqual(
223
229
  messages.map(message => message.entryKey!),
224
230
  );
225
231
  });
226
232
 
227
233
  it('returns an empty array if no messages are found', async () => {
228
- await expect(store.getPendingL1ToL2MessageKeys(1)).resolves.toEqual([]);
234
+ await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([]);
229
235
  });
230
236
  });
231
237
 
232
- describe('confirmL1ToL2Messages', () => {
238
+ describe('confirmL1ToL2EntryKeys', () => {
233
239
  it('updates a message from pending to confirmed', async () => {
234
240
  const message = L1ToL2Message.random(Fr.random());
235
241
  await store.addPendingL1ToL2Messages([message], 1n);
236
- await expect(store.confirmL1ToL2Messages([message.entryKey!])).resolves.toEqual(true);
242
+ await expect(store.confirmL1ToL2EntryKeys([message.entryKey!])).resolves.toEqual(true);
237
243
  });
238
244
 
239
245
  it('once confirmed, a message is no longer pending', async () => {
240
246
  const message = L1ToL2Message.random(Fr.random());
241
247
  await store.addPendingL1ToL2Messages([message], 1n);
242
- await store.confirmL1ToL2Messages([message.entryKey!]);
243
- await expect(store.getPendingL1ToL2MessageKeys(1)).resolves.toEqual([]);
248
+ await store.confirmL1ToL2EntryKeys([message.entryKey!]);
249
+ await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([]);
244
250
  });
245
251
 
246
252
  it('once confirmed a message can also be pending if added again', async () => {
247
253
  const message = L1ToL2Message.random(Fr.random());
248
254
  await store.addPendingL1ToL2Messages([message], 1n);
249
- await store.confirmL1ToL2Messages([message.entryKey!]);
255
+ await store.confirmL1ToL2EntryKeys([message.entryKey!]);
250
256
  await store.addPendingL1ToL2Messages([message], 2n);
251
- await expect(store.getPendingL1ToL2MessageKeys(2)).resolves.toEqual([message.entryKey!]);
257
+ await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([message.entryKey!]);
252
258
  });
253
259
 
254
260
  it('once confirmed a message can remain pending if more of it were pending', async () => {
255
261
  const message = L1ToL2Message.random(Fr.random());
256
262
  await store.addPendingL1ToL2Messages([message, message], 1n);
257
- await store.confirmL1ToL2Messages([message.entryKey!]);
258
- await expect(store.getPendingL1ToL2MessageKeys(1)).resolves.toEqual([message.entryKey!]);
263
+ await store.confirmL1ToL2EntryKeys([message.entryKey!]);
264
+ await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([message.entryKey!]);
259
265
  });
260
266
  });
261
267
 
@@ -263,62 +269,62 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
263
269
  it('cancels a pending message', async () => {
264
270
  const message = L1ToL2Message.random(Fr.random());
265
271
  await store.addPendingL1ToL2Messages([message], 1n);
266
- await store.cancelPendingL1ToL2Messages([message.entryKey!], 1n);
267
- await expect(store.getPendingL1ToL2MessageKeys(1)).resolves.toEqual([]);
272
+ await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 1n);
273
+ await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([]);
268
274
  });
269
275
 
270
276
  it('cancels only one of the pending messages if duplicates exist', async () => {
271
277
  const message = L1ToL2Message.random(Fr.random());
272
278
  await store.addPendingL1ToL2Messages([message, message], 1n);
273
- await store.cancelPendingL1ToL2Messages([message.entryKey!], 1n);
274
- await expect(store.getPendingL1ToL2MessageKeys(2)).resolves.toEqual([message.entryKey]);
279
+ await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 1n);
280
+ await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([message.entryKey]);
275
281
  });
276
282
 
277
283
  it('once canceled a message can also be pending if added again', async () => {
278
284
  const message = L1ToL2Message.random(Fr.random());
279
285
  await store.addPendingL1ToL2Messages([message], 1n);
280
286
 
281
- await store.cancelPendingL1ToL2Messages([message.entryKey!], 1n);
282
- await expect(store.getPendingL1ToL2MessageKeys(1)).resolves.toEqual([]);
287
+ await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 1n);
288
+ await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([]);
283
289
 
284
290
  await store.addPendingL1ToL2Messages([message], 2n);
285
- await expect(store.getPendingL1ToL2MessageKeys(1)).resolves.toEqual([message.entryKey!]);
291
+ await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([message.entryKey!]);
286
292
  });
287
293
 
288
294
  it('allows adding and cancelling in the same block', async () => {
289
295
  const message = L1ToL2Message.random(Fr.random());
290
296
  await store.addPendingL1ToL2Messages([message], 1n);
291
- await store.cancelPendingL1ToL2Messages([message.entryKey!], 1n);
292
- await expect(store.getPendingL1ToL2MessageKeys(1)).resolves.toEqual([]);
297
+ await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 1n);
298
+ await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([]);
293
299
  });
294
300
 
295
301
  it('allows duplicates cancellations in different positions in the same block', async () => {
296
302
  const message = L1ToL2Message.random(Fr.random());
297
303
  await store.addPendingL1ToL2Messages([message, message], 1n);
298
304
 
299
- await store.cancelPendingL1ToL2Messages([message.entryKey!, message.entryKey!], 1n);
305
+ await store.cancelPendingL1ToL2EntryKeys([message.entryKey!, message.entryKey!], 1n);
300
306
 
301
- await expect(store.getPendingL1ToL2MessageKeys(2)).resolves.toEqual([]);
307
+ await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([]);
302
308
  });
303
309
 
304
310
  it('allows duplicates cancellations in different blocks', async () => {
305
311
  const message = L1ToL2Message.random(Fr.random());
306
312
  await store.addPendingL1ToL2Messages([message, message], 1n);
307
313
 
308
- await store.cancelPendingL1ToL2Messages([message.entryKey!], 2n);
309
- await store.cancelPendingL1ToL2Messages([message.entryKey!], 3n);
314
+ await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 2n);
315
+ await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 3n);
310
316
 
311
- await expect(store.getPendingL1ToL2MessageKeys(2)).resolves.toEqual([]);
317
+ await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([]);
312
318
  });
313
319
 
314
320
  it('is idempotent', async () => {
315
321
  const message = L1ToL2Message.random(Fr.random());
316
322
  await store.addPendingL1ToL2Messages([message, message], 1n);
317
323
 
318
- await store.cancelPendingL1ToL2Messages([message.entryKey!], 2n);
319
- await store.cancelPendingL1ToL2Messages([message.entryKey!], 2n);
324
+ await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 2n);
325
+ await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 2n);
320
326
 
321
- await expect(store.getPendingL1ToL2MessageKeys(2)).resolves.toEqual([message.entryKey!]);
327
+ await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([message.entryKey!]);
322
328
  });
323
329
  });
324
330
 
@@ -363,11 +369,12 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
363
369
  beforeEach(async () => {
364
370
  block = L2Block.random(1);
365
371
  await store.addBlocks([block]);
372
+ await store.addBlockBodies([block.body]);
366
373
  });
367
374
 
368
375
  it('returns previously stored contract data', async () => {
369
- await expect(store.getContractData(block.newContractData[0].contractAddress)).resolves.toEqual(
370
- block.newContractData[0],
376
+ await expect(store.getContractData(block.body.txEffects[0].contractData[0].contractAddress)).resolves.toEqual(
377
+ block.body.txEffects[0].contractData[0],
371
378
  );
372
379
  });
373
380
 
@@ -381,10 +388,13 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
381
388
  beforeEach(async () => {
382
389
  block = L2Block.random(1);
383
390
  await store.addBlocks([block]);
391
+ await store.addBlockBodies([block.body]);
384
392
  });
385
393
 
386
394
  it('returns the contract data for a known block', async () => {
387
- await expect(store.getContractDataInBlock(block.number)).resolves.toEqual(block.newContractData);
395
+ await expect(store.getContractDataInBlock(block.number)).resolves.toEqual(
396
+ block.body.txEffects.flatMap(txEffect => txEffect.contractData),
397
+ );
388
398
  });
389
399
 
390
400
  it('returns an empty array if contract data is not found', async () => {
@@ -396,6 +406,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
396
406
  it('stores extended contract data', async () => {
397
407
  const block = L2Block.random(1);
398
408
  await store.addBlocks([block]);
409
+ await store.addBlockBodies([block.body]);
399
410
  await expect(store.addExtendedContractData([ExtendedContractData.random()], block.number)).resolves.toEqual(
400
411
  true,
401
412
  );
@@ -408,11 +419,13 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
408
419
  it('"pushes" extended contract data and does not overwrite', async () => {
409
420
  const block = L2Block.random(1);
410
421
  await store.addBlocks([block]);
422
+ await store.addBlockBodies([block.body]);
411
423
 
412
- const firstContract = ExtendedContractData.random(block.newContractData[0]);
424
+ // Assuming one contract per tx, and the first two txs
425
+ const firstContract = ExtendedContractData.random(block.body.txEffects[0].contractData[0]);
413
426
  await store.addExtendedContractData([firstContract], block.number);
414
427
 
415
- const secondContract = ExtendedContractData.random(block.newContractData[1]);
428
+ const secondContract = ExtendedContractData.random(block.body.txEffects[1].contractData[0]);
416
429
  await store.addExtendedContractData([secondContract], block.number);
417
430
 
418
431
  await expect(store.getExtendedContractDataInBlock(block.number)).resolves.toEqual([
@@ -427,8 +440,9 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
427
440
  let extendedContractData: ExtendedContractData;
428
441
  beforeEach(async () => {
429
442
  block = L2Block.random(1);
430
- extendedContractData = ExtendedContractData.random(block.newContractData[0]);
443
+ extendedContractData = ExtendedContractData.random(block.body.txEffects[0].contractData[0]);
431
444
  await store.addBlocks([block]);
445
+ await store.addBlockBodies([block.body]);
432
446
  await store.addExtendedContractData([extendedContractData], block.number);
433
447
  });
434
448
 
@@ -448,8 +462,9 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
448
462
  let extendedContractData: ExtendedContractData;
449
463
  beforeEach(async () => {
450
464
  block = L2Block.random(1);
451
- extendedContractData = ExtendedContractData.random(block.newContractData[0]);
465
+ extendedContractData = ExtendedContractData.random(block.body.txEffects[0].contractData[0]);
452
466
  await store.addBlocks([block]);
467
+ await store.addBlockBodies([block.body]);
453
468
  await store.addExtendedContractData([extendedContractData], block.number);
454
469
  });
455
470
 
@@ -477,8 +492,10 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
477
492
  );
478
493
 
479
494
  await store.addBlocks(blocks);
495
+ await store.addBlockBodies(blocks.map(block => block.body));
496
+
480
497
  await Promise.all(
481
- blocks.map(block => store.addLogs(block.newEncryptedLogs, block.newUnencryptedLogs, block.number)),
498
+ blocks.map(block => store.addLogs(block.body.encryptedLogs, block.body.unencryptedLogs, block.number)),
482
499
  );
483
500
  });
484
501
 
@@ -530,9 +547,8 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
530
547
  const targetFunctionLogIndex = Math.floor(Math.random() * numPublicFunctionCalls);
531
548
  const targetLogIndex = Math.floor(Math.random() * numUnencryptedLogs);
532
549
  const targetContractAddress = UnencryptedL2Log.fromBuffer(
533
- blocks[targetBlockIndex].newUnencryptedLogs!.txLogs[targetTxIndex].functionLogs[targetFunctionLogIndex].logs[
534
- targetLogIndex
535
- ],
550
+ blocks[targetBlockIndex].body.txEffects[targetTxIndex].unencryptedLogs.functionLogs[targetFunctionLogIndex]
551
+ .logs[targetLogIndex],
536
552
  ).contractAddress;
537
553
 
538
554
  const response = await store.getUnencryptedLogs({ contractAddress: targetContractAddress });
@@ -551,9 +567,8 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
551
567
  const targetFunctionLogIndex = Math.floor(Math.random() * numPublicFunctionCalls);
552
568
  const targetLogIndex = Math.floor(Math.random() * numUnencryptedLogs);
553
569
  const targetSelector = UnencryptedL2Log.fromBuffer(
554
- blocks[targetBlockIndex].newUnencryptedLogs!.txLogs[targetTxIndex].functionLogs[targetFunctionLogIndex].logs[
555
- targetLogIndex
556
- ],
570
+ blocks[targetBlockIndex].body.txEffects[targetTxIndex].unencryptedLogs.functionLogs[targetFunctionLogIndex]
571
+ .logs[targetLogIndex],
557
572
  ).selector;
558
573
 
559
574
  const response = await store.getUnencryptedLogs({ selector: targetSelector });
@@ -1,5 +1,5 @@
1
- import { ExtendedContractData, L1ToL2Message, L2Block } from '@aztec/circuit-types';
2
- import { Fr } from '@aztec/circuits.js';
1
+ import { Body, ExtendedContractData, L1ToL2Message } from '@aztec/circuit-types';
2
+ import { AppendOnlyTreeSnapshot, Fr, Header } from '@aztec/circuits.js';
3
3
  import { EthAddress } from '@aztec/foundation/eth-address';
4
4
 
5
5
  import { PublicClient } from 'viem';
@@ -9,10 +9,12 @@ import {
9
9
  getL1ToL2MessageCancelledLogs,
10
10
  getL2BlockProcessedLogs,
11
11
  getPendingL1ToL2MessageLogs,
12
- processBlockLogs,
12
+ getTxsPublishedLogs,
13
13
  processCancelledL1ToL2MessagesLogs,
14
14
  processContractDeploymentLogs,
15
+ processL2BlockProcessedLogs,
15
16
  processPendingL1ToL2MessageAddedLogs,
17
+ processTxsPublishedLogs,
16
18
  } from './eth_log_handlers.js';
17
19
 
18
20
  /**
@@ -30,24 +32,24 @@ type DataRetrieval<T> = {
30
32
  };
31
33
 
32
34
  /**
33
- * Fetches new L2 Blocks.
35
+ * Fetches new L2 block metadata (header, archive snapshot).
34
36
  * @param publicClient - The viem public client to use for transaction retrieval.
35
37
  * @param rollupAddress - The address of the rollup contract.
36
38
  * @param blockUntilSynced - If true, blocks until the archiver has fully synced.
37
39
  * @param searchStartBlock - The block number to use for starting the search.
38
40
  * @param searchEndBlock - The highest block number that we should search up to.
39
41
  * @param expectedNextL2BlockNum - The next L2 block number that we expect to find.
40
- * @returns An array of L2 Blocks and the next eth block to search from
42
+ * @returns An array of tuples representing block metadata including the header, archive tree snapshot, and associated l1 block number; as well as the next eth block to search from.
41
43
  */
42
- export async function retrieveBlocks(
44
+ export async function retrieveBlockMetadataFromRollup(
43
45
  publicClient: PublicClient,
44
46
  rollupAddress: EthAddress,
45
47
  blockUntilSynced: boolean,
46
48
  searchStartBlock: bigint,
47
49
  searchEndBlock: bigint,
48
50
  expectedNextL2BlockNum: bigint,
49
- ): Promise<DataRetrieval<L2Block>> {
50
- const retrievedBlocks: L2Block[] = [];
51
+ ): Promise<DataRetrieval<[Header, AppendOnlyTreeSnapshot, bigint]>> {
52
+ const retrievedBlockMetadata: [Header, AppendOnlyTreeSnapshot, bigint][] = [];
51
53
  do {
52
54
  if (searchStartBlock > searchEndBlock) {
53
55
  break;
@@ -62,12 +64,55 @@ export async function retrieveBlocks(
62
64
  break;
63
65
  }
64
66
 
65
- const newBlocks = await processBlockLogs(publicClient, expectedNextL2BlockNum, l2BlockProcessedLogs);
66
- retrievedBlocks.push(...newBlocks);
67
+ const newBlockMetadata = await processL2BlockProcessedLogs(
68
+ publicClient,
69
+ expectedNextL2BlockNum,
70
+ l2BlockProcessedLogs,
71
+ );
72
+ retrievedBlockMetadata.push(...newBlockMetadata);
67
73
  searchStartBlock = l2BlockProcessedLogs[l2BlockProcessedLogs.length - 1].blockNumber! + 1n;
68
- expectedNextL2BlockNum += BigInt(newBlocks.length);
74
+ expectedNextL2BlockNum += BigInt(newBlockMetadata.length);
75
+ } while (blockUntilSynced && searchStartBlock <= searchEndBlock);
76
+ return { nextEthBlockNumber: searchStartBlock, retrievedData: retrievedBlockMetadata };
77
+ }
78
+
79
+ /**
80
+ * Fetches new L2 block bodies and their hashes.
81
+ * @param publicClient - The viem public client to use for transaction retrieval.
82
+ * @param availabilityOracleAddress - The address of the availability oracle contract.
83
+ * @param blockUntilSynced - If true, blocks until the archiver has fully synced.
84
+ * @param searchStartBlock - The block number to use for starting the search.
85
+ * @param searchEndBlock - The highest block number that we should search up to.
86
+ * @returns A array of tuples of L2 block bodies and their associated hash as well as the next eth block to search from
87
+ */
88
+ export async function retrieveBlockBodiesFromAvailabilityOracle(
89
+ publicClient: PublicClient,
90
+ availabilityOracleAddress: EthAddress,
91
+ blockUntilSynced: boolean,
92
+ searchStartBlock: bigint,
93
+ searchEndBlock: bigint,
94
+ ): Promise<DataRetrieval<[Body, Buffer]>> {
95
+ const retrievedBlockBodies: [Body, Buffer][] = [];
96
+
97
+ do {
98
+ if (searchStartBlock > searchEndBlock) {
99
+ break;
100
+ }
101
+ const l2TxsPublishedLogs = await getTxsPublishedLogs(
102
+ publicClient,
103
+ availabilityOracleAddress,
104
+ searchStartBlock,
105
+ searchEndBlock,
106
+ );
107
+ if (l2TxsPublishedLogs.length === 0) {
108
+ break;
109
+ }
110
+
111
+ const newBlockBodies = await processTxsPublishedLogs(publicClient, l2TxsPublishedLogs);
112
+ retrievedBlockBodies.push(...newBlockBodies);
113
+ searchStartBlock = l2TxsPublishedLogs[l2TxsPublishedLogs.length - 1].blockNumber! + 1n;
69
114
  } while (blockUntilSynced && searchStartBlock <= searchEndBlock);
70
- return { nextEthBlockNumber: searchStartBlock, retrievedData: retrievedBlocks };
115
+ return { nextEthBlockNumber: searchStartBlock, retrievedData: retrievedBlockBodies };
71
116
  }
72
117
 
73
118
  /**
@@ -77,7 +122,7 @@ export async function retrieveBlocks(
77
122
  * @param blockUntilSynced - If true, blocks until the archiver has fully synced.
78
123
  * @param searchStartBlock - The block number to use for starting the search.
79
124
  * @param searchEndBlock - The highest block number that we should search up to.
80
- * @param blockHashMapping - A mapping from block number to relevant block hash.
125
+ * @param blockNumberToBodyHash - A mapping from block number to relevant body hash.
81
126
  * @returns An array of ExtendedContractData and their equivalent L2 Block number along with the next eth block to search from..
82
127
  */
83
128
  export async function retrieveNewContractData(
@@ -86,7 +131,7 @@ export async function retrieveNewContractData(
86
131
  blockUntilSynced: boolean,
87
132
  searchStartBlock: bigint,
88
133
  searchEndBlock: bigint,
89
- blockHashMapping: { [key: number]: Buffer | undefined },
134
+ blockNumberToBodyHash: { [key: number]: Buffer | undefined },
90
135
  ): Promise<DataRetrieval<[ExtendedContractData[], number]>> {
91
136
  let retrievedNewContracts: [ExtendedContractData[], number][] = [];
92
137
  do {
@@ -102,7 +147,7 @@ export async function retrieveNewContractData(
102
147
  if (contractDataLogs.length === 0) {
103
148
  break;
104
149
  }
105
- const newContracts = processContractDeploymentLogs(blockHashMapping, contractDataLogs);
150
+ const newContracts = processContractDeploymentLogs(blockNumberToBodyHash, contractDataLogs);
106
151
  retrievedNewContracts = retrievedNewContracts.concat(newContracts);
107
152
  searchStartBlock = (contractDataLogs.findLast(cd => !!cd)?.blockNumber || searchStartBlock) + 1n;
108
153
  } while (blockUntilSynced && searchStartBlock <= searchEndBlock);
@@ -154,7 +199,7 @@ export async function retrieveNewPendingL1ToL2Messages(
154
199
  * @param blockUntilSynced - If true, blocks until the archiver has fully synced.
155
200
  * @param searchStartBlock - The block number to use for starting the search.
156
201
  * @param searchEndBlock - The highest block number that we should search up to.
157
- * @returns An array of message keys that were cancelled and next eth block to search from.
202
+ * @returns An array of entry keys that were cancelled and next eth block to search from.
158
203
  */
159
204
  export async function retrieveNewCancelledL1ToL2Messages(
160
205
  publicClient: PublicClient,