@aztec/archiver 3.0.0-canary.a9708bd → 3.0.0-devnet.2-patch.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/README.md +27 -6
- package/dest/archiver/archiver.d.ts +87 -64
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +463 -278
- package/dest/archiver/archiver_store.d.ts +46 -28
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +316 -143
- package/dest/archiver/config.d.ts +6 -23
- package/dest/archiver/config.d.ts.map +1 -1
- package/dest/archiver/config.js +19 -12
- package/dest/archiver/errors.d.ts +1 -1
- package/dest/archiver/errors.d.ts.map +1 -1
- package/dest/archiver/index.d.ts +1 -1
- package/dest/archiver/instrumentation.d.ts +5 -3
- package/dest/archiver/instrumentation.d.ts.map +1 -1
- package/dest/archiver/instrumentation.js +14 -0
- package/dest/archiver/kv_archiver_store/block_store.d.ts +45 -9
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +99 -12
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +2 -2
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.js +1 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +2 -2
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +30 -30
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +26 -15
- package/dest/archiver/kv_archiver_store/log_store.d.ts +3 -10
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +4 -26
- package/dest/archiver/kv_archiver_store/message_store.d.ts +6 -5
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +15 -14
- package/dest/archiver/l1/bin/retrieve-calldata.d.ts +3 -0
- package/dest/archiver/l1/bin/retrieve-calldata.d.ts.map +1 -0
- package/dest/archiver/l1/bin/retrieve-calldata.js +147 -0
- package/dest/archiver/l1/calldata_retriever.d.ts +98 -0
- package/dest/archiver/l1/calldata_retriever.d.ts.map +1 -0
- package/dest/archiver/l1/calldata_retriever.js +403 -0
- package/dest/archiver/l1/data_retrieval.d.ts +87 -0
- package/dest/archiver/l1/data_retrieval.d.ts.map +1 -0
- package/dest/archiver/{data_retrieval.js → l1/data_retrieval.js} +118 -154
- package/dest/archiver/l1/debug_tx.d.ts +19 -0
- package/dest/archiver/l1/debug_tx.d.ts.map +1 -0
- package/dest/archiver/l1/debug_tx.js +73 -0
- package/dest/archiver/l1/spire_proposer.d.ts +70 -0
- package/dest/archiver/l1/spire_proposer.d.ts.map +1 -0
- package/dest/archiver/l1/spire_proposer.js +157 -0
- package/dest/archiver/l1/trace_tx.d.ts +97 -0
- package/dest/archiver/l1/trace_tx.d.ts.map +1 -0
- package/dest/archiver/l1/trace_tx.js +91 -0
- package/dest/archiver/l1/types.d.ts +12 -0
- package/dest/archiver/l1/types.d.ts.map +1 -0
- package/dest/archiver/l1/types.js +3 -0
- package/dest/archiver/l1/validate_trace.d.ts +29 -0
- package/dest/archiver/l1/validate_trace.d.ts.map +1 -0
- package/dest/archiver/l1/validate_trace.js +150 -0
- package/dest/archiver/structs/data_retrieval.d.ts +1 -1
- package/dest/archiver/structs/inbox_message.d.ts +4 -4
- package/dest/archiver/structs/inbox_message.d.ts.map +1 -1
- package/dest/archiver/structs/inbox_message.js +6 -5
- package/dest/archiver/structs/published.d.ts +3 -2
- package/dest/archiver/structs/published.d.ts.map +1 -1
- package/dest/archiver/validation.d.ts +10 -4
- package/dest/archiver/validation.d.ts.map +1 -1
- package/dest/archiver/validation.js +66 -44
- package/dest/factory.d.ts +3 -11
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +5 -17
- package/dest/index.d.ts +2 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -1
- package/dest/rpc/index.d.ts +2 -2
- package/dest/test/index.d.ts +1 -1
- package/dest/test/mock_archiver.d.ts +16 -8
- package/dest/test/mock_archiver.d.ts.map +1 -1
- package/dest/test/mock_archiver.js +19 -14
- package/dest/test/mock_l1_to_l2_message_source.d.ts +7 -6
- package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
- package/dest/test/mock_l1_to_l2_message_source.js +10 -9
- package/dest/test/mock_l2_block_source.d.ts +24 -20
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +79 -13
- package/dest/test/mock_structs.d.ts +3 -2
- package/dest/test/mock_structs.d.ts.map +1 -1
- package/dest/test/mock_structs.js +9 -8
- package/package.json +18 -17
- package/src/archiver/archiver.ts +610 -363
- package/src/archiver/archiver_store.ts +55 -28
- package/src/archiver/archiver_store_test_suite.ts +369 -143
- package/src/archiver/config.ts +26 -51
- package/src/archiver/instrumentation.ts +19 -2
- package/src/archiver/kv_archiver_store/block_store.ts +139 -21
- package/src/archiver/kv_archiver_store/contract_class_store.ts +1 -1
- package/src/archiver/kv_archiver_store/contract_instance_store.ts +1 -1
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +48 -33
- package/src/archiver/kv_archiver_store/log_store.ts +4 -30
- package/src/archiver/kv_archiver_store/message_store.ts +21 -18
- package/src/archiver/l1/README.md +98 -0
- package/src/archiver/l1/bin/retrieve-calldata.ts +182 -0
- package/src/archiver/l1/calldata_retriever.ts +531 -0
- package/src/archiver/{data_retrieval.ts → l1/data_retrieval.ts} +198 -242
- package/src/archiver/l1/debug_tx.ts +99 -0
- package/src/archiver/l1/spire_proposer.ts +160 -0
- package/src/archiver/l1/trace_tx.ts +128 -0
- package/src/archiver/l1/types.ts +13 -0
- package/src/archiver/l1/validate_trace.ts +211 -0
- package/src/archiver/structs/inbox_message.ts +8 -8
- package/src/archiver/structs/published.ts +2 -1
- package/src/archiver/validation.ts +86 -32
- package/src/factory.ts +6 -26
- package/src/index.ts +1 -1
- package/src/test/fixtures/debug_traceTransaction-multicall3.json +88 -0
- package/src/test/fixtures/debug_traceTransaction-multiplePropose.json +153 -0
- package/src/test/fixtures/debug_traceTransaction-proxied.json +122 -0
- package/src/test/fixtures/trace_transaction-multicall3.json +65 -0
- package/src/test/fixtures/trace_transaction-multiplePropose.json +319 -0
- package/src/test/fixtures/trace_transaction-proxied.json +128 -0
- package/src/test/fixtures/trace_transaction-randomRevert.json +216 -0
- package/src/test/mock_archiver.ts +22 -16
- package/src/test/mock_l1_to_l2_message_source.ts +10 -9
- package/src/test/mock_l2_block_source.ts +110 -27
- package/src/test/mock_structs.ts +10 -9
- package/dest/archiver/data_retrieval.d.ts +0 -78
- package/dest/archiver/data_retrieval.d.ts.map +0 -1
|
@@ -2,17 +2,26 @@ import {
|
|
|
2
2
|
INITIAL_L2_BLOCK_NUM,
|
|
3
3
|
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
4
4
|
PRIVATE_LOG_SIZE_IN_FIELDS,
|
|
5
|
-
PUBLIC_LOG_SIZE_IN_FIELDS,
|
|
6
5
|
} from '@aztec/constants';
|
|
7
6
|
import { makeTuple } from '@aztec/foundation/array';
|
|
7
|
+
import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
8
8
|
import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
|
|
9
9
|
import { times, timesParallel } from '@aztec/foundation/collection';
|
|
10
|
-
import { randomInt } from '@aztec/foundation/crypto';
|
|
11
|
-
import { Fr } from '@aztec/foundation/
|
|
10
|
+
import { randomInt } from '@aztec/foundation/crypto/random';
|
|
11
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
12
12
|
import { toArray } from '@aztec/foundation/iterable';
|
|
13
13
|
import { sleep } from '@aztec/foundation/sleep';
|
|
14
14
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
CommitteeAttestation,
|
|
17
|
+
EthAddress,
|
|
18
|
+
L2Block,
|
|
19
|
+
L2BlockHash,
|
|
20
|
+
PublishedL2Block,
|
|
21
|
+
type ValidateBlockResult,
|
|
22
|
+
randomBlockInfo,
|
|
23
|
+
wrapDataInBlock,
|
|
24
|
+
} from '@aztec/stdlib/block';
|
|
16
25
|
import {
|
|
17
26
|
type ContractClassPublic,
|
|
18
27
|
type ContractInstanceWithAddress,
|
|
@@ -34,7 +43,6 @@ import type { ArchiverDataStore, ArchiverL1SynchPoint } from './archiver_store.j
|
|
|
34
43
|
import { BlockNumberNotSequentialError, InitialBlockNumberNotSequentialError } from './errors.js';
|
|
35
44
|
import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
36
45
|
import type { InboxMessage } from './structs/inbox_message.js';
|
|
37
|
-
import type { PublishedL2Block } from './structs/published.js';
|
|
38
46
|
|
|
39
47
|
/**
|
|
40
48
|
* @param testName - The name of the test suite.
|
|
@@ -58,15 +66,16 @@ export function describeArchiverDataStore(
|
|
|
58
66
|
|
|
59
67
|
const makeBlockHash = (blockNumber: number) => `0x${blockNumber.toString(16).padStart(64, '0')}`;
|
|
60
68
|
|
|
61
|
-
const makePublished = (block: L2Block, l1BlockNumber: number): PublishedL2Block =>
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
const makePublished = (block: L2Block, l1BlockNumber: number): PublishedL2Block =>
|
|
70
|
+
PublishedL2Block.fromFields({
|
|
71
|
+
block: block,
|
|
72
|
+
l1: {
|
|
73
|
+
blockNumber: BigInt(l1BlockNumber),
|
|
74
|
+
blockHash: makeBlockHash(l1BlockNumber),
|
|
75
|
+
timestamp: BigInt(l1BlockNumber * 1000),
|
|
76
|
+
},
|
|
77
|
+
attestations: times(3, CommitteeAttestation.random),
|
|
78
|
+
});
|
|
70
79
|
|
|
71
80
|
const expectBlocksEqual = (actual: PublishedL2Block[], expected: PublishedL2Block[]) => {
|
|
72
81
|
expect(actual.length).toEqual(expected.length);
|
|
@@ -81,7 +90,7 @@ export function describeArchiverDataStore(
|
|
|
81
90
|
|
|
82
91
|
beforeEach(async () => {
|
|
83
92
|
store = await getStore();
|
|
84
|
-
blocks = await timesParallel(10, async i => makePublished(await L2Block.random(i + 1), i + 10));
|
|
93
|
+
blocks = await timesParallel(10, async i => makePublished(await L2Block.random(BlockNumber(i + 1)), i + 10));
|
|
85
94
|
});
|
|
86
95
|
|
|
87
96
|
describe('addBlocks', () => {
|
|
@@ -95,15 +104,18 @@ export function describeArchiverDataStore(
|
|
|
95
104
|
});
|
|
96
105
|
|
|
97
106
|
it('throws an error if the previous block does not exist in the store', async () => {
|
|
98
|
-
const block = makePublished(await L2Block.random(2), 2);
|
|
107
|
+
const block = makePublished(await L2Block.random(BlockNumber(2)), 2);
|
|
99
108
|
await expect(store.addBlocks([block])).rejects.toThrow(InitialBlockNumberNotSequentialError);
|
|
100
|
-
await expect(store.getPublishedBlocks(1, 10)).resolves.toEqual([]);
|
|
109
|
+
await expect(store.getPublishedBlocks(BlockNumber(1), 10)).resolves.toEqual([]);
|
|
101
110
|
});
|
|
102
111
|
|
|
103
112
|
it('throws an error if there is a gap in the blocks being added', async () => {
|
|
104
|
-
const blocks = [
|
|
113
|
+
const blocks = [
|
|
114
|
+
makePublished(await L2Block.random(BlockNumber(1)), 1),
|
|
115
|
+
makePublished(await L2Block.random(BlockNumber(3)), 3),
|
|
116
|
+
];
|
|
105
117
|
await expect(store.addBlocks(blocks)).rejects.toThrow(BlockNumberNotSequentialError);
|
|
106
|
-
await expect(store.getPublishedBlocks(1, 10)).resolves.toEqual([]);
|
|
118
|
+
await expect(store.getPublishedBlocks(BlockNumber(1), 10)).resolves.toEqual([]);
|
|
107
119
|
});
|
|
108
120
|
});
|
|
109
121
|
|
|
@@ -121,18 +133,44 @@ export function describeArchiverDataStore(
|
|
|
121
133
|
});
|
|
122
134
|
|
|
123
135
|
it('can unwind multiple empty blocks', async () => {
|
|
124
|
-
const emptyBlocks = await timesParallel(10, async i =>
|
|
136
|
+
const emptyBlocks = await timesParallel(10, async i =>
|
|
137
|
+
makePublished(await L2Block.random(BlockNumber(i + 1), 0), i + 10),
|
|
138
|
+
);
|
|
125
139
|
await store.addBlocks(emptyBlocks);
|
|
126
140
|
expect(await store.getSynchedL2BlockNumber()).toBe(10);
|
|
127
141
|
|
|
128
|
-
await store.unwindBlocks(10, 3);
|
|
142
|
+
await store.unwindBlocks(BlockNumber(10), 3);
|
|
129
143
|
expect(await store.getSynchedL2BlockNumber()).toBe(7);
|
|
130
|
-
expect((await store.getPublishedBlocks(1, 10)).map(b => b.block.number)).toEqual([
|
|
144
|
+
expect((await store.getPublishedBlocks(BlockNumber(1), 10)).map(b => b.block.number)).toEqual([
|
|
145
|
+
1, 2, 3, 4, 5, 6, 7,
|
|
146
|
+
]);
|
|
131
147
|
});
|
|
132
148
|
|
|
133
149
|
it('refuses to unwind blocks if the tip is not the last block', async () => {
|
|
134
150
|
await store.addBlocks(blocks);
|
|
135
|
-
await expect(store.unwindBlocks(5, 1)).rejects.toThrow(/can only unwind blocks from the tip/i);
|
|
151
|
+
await expect(store.unwindBlocks(BlockNumber(5), 1)).rejects.toThrow(/can only unwind blocks from the tip/i);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('unwound blocks and headers cannot be retrieved by hash or archive', async () => {
|
|
155
|
+
await store.addBlocks(blocks);
|
|
156
|
+
const lastBlock = blocks[blocks.length - 1];
|
|
157
|
+
const blockHash = await lastBlock.block.hash();
|
|
158
|
+
const archive = lastBlock.block.archive.root;
|
|
159
|
+
|
|
160
|
+
// Verify block and header exist before unwinding
|
|
161
|
+
expect(await store.getPublishedBlockByHash(blockHash)).toBeDefined();
|
|
162
|
+
expect(await store.getPublishedBlockByArchive(archive)).toBeDefined();
|
|
163
|
+
expect(await store.getBlockHeaderByHash(blockHash)).toBeDefined();
|
|
164
|
+
expect(await store.getBlockHeaderByArchive(archive)).toBeDefined();
|
|
165
|
+
|
|
166
|
+
// Unwind the block
|
|
167
|
+
await store.unwindBlocks(lastBlock.block.number, 1);
|
|
168
|
+
|
|
169
|
+
// Verify neither block nor header can be retrieved after unwinding
|
|
170
|
+
expect(await store.getPublishedBlockByHash(blockHash)).toBeUndefined();
|
|
171
|
+
expect(await store.getPublishedBlockByArchive(archive)).toBeUndefined();
|
|
172
|
+
expect(await store.getBlockHeaderByHash(blockHash)).toBeUndefined();
|
|
173
|
+
expect(await store.getBlockHeaderByArchive(archive)).toBeUndefined();
|
|
136
174
|
});
|
|
137
175
|
});
|
|
138
176
|
|
|
@@ -142,32 +180,117 @@ export function describeArchiverDataStore(
|
|
|
142
180
|
});
|
|
143
181
|
|
|
144
182
|
it.each(blockTests)('retrieves previously stored blocks', async (start, limit, getExpectedBlocks) => {
|
|
145
|
-
expectBlocksEqual(await store.getPublishedBlocks(start, limit), getExpectedBlocks());
|
|
183
|
+
expectBlocksEqual(await store.getPublishedBlocks(BlockNumber(start), limit), getExpectedBlocks());
|
|
146
184
|
});
|
|
147
185
|
|
|
148
186
|
it('returns an empty array if no blocks are found', async () => {
|
|
149
|
-
await expect(store.getPublishedBlocks(12, 1)).resolves.toEqual([]);
|
|
187
|
+
await expect(store.getPublishedBlocks(BlockNumber(12), 1)).resolves.toEqual([]);
|
|
150
188
|
});
|
|
151
189
|
|
|
152
190
|
it('throws an error if limit is invalid', async () => {
|
|
153
|
-
await expect(store.getPublishedBlocks(1, 0)).rejects.toThrow('Invalid limit: 0');
|
|
191
|
+
await expect(store.getPublishedBlocks(BlockNumber(1), 0)).rejects.toThrow('Invalid limit: 0');
|
|
154
192
|
});
|
|
155
193
|
|
|
156
194
|
it('throws an error if `from` it is out of range', async () => {
|
|
157
|
-
await expect(store.getPublishedBlocks(INITIAL_L2_BLOCK_NUM - 100, 1)).rejects.toThrow(
|
|
195
|
+
await expect(store.getPublishedBlocks((INITIAL_L2_BLOCK_NUM - 100) as BlockNumber, 1)).rejects.toThrow(
|
|
196
|
+
'Invalid start: -99',
|
|
197
|
+
);
|
|
158
198
|
});
|
|
159
199
|
|
|
160
200
|
it('throws an error if unexpected initial block number is found', async () => {
|
|
161
|
-
await store.addBlocks([makePublished(await L2Block.random(21), 31)], { force: true });
|
|
162
|
-
await expect(store.getPublishedBlocks(20, 1)).rejects.toThrow(`mismatch`);
|
|
201
|
+
await store.addBlocks([makePublished(await L2Block.random(BlockNumber(21)), 31)], { force: true });
|
|
202
|
+
await expect(store.getPublishedBlocks(BlockNumber(20), 1)).rejects.toThrow(`mismatch`);
|
|
163
203
|
});
|
|
164
204
|
|
|
165
205
|
it('throws an error if a gap is found', async () => {
|
|
166
206
|
await store.addBlocks(
|
|
167
|
-
[
|
|
207
|
+
[
|
|
208
|
+
makePublished(await L2Block.random(BlockNumber(20)), 30),
|
|
209
|
+
makePublished(await L2Block.random(BlockNumber(22)), 32),
|
|
210
|
+
],
|
|
168
211
|
{ force: true },
|
|
169
212
|
);
|
|
170
|
-
await expect(store.getPublishedBlocks(20, 2)).rejects.toThrow(`mismatch`);
|
|
213
|
+
await expect(store.getPublishedBlocks(BlockNumber(20), 2)).rejects.toThrow(`mismatch`);
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
describe('getPublishedBlockByHash', () => {
|
|
218
|
+
beforeEach(async () => {
|
|
219
|
+
await store.addBlocks(blocks);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('retrieves a block by its hash', async () => {
|
|
223
|
+
const expectedBlock = blocks[5];
|
|
224
|
+
const blockHash = await expectedBlock.block.hash();
|
|
225
|
+
const retrievedBlock = await store.getPublishedBlockByHash(blockHash);
|
|
226
|
+
|
|
227
|
+
expect(retrievedBlock).toBeDefined();
|
|
228
|
+
expectBlocksEqual([retrievedBlock!], [expectedBlock]);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('returns undefined for non-existent block hash', async () => {
|
|
232
|
+
const nonExistentHash = Fr.random();
|
|
233
|
+
await expect(store.getPublishedBlockByHash(nonExistentHash)).resolves.toBeUndefined();
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
describe('getPublishedBlockByArchive', () => {
|
|
238
|
+
beforeEach(async () => {
|
|
239
|
+
await store.addBlocks(blocks);
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it('retrieves a block by its archive root', async () => {
|
|
243
|
+
const expectedBlock = blocks[3];
|
|
244
|
+
const archive = expectedBlock.block.archive.root;
|
|
245
|
+
const retrievedBlock = await store.getPublishedBlockByArchive(archive);
|
|
246
|
+
|
|
247
|
+
expect(retrievedBlock).toBeDefined();
|
|
248
|
+
expectBlocksEqual([retrievedBlock!], [expectedBlock]);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it('returns undefined for non-existent archive root', async () => {
|
|
252
|
+
const nonExistentArchive = Fr.random();
|
|
253
|
+
await expect(store.getPublishedBlockByArchive(nonExistentArchive)).resolves.toBeUndefined();
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
describe('getBlockHeaderByHash', () => {
|
|
258
|
+
beforeEach(async () => {
|
|
259
|
+
await store.addBlocks(blocks);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it('retrieves a block header by its hash', async () => {
|
|
263
|
+
const expectedBlock = blocks[7];
|
|
264
|
+
const blockHash = await expectedBlock.block.hash();
|
|
265
|
+
const retrievedHeader = await store.getBlockHeaderByHash(blockHash);
|
|
266
|
+
|
|
267
|
+
expect(retrievedHeader).toBeDefined();
|
|
268
|
+
expect(retrievedHeader!.equals(expectedBlock.block.getBlockHeader())).toBe(true);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('returns undefined for non-existent block hash', async () => {
|
|
272
|
+
const nonExistentHash = Fr.random();
|
|
273
|
+
await expect(store.getBlockHeaderByHash(nonExistentHash)).resolves.toBeUndefined();
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
describe('getBlockHeaderByArchive', () => {
|
|
278
|
+
beforeEach(async () => {
|
|
279
|
+
await store.addBlocks(blocks);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('retrieves a block header by its archive root', async () => {
|
|
283
|
+
const expectedBlock = blocks[2];
|
|
284
|
+
const archive = expectedBlock.block.archive.root;
|
|
285
|
+
const retrievedHeader = await store.getBlockHeaderByArchive(archive);
|
|
286
|
+
|
|
287
|
+
expect(retrievedHeader).toBeDefined();
|
|
288
|
+
expect(retrievedHeader!.equals(expectedBlock.block.getBlockHeader())).toBe(true);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it('returns undefined for non-existent archive root', async () => {
|
|
292
|
+
const nonExistentArchive = Fr.random();
|
|
293
|
+
await expect(store.getBlockHeaderByArchive(nonExistentArchive)).resolves.toBeUndefined();
|
|
171
294
|
});
|
|
172
295
|
});
|
|
173
296
|
|
|
@@ -229,36 +352,19 @@ export function describeArchiverDataStore(
|
|
|
229
352
|
});
|
|
230
353
|
});
|
|
231
354
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
await expect(store.addLogs([block])).resolves.toEqual(true);
|
|
355
|
+
it('deleteLogs', async () => {
|
|
356
|
+
const block = blocks[0].block;
|
|
357
|
+
await store.addBlocks([blocks[0]]);
|
|
358
|
+
await expect(store.addLogs([block])).resolves.toEqual(true);
|
|
237
359
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
expect((await store.getPublicLogs({ fromBlock: 1 })).logs.length).toEqual(
|
|
242
|
-
block.body.txEffects.map(txEffect => txEffect.publicLogs).flat().length,
|
|
243
|
-
);
|
|
360
|
+
expect((await store.getPublicLogs({ fromBlock: BlockNumber(1) })).logs.length).toEqual(
|
|
361
|
+
block.body.txEffects.map(txEffect => txEffect.publicLogs).flat().length,
|
|
362
|
+
);
|
|
244
363
|
|
|
245
|
-
|
|
246
|
-
|
|
364
|
+
// This one is a pain for memory as we would never want to just delete memory in the middle.
|
|
365
|
+
await store.deleteLogs([block]);
|
|
247
366
|
|
|
248
|
-
|
|
249
|
-
expect((await store.getPublicLogs({ fromBlock: 1 })).logs.length).toEqual(0);
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
describe('getPrivateLogs', () => {
|
|
254
|
-
it('gets added private logs', async () => {
|
|
255
|
-
const block = blocks[0].block;
|
|
256
|
-
await store.addBlocks([blocks[0]]);
|
|
257
|
-
await store.addLogs([block]);
|
|
258
|
-
|
|
259
|
-
const privateLogs = await store.getPrivateLogs(1, 1);
|
|
260
|
-
expect(privateLogs).toEqual(block.body.txEffects.map(txEffect => txEffect.privateLogs).flat());
|
|
261
|
-
});
|
|
367
|
+
expect((await store.getPublicLogs({ fromBlock: BlockNumber(1) })).logs.length).toEqual(0);
|
|
262
368
|
});
|
|
263
369
|
|
|
264
370
|
describe('getTxEffect', () => {
|
|
@@ -290,13 +396,13 @@ export function describeArchiverDataStore(
|
|
|
290
396
|
});
|
|
291
397
|
|
|
292
398
|
it.each([
|
|
293
|
-
() =>
|
|
294
|
-
() =>
|
|
295
|
-
() =>
|
|
296
|
-
() =>
|
|
297
|
-
() =>
|
|
399
|
+
() => wrapDataInBlock(blocks[0].block.body.txEffects[0], blocks[0].block),
|
|
400
|
+
() => wrapDataInBlock(blocks[9].block.body.txEffects[3], blocks[9].block),
|
|
401
|
+
() => wrapDataInBlock(blocks[3].block.body.txEffects[1], blocks[3].block),
|
|
402
|
+
() => wrapDataInBlock(blocks[5].block.body.txEffects[2], blocks[5].block),
|
|
403
|
+
() => wrapDataInBlock(blocks[1].block.body.txEffects[0], blocks[1].block),
|
|
298
404
|
])('tries to retrieves a previously stored transaction after deleted', async getExpectedTx => {
|
|
299
|
-
await store.unwindBlocks(blocks.length, blocks.length);
|
|
405
|
+
await store.unwindBlocks(BlockNumber(blocks.length), blocks.length);
|
|
300
406
|
|
|
301
407
|
const expectedTx = await getExpectedTx();
|
|
302
408
|
const actualTx = await store.getTxEffect(expectedTx.data.txHash);
|
|
@@ -308,7 +414,7 @@ export function describeArchiverDataStore(
|
|
|
308
414
|
});
|
|
309
415
|
|
|
310
416
|
it('does not fail if the block is unwound while requesting a tx', async () => {
|
|
311
|
-
const expectedTx = await
|
|
417
|
+
const expectedTx = await wrapDataInBlock(blocks[1].block.body.txEffects[0], blocks[1].block);
|
|
312
418
|
let done = false;
|
|
313
419
|
void (async () => {
|
|
314
420
|
while (!done) {
|
|
@@ -316,14 +422,14 @@ export function describeArchiverDataStore(
|
|
|
316
422
|
await sleep(1);
|
|
317
423
|
}
|
|
318
424
|
})();
|
|
319
|
-
await store.unwindBlocks(blocks.length, blocks.length);
|
|
425
|
+
await store.unwindBlocks(BlockNumber(blocks.length), blocks.length);
|
|
320
426
|
done = true;
|
|
321
427
|
expect(await store.getTxEffect(expectedTx.data.txHash)).toEqual(undefined);
|
|
322
428
|
});
|
|
323
429
|
});
|
|
324
430
|
|
|
325
431
|
describe('L1 to L2 Messages', () => {
|
|
326
|
-
const
|
|
432
|
+
const initialCheckpointNumber = CheckpointNumber(13);
|
|
327
433
|
|
|
328
434
|
const checkMessages = async (msgs: InboxMessage[]) => {
|
|
329
435
|
expect(await store.getLastL1ToL2Message()).toEqual(msgs.at(-1));
|
|
@@ -331,43 +437,50 @@ export function describeArchiverDataStore(
|
|
|
331
437
|
expect(await store.getTotalL1ToL2MessageCount()).toEqual(BigInt(msgs.length));
|
|
332
438
|
};
|
|
333
439
|
|
|
334
|
-
const makeInboxMessagesWithFullBlocks = (
|
|
440
|
+
const makeInboxMessagesWithFullBlocks = (
|
|
441
|
+
blockCount: number,
|
|
442
|
+
opts: { initialCheckpointNumber?: CheckpointNumber } = {},
|
|
443
|
+
) =>
|
|
335
444
|
makeInboxMessages(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * blockCount, {
|
|
336
445
|
overrideFn: (msg, i) => {
|
|
337
|
-
const
|
|
338
|
-
(opts.
|
|
446
|
+
const checkpointNumber = CheckpointNumber(
|
|
447
|
+
(opts.initialCheckpointNumber ?? initialCheckpointNumber) +
|
|
448
|
+
Math.floor(i / NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP),
|
|
449
|
+
);
|
|
339
450
|
const index =
|
|
340
|
-
InboxLeaf.
|
|
341
|
-
return { ...msg,
|
|
451
|
+
InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) + BigInt(i % NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
452
|
+
return { ...msg, checkpointNumber, index };
|
|
342
453
|
},
|
|
343
454
|
});
|
|
344
455
|
|
|
345
456
|
it('stores first message ever', async () => {
|
|
346
|
-
const msg = makeInboxMessage(Buffer16.ZERO, { index: 0n,
|
|
457
|
+
const msg = makeInboxMessage(Buffer16.ZERO, { index: 0n, checkpointNumber: CheckpointNumber(1) });
|
|
347
458
|
await store.addL1ToL2Messages([msg]);
|
|
348
459
|
|
|
349
460
|
await checkMessages([msg]);
|
|
350
|
-
expect(await store.getL1ToL2Messages(1)).toEqual([msg.leaf]);
|
|
461
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(1))).toEqual([msg.leaf]);
|
|
351
462
|
});
|
|
352
463
|
|
|
353
464
|
it('stores single message', async () => {
|
|
354
|
-
const msg = makeInboxMessage(Buffer16.ZERO, {
|
|
465
|
+
const msg = makeInboxMessage(Buffer16.ZERO, { checkpointNumber: CheckpointNumber(2) });
|
|
355
466
|
await store.addL1ToL2Messages([msg]);
|
|
356
467
|
|
|
357
468
|
await checkMessages([msg]);
|
|
358
|
-
expect(await store.getL1ToL2Messages(2)).toEqual([msg.leaf]);
|
|
469
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(2))).toEqual([msg.leaf]);
|
|
359
470
|
});
|
|
360
471
|
|
|
361
472
|
it('stores and returns messages across different blocks', async () => {
|
|
362
|
-
const msgs = makeInboxMessages(5, {
|
|
473
|
+
const msgs = makeInboxMessages(5, { initialCheckpointNumber });
|
|
363
474
|
await store.addL1ToL2Messages(msgs);
|
|
364
475
|
|
|
365
476
|
await checkMessages(msgs);
|
|
366
|
-
expect(await store.getL1ToL2Messages(
|
|
477
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 2))).toEqual(
|
|
478
|
+
[msgs[2]].map(m => m.leaf),
|
|
479
|
+
);
|
|
367
480
|
});
|
|
368
481
|
|
|
369
482
|
it('stores the same messages again', async () => {
|
|
370
|
-
const msgs = makeInboxMessages(5, {
|
|
483
|
+
const msgs = makeInboxMessages(5, { initialCheckpointNumber });
|
|
371
484
|
await store.addL1ToL2Messages(msgs);
|
|
372
485
|
await store.addL1ToL2Messages(msgs.slice(2));
|
|
373
486
|
|
|
@@ -375,26 +488,29 @@ export function describeArchiverDataStore(
|
|
|
375
488
|
});
|
|
376
489
|
|
|
377
490
|
it('stores and returns messages across different blocks with gaps', async () => {
|
|
378
|
-
const msgs1 = makeInboxMessages(3, {
|
|
379
|
-
const msgs2 = makeInboxMessages(3, {
|
|
491
|
+
const msgs1 = makeInboxMessages(3, { initialCheckpointNumber: CheckpointNumber(1) });
|
|
492
|
+
const msgs2 = makeInboxMessages(3, {
|
|
493
|
+
initialCheckpointNumber: CheckpointNumber(20),
|
|
494
|
+
initialHash: msgs1.at(-1)!.rollingHash,
|
|
495
|
+
});
|
|
380
496
|
|
|
381
497
|
await store.addL1ToL2Messages(msgs1);
|
|
382
498
|
await store.addL1ToL2Messages(msgs2);
|
|
383
499
|
|
|
384
500
|
await checkMessages([...msgs1, ...msgs2]);
|
|
385
501
|
|
|
386
|
-
expect(await store.getL1ToL2Messages(1)).toEqual([msgs1[0].leaf]);
|
|
387
|
-
expect(await store.getL1ToL2Messages(4)).toEqual([]);
|
|
388
|
-
expect(await store.getL1ToL2Messages(20)).toEqual([msgs2[0].leaf]);
|
|
389
|
-
expect(await store.getL1ToL2Messages(24)).toEqual([]);
|
|
502
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(1))).toEqual([msgs1[0].leaf]);
|
|
503
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(4))).toEqual([]);
|
|
504
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(20))).toEqual([msgs2[0].leaf]);
|
|
505
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(24))).toEqual([]);
|
|
390
506
|
});
|
|
391
507
|
|
|
392
508
|
it('stores and returns messages with block numbers larger than a byte', async () => {
|
|
393
|
-
const msgs = makeInboxMessages(5, {
|
|
509
|
+
const msgs = makeInboxMessages(5, { initialCheckpointNumber: CheckpointNumber(1000) });
|
|
394
510
|
await store.addL1ToL2Messages(msgs);
|
|
395
511
|
|
|
396
512
|
await checkMessages(msgs);
|
|
397
|
-
expect(await store.getL1ToL2Messages(1002)).toEqual([msgs[2]].map(m => m.leaf));
|
|
513
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(1002))).toEqual([msgs[2]].map(m => m.leaf));
|
|
398
514
|
});
|
|
399
515
|
|
|
400
516
|
it('stores and returns multiple messages per block', async () => {
|
|
@@ -402,7 +518,7 @@ export function describeArchiverDataStore(
|
|
|
402
518
|
await store.addL1ToL2Messages(msgs);
|
|
403
519
|
|
|
404
520
|
await checkMessages(msgs);
|
|
405
|
-
const blockMessages = await store.getL1ToL2Messages(
|
|
521
|
+
const blockMessages = await store.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 1));
|
|
406
522
|
expect(blockMessages).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
407
523
|
expect(blockMessages).toEqual(
|
|
408
524
|
msgs.slice(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2).map(m => m.leaf),
|
|
@@ -410,17 +526,21 @@ export function describeArchiverDataStore(
|
|
|
410
526
|
});
|
|
411
527
|
|
|
412
528
|
it('stores messages in multiple operations', async () => {
|
|
413
|
-
const msgs = makeInboxMessages(20, {
|
|
529
|
+
const msgs = makeInboxMessages(20, { initialCheckpointNumber });
|
|
414
530
|
await store.addL1ToL2Messages(msgs.slice(0, 10));
|
|
415
531
|
await store.addL1ToL2Messages(msgs.slice(10, 20));
|
|
416
532
|
|
|
417
|
-
expect(await store.getL1ToL2Messages(
|
|
418
|
-
|
|
533
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 2))).toEqual(
|
|
534
|
+
[msgs[2]].map(m => m.leaf),
|
|
535
|
+
);
|
|
536
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(initialCheckpointNumber + 12))).toEqual(
|
|
537
|
+
[msgs[12]].map(m => m.leaf),
|
|
538
|
+
);
|
|
419
539
|
await checkMessages(msgs);
|
|
420
540
|
});
|
|
421
541
|
|
|
422
542
|
it('iterates over messages from start index', async () => {
|
|
423
|
-
const msgs = makeInboxMessages(10, {
|
|
543
|
+
const msgs = makeInboxMessages(10, { initialCheckpointNumber });
|
|
424
544
|
await store.addL1ToL2Messages(msgs);
|
|
425
545
|
|
|
426
546
|
const iterated = await toArray(store.iterateL1ToL2Messages({ start: msgs[3].index }));
|
|
@@ -428,8 +548,9 @@ export function describeArchiverDataStore(
|
|
|
428
548
|
});
|
|
429
549
|
|
|
430
550
|
it('iterates over messages in reverse', async () => {
|
|
431
|
-
const msgs = makeInboxMessages(10, {
|
|
551
|
+
const msgs = makeInboxMessages(10, { initialCheckpointNumber });
|
|
432
552
|
await store.addL1ToL2Messages(msgs);
|
|
553
|
+
initialCheckpointNumber;
|
|
433
554
|
|
|
434
555
|
const iterated = await toArray(store.iterateL1ToL2Messages({ reverse: true, end: msgs[3].index }));
|
|
435
556
|
expect(iterated).toEqual(msgs.slice(0, 4).reverse());
|
|
@@ -441,8 +562,8 @@ export function describeArchiverDataStore(
|
|
|
441
562
|
});
|
|
442
563
|
|
|
443
564
|
it('throws if block number for the first message is out of order', async () => {
|
|
444
|
-
const msgs = makeInboxMessages(4, {
|
|
445
|
-
msgs[2].
|
|
565
|
+
const msgs = makeInboxMessages(4, { initialCheckpointNumber });
|
|
566
|
+
msgs[2].checkpointNumber = CheckpointNumber(initialCheckpointNumber - 1);
|
|
446
567
|
await store.addL1ToL2Messages(msgs.slice(0, 2));
|
|
447
568
|
await expect(store.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError);
|
|
448
569
|
});
|
|
@@ -456,28 +577,28 @@ export function describeArchiverDataStore(
|
|
|
456
577
|
it('throws if rolling hash for first message is not correct', async () => {
|
|
457
578
|
const msgs = makeInboxMessages(4);
|
|
458
579
|
msgs[2].rollingHash = Buffer16.random();
|
|
459
|
-
await store.addL1ToL2Messages(msgs.slice(0, 2));
|
|
580
|
+
await store.addL1ToL2Messages(msgs.slice(0, CheckpointNumber(2)));
|
|
460
581
|
await expect(store.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError);
|
|
461
582
|
});
|
|
462
583
|
|
|
463
584
|
it('throws if index is not in the correct range', async () => {
|
|
464
|
-
const msgs = makeInboxMessages(5, {
|
|
585
|
+
const msgs = makeInboxMessages(5, { initialCheckpointNumber });
|
|
465
586
|
msgs.at(-1)!.index += 100n;
|
|
466
587
|
await expect(store.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError);
|
|
467
588
|
});
|
|
468
589
|
|
|
469
590
|
it('throws if first index in block has gaps', async () => {
|
|
470
|
-
const msgs = makeInboxMessages(4, {
|
|
591
|
+
const msgs = makeInboxMessages(4, { initialCheckpointNumber });
|
|
471
592
|
msgs[2].index++;
|
|
472
593
|
await expect(store.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError);
|
|
473
594
|
});
|
|
474
595
|
|
|
475
596
|
it('throws if index does not follow previous one', async () => {
|
|
476
597
|
const msgs = makeInboxMessages(2, {
|
|
477
|
-
|
|
598
|
+
initialCheckpointNumber,
|
|
478
599
|
overrideFn: (msg, i) => ({
|
|
479
600
|
...msg,
|
|
480
|
-
|
|
601
|
+
checkpointNumber: CheckpointNumber(2),
|
|
481
602
|
index: BigInt(i + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2),
|
|
482
603
|
}),
|
|
483
604
|
});
|
|
@@ -486,28 +607,28 @@ export function describeArchiverDataStore(
|
|
|
486
607
|
});
|
|
487
608
|
|
|
488
609
|
it('removes messages up to the given block number', async () => {
|
|
489
|
-
const msgs = makeInboxMessagesWithFullBlocks(4, {
|
|
610
|
+
const msgs = makeInboxMessagesWithFullBlocks(4, { initialCheckpointNumber: CheckpointNumber(1) });
|
|
490
611
|
|
|
491
612
|
await store.addL1ToL2Messages(msgs);
|
|
492
613
|
await checkMessages(msgs);
|
|
493
614
|
|
|
494
|
-
expect(await store.getL1ToL2Messages(1)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
495
|
-
expect(await store.getL1ToL2Messages(2)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
496
|
-
expect(await store.getL1ToL2Messages(3)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
497
|
-
expect(await store.getL1ToL2Messages(4)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
615
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(1))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
616
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(2))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
617
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(3))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
618
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(4))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
498
619
|
|
|
499
|
-
await store.
|
|
620
|
+
await store.rollbackL1ToL2MessagesToCheckpoint(CheckpointNumber(2));
|
|
500
621
|
|
|
501
|
-
expect(await store.getL1ToL2Messages(1)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
502
|
-
expect(await store.getL1ToL2Messages(2)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
503
|
-
expect(await store.getL1ToL2Messages(3)).toHaveLength(0);
|
|
504
|
-
expect(await store.getL1ToL2Messages(4)).toHaveLength(0);
|
|
622
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(1))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
623
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(2))).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
624
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(3))).toHaveLength(0);
|
|
625
|
+
expect(await store.getL1ToL2Messages(CheckpointNumber(4))).toHaveLength(0);
|
|
505
626
|
|
|
506
627
|
await checkMessages(msgs.slice(0, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2));
|
|
507
628
|
});
|
|
508
629
|
|
|
509
630
|
it('removes messages starting with the given index', async () => {
|
|
510
|
-
const msgs = makeInboxMessagesWithFullBlocks(4, {
|
|
631
|
+
const msgs = makeInboxMessagesWithFullBlocks(4, { initialCheckpointNumber: CheckpointNumber(1) });
|
|
511
632
|
await store.addL1ToL2Messages(msgs);
|
|
512
633
|
|
|
513
634
|
await store.removeL1ToL2Messages(msgs[13].index);
|
|
@@ -527,7 +648,7 @@ export function describeArchiverDataStore(
|
|
|
527
648
|
originalContractClassId: classId,
|
|
528
649
|
});
|
|
529
650
|
contractInstance = { ...randomInstance, address: await AztecAddress.random() };
|
|
530
|
-
await store.addContractInstances([contractInstance], blockNum);
|
|
651
|
+
await store.addContractInstances([contractInstance], BlockNumber(blockNum));
|
|
531
652
|
});
|
|
532
653
|
|
|
533
654
|
it('returns previously stored contract instances', async () => {
|
|
@@ -541,7 +662,7 @@ export function describeArchiverDataStore(
|
|
|
541
662
|
});
|
|
542
663
|
|
|
543
664
|
it('returns undefined if previously stored contract instances was deleted', async () => {
|
|
544
|
-
await store.deleteContractInstances([contractInstance], blockNum);
|
|
665
|
+
await store.deleteContractInstances([contractInstance], BlockNumber(blockNum));
|
|
545
666
|
await expect(store.getContractInstance(contractInstance.address, timestamp)).resolves.toBeUndefined();
|
|
546
667
|
});
|
|
547
668
|
});
|
|
@@ -560,7 +681,7 @@ export function describeArchiverDataStore(
|
|
|
560
681
|
originalContractClassId: classId,
|
|
561
682
|
});
|
|
562
683
|
contractInstance = { ...randomInstance, address: await AztecAddress.random() };
|
|
563
|
-
await store.addContractInstances([contractInstance], 1);
|
|
684
|
+
await store.addContractInstances([contractInstance], BlockNumber(1));
|
|
564
685
|
await store.addContractInstanceUpdates(
|
|
565
686
|
[
|
|
566
687
|
{
|
|
@@ -602,7 +723,7 @@ export function describeArchiverDataStore(
|
|
|
602
723
|
...randomInstance,
|
|
603
724
|
address: await AztecAddress.random(),
|
|
604
725
|
};
|
|
605
|
-
await store.addContractInstances([otherContractInstance], 1);
|
|
726
|
+
await store.addContractInstances([otherContractInstance], BlockNumber(1));
|
|
606
727
|
|
|
607
728
|
const fetchedInstance = await store.getContractInstance(otherContractInstance.address, timestampOfChange + 1n);
|
|
608
729
|
expect(fetchedInstance?.originalContractClassId).toEqual(otherClassId);
|
|
@@ -620,7 +741,7 @@ export function describeArchiverDataStore(
|
|
|
620
741
|
...randomInstance,
|
|
621
742
|
address: await AztecAddress.random(),
|
|
622
743
|
};
|
|
623
|
-
await store.addContractInstances([otherContractInstance], 1);
|
|
744
|
+
await store.addContractInstances([otherContractInstance], BlockNumber(1));
|
|
624
745
|
await store.addContractInstanceUpdates(
|
|
625
746
|
[
|
|
626
747
|
{
|
|
@@ -648,7 +769,7 @@ export function describeArchiverDataStore(
|
|
|
648
769
|
await store.addContractClasses(
|
|
649
770
|
[contractClass],
|
|
650
771
|
[await computePublicBytecodeCommitment(contractClass.packedBytecode)],
|
|
651
|
-
blockNum,
|
|
772
|
+
BlockNumber(blockNum),
|
|
652
773
|
);
|
|
653
774
|
});
|
|
654
775
|
|
|
@@ -657,7 +778,7 @@ export function describeArchiverDataStore(
|
|
|
657
778
|
});
|
|
658
779
|
|
|
659
780
|
it('returns undefined if the initial deployed contract class was deleted', async () => {
|
|
660
|
-
await store.deleteContractClasses([contractClass], blockNum);
|
|
781
|
+
await store.deleteContractClasses([contractClass], BlockNumber(blockNum));
|
|
661
782
|
await expect(store.getContractClass(contractClass.id)).resolves.toBeUndefined();
|
|
662
783
|
});
|
|
663
784
|
|
|
@@ -665,9 +786,9 @@ export function describeArchiverDataStore(
|
|
|
665
786
|
await store.addContractClasses(
|
|
666
787
|
[contractClass],
|
|
667
788
|
[await computePublicBytecodeCommitment(contractClass.packedBytecode)],
|
|
668
|
-
blockNum + 1,
|
|
789
|
+
BlockNumber(blockNum + 1),
|
|
669
790
|
);
|
|
670
|
-
await store.deleteContractClasses([contractClass], blockNum + 1);
|
|
791
|
+
await store.deleteContractClasses([contractClass], BlockNumber(blockNum + 1));
|
|
671
792
|
await expect(store.getContractClass(contractClass.id)).resolves.toMatchObject(contractClass);
|
|
672
793
|
});
|
|
673
794
|
|
|
@@ -728,8 +849,8 @@ export function describeArchiverDataStore(
|
|
|
728
849
|
const makePublicLog = (tag: Fr) =>
|
|
729
850
|
PublicLog.from({
|
|
730
851
|
contractAddress: AztecAddress.fromNumber(1),
|
|
731
|
-
|
|
732
|
-
|
|
852
|
+
// Arbitrary length
|
|
853
|
+
fields: new Array(10).fill(null).map((_, i) => (!i ? tag : new Fr(tag.toNumber() + i))),
|
|
733
854
|
});
|
|
734
855
|
|
|
735
856
|
const mockPrivateLogs = (blockNumber: number, txIndex: number) => {
|
|
@@ -747,8 +868,8 @@ export function describeArchiverDataStore(
|
|
|
747
868
|
};
|
|
748
869
|
|
|
749
870
|
const mockBlockWithLogs = async (blockNumber: number): Promise<PublishedL2Block> => {
|
|
750
|
-
const block = await L2Block.random(blockNumber);
|
|
751
|
-
block.header.globalVariables.blockNumber = blockNumber;
|
|
871
|
+
const block = await L2Block.random(BlockNumber(blockNumber));
|
|
872
|
+
block.header.globalVariables.blockNumber = BlockNumber(blockNumber);
|
|
752
873
|
|
|
753
874
|
block.body.txEffects = await timesParallel(numTxsPerBlock, async (txIndex: number) => {
|
|
754
875
|
const txEffect = await TxEffect.random();
|
|
@@ -757,7 +878,7 @@ export function describeArchiverDataStore(
|
|
|
757
878
|
return txEffect;
|
|
758
879
|
});
|
|
759
880
|
|
|
760
|
-
return {
|
|
881
|
+
return PublishedL2Block.fromFields({
|
|
761
882
|
block: block,
|
|
762
883
|
attestations: times(3, CommitteeAttestation.random),
|
|
763
884
|
l1: {
|
|
@@ -765,7 +886,7 @@ export function describeArchiverDataStore(
|
|
|
765
886
|
blockHash: makeBlockHash(blockNumber),
|
|
766
887
|
timestamp: BigInt(blockNumber),
|
|
767
888
|
},
|
|
768
|
-
};
|
|
889
|
+
});
|
|
769
890
|
};
|
|
770
891
|
|
|
771
892
|
beforeEach(async () => {
|
|
@@ -878,11 +999,13 @@ export function describeArchiverDataStore(
|
|
|
878
999
|
let blocks: PublishedL2Block[];
|
|
879
1000
|
|
|
880
1001
|
beforeEach(async () => {
|
|
881
|
-
blocks = await timesParallel(numBlocks, async (index: number) =>
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
1002
|
+
blocks = await timesParallel(numBlocks, async (index: number) =>
|
|
1003
|
+
PublishedL2Block.fromFields({
|
|
1004
|
+
block: await L2Block.random(BlockNumber(index + 1), txsPerBlock, numPublicFunctionCalls, numPublicLogs),
|
|
1005
|
+
l1: { blockNumber: BigInt(index), blockHash: makeBlockHash(index), timestamp: BigInt(index) },
|
|
1006
|
+
attestations: times(3, CommitteeAttestation.random),
|
|
1007
|
+
}),
|
|
1008
|
+
);
|
|
886
1009
|
|
|
887
1010
|
await store.addBlocks(blocks);
|
|
888
1011
|
await store.addLogs(blocks.map(b => b.block));
|
|
@@ -895,7 +1018,7 @@ export function describeArchiverDataStore(
|
|
|
895
1018
|
const targetTxHash = blocks[targetBlockIndex].block.body.txEffects[targetTxIndex].txHash;
|
|
896
1019
|
|
|
897
1020
|
await Promise.all([
|
|
898
|
-
store.unwindBlocks(blocks.length, blocks.length),
|
|
1021
|
+
store.unwindBlocks(BlockNumber(blocks.length), blocks.length),
|
|
899
1022
|
store.deleteLogs(blocks.map(b => b.block)),
|
|
900
1023
|
]);
|
|
901
1024
|
|
|
@@ -970,7 +1093,7 @@ export function describeArchiverDataStore(
|
|
|
970
1093
|
const targetTxIndex = randomInt(txsPerBlock);
|
|
971
1094
|
const targetLogIndex = randomInt(numPublicLogs);
|
|
972
1095
|
|
|
973
|
-
const afterLog = new LogId(targetBlockIndex + INITIAL_L2_BLOCK_NUM, targetTxIndex, targetLogIndex);
|
|
1096
|
+
const afterLog = new LogId(BlockNumber(targetBlockIndex + INITIAL_L2_BLOCK_NUM), targetTxIndex, targetLogIndex);
|
|
974
1097
|
|
|
975
1098
|
const response = await store.getPublicLogs({ afterLog });
|
|
976
1099
|
const logs = response.logs;
|
|
@@ -992,42 +1115,54 @@ export function describeArchiverDataStore(
|
|
|
992
1115
|
it('"txHash" filter param is ignored when "afterLog" is set', async () => {
|
|
993
1116
|
// Get random txHash
|
|
994
1117
|
const txHash = TxHash.random();
|
|
995
|
-
const afterLog = new LogId(1, 0, 0);
|
|
1118
|
+
const afterLog = new LogId(BlockNumber(1), 0, 0);
|
|
996
1119
|
|
|
997
1120
|
const response = await store.getPublicLogs({ txHash, afterLog });
|
|
998
1121
|
expect(response.logs.length).toBeGreaterThan(1);
|
|
999
1122
|
});
|
|
1000
1123
|
|
|
1001
1124
|
it('intersecting works', async () => {
|
|
1002
|
-
let logs = (await store.getPublicLogs({ fromBlock: -10, toBlock: -5 })).logs;
|
|
1125
|
+
let logs = (await store.getPublicLogs({ fromBlock: -10 as BlockNumber, toBlock: -5 as BlockNumber })).logs;
|
|
1003
1126
|
expect(logs.length).toBe(0);
|
|
1004
1127
|
|
|
1005
1128
|
// "fromBlock" gets correctly trimmed to range and "toBlock" is exclusive
|
|
1006
|
-
logs = (await store.getPublicLogs({ fromBlock: -10, toBlock: 5 })).logs;
|
|
1129
|
+
logs = (await store.getPublicLogs({ fromBlock: -10 as BlockNumber, toBlock: BlockNumber(5) })).logs;
|
|
1007
1130
|
let blockNumbers = new Set(logs.map(log => log.id.blockNumber));
|
|
1008
1131
|
expect(blockNumbers).toEqual(new Set([1, 2, 3, 4]));
|
|
1009
1132
|
|
|
1010
1133
|
// "toBlock" should be exclusive
|
|
1011
|
-
logs = (await store.getPublicLogs({ fromBlock: 1, toBlock: 1 })).logs;
|
|
1134
|
+
logs = (await store.getPublicLogs({ fromBlock: BlockNumber(1), toBlock: BlockNumber(1) })).logs;
|
|
1012
1135
|
expect(logs.length).toBe(0);
|
|
1013
1136
|
|
|
1014
|
-
logs = (await store.getPublicLogs({ fromBlock: 10, toBlock: 5 })).logs;
|
|
1137
|
+
logs = (await store.getPublicLogs({ fromBlock: BlockNumber(10), toBlock: BlockNumber(5) })).logs;
|
|
1015
1138
|
expect(logs.length).toBe(0);
|
|
1016
1139
|
|
|
1017
1140
|
// both "fromBlock" and "toBlock" get correctly capped to range and logs from all blocks are returned
|
|
1018
|
-
logs = (await store.getPublicLogs({ fromBlock: -100, toBlock: +100 })).logs;
|
|
1141
|
+
logs = (await store.getPublicLogs({ fromBlock: -100 as BlockNumber, toBlock: +100 })).logs;
|
|
1019
1142
|
blockNumbers = new Set(logs.map(log => log.id.blockNumber));
|
|
1020
1143
|
expect(blockNumbers.size).toBe(numBlocks);
|
|
1021
1144
|
|
|
1022
1145
|
// intersecting with "afterLog" works
|
|
1023
|
-
logs = (
|
|
1146
|
+
logs = (
|
|
1147
|
+
await store.getPublicLogs({
|
|
1148
|
+
fromBlock: BlockNumber(2),
|
|
1149
|
+
toBlock: BlockNumber(5),
|
|
1150
|
+
afterLog: new LogId(BlockNumber(4), 0, 0),
|
|
1151
|
+
})
|
|
1152
|
+
).logs;
|
|
1024
1153
|
blockNumbers = new Set(logs.map(log => log.id.blockNumber));
|
|
1025
1154
|
expect(blockNumbers).toEqual(new Set([4]));
|
|
1026
1155
|
|
|
1027
|
-
logs = (await store.getPublicLogs({ toBlock: 5, afterLog: new LogId(5, 1, 0) })).logs;
|
|
1156
|
+
logs = (await store.getPublicLogs({ toBlock: BlockNumber(5), afterLog: new LogId(BlockNumber(5), 1, 0) })).logs;
|
|
1028
1157
|
expect(logs.length).toBe(0);
|
|
1029
1158
|
|
|
1030
|
-
logs = (
|
|
1159
|
+
logs = (
|
|
1160
|
+
await store.getPublicLogs({
|
|
1161
|
+
fromBlock: BlockNumber(2),
|
|
1162
|
+
toBlock: BlockNumber(5),
|
|
1163
|
+
afterLog: new LogId(BlockNumber(100), 0, 0),
|
|
1164
|
+
})
|
|
1165
|
+
).logs;
|
|
1031
1166
|
expect(logs.length).toBe(0);
|
|
1032
1167
|
});
|
|
1033
1168
|
|
|
@@ -1037,7 +1172,7 @@ export function describeArchiverDataStore(
|
|
|
1037
1172
|
const targetTxIndex = randomInt(txsPerBlock);
|
|
1038
1173
|
const targetLogIndex = randomInt(numPublicLogs);
|
|
1039
1174
|
|
|
1040
|
-
const afterLog = new LogId(targetBlockIndex + INITIAL_L2_BLOCK_NUM, targetTxIndex, targetLogIndex);
|
|
1175
|
+
const afterLog = new LogId(BlockNumber(targetBlockIndex + INITIAL_L2_BLOCK_NUM), targetTxIndex, targetLogIndex);
|
|
1041
1176
|
|
|
1042
1177
|
const response = await store.getPublicLogs({ afterLog, fromBlock: afterLog.blockNumber });
|
|
1043
1178
|
const logs = response.logs;
|
|
@@ -1056,5 +1191,96 @@ export function describeArchiverDataStore(
|
|
|
1056
1191
|
}
|
|
1057
1192
|
});
|
|
1058
1193
|
});
|
|
1194
|
+
|
|
1195
|
+
describe('pendingChainValidationStatus', () => {
|
|
1196
|
+
it('should return undefined when no status is set', async () => {
|
|
1197
|
+
const status = await store.getPendingChainValidationStatus();
|
|
1198
|
+
expect(status).toBeUndefined();
|
|
1199
|
+
});
|
|
1200
|
+
|
|
1201
|
+
it('should store and retrieve a valid validation status', async () => {
|
|
1202
|
+
const validStatus: ValidateBlockResult = { valid: true };
|
|
1203
|
+
|
|
1204
|
+
await store.setPendingChainValidationStatus(validStatus);
|
|
1205
|
+
const retrievedStatus = await store.getPendingChainValidationStatus();
|
|
1206
|
+
|
|
1207
|
+
expect(retrievedStatus).toEqual(validStatus);
|
|
1208
|
+
});
|
|
1209
|
+
|
|
1210
|
+
it('should store and retrieve an invalid validation status with insufficient attestations', async () => {
|
|
1211
|
+
const invalidStatus: ValidateBlockResult = {
|
|
1212
|
+
valid: false,
|
|
1213
|
+
block: randomBlockInfo(1),
|
|
1214
|
+
committee: [EthAddress.random(), EthAddress.random()],
|
|
1215
|
+
epoch: EpochNumber(123),
|
|
1216
|
+
seed: 456n,
|
|
1217
|
+
attestors: [EthAddress.random()],
|
|
1218
|
+
attestations: [CommitteeAttestation.random()],
|
|
1219
|
+
reason: 'insufficient-attestations',
|
|
1220
|
+
};
|
|
1221
|
+
|
|
1222
|
+
await store.setPendingChainValidationStatus(invalidStatus);
|
|
1223
|
+
const retrievedStatus = await store.getPendingChainValidationStatus();
|
|
1224
|
+
|
|
1225
|
+
expect(retrievedStatus).toEqual(invalidStatus);
|
|
1226
|
+
});
|
|
1227
|
+
|
|
1228
|
+
it('should store and retrieve an invalid validation status with invalid attestation', async () => {
|
|
1229
|
+
const invalidStatus: ValidateBlockResult = {
|
|
1230
|
+
valid: false,
|
|
1231
|
+
block: randomBlockInfo(2),
|
|
1232
|
+
committee: [EthAddress.random()],
|
|
1233
|
+
attestors: [EthAddress.random()],
|
|
1234
|
+
epoch: EpochNumber(789),
|
|
1235
|
+
seed: 101n,
|
|
1236
|
+
attestations: [CommitteeAttestation.random()],
|
|
1237
|
+
reason: 'invalid-attestation',
|
|
1238
|
+
invalidIndex: 5,
|
|
1239
|
+
};
|
|
1240
|
+
|
|
1241
|
+
await store.setPendingChainValidationStatus(invalidStatus);
|
|
1242
|
+
const retrievedStatus = await store.getPendingChainValidationStatus();
|
|
1243
|
+
|
|
1244
|
+
expect(retrievedStatus).toEqual(invalidStatus);
|
|
1245
|
+
});
|
|
1246
|
+
|
|
1247
|
+
it('should overwrite existing status when setting a new one', async () => {
|
|
1248
|
+
const firstStatus: ValidateBlockResult = { valid: true };
|
|
1249
|
+
const secondStatus: ValidateBlockResult = {
|
|
1250
|
+
valid: false,
|
|
1251
|
+
block: randomBlockInfo(3),
|
|
1252
|
+
committee: [EthAddress.random()],
|
|
1253
|
+
epoch: EpochNumber(999),
|
|
1254
|
+
seed: 888n,
|
|
1255
|
+
attestors: [EthAddress.random()],
|
|
1256
|
+
attestations: [CommitteeAttestation.random()],
|
|
1257
|
+
reason: 'insufficient-attestations',
|
|
1258
|
+
};
|
|
1259
|
+
|
|
1260
|
+
await store.setPendingChainValidationStatus(firstStatus);
|
|
1261
|
+
await store.setPendingChainValidationStatus(secondStatus);
|
|
1262
|
+
const retrievedStatus = await store.getPendingChainValidationStatus();
|
|
1263
|
+
|
|
1264
|
+
expect(retrievedStatus).toEqual(secondStatus);
|
|
1265
|
+
});
|
|
1266
|
+
|
|
1267
|
+
it('should handle empty committee and attestations arrays', async () => {
|
|
1268
|
+
const statusWithEmptyArrays: ValidateBlockResult = {
|
|
1269
|
+
valid: false,
|
|
1270
|
+
block: randomBlockInfo(4),
|
|
1271
|
+
committee: [],
|
|
1272
|
+
epoch: EpochNumber(0),
|
|
1273
|
+
seed: 0n,
|
|
1274
|
+
attestors: [],
|
|
1275
|
+
attestations: [],
|
|
1276
|
+
reason: 'insufficient-attestations',
|
|
1277
|
+
};
|
|
1278
|
+
|
|
1279
|
+
await store.setPendingChainValidationStatus(statusWithEmptyArrays);
|
|
1280
|
+
const retrievedStatus = await store.getPendingChainValidationStatus();
|
|
1281
|
+
|
|
1282
|
+
expect(retrievedStatus).toEqual(statusWithEmptyArrays);
|
|
1283
|
+
});
|
|
1284
|
+
});
|
|
1059
1285
|
});
|
|
1060
1286
|
}
|