@aztec/archiver 0.28.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/archiver/archiver.d.ts +13 -53
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +42 -180
- package/dest/archiver/archiver_store.d.ts +17 -63
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +26 -168
- package/dest/archiver/data_retrieval.d.ts +5 -26
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +10 -64
- package/dest/archiver/eth_log_handlers.d.ts +5 -36
- package/dest/archiver/eth_log_handlers.d.ts.map +1 -1
- package/dest/archiver/eth_log_handlers.js +7 -75
- package/dest/archiver/kv_archiver_store/block_store.d.ts +2 -2
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +3 -3
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +11 -52
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +21 -84
- package/dest/archiver/kv_archiver_store/message_store.d.ts +10 -41
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +31 -136
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +8 -41
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +22 -79
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +14 -76
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +22 -134
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +3 -15
- package/dest/rpc/archiver_client.d.ts.map +1 -1
- package/dest/rpc/archiver_client.js +2 -6
- package/dest/rpc/archiver_server.d.ts.map +1 -1
- package/dest/rpc/archiver_server.js +2 -6
- package/package.json +9 -9
- package/src/archiver/archiver.ts +47 -230
- package/src/archiver/archiver_store.ts +17 -72
- package/src/archiver/archiver_store_test_suite.ts +25 -208
- package/src/archiver/data_retrieval.ts +11 -93
- package/src/archiver/eth_log_handlers.ts +10 -104
- package/src/archiver/kv_archiver_store/block_store.ts +2 -2
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +19 -89
- package/src/archiver/kv_archiver_store/message_store.ts +36 -165
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +21 -90
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +23 -150
- package/src/index.ts +1 -15
- package/src/rpc/archiver_client.ts +0 -8
- package/src/rpc/archiver_server.ts +0 -8
- package/dest/archiver/kv_archiver_store/contract_store.d.ts +0 -26
- package/dest/archiver/kv_archiver_store/contract_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/contract_store.js +0 -49
- 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';
|
|
@@ -71,7 +62,7 @@ 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.
|
|
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 () => {
|
|
@@ -79,64 +70,38 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
79
70
|
});
|
|
80
71
|
});
|
|
81
72
|
|
|
82
|
-
describe('
|
|
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.
|
|
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.
|
|
80
|
+
await expect(store.getSynchedL2BlockNumber()).resolves.toEqual(blocks.at(-1)!.number);
|
|
90
81
|
});
|
|
91
82
|
});
|
|
92
83
|
|
|
93
|
-
describe('
|
|
84
|
+
describe('getSynchedL1BlockNumbers', () => {
|
|
94
85
|
it('returns 0n if no blocks have been added', async () => {
|
|
95
|
-
await expect(store.
|
|
96
|
-
|
|
97
|
-
|
|
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.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
cancelledMessages: 0n,
|
|
109
|
-
newMessages: 0n,
|
|
94
|
+
await expect(store.getSynchedL1BlockNumbers()).resolves.toEqual({
|
|
95
|
+
blocks: blocks.at(-1)!.getL1BlockNumber(),
|
|
96
|
+
messages: 0n,
|
|
110
97
|
});
|
|
111
98
|
});
|
|
112
99
|
|
|
113
|
-
it('returns the L1 block number that most recently added
|
|
114
|
-
await store.
|
|
115
|
-
await expect(store.
|
|
116
|
-
|
|
117
|
-
|
|
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,
|
|
129
|
-
});
|
|
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,
|
|
100
|
+
it('returns the L1 block number that most recently added messages from inbox', async () => {
|
|
101
|
+
await store.addL1ToL2Messages([new InboxLeaf(0n, 0n, Fr.ZERO)], 1n);
|
|
102
|
+
await expect(store.getSynchedL1BlockNumbers()).resolves.toEqual({
|
|
103
|
+
blocks: 0n,
|
|
104
|
+
messages: 1n,
|
|
140
105
|
});
|
|
141
106
|
});
|
|
142
107
|
});
|
|
@@ -194,47 +159,18 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
194
159
|
});
|
|
195
160
|
});
|
|
196
161
|
|
|
197
|
-
describe('
|
|
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', () => {
|
|
162
|
+
describe('L1 to L2 Messages', () => {
|
|
227
163
|
const l2BlockNumber = 13n;
|
|
228
164
|
const l1ToL2MessageSubtreeSize = 2 ** L1_TO_L2_MSG_SUBTREE_HEIGHT;
|
|
229
165
|
|
|
230
166
|
const generateBlockMessages = (blockNumber: bigint, numMessages: number) =>
|
|
231
|
-
Array.from({ length: numMessages }, (_, i) => new
|
|
167
|
+
Array.from({ length: numMessages }, (_, i) => new InboxLeaf(blockNumber, BigInt(i), Fr.random()));
|
|
232
168
|
|
|
233
169
|
it('returns messages in correct order', async () => {
|
|
234
170
|
const msgs = generateBlockMessages(l2BlockNumber, l1ToL2MessageSubtreeSize);
|
|
235
171
|
const shuffledMessages = msgs.slice().sort(() => randomInt(1) - 0.5);
|
|
236
|
-
await store.
|
|
237
|
-
const retrievedMessages = await store.
|
|
172
|
+
await store.addL1ToL2Messages(shuffledMessages, 100n);
|
|
173
|
+
const retrievedMessages = await store.getL1ToL2Messages(l2BlockNumber);
|
|
238
174
|
|
|
239
175
|
const expectedLeavesOrder = msgs.map(msg => msg.leaf);
|
|
240
176
|
expect(expectedLeavesOrder).toEqual(retrievedMessages);
|
|
@@ -244,11 +180,11 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
244
180
|
const msgs = generateBlockMessages(l2BlockNumber, l1ToL2MessageSubtreeSize - 1);
|
|
245
181
|
// We replace a message with index 4 with a message with index at the end of the tree
|
|
246
182
|
// --> with that there will be a gap and it will be impossible to sequence the messages
|
|
247
|
-
msgs[4] = new
|
|
183
|
+
msgs[4] = new InboxLeaf(l2BlockNumber, BigInt(l1ToL2MessageSubtreeSize - 1), Fr.random());
|
|
248
184
|
|
|
249
|
-
await store.
|
|
185
|
+
await store.addL1ToL2Messages(msgs, 100n);
|
|
250
186
|
await expect(async () => {
|
|
251
|
-
await store.
|
|
187
|
+
await store.getL1ToL2Messages(l2BlockNumber);
|
|
252
188
|
}).rejects.toThrow(`L1 to L2 message gap found in block ${l2BlockNumber}`);
|
|
253
189
|
});
|
|
254
190
|
|
|
@@ -256,130 +192,11 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
256
192
|
const msgs = generateBlockMessages(l2BlockNumber, l1ToL2MessageSubtreeSize + 1);
|
|
257
193
|
|
|
258
194
|
await expect(async () => {
|
|
259
|
-
await store.
|
|
195
|
+
await store.addL1ToL2Messages(msgs, 100n);
|
|
260
196
|
}).rejects.toThrow(`Message index ${l1ToL2MessageSubtreeSize} out of subtree range`);
|
|
261
197
|
});
|
|
262
198
|
});
|
|
263
199
|
|
|
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
200
|
describe('contractInstances', () => {
|
|
384
201
|
let contractInstance: ContractInstanceWithAddress;
|
|
385
202
|
const blockNum = 10;
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import { Body,
|
|
2
|
-
import { AppendOnlyTreeSnapshot,
|
|
1
|
+
import { Body, InboxLeaf } from '@aztec/circuit-types';
|
|
2
|
+
import { AppendOnlyTreeSnapshot, Header } from '@aztec/circuits.js';
|
|
3
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
4
|
|
|
5
5
|
import { PublicClient } from 'viem';
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
|
-
getL1ToL2MessageCancelledLogs,
|
|
9
8
|
getL2BlockProcessedLogs,
|
|
10
9
|
getLeafInsertedLogs,
|
|
11
|
-
getPendingL1ToL2MessageLogs,
|
|
12
10
|
getTxsPublishedLogs,
|
|
13
|
-
processCancelledL1ToL2MessagesLogs,
|
|
14
11
|
processL2BlockProcessedLogs,
|
|
15
12
|
processLeafInsertedLogs,
|
|
16
|
-
processPendingL1ToL2MessageAddedLogs,
|
|
17
13
|
processTxsPublishedLogs,
|
|
18
14
|
} from './eth_log_handlers.js';
|
|
19
15
|
|
|
@@ -116,112 +112,34 @@ export async function retrieveBlockBodiesFromAvailabilityOracle(
|
|
|
116
112
|
}
|
|
117
113
|
|
|
118
114
|
/**
|
|
119
|
-
* Fetch
|
|
115
|
+
* Fetch L1 to L2 messages.
|
|
120
116
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
121
117
|
* @param inboxAddress - The address of the inbox contract to fetch messages from.
|
|
122
118
|
* @param blockUntilSynced - If true, blocks until the archiver has fully synced.
|
|
123
119
|
* @param searchStartBlock - The block number to use for starting the search.
|
|
124
120
|
* @param searchEndBlock - The highest block number that we should search up to.
|
|
125
|
-
* @returns An array of
|
|
121
|
+
* @returns An array of InboxLeaf and next eth block to search from.
|
|
126
122
|
*/
|
|
127
|
-
export async function
|
|
123
|
+
export async function retrieveL1ToL2Messages(
|
|
128
124
|
publicClient: PublicClient,
|
|
129
125
|
inboxAddress: EthAddress,
|
|
130
126
|
blockUntilSynced: boolean,
|
|
131
127
|
searchStartBlock: bigint,
|
|
132
128
|
searchEndBlock: bigint,
|
|
133
|
-
): Promise<DataRetrieval<
|
|
134
|
-
const
|
|
129
|
+
): Promise<DataRetrieval<InboxLeaf>> {
|
|
130
|
+
const retrievedL1ToL2Messages: InboxLeaf[] = [];
|
|
135
131
|
do {
|
|
136
132
|
if (searchStartBlock > searchEndBlock) {
|
|
137
133
|
break;
|
|
138
134
|
}
|
|
139
|
-
const
|
|
140
|
-
publicClient,
|
|
141
|
-
inboxAddress,
|
|
142
|
-
searchStartBlock,
|
|
143
|
-
searchEndBlock,
|
|
144
|
-
);
|
|
145
|
-
if (newL1ToL2MessageLogs.length === 0) {
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
const newL1ToL2Messages = processPendingL1ToL2MessageAddedLogs(newL1ToL2MessageLogs);
|
|
149
|
-
retrievedNewL1ToL2Messages.push(...newL1ToL2Messages);
|
|
150
|
-
// handles the case when there are no new messages:
|
|
151
|
-
searchStartBlock = (newL1ToL2MessageLogs.findLast(msgLog => !!msgLog)?.blockNumber || searchStartBlock) + 1n;
|
|
152
|
-
} while (blockUntilSynced && searchStartBlock <= searchEndBlock);
|
|
153
|
-
return { nextEthBlockNumber: searchStartBlock, retrievedData: retrievedNewL1ToL2Messages };
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Fetch new L1 to L2 messages.
|
|
158
|
-
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
159
|
-
* @param newInboxAddress - The address of the inbox contract to fetch messages from.
|
|
160
|
-
* @param blockUntilSynced - If true, blocks until the archiver has fully synced.
|
|
161
|
-
* @param searchStartBlock - The block number to use for starting the search.
|
|
162
|
-
* @param searchEndBlock - The highest block number that we should search up to.
|
|
163
|
-
* @returns An array of NewInboxLeaf and next eth block to search from.
|
|
164
|
-
*/
|
|
165
|
-
export async function retrieveNewL1ToL2Messages(
|
|
166
|
-
publicClient: PublicClient,
|
|
167
|
-
newInboxAddress: EthAddress,
|
|
168
|
-
blockUntilSynced: boolean,
|
|
169
|
-
searchStartBlock: bigint,
|
|
170
|
-
searchEndBlock: bigint,
|
|
171
|
-
): Promise<DataRetrieval<NewInboxLeaf>> {
|
|
172
|
-
const retrievedNewL1ToL2Messages: NewInboxLeaf[] = [];
|
|
173
|
-
do {
|
|
174
|
-
if (searchStartBlock > searchEndBlock) {
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
const leafInsertedLogs = await getLeafInsertedLogs(publicClient, newInboxAddress, searchStartBlock, searchEndBlock);
|
|
135
|
+
const leafInsertedLogs = await getLeafInsertedLogs(publicClient, inboxAddress, searchStartBlock, searchEndBlock);
|
|
178
136
|
if (leafInsertedLogs.length === 0) {
|
|
179
137
|
break;
|
|
180
138
|
}
|
|
181
|
-
const
|
|
182
|
-
|
|
139
|
+
const l1ToL2Messages = processLeafInsertedLogs(leafInsertedLogs);
|
|
140
|
+
retrievedL1ToL2Messages.push(...l1ToL2Messages);
|
|
183
141
|
// handles the case when there are no new messages:
|
|
184
142
|
searchStartBlock = (leafInsertedLogs.findLast(msgLog => !!msgLog)?.blockNumber || searchStartBlock) + 1n;
|
|
185
143
|
} while (blockUntilSynced && searchStartBlock <= searchEndBlock);
|
|
186
|
-
return { nextEthBlockNumber: searchStartBlock, retrievedData:
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Fetch newly cancelled L1 to L2 messages.
|
|
191
|
-
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
192
|
-
* @param inboxAddress - The address of the inbox contract to fetch messages from.
|
|
193
|
-
* @param blockUntilSynced - If true, blocks until the archiver has fully synced.
|
|
194
|
-
* @param searchStartBlock - The block number to use for starting the search.
|
|
195
|
-
* @param searchEndBlock - The highest block number that we should search up to.
|
|
196
|
-
* @returns An array of entry keys that were cancelled and next eth block to search from.
|
|
197
|
-
* TODO(#4492): Nuke the following when purging the old inbox
|
|
198
|
-
*/
|
|
199
|
-
export async function retrieveNewCancelledL1ToL2Messages(
|
|
200
|
-
publicClient: PublicClient,
|
|
201
|
-
inboxAddress: EthAddress,
|
|
202
|
-
blockUntilSynced: boolean,
|
|
203
|
-
searchStartBlock: bigint,
|
|
204
|
-
searchEndBlock: bigint,
|
|
205
|
-
): Promise<DataRetrieval<[Fr, bigint]>> {
|
|
206
|
-
const retrievedNewCancelledL1ToL2Messages: [Fr, bigint][] = [];
|
|
207
|
-
do {
|
|
208
|
-
if (searchStartBlock > searchEndBlock) {
|
|
209
|
-
break;
|
|
210
|
-
}
|
|
211
|
-
const newL1ToL2MessageCancelledLogs = await getL1ToL2MessageCancelledLogs(
|
|
212
|
-
publicClient,
|
|
213
|
-
inboxAddress,
|
|
214
|
-
searchStartBlock,
|
|
215
|
-
searchEndBlock,
|
|
216
|
-
);
|
|
217
|
-
if (newL1ToL2MessageCancelledLogs.length === 0) {
|
|
218
|
-
break;
|
|
219
|
-
}
|
|
220
|
-
const newCancelledL1ToL2Messages = processCancelledL1ToL2MessagesLogs(newL1ToL2MessageCancelledLogs);
|
|
221
|
-
retrievedNewCancelledL1ToL2Messages.push(...newCancelledL1ToL2Messages);
|
|
222
|
-
// handles the case when there are no new messages:
|
|
223
|
-
searchStartBlock =
|
|
224
|
-
(newL1ToL2MessageCancelledLogs.findLast(msgLog => !!msgLog)?.blockNumber || searchStartBlock) + 1n;
|
|
225
|
-
} while (blockUntilSynced && searchStartBlock <= searchEndBlock);
|
|
226
|
-
return { nextEthBlockNumber: searchStartBlock, retrievedData: retrievedNewCancelledL1ToL2Messages };
|
|
144
|
+
return { nextEthBlockNumber: searchStartBlock, retrievedData: retrievedL1ToL2Messages };
|
|
227
145
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { Body,
|
|
1
|
+
import { Body, InboxLeaf } from '@aztec/circuit-types';
|
|
2
2
|
import { AppendOnlyTreeSnapshot, Header } from '@aztec/circuits.js';
|
|
3
|
-
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
4
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
4
|
import { Fr } from '@aztec/foundation/fields';
|
|
6
5
|
import { numToUInt32BE } from '@aztec/foundation/serialize';
|
|
7
|
-
import { AvailabilityOracleAbi, InboxAbi,
|
|
6
|
+
import { AvailabilityOracleAbi, InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
8
7
|
|
|
9
8
|
import { Hex, Log, PublicClient, decodeFunctionData, getAbiItem, getAddress, hexToBytes } from 'viem';
|
|
10
9
|
|
|
@@ -14,59 +13,16 @@ import { Hex, Log, PublicClient, decodeFunctionData, getAbiItem, getAddress, hex
|
|
|
14
13
|
* @returns Array of all processed LeafInserted logs
|
|
15
14
|
*/
|
|
16
15
|
export function processLeafInsertedLogs(
|
|
17
|
-
logs: Log<bigint, number, false, undefined, true, typeof
|
|
18
|
-
):
|
|
19
|
-
const leaves:
|
|
16
|
+
logs: Log<bigint, number, false, undefined, true, typeof InboxAbi, 'LeafInserted'>[],
|
|
17
|
+
): InboxLeaf[] {
|
|
18
|
+
const leaves: InboxLeaf[] = [];
|
|
20
19
|
for (const log of logs) {
|
|
21
20
|
const { blockNumber, index, value } = log.args;
|
|
22
|
-
leaves.push(new
|
|
21
|
+
leaves.push(new InboxLeaf(blockNumber, index, Fr.fromString(value)));
|
|
23
22
|
}
|
|
24
23
|
return leaves;
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
/**
|
|
28
|
-
* Processes newly received MessageAdded (L1 to L2) logs.
|
|
29
|
-
* @param logs - MessageAdded logs.
|
|
30
|
-
* @returns Array of all Pending L1 to L2 messages that were processed
|
|
31
|
-
*/
|
|
32
|
-
export function processPendingL1ToL2MessageAddedLogs(
|
|
33
|
-
logs: Log<bigint, number, false, undefined, true, typeof InboxAbi, 'MessageAdded'>[],
|
|
34
|
-
): [L1ToL2Message, bigint][] {
|
|
35
|
-
const l1ToL2Messages: [L1ToL2Message, bigint][] = [];
|
|
36
|
-
for (const log of logs) {
|
|
37
|
-
const { sender, senderChainId, recipient, recipientVersion, content, secretHash, deadline, fee, entryKey } =
|
|
38
|
-
log.args;
|
|
39
|
-
l1ToL2Messages.push([
|
|
40
|
-
new L1ToL2Message(
|
|
41
|
-
new L1Actor(EthAddress.fromString(sender), Number(senderChainId)),
|
|
42
|
-
new L2Actor(AztecAddress.fromString(recipient), Number(recipientVersion)),
|
|
43
|
-
Fr.fromString(content),
|
|
44
|
-
Fr.fromString(secretHash),
|
|
45
|
-
deadline,
|
|
46
|
-
Number(fee),
|
|
47
|
-
Fr.fromString(entryKey),
|
|
48
|
-
),
|
|
49
|
-
log.blockNumber!,
|
|
50
|
-
]);
|
|
51
|
-
}
|
|
52
|
-
return l1ToL2Messages;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Process newly received L1ToL2MessageCancelled logs.
|
|
57
|
-
* @param logs - L1ToL2MessageCancelled logs.
|
|
58
|
-
* @returns Array of entry keys of the L1 to L2 messages that were cancelled
|
|
59
|
-
*/
|
|
60
|
-
export function processCancelledL1ToL2MessagesLogs(
|
|
61
|
-
logs: Log<bigint, number, false, undefined, true, typeof InboxAbi, 'L1ToL2MessageCancelled'>[],
|
|
62
|
-
): [Fr, bigint][] {
|
|
63
|
-
const cancelledL1ToL2Messages: [Fr, bigint][] = [];
|
|
64
|
-
for (const log of logs) {
|
|
65
|
-
cancelledL1ToL2Messages.push([Fr.fromString(log.args.entryKey), log.blockNumber!]);
|
|
66
|
-
}
|
|
67
|
-
return cancelledL1ToL2Messages;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
26
|
/**
|
|
71
27
|
* Processes newly received L2BlockProcessed logs.
|
|
72
28
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
@@ -235,73 +191,23 @@ export function getTxsPublishedLogs(
|
|
|
235
191
|
}
|
|
236
192
|
|
|
237
193
|
/**
|
|
238
|
-
* Get relevant `
|
|
239
|
-
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
240
|
-
* @param inboxAddress - The address of the inbox contract.
|
|
241
|
-
* @param fromBlock - First block to get logs from (inclusive).
|
|
242
|
-
* @param toBlock - Last block to get logs from (inclusive).
|
|
243
|
-
* @returns An array of `MessageAdded` logs.
|
|
244
|
-
*/
|
|
245
|
-
export function getPendingL1ToL2MessageLogs(
|
|
246
|
-
publicClient: PublicClient,
|
|
247
|
-
inboxAddress: EthAddress,
|
|
248
|
-
fromBlock: bigint,
|
|
249
|
-
toBlock: bigint,
|
|
250
|
-
): Promise<Log<bigint, number, false, undefined, true, typeof InboxAbi, 'MessageAdded'>[]> {
|
|
251
|
-
return publicClient.getLogs({
|
|
252
|
-
address: getAddress(inboxAddress.toString()),
|
|
253
|
-
event: getAbiItem({
|
|
254
|
-
abi: InboxAbi,
|
|
255
|
-
name: 'MessageAdded',
|
|
256
|
-
}),
|
|
257
|
-
fromBlock,
|
|
258
|
-
toBlock: toBlock + 1n, // the toBlock argument in getLogs is exclusive
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Get relevant `L1ToL2MessageCancelled` logs emitted by Inbox on chain when pending messages are cancelled
|
|
194
|
+
* Get relevant `LeafInserted` logs emitted by Inbox on chain.
|
|
264
195
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
265
196
|
* @param inboxAddress - The address of the inbox contract.
|
|
266
197
|
* @param fromBlock - First block to get logs from (inclusive).
|
|
267
198
|
* @param toBlock - Last block to get logs from (inclusive).
|
|
268
|
-
* @returns An array of `
|
|
199
|
+
* @returns An array of `LeafInserted` logs.
|
|
269
200
|
*/
|
|
270
|
-
export function
|
|
201
|
+
export function getLeafInsertedLogs(
|
|
271
202
|
publicClient: PublicClient,
|
|
272
203
|
inboxAddress: EthAddress,
|
|
273
204
|
fromBlock: bigint,
|
|
274
205
|
toBlock: bigint,
|
|
275
|
-
): Promise<Log<bigint, number, false, undefined, true, typeof InboxAbi, '
|
|
206
|
+
): Promise<Log<bigint, number, false, undefined, true, typeof InboxAbi, 'LeafInserted'>[]> {
|
|
276
207
|
return publicClient.getLogs({
|
|
277
208
|
address: getAddress(inboxAddress.toString()),
|
|
278
209
|
event: getAbiItem({
|
|
279
210
|
abi: InboxAbi,
|
|
280
|
-
name: 'L1ToL2MessageCancelled',
|
|
281
|
-
}),
|
|
282
|
-
fromBlock,
|
|
283
|
-
toBlock: toBlock + 1n, // the toBlock argument in getLogs is exclusive
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* Get relevant `LeafInserted` logs emitted by NewInbox on chain.
|
|
289
|
-
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
290
|
-
* @param newInboxAddress - The address of the new inbox contract.
|
|
291
|
-
* @param fromBlock - First block to get logs from (inclusive).
|
|
292
|
-
* @param toBlock - Last block to get logs from (inclusive).
|
|
293
|
-
* @returns An array of `LeafInserted` logs.
|
|
294
|
-
*/
|
|
295
|
-
export function getLeafInsertedLogs(
|
|
296
|
-
publicClient: PublicClient,
|
|
297
|
-
newInboxAddress: EthAddress,
|
|
298
|
-
fromBlock: bigint,
|
|
299
|
-
toBlock: bigint,
|
|
300
|
-
): Promise<Log<bigint, number, false, undefined, true, typeof NewInboxAbi, 'LeafInserted'>[]> {
|
|
301
|
-
return publicClient.getLogs({
|
|
302
|
-
address: getAddress(newInboxAddress.toString()),
|
|
303
|
-
event: getAbiItem({
|
|
304
|
-
abi: NewInboxAbi,
|
|
305
211
|
name: 'LeafInserted',
|
|
306
212
|
}),
|
|
307
213
|
fromBlock,
|
|
@@ -155,7 +155,7 @@ export class BlockStore {
|
|
|
155
155
|
* Gets the number of the latest L2 block processed.
|
|
156
156
|
* @returns The number of the latest L2 block processed.
|
|
157
157
|
*/
|
|
158
|
-
|
|
158
|
+
getSynchedL2BlockNumber(): number {
|
|
159
159
|
const [lastBlockNumber] = this.#blocks.keys({ reverse: true, limit: 1 });
|
|
160
160
|
return typeof lastBlockNumber === 'number' ? lastBlockNumber : INITIAL_L2_BLOCK_NUM - 1;
|
|
161
161
|
}
|
|
@@ -164,7 +164,7 @@ export class BlockStore {
|
|
|
164
164
|
* Gets the most recent L1 block processed.
|
|
165
165
|
* @returns The L1 block that published the latest L2 block
|
|
166
166
|
*/
|
|
167
|
-
|
|
167
|
+
getSynchedL1BlockNumber(): bigint {
|
|
168
168
|
const [lastBlock] = this.#blocks.values({ reverse: true, limit: 1 });
|
|
169
169
|
if (!lastBlock) {
|
|
170
170
|
return 0n;
|