@aztec/archiver 0.28.1 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dest/archiver/archiver.d.ts +13 -53
  2. package/dest/archiver/archiver.d.ts.map +1 -1
  3. package/dest/archiver/archiver.js +60 -199
  4. package/dest/archiver/archiver_store.d.ts +21 -67
  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 +60 -199
  8. package/dest/archiver/config.d.ts.map +1 -1
  9. package/dest/archiver/config.js +6 -2
  10. package/dest/archiver/data_retrieval.d.ts +10 -32
  11. package/dest/archiver/data_retrieval.d.ts.map +1 -1
  12. package/dest/archiver/data_retrieval.js +13 -67
  13. package/dest/archiver/eth_log_handlers.d.ts +7 -38
  14. package/dest/archiver/eth_log_handlers.d.ts.map +1 -1
  15. package/dest/archiver/eth_log_handlers.js +9 -77
  16. package/dest/archiver/kv_archiver_store/block_store.d.ts +5 -4
  17. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
  18. package/dest/archiver/kv_archiver_store/block_store.js +12 -15
  19. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +15 -56
  20. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
  21. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +23 -87
  22. package/dest/archiver/kv_archiver_store/message_store.d.ts +12 -43
  23. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
  24. package/dest/archiver/kv_archiver_store/message_store.js +32 -141
  25. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +8 -41
  26. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +1 -1
  27. package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +22 -79
  28. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +20 -81
  29. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
  30. package/dest/archiver/memory_archiver_store/memory_archiver_store.js +30 -143
  31. package/dest/index.d.ts.map +1 -1
  32. package/dest/index.js +3 -15
  33. package/dest/rpc/archiver_client.d.ts.map +1 -1
  34. package/dest/rpc/archiver_client.js +2 -6
  35. package/dest/rpc/archiver_server.d.ts.map +1 -1
  36. package/dest/rpc/archiver_server.js +2 -6
  37. package/package.json +9 -9
  38. package/src/archiver/archiver.ts +80 -267
  39. package/src/archiver/archiver_store.ts +22 -76
  40. package/src/archiver/archiver_store_test_suite.ts +78 -243
  41. package/src/archiver/config.ts +6 -0
  42. package/src/archiver/data_retrieval.ts +19 -101
  43. package/src/archiver/eth_log_handlers.ts +14 -108
  44. package/src/archiver/kv_archiver_store/block_store.ts +13 -14
  45. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +23 -93
  46. package/src/archiver/kv_archiver_store/message_store.ts +38 -169
  47. package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +21 -90
  48. package/src/archiver/memory_archiver_store/memory_archiver_store.ts +33 -161
  49. package/src/index.ts +1 -15
  50. package/src/rpc/archiver_client.ts +0 -8
  51. package/src/rpc/archiver_server.ts +0 -8
  52. package/dest/archiver/kv_archiver_store/contract_store.d.ts +0 -26
  53. package/dest/archiver/kv_archiver_store/contract_store.d.ts.map +0 -1
  54. package/dest/archiver/kv_archiver_store/contract_store.js +0 -49
  55. package/src/archiver/kv_archiver_store/contract_store.ts +0 -55
@@ -1,13 +1,4 @@
1
- import {
2
- L1ToL2Message,
3
- L2Block,
4
- L2BlockContext,
5
- LogId,
6
- LogType,
7
- NewInboxLeaf,
8
- TxHash,
9
- UnencryptedL2Log,
10
- } from '@aztec/circuit-types';
1
+ import { InboxLeaf, L2Block, L2BlockContext, LogId, LogType, TxHash, UnencryptedL2Log } from '@aztec/circuit-types';
11
2
  import '@aztec/circuit-types/jest';
12
3
  import { AztecAddress, Fr, INITIAL_L2_BLOCK_NUM, L1_TO_L2_MSG_SUBTREE_HEIGHT } from '@aztec/circuits.js';
13
4
  import { makeContractClassPublic } from '@aztec/circuits.js/testing';
@@ -15,6 +6,7 @@ import { randomBytes, randomInt } from '@aztec/foundation/crypto';
15
6
  import { ContractClassPublic, ContractInstanceWithAddress, SerializableContractInstance } from '@aztec/types/contracts';
16
7
 
17
8
  import { ArchiverDataStore } from './archiver_store.js';
9
+ import { DataRetrieval } from './data_retrieval.js';
18
10
 
19
11
  /**
20
12
  * @param testName - The name of the test suite.
@@ -23,27 +15,26 @@ import { ArchiverDataStore } from './archiver_store.js';
23
15
  export function describeArchiverDataStore(testName: string, getStore: () => ArchiverDataStore) {
24
16
  describe(testName, () => {
25
17
  let store: ArchiverDataStore;
26
- let blocks: L2Block[];
18
+ let blocks: DataRetrieval<L2Block>;
27
19
  const blockTests: [number, number, () => L2Block[]][] = [
28
- [1, 1, () => blocks.slice(0, 1)],
29
- [10, 1, () => blocks.slice(9, 10)],
30
- [1, 10, () => blocks.slice(0, 10)],
31
- [2, 5, () => blocks.slice(1, 6)],
32
- [5, 2, () => blocks.slice(4, 6)],
20
+ [1, 1, () => blocks.retrievedData.slice(0, 1)],
21
+ [10, 1, () => blocks.retrievedData.slice(9, 10)],
22
+ [1, 10, () => blocks.retrievedData.slice(0, 10)],
23
+ [2, 5, () => blocks.retrievedData.slice(1, 6)],
24
+ [5, 2, () => blocks.retrievedData.slice(4, 6)],
33
25
  ];
34
26
 
35
27
  beforeEach(() => {
36
28
  store = getStore();
37
- blocks = Array.from({ length: 10 }).map((_, i) => {
38
- const block = L2Block.random(i + 1);
39
- block.setL1BlockNumber(BigInt(i + 1));
40
- return block;
41
- });
29
+ blocks = {
30
+ lastProcessedL1BlockNumber: 5n,
31
+ retrievedData: Array.from({ length: 10 }).map((_, i) => L2Block.random(i + 1)),
32
+ };
42
33
  });
43
34
 
44
35
  describe('addBlocks', () => {
45
36
  it('returns success when adding block bodies', async () => {
46
- await expect(store.addBlockBodies(blocks.map(block => block.body))).resolves.toBe(true);
37
+ await expect(store.addBlockBodies(blocks.retrievedData.map(block => block.body))).resolves.toBe(true);
47
38
  });
48
39
 
49
40
  it('returns success when adding blocks', async () => {
@@ -59,7 +50,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
59
50
  describe('getBlocks', () => {
60
51
  beforeEach(async () => {
61
52
  await store.addBlocks(blocks);
62
- await store.addBlockBodies(blocks.map(block => block.body));
53
+ await store.addBlockBodies(blocks.retrievedData.map(block => block.body));
63
54
  });
64
55
 
65
56
  it.each(blockTests)('retrieves previously stored blocks', async (start, limit, getExpectedBlocks) => {
@@ -71,72 +62,49 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
71
62
  });
72
63
 
73
64
  it('throws an error if limit is invalid', async () => {
74
- await expect(store.getBlocks(1, 0)).rejects.toThrowError('Invalid limit: 0');
65
+ await expect(store.getBlocks(1, 0)).rejects.toThrow('Invalid limit: 0');
75
66
  });
76
67
 
77
68
  it('resets `from` to the first block if it is out of range', async () => {
78
- await expect(store.getBlocks(INITIAL_L2_BLOCK_NUM - 100, 1)).resolves.toEqual(blocks.slice(0, 1));
69
+ await expect(store.getBlocks(INITIAL_L2_BLOCK_NUM - 100, 1)).resolves.toEqual(blocks.retrievedData.slice(0, 1));
79
70
  });
80
71
  });
81
72
 
82
- describe('getBlockNumber', () => {
73
+ describe('getSyncedL2BlockNumber', () => {
83
74
  it('returns the block number before INITIAL_L2_BLOCK_NUM if no blocks have been added', async () => {
84
- await expect(store.getBlockNumber()).resolves.toEqual(INITIAL_L2_BLOCK_NUM - 1);
75
+ await expect(store.getSynchedL2BlockNumber()).resolves.toEqual(INITIAL_L2_BLOCK_NUM - 1);
85
76
  });
86
77
 
87
78
  it("returns the most recently added block's number", async () => {
88
79
  await store.addBlocks(blocks);
89
- await expect(store.getBlockNumber()).resolves.toEqual(blocks.at(-1)!.number);
80
+ await expect(store.getSynchedL2BlockNumber()).resolves.toEqual(blocks.retrievedData.at(-1)!.number);
90
81
  });
91
82
  });
92
83
 
93
- describe('getL1BlockNumber', () => {
84
+ describe('getSynchedL1BlockNumbers', () => {
94
85
  it('returns 0n if no blocks have been added', async () => {
95
- await expect(store.getL1BlockNumber()).resolves.toEqual({
96
- addedBlock: 0n,
97
- addedMessages: 0n,
98
- cancelledMessages: 0n,
99
- newMessages: 0n,
86
+ await expect(store.getSynchedL1BlockNumbers()).resolves.toEqual({
87
+ blocks: 0n,
88
+ messages: 0n,
100
89
  });
101
90
  });
102
91
 
103
92
  it('returns the L1 block number in which the most recent L2 block was published', async () => {
104
93
  await store.addBlocks(blocks);
105
- await expect(store.getL1BlockNumber()).resolves.toEqual({
106
- addedBlock: blocks.at(-1)!.getL1BlockNumber(),
107
- addedMessages: 0n,
108
- cancelledMessages: 0n,
109
- newMessages: 0n,
94
+ await expect(store.getSynchedL1BlockNumbers()).resolves.toEqual({
95
+ blocks: blocks.lastProcessedL1BlockNumber,
96
+ messages: 0n,
110
97
  });
111
98
  });
112
99
 
113
- it('returns the L1 block number that most recently added pending messages', async () => {
114
- await store.addPendingL1ToL2Messages([L1ToL2Message.random(Fr.random())], 1n);
115
- await expect(store.getL1BlockNumber()).resolves.toEqual({
116
- addedBlock: 0n,
117
- addedMessages: 1n,
118
- cancelledMessages: 0n,
119
- newMessages: 0n,
120
- });
121
- });
122
- it('returns the L1 block number that most recently added messages from new inbox', async () => {
123
- await store.addNewL1ToL2Messages([new NewInboxLeaf(0n, 0n, Fr.ZERO)], 1n);
124
- await expect(store.getL1BlockNumber()).resolves.toEqual({
125
- addedBlock: 0n,
126
- addedMessages: 0n,
127
- cancelledMessages: 0n,
128
- newMessages: 1n,
100
+ it('returns the L1 block number that most recently added messages from inbox', async () => {
101
+ await store.addL1ToL2Messages({
102
+ lastProcessedL1BlockNumber: 1n,
103
+ retrievedData: [new InboxLeaf(0n, 0n, Fr.ZERO)],
129
104
  });
130
- });
131
- it('returns the L1 block number that most recently cancelled pending messages', async () => {
132
- const message = L1ToL2Message.random(Fr.random());
133
- await store.addPendingL1ToL2Messages([message], 1n);
134
- await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 2n);
135
- await expect(store.getL1BlockNumber()).resolves.toEqual({
136
- addedBlock: 0n,
137
- addedMessages: 1n,
138
- cancelledMessages: 2n,
139
- newMessages: 0n,
105
+ await expect(store.getSynchedL1BlockNumbers()).resolves.toEqual({
106
+ blocks: 0n,
107
+ messages: 1n,
140
108
  });
141
109
  });
142
110
  });
@@ -144,7 +112,11 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
144
112
  describe('addLogs', () => {
145
113
  it('adds encrypted & unencrypted logs', async () => {
146
114
  await expect(
147
- store.addLogs(blocks[0].body.encryptedLogs, blocks[0].body.unencryptedLogs, blocks[0].number),
115
+ store.addLogs(
116
+ blocks.retrievedData[0].body.encryptedLogs,
117
+ blocks.retrievedData[0].body.unencryptedLogs,
118
+ blocks.retrievedData[0].number,
119
+ ),
148
120
  ).resolves.toEqual(true);
149
121
  });
150
122
  });
@@ -155,7 +127,9 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
155
127
  ])('getLogs (%s)', (_, logType) => {
156
128
  beforeEach(async () => {
157
129
  await Promise.all(
158
- blocks.map(block => store.addLogs(block.body.encryptedLogs, block.body.unencryptedLogs, block.number)),
130
+ blocks.retrievedData.map(block =>
131
+ store.addLogs(block.body.encryptedLogs, block.body.unencryptedLogs, block.number),
132
+ ),
159
133
  );
160
134
  });
161
135
 
@@ -171,18 +145,20 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
171
145
  describe('getTxEffect', () => {
172
146
  beforeEach(async () => {
173
147
  await Promise.all(
174
- blocks.map(block => store.addLogs(block.body.encryptedLogs, block.body.unencryptedLogs, block.number)),
148
+ blocks.retrievedData.map(block =>
149
+ store.addLogs(block.body.encryptedLogs, block.body.unencryptedLogs, block.number),
150
+ ),
175
151
  );
176
152
  await store.addBlocks(blocks);
177
- await store.addBlockBodies(blocks.map(block => block.body));
153
+ await store.addBlockBodies(blocks.retrievedData.map(block => block.body));
178
154
  });
179
155
 
180
156
  it.each([
181
- () => blocks[0].getTx(0),
182
- () => blocks[9].getTx(3),
183
- () => blocks[3].getTx(1),
184
- () => blocks[5].getTx(2),
185
- () => blocks[1].getTx(0),
157
+ () => blocks.retrievedData[0].getTx(0),
158
+ () => blocks.retrievedData[9].getTx(3),
159
+ () => blocks.retrievedData[3].getTx(1),
160
+ () => blocks.retrievedData[5].getTx(2),
161
+ () => blocks.retrievedData[1].getTx(0),
186
162
  ])('retrieves a previously stored transaction', async getExpectedTx => {
187
163
  const expectedTx = getExpectedTx();
188
164
  const actualTx = await store.getTxEffect(expectedTx.txHash);
@@ -194,47 +170,18 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
194
170
  });
195
171
  });
196
172
 
197
- describe('addPendingL1ToL2Messages', () => {
198
- it('stores pending L1 to L2 messages', async () => {
199
- await expect(store.addPendingL1ToL2Messages([L1ToL2Message.random(Fr.random())], 1n)).resolves.toEqual(true);
200
- });
201
-
202
- it('allows duplicate pending messages in different positions in the same block', async () => {
203
- const message = L1ToL2Message.random(Fr.random());
204
- await expect(store.addPendingL1ToL2Messages([message, message], 1n)).resolves.toEqual(true);
205
-
206
- await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([message.entryKey!, message.entryKey!]);
207
- });
208
-
209
- it('allows duplicate pending messages in different blocks', async () => {
210
- const message = L1ToL2Message.random(Fr.random());
211
- await expect(store.addPendingL1ToL2Messages([message], 1n)).resolves.toEqual(true);
212
- await expect(store.addPendingL1ToL2Messages([message], 2n)).resolves.toEqual(true);
213
-
214
- await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([message.entryKey!, message.entryKey!]);
215
- });
216
-
217
- it('is idempotent', async () => {
218
- const message = L1ToL2Message.random(Fr.random());
219
- await expect(store.addPendingL1ToL2Messages([message], 1n)).resolves.toEqual(true);
220
- await expect(store.addPendingL1ToL2Messages([message], 1n)).resolves.toEqual(false);
221
- await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([message.entryKey!]);
222
- });
223
- });
224
-
225
- // TODO(#4492): Drop the "New" below once the old inbox is purged
226
- describe('New L1 to L2 Messages', () => {
173
+ describe('L1 to L2 Messages', () => {
227
174
  const l2BlockNumber = 13n;
228
175
  const l1ToL2MessageSubtreeSize = 2 ** L1_TO_L2_MSG_SUBTREE_HEIGHT;
229
176
 
230
177
  const generateBlockMessages = (blockNumber: bigint, numMessages: number) =>
231
- Array.from({ length: numMessages }, (_, i) => new NewInboxLeaf(blockNumber, BigInt(i), Fr.random()));
178
+ Array.from({ length: numMessages }, (_, i) => new InboxLeaf(blockNumber, BigInt(i), Fr.random()));
232
179
 
233
180
  it('returns messages in correct order', async () => {
234
181
  const msgs = generateBlockMessages(l2BlockNumber, l1ToL2MessageSubtreeSize);
235
182
  const shuffledMessages = msgs.slice().sort(() => randomInt(1) - 0.5);
236
- await store.addNewL1ToL2Messages(shuffledMessages, 100n);
237
- const retrievedMessages = await store.getNewL1ToL2Messages(l2BlockNumber);
183
+ await store.addL1ToL2Messages({ lastProcessedL1BlockNumber: 100n, retrievedData: shuffledMessages });
184
+ const retrievedMessages = await store.getL1ToL2Messages(l2BlockNumber);
238
185
 
239
186
  const expectedLeavesOrder = msgs.map(msg => msg.leaf);
240
187
  expect(expectedLeavesOrder).toEqual(retrievedMessages);
@@ -244,11 +191,11 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
244
191
  const msgs = generateBlockMessages(l2BlockNumber, l1ToL2MessageSubtreeSize - 1);
245
192
  // We replace a message with index 4 with a message with index at the end of the tree
246
193
  // --> with that there will be a gap and it will be impossible to sequence the messages
247
- msgs[4] = new NewInboxLeaf(l2BlockNumber, BigInt(l1ToL2MessageSubtreeSize - 1), Fr.random());
194
+ msgs[4] = new InboxLeaf(l2BlockNumber, BigInt(l1ToL2MessageSubtreeSize - 1), Fr.random());
248
195
 
249
- await store.addNewL1ToL2Messages(msgs, 100n);
196
+ await store.addL1ToL2Messages({ lastProcessedL1BlockNumber: 100n, retrievedData: msgs });
250
197
  await expect(async () => {
251
- await store.getNewL1ToL2Messages(l2BlockNumber);
198
+ await store.getL1ToL2Messages(l2BlockNumber);
252
199
  }).rejects.toThrow(`L1 to L2 message gap found in block ${l2BlockNumber}`);
253
200
  });
254
201
 
@@ -256,130 +203,11 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
256
203
  const msgs = generateBlockMessages(l2BlockNumber, l1ToL2MessageSubtreeSize + 1);
257
204
 
258
205
  await expect(async () => {
259
- await store.addNewL1ToL2Messages(msgs, 100n);
206
+ await store.addL1ToL2Messages({ lastProcessedL1BlockNumber: 100n, retrievedData: msgs });
260
207
  }).rejects.toThrow(`Message index ${l1ToL2MessageSubtreeSize} out of subtree range`);
261
208
  });
262
209
  });
263
210
 
264
- describe('getPendingL1ToL2EntryKeys', () => {
265
- it('returns previously stored pending L1 to L2 messages', async () => {
266
- const message = L1ToL2Message.random(Fr.random());
267
- await store.addPendingL1ToL2Messages([message], 1n);
268
- await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([message.entryKey!]);
269
- });
270
-
271
- // TODO(@spalladino): Fix and re-enable
272
- it.skip('returns messages ordered by fee', async () => {
273
- const messages = Array.from({ length: 3 }, () => L1ToL2Message.random(Fr.random()));
274
- // add a duplicate message
275
- messages.push(messages[0]);
276
-
277
- await store.addPendingL1ToL2Messages(messages, 1n);
278
-
279
- messages.sort((a, b) => b.fee - a.fee);
280
- await expect(store.getPendingL1ToL2EntryKeys(messages.length)).resolves.toEqual(
281
- messages.map(message => message.entryKey!),
282
- );
283
- });
284
-
285
- it('returns an empty array if no messages are found', async () => {
286
- await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([]);
287
- });
288
- });
289
-
290
- describe('confirmL1ToL2EntryKeys', () => {
291
- it('updates a message from pending to confirmed', async () => {
292
- const message = L1ToL2Message.random(Fr.random());
293
- await store.addPendingL1ToL2Messages([message], 1n);
294
- await expect(store.confirmL1ToL2EntryKeys([message.entryKey!])).resolves.toEqual(true);
295
- });
296
-
297
- it('once confirmed, a message is no longer pending', async () => {
298
- const message = L1ToL2Message.random(Fr.random());
299
- await store.addPendingL1ToL2Messages([message], 1n);
300
- await store.confirmL1ToL2EntryKeys([message.entryKey!]);
301
- await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([]);
302
- });
303
-
304
- it('once confirmed a message can also be pending if added again', async () => {
305
- const message = L1ToL2Message.random(Fr.random());
306
- await store.addPendingL1ToL2Messages([message], 1n);
307
- await store.confirmL1ToL2EntryKeys([message.entryKey!]);
308
- await store.addPendingL1ToL2Messages([message], 2n);
309
- await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([message.entryKey!]);
310
- });
311
-
312
- it('once confirmed a message can remain pending if more of it were pending', async () => {
313
- const message = L1ToL2Message.random(Fr.random());
314
- await store.addPendingL1ToL2Messages([message, message], 1n);
315
- await store.confirmL1ToL2EntryKeys([message.entryKey!]);
316
- await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([message.entryKey!]);
317
- });
318
- });
319
-
320
- describe('cancelL1ToL2Messages', () => {
321
- it('cancels a pending message', async () => {
322
- const message = L1ToL2Message.random(Fr.random());
323
- await store.addPendingL1ToL2Messages([message], 1n);
324
- await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 1n);
325
- await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([]);
326
- });
327
-
328
- it('cancels only one of the pending messages if duplicates exist', async () => {
329
- const message = L1ToL2Message.random(Fr.random());
330
- await store.addPendingL1ToL2Messages([message, message], 1n);
331
- await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 1n);
332
- await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([message.entryKey]);
333
- });
334
-
335
- it('once canceled a message can also be pending if added again', async () => {
336
- const message = L1ToL2Message.random(Fr.random());
337
- await store.addPendingL1ToL2Messages([message], 1n);
338
-
339
- await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 1n);
340
- await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([]);
341
-
342
- await store.addPendingL1ToL2Messages([message], 2n);
343
- await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([message.entryKey!]);
344
- });
345
-
346
- it('allows adding and cancelling in the same block', async () => {
347
- const message = L1ToL2Message.random(Fr.random());
348
- await store.addPendingL1ToL2Messages([message], 1n);
349
- await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 1n);
350
- await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([]);
351
- });
352
-
353
- it('allows duplicates cancellations in different positions in the same block', async () => {
354
- const message = L1ToL2Message.random(Fr.random());
355
- await store.addPendingL1ToL2Messages([message, message], 1n);
356
-
357
- await store.cancelPendingL1ToL2EntryKeys([message.entryKey!, message.entryKey!], 1n);
358
-
359
- await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([]);
360
- });
361
-
362
- it('allows duplicates cancellations in different blocks', async () => {
363
- const message = L1ToL2Message.random(Fr.random());
364
- await store.addPendingL1ToL2Messages([message, message], 1n);
365
-
366
- await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 2n);
367
- await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 3n);
368
-
369
- await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([]);
370
- });
371
-
372
- it('is idempotent', async () => {
373
- const message = L1ToL2Message.random(Fr.random());
374
- await store.addPendingL1ToL2Messages([message, message], 1n);
375
-
376
- await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 2n);
377
- await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 2n);
378
-
379
- await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([message.entryKey!]);
380
- });
381
- });
382
-
383
211
  describe('contractInstances', () => {
384
212
  let contractInstance: ContractInstanceWithAddress;
385
213
  const blockNum = 10;
@@ -421,20 +249,25 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
421
249
  const numPublicFunctionCalls = 3;
422
250
  const numUnencryptedLogs = 4;
423
251
  const numBlocks = 10;
424
- let blocks: L2Block[];
252
+ let blocks: DataRetrieval<L2Block>;
425
253
 
426
254
  beforeEach(async () => {
427
- blocks = Array(numBlocks)
428
- .fill(0)
429
- .map((_, index: number) =>
430
- L2Block.random(index + 1, txsPerBlock, 2, numPublicFunctionCalls, 2, numUnencryptedLogs),
431
- );
255
+ blocks = {
256
+ lastProcessedL1BlockNumber: 4n,
257
+ retrievedData: Array(numBlocks)
258
+ .fill(0)
259
+ .map((_, index: number) =>
260
+ L2Block.random(index + 1, txsPerBlock, 2, numPublicFunctionCalls, 2, numUnencryptedLogs),
261
+ ),
262
+ };
432
263
 
433
264
  await store.addBlocks(blocks);
434
- await store.addBlockBodies(blocks.map(block => block.body));
265
+ await store.addBlockBodies(blocks.retrievedData.map(block => block.body));
435
266
 
436
267
  await Promise.all(
437
- blocks.map(block => store.addLogs(block.body.encryptedLogs, block.body.unencryptedLogs, block.number)),
268
+ blocks.retrievedData.map(block =>
269
+ store.addLogs(block.body.encryptedLogs, block.body.unencryptedLogs, block.number),
270
+ ),
438
271
  );
439
272
  });
440
273
 
@@ -442,7 +275,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
442
275
  // get random tx
443
276
  const targetBlockIndex = randomInt(numBlocks);
444
277
  const targetTxIndex = randomInt(txsPerBlock);
445
- const targetTxHash = new L2BlockContext(blocks[targetBlockIndex]).getTxHash(targetTxIndex);
278
+ const targetTxHash = new L2BlockContext(blocks.retrievedData[targetBlockIndex]).getTxHash(targetTxIndex);
446
279
 
447
280
  const response = await store.getUnencryptedLogs({ txHash: targetTxHash });
448
281
  const logs = response.logs;
@@ -486,8 +319,9 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
486
319
  const targetFunctionLogIndex = randomInt(numPublicFunctionCalls);
487
320
  const targetLogIndex = randomInt(numUnencryptedLogs);
488
321
  const targetContractAddress = UnencryptedL2Log.fromBuffer(
489
- blocks[targetBlockIndex].body.txEffects[targetTxIndex].unencryptedLogs.functionLogs[targetFunctionLogIndex]
490
- .logs[targetLogIndex],
322
+ blocks.retrievedData[targetBlockIndex].body.txEffects[targetTxIndex].unencryptedLogs.functionLogs[
323
+ targetFunctionLogIndex
324
+ ].logs[targetLogIndex],
491
325
  ).contractAddress;
492
326
 
493
327
  const response = await store.getUnencryptedLogs({ contractAddress: targetContractAddress });
@@ -506,8 +340,9 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
506
340
  const targetFunctionLogIndex = randomInt(numPublicFunctionCalls);
507
341
  const targetLogIndex = randomInt(numUnencryptedLogs);
508
342
  const targetSelector = UnencryptedL2Log.fromBuffer(
509
- blocks[targetBlockIndex].body.txEffects[targetTxIndex].unencryptedLogs.functionLogs[targetFunctionLogIndex]
510
- .logs[targetLogIndex],
343
+ blocks.retrievedData[targetBlockIndex].body.txEffects[targetTxIndex].unencryptedLogs.functionLogs[
344
+ targetFunctionLogIndex
345
+ ].logs[targetLogIndex],
511
346
  ).selector;
512
347
 
513
348
  const response = await store.getUnencryptedLogs({ selector: targetSelector });
@@ -62,6 +62,8 @@ export function getConfigEnvVars(): ArchiverConfig {
62
62
  INBOX_CONTRACT_ADDRESS,
63
63
  OUTBOX_CONTRACT_ADDRESS,
64
64
  REGISTRY_CONTRACT_ADDRESS,
65
+ GAS_TOKEN_CONTRACT_ADDRESS,
66
+ GAS_PORTAL_CONTRACT_ADDRESS,
65
67
  DATA_DIRECTORY,
66
68
  } = process.env;
67
69
  // Populate the relevant addresses for use by the archiver.
@@ -73,6 +75,10 @@ export function getConfigEnvVars(): ArchiverConfig {
73
75
  registryAddress: REGISTRY_CONTRACT_ADDRESS ? EthAddress.fromString(REGISTRY_CONTRACT_ADDRESS) : EthAddress.ZERO,
74
76
  inboxAddress: INBOX_CONTRACT_ADDRESS ? EthAddress.fromString(INBOX_CONTRACT_ADDRESS) : EthAddress.ZERO,
75
77
  outboxAddress: OUTBOX_CONTRACT_ADDRESS ? EthAddress.fromString(OUTBOX_CONTRACT_ADDRESS) : EthAddress.ZERO,
78
+ gasTokenAddress: GAS_TOKEN_CONTRACT_ADDRESS ? EthAddress.fromString(GAS_TOKEN_CONTRACT_ADDRESS) : EthAddress.ZERO,
79
+ gasPortalAddress: GAS_PORTAL_CONTRACT_ADDRESS
80
+ ? EthAddress.fromString(GAS_PORTAL_CONTRACT_ADDRESS)
81
+ : EthAddress.ZERO,
76
82
  };
77
83
  return {
78
84
  rpcUrl: ETHEREUM_HOST || 'http://127.0.0.1:8545/',