@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.
- package/dest/archiver/archiver.d.ts +13 -53
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +60 -199
- package/dest/archiver/archiver_store.d.ts +21 -67
- 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 +60 -199
- package/dest/archiver/config.d.ts.map +1 -1
- package/dest/archiver/config.js +6 -2
- package/dest/archiver/data_retrieval.d.ts +10 -32
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +13 -67
- package/dest/archiver/eth_log_handlers.d.ts +7 -38
- package/dest/archiver/eth_log_handlers.d.ts.map +1 -1
- package/dest/archiver/eth_log_handlers.js +9 -77
- package/dest/archiver/kv_archiver_store/block_store.d.ts +5 -4
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +12 -15
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +15 -56
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +23 -87
- package/dest/archiver/kv_archiver_store/message_store.d.ts +12 -43
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +32 -141
- 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 +20 -81
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +30 -143
- 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 +80 -267
- package/src/archiver/archiver_store.ts +22 -76
- package/src/archiver/archiver_store_test_suite.ts +78 -243
- package/src/archiver/config.ts +6 -0
- package/src/archiver/data_retrieval.ts +19 -101
- package/src/archiver/eth_log_handlers.ts +14 -108
- package/src/archiver/kv_archiver_store/block_store.ts +13 -14
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +23 -93
- package/src/archiver/kv_archiver_store/message_store.ts +38 -169
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +21 -90
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +33 -161
- 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';
|
|
@@ -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 =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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.
|
|
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('
|
|
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.retrievedData.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.lastProcessedL1BlockNumber,
|
|
96
|
+
messages: 0n,
|
|
110
97
|
});
|
|
111
98
|
});
|
|
112
99
|
|
|
113
|
-
it('returns the L1 block number that most recently added
|
|
114
|
-
await store.
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
132
|
-
|
|
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(
|
|
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 =>
|
|
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 =>
|
|
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('
|
|
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
|
|
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.
|
|
237
|
-
const retrievedMessages = await store.
|
|
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
|
|
194
|
+
msgs[4] = new InboxLeaf(l2BlockNumber, BigInt(l1ToL2MessageSubtreeSize - 1), Fr.random());
|
|
248
195
|
|
|
249
|
-
await store.
|
|
196
|
+
await store.addL1ToL2Messages({ lastProcessedL1BlockNumber: 100n, retrievedData: msgs });
|
|
250
197
|
await expect(async () => {
|
|
251
|
-
await store.
|
|
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.
|
|
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 =
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
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 =>
|
|
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[
|
|
490
|
-
|
|
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[
|
|
510
|
-
|
|
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 });
|
package/src/archiver/config.ts
CHANGED
|
@@ -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/',
|