@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.
- package/dest/archiver/archiver.d.ts +15 -11
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +67 -72
- package/dest/archiver/archiver_store.d.ts +37 -15
- 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 +70 -54
- package/dest/archiver/data_retrieval.d.ts +18 -8
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +39 -14
- package/dest/archiver/eth_log_handlers.d.ts +25 -23
- package/dest/archiver/eth_log_handlers.d.ts.map +1 -1
- package/dest/archiver/eth_log_handlers.js +98 -57
- package/dest/archiver/kv_archiver_store/block_body_store.d.ts +27 -0
- package/dest/archiver/kv_archiver_store/block_body_store.d.ts.map +1 -0
- package/dest/archiver/kv_archiver_store/block_body_store.js +47 -0
- package/dest/archiver/kv_archiver_store/block_store.d.ts +19 -11
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +58 -30
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +1 -0
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.js +4 -1
- package/dest/archiver/kv_archiver_store/contract_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_store.js +6 -3
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +36 -16
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +52 -22
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +4 -3
- package/dest/archiver/kv_archiver_store/message_store.d.ts +9 -9
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +34 -31
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +6 -6
- 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 +18 -18
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +41 -16
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +78 -29
- package/dest/index.js +2 -2
- package/dest/rpc/archiver_client.d.ts.map +1 -1
- package/dest/rpc/archiver_client.js +3 -3
- package/dest/rpc/archiver_server.d.ts.map +1 -1
- package/dest/rpc/archiver_server.js +4 -3
- package/package.json +10 -10
- package/src/archiver/archiver.ts +95 -92
- package/src/archiver/archiver_store.ts +42 -15
- package/src/archiver/archiver_store_test_suite.ts +73 -58
- package/src/archiver/data_retrieval.ts +61 -16
- package/src/archiver/eth_log_handlers.ts +142 -68
- package/src/archiver/kv_archiver_store/block_body_store.ts +54 -0
- package/src/archiver/kv_archiver_store/block_store.ts +71 -36
- package/src/archiver/kv_archiver_store/contract_class_store.ts +4 -0
- package/src/archiver/kv_archiver_store/contract_store.ts +7 -2
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +56 -20
- package/src/archiver/kv_archiver_store/log_store.ts +2 -2
- package/src/archiver/kv_archiver_store/message_store.ts +34 -30
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +17 -17
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +91 -29
- package/src/index.ts +1 -0
- package/src/rpc/archiver_client.ts +3 -1
- 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/
|
|
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.
|
|
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].
|
|
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.
|
|
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.
|
|
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('
|
|
158
|
+
describe('getTxEffect', () => {
|
|
155
159
|
beforeEach(async () => {
|
|
156
160
|
await Promise.all(
|
|
157
|
-
blocks.map(block => store.addLogs(block.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
208
|
+
await expect(store.getPendingL1ToL2EntryKeys(2)).resolves.toEqual([message.entryKey!]);
|
|
204
209
|
});
|
|
205
210
|
});
|
|
206
211
|
|
|
207
|
-
describe('
|
|
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.
|
|
216
|
+
await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([message.entryKey!]);
|
|
212
217
|
});
|
|
213
218
|
|
|
214
|
-
|
|
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.
|
|
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.
|
|
234
|
+
await expect(store.getPendingL1ToL2EntryKeys(1)).resolves.toEqual([]);
|
|
229
235
|
});
|
|
230
236
|
});
|
|
231
237
|
|
|
232
|
-
describe('
|
|
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.
|
|
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.
|
|
243
|
-
await expect(store.
|
|
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.
|
|
255
|
+
await store.confirmL1ToL2EntryKeys([message.entryKey!]);
|
|
250
256
|
await store.addPendingL1ToL2Messages([message], 2n);
|
|
251
|
-
await expect(store.
|
|
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.
|
|
258
|
-
await expect(store.
|
|
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.
|
|
267
|
-
await expect(store.
|
|
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.
|
|
274
|
-
await expect(store.
|
|
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.
|
|
282
|
-
await expect(store.
|
|
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.
|
|
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.
|
|
292
|
-
await expect(store.
|
|
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.
|
|
305
|
+
await store.cancelPendingL1ToL2EntryKeys([message.entryKey!, message.entryKey!], 1n);
|
|
300
306
|
|
|
301
|
-
await expect(store.
|
|
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.
|
|
309
|
-
await store.
|
|
314
|
+
await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 2n);
|
|
315
|
+
await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 3n);
|
|
310
316
|
|
|
311
|
-
await expect(store.
|
|
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.
|
|
319
|
-
await store.
|
|
324
|
+
await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 2n);
|
|
325
|
+
await store.cancelPendingL1ToL2EntryKeys([message.entryKey!], 2n);
|
|
320
326
|
|
|
321
|
-
await expect(store.
|
|
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.
|
|
370
|
-
block.
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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].
|
|
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].
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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<
|
|
50
|
-
const
|
|
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
|
|
66
|
-
|
|
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(
|
|
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:
|
|
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
|
|
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
|
-
|
|
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(
|
|
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
|
|
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,
|