@aztec/archiver 0.0.0-test.1 → 0.0.1-commit.5476d83
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 +147 -57
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +841 -333
- package/dest/archiver/archiver_store.d.ts +85 -50
- 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 +708 -213
- package/dest/archiver/config.d.ts +5 -21
- package/dest/archiver/config.d.ts.map +1 -1
- package/dest/archiver/config.js +21 -12
- package/dest/archiver/data_retrieval.d.ts +32 -27
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +197 -94
- package/dest/archiver/errors.d.ts +9 -1
- package/dest/archiver/errors.d.ts.map +1 -1
- package/dest/archiver/errors.js +12 -0
- package/dest/archiver/index.d.ts +3 -4
- package/dest/archiver/index.d.ts.map +1 -1
- package/dest/archiver/index.js +1 -2
- package/dest/archiver/instrumentation.d.ts +12 -6
- package/dest/archiver/instrumentation.d.ts.map +1 -1
- package/dest/archiver/instrumentation.js +58 -17
- package/dest/archiver/kv_archiver_store/block_store.d.ts +48 -11
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +216 -63
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +3 -3
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.js +12 -18
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +11 -8
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.js +30 -16
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +50 -35
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +88 -46
- package/dest/archiver/kv_archiver_store/log_store.d.ts +2 -2
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +18 -46
- package/dest/archiver/kv_archiver_store/message_store.d.ts +23 -17
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +150 -48
- package/dest/archiver/structs/data_retrieval.d.ts +1 -1
- package/dest/archiver/structs/inbox_message.d.ts +15 -0
- package/dest/archiver/structs/inbox_message.d.ts.map +1 -0
- package/dest/archiver/structs/inbox_message.js +38 -0
- package/dest/archiver/structs/published.d.ts +3 -11
- package/dest/archiver/structs/published.d.ts.map +1 -1
- package/dest/archiver/structs/published.js +1 -1
- package/dest/archiver/validation.d.ts +17 -0
- package/dest/archiver/validation.d.ts.map +1 -0
- package/dest/archiver/validation.js +98 -0
- package/dest/factory.d.ts +8 -13
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +18 -49
- 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 -3
- package/dest/rpc/index.d.ts.map +1 -1
- package/dest/rpc/index.js +1 -4
- package/dest/test/index.d.ts +1 -1
- package/dest/test/mock_archiver.d.ts +2 -2
- package/dest/test/mock_archiver.d.ts.map +1 -1
- package/dest/test/mock_l1_to_l2_message_source.d.ts +5 -3
- package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
- package/dest/test/mock_l1_to_l2_message_source.js +14 -1
- package/dest/test/mock_l2_block_source.d.ts +38 -10
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +119 -8
- package/dest/test/mock_structs.d.ts +9 -0
- package/dest/test/mock_structs.d.ts.map +1 -0
- package/dest/test/mock_structs.js +37 -0
- package/package.json +28 -30
- package/src/archiver/archiver.ts +1087 -410
- package/src/archiver/archiver_store.ts +97 -55
- package/src/archiver/archiver_store_test_suite.ts +664 -210
- package/src/archiver/config.ts +28 -41
- package/src/archiver/data_retrieval.ts +279 -125
- package/src/archiver/errors.ts +21 -0
- package/src/archiver/index.ts +2 -3
- package/src/archiver/instrumentation.ts +77 -22
- package/src/archiver/kv_archiver_store/block_store.ts +270 -72
- package/src/archiver/kv_archiver_store/contract_class_store.ts +13 -23
- package/src/archiver/kv_archiver_store/contract_instance_store.ts +35 -27
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +127 -63
- package/src/archiver/kv_archiver_store/log_store.ts +24 -62
- package/src/archiver/kv_archiver_store/message_store.ts +209 -53
- package/src/archiver/structs/inbox_message.ts +41 -0
- package/src/archiver/structs/published.ts +2 -11
- package/src/archiver/validation.ts +124 -0
- package/src/factory.ts +24 -66
- package/src/index.ts +1 -1
- package/src/rpc/index.ts +1 -5
- package/src/test/mock_archiver.ts +1 -1
- package/src/test/mock_l1_to_l2_message_source.ts +14 -3
- package/src/test/mock_l2_block_source.ts +158 -13
- package/src/test/mock_structs.ts +49 -0
- package/dest/archiver/kv_archiver_store/nullifier_store.d.ts +0 -12
- package/dest/archiver/kv_archiver_store/nullifier_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/nullifier_store.js +0 -73
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +0 -23
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +0 -1
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +0 -49
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +0 -175
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +0 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +0 -636
- package/src/archiver/kv_archiver_store/nullifier_store.ts +0 -97
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +0 -61
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +0 -801
|
@@ -1,15 +1,23 @@
|
|
|
1
|
-
import { INITIAL_L2_BLOCK_NUM,
|
|
1
|
+
import { INITIAL_L2_BLOCK_NUM, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, PRIVATE_LOG_SIZE_IN_FIELDS } from '@aztec/constants';
|
|
2
|
+
import { makeTuple } from '@aztec/foundation/array';
|
|
3
|
+
import { EpochNumber } from '@aztec/foundation/branded-types';
|
|
4
|
+
import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
|
|
2
5
|
import { times, timesParallel } from '@aztec/foundation/collection';
|
|
3
6
|
import { randomInt } from '@aztec/foundation/crypto';
|
|
4
7
|
import { Fr } from '@aztec/foundation/fields';
|
|
8
|
+
import { toArray } from '@aztec/foundation/iterable';
|
|
9
|
+
import { sleep } from '@aztec/foundation/sleep';
|
|
5
10
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
6
|
-
import { L2Block, wrapInBlock } from '@aztec/stdlib/block';
|
|
11
|
+
import { CommitteeAttestation, EthAddress, L2Block, L2BlockHash, PublishedL2Block, randomBlockInfo, wrapInBlock } from '@aztec/stdlib/block';
|
|
7
12
|
import { SerializableContractInstance, computePublicBytecodeCommitment } from '@aztec/stdlib/contract';
|
|
8
13
|
import { LogId, PrivateLog, PublicLog } from '@aztec/stdlib/logs';
|
|
9
14
|
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
10
|
-
import { makeContractClassPublic, makeExecutablePrivateFunctionWithMembershipProof,
|
|
15
|
+
import { makeContractClassPublic, makeExecutablePrivateFunctionWithMembershipProof, makeUtilityFunctionWithMembershipProof } from '@aztec/stdlib/testing';
|
|
11
16
|
import '@aztec/stdlib/testing/jest';
|
|
12
17
|
import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
18
|
+
import { makeInboxMessage, makeInboxMessages } from '../test/mock_structs.js';
|
|
19
|
+
import { BlockNumberNotSequentialError, InitialBlockNumberNotSequentialError } from './errors.js';
|
|
20
|
+
import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
13
21
|
/**
|
|
14
22
|
* @param testName - The name of the test suite.
|
|
15
23
|
* @param getStore - Returns an instance of a store that's already been initialized.
|
|
@@ -44,17 +52,29 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
44
52
|
()=>blocks.slice(4, 6)
|
|
45
53
|
]
|
|
46
54
|
];
|
|
47
|
-
const
|
|
48
|
-
|
|
55
|
+
const makeBlockHash = (blockNumber)=>`0x${blockNumber.toString(16).padStart(64, '0')}`;
|
|
56
|
+
const makePublished = (block, l1BlockNumber)=>PublishedL2Block.fromFields({
|
|
57
|
+
block: block,
|
|
49
58
|
l1: {
|
|
50
59
|
blockNumber: BigInt(l1BlockNumber),
|
|
51
|
-
blockHash:
|
|
60
|
+
blockHash: makeBlockHash(l1BlockNumber),
|
|
52
61
|
timestamp: BigInt(l1BlockNumber * 1000)
|
|
53
|
-
}
|
|
62
|
+
},
|
|
63
|
+
attestations: times(3, CommitteeAttestation.random)
|
|
54
64
|
});
|
|
65
|
+
const expectBlocksEqual = (actual, expected)=>{
|
|
66
|
+
expect(actual.length).toEqual(expected.length);
|
|
67
|
+
for(let i = 0; i < expected.length; i++){
|
|
68
|
+
const expectedBlock = expected[i];
|
|
69
|
+
const actualBlock = actual[i];
|
|
70
|
+
expect(actualBlock.l1).toEqual(expectedBlock.l1);
|
|
71
|
+
expect(actualBlock.block.equals(expectedBlock.block)).toBe(true);
|
|
72
|
+
expect(actualBlock.attestations.every((a, i)=>a.equals(expectedBlock.attestations[i]))).toBe(true);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
55
75
|
beforeEach(async ()=>{
|
|
56
76
|
store = await getStore();
|
|
57
|
-
blocks = await timesParallel(10, async (i)=>
|
|
77
|
+
blocks = await timesParallel(10, async (i)=>makePublished(await L2Block.random(i + 1), i + 10));
|
|
58
78
|
});
|
|
59
79
|
describe('addBlocks', ()=>{
|
|
60
80
|
it('returns success when adding blocks', async ()=>{
|
|
@@ -64,25 +84,40 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
64
84
|
await store.addBlocks(blocks);
|
|
65
85
|
await expect(store.addBlocks(blocks)).resolves.toBe(true);
|
|
66
86
|
});
|
|
87
|
+
it('throws an error if the previous block does not exist in the store', async ()=>{
|
|
88
|
+
const block = makePublished(await L2Block.random(2), 2);
|
|
89
|
+
await expect(store.addBlocks([
|
|
90
|
+
block
|
|
91
|
+
])).rejects.toThrow(InitialBlockNumberNotSequentialError);
|
|
92
|
+
await expect(store.getPublishedBlocks(1, 10)).resolves.toEqual([]);
|
|
93
|
+
});
|
|
94
|
+
it('throws an error if there is a gap in the blocks being added', async ()=>{
|
|
95
|
+
const blocks = [
|
|
96
|
+
makePublished(await L2Block.random(1), 1),
|
|
97
|
+
makePublished(await L2Block.random(3), 3)
|
|
98
|
+
];
|
|
99
|
+
await expect(store.addBlocks(blocks)).rejects.toThrow(BlockNumberNotSequentialError);
|
|
100
|
+
await expect(store.getPublishedBlocks(1, 10)).resolves.toEqual([]);
|
|
101
|
+
});
|
|
67
102
|
});
|
|
68
103
|
describe('unwindBlocks', ()=>{
|
|
69
104
|
it('unwinding blocks will remove blocks from the chain', async ()=>{
|
|
70
105
|
await store.addBlocks(blocks);
|
|
71
106
|
const blockNumber = await store.getSynchedL2BlockNumber();
|
|
72
|
-
|
|
107
|
+
expectBlocksEqual(await store.getPublishedBlocks(blockNumber, 1), [
|
|
73
108
|
blocks[blocks.length - 1]
|
|
74
109
|
]);
|
|
75
110
|
await store.unwindBlocks(blockNumber, 1);
|
|
76
111
|
expect(await store.getSynchedL2BlockNumber()).toBe(blockNumber - 1);
|
|
77
|
-
expect(await store.
|
|
112
|
+
expect(await store.getPublishedBlocks(blockNumber, 1)).toEqual([]);
|
|
78
113
|
});
|
|
79
114
|
it('can unwind multiple empty blocks', async ()=>{
|
|
80
|
-
const emptyBlocks = await timesParallel(10, async (i)=>
|
|
115
|
+
const emptyBlocks = await timesParallel(10, async (i)=>makePublished(await L2Block.random(i + 1, 0), i + 10));
|
|
81
116
|
await store.addBlocks(emptyBlocks);
|
|
82
117
|
expect(await store.getSynchedL2BlockNumber()).toBe(10);
|
|
83
118
|
await store.unwindBlocks(10, 3);
|
|
84
119
|
expect(await store.getSynchedL2BlockNumber()).toBe(7);
|
|
85
|
-
expect((await store.
|
|
120
|
+
expect((await store.getPublishedBlocks(1, 10)).map((b)=>b.block.number)).toEqual([
|
|
86
121
|
1,
|
|
87
122
|
2,
|
|
88
123
|
3,
|
|
@@ -96,22 +131,129 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
96
131
|
await store.addBlocks(blocks);
|
|
97
132
|
await expect(store.unwindBlocks(5, 1)).rejects.toThrow(/can only unwind blocks from the tip/i);
|
|
98
133
|
});
|
|
134
|
+
it('unwound blocks and headers cannot be retrieved by hash or archive', async ()=>{
|
|
135
|
+
await store.addBlocks(blocks);
|
|
136
|
+
const lastBlock = blocks[blocks.length - 1];
|
|
137
|
+
const blockHash = await lastBlock.block.hash();
|
|
138
|
+
const archive = lastBlock.block.archive.root;
|
|
139
|
+
// Verify block and header exist before unwinding
|
|
140
|
+
expect(await store.getPublishedBlockByHash(blockHash)).toBeDefined();
|
|
141
|
+
expect(await store.getPublishedBlockByArchive(archive)).toBeDefined();
|
|
142
|
+
expect(await store.getBlockHeaderByHash(blockHash)).toBeDefined();
|
|
143
|
+
expect(await store.getBlockHeaderByArchive(archive)).toBeDefined();
|
|
144
|
+
// Unwind the block
|
|
145
|
+
await store.unwindBlocks(lastBlock.block.number, 1);
|
|
146
|
+
// Verify neither block nor header can be retrieved after unwinding
|
|
147
|
+
expect(await store.getPublishedBlockByHash(blockHash)).toBeUndefined();
|
|
148
|
+
expect(await store.getPublishedBlockByArchive(archive)).toBeUndefined();
|
|
149
|
+
expect(await store.getBlockHeaderByHash(blockHash)).toBeUndefined();
|
|
150
|
+
expect(await store.getBlockHeaderByArchive(archive)).toBeUndefined();
|
|
151
|
+
});
|
|
99
152
|
});
|
|
100
153
|
describe('getBlocks', ()=>{
|
|
101
154
|
beforeEach(async ()=>{
|
|
102
155
|
await store.addBlocks(blocks);
|
|
103
156
|
});
|
|
104
157
|
it.each(blockTests)('retrieves previously stored blocks', async (start, limit, getExpectedBlocks)=>{
|
|
105
|
-
await
|
|
158
|
+
expectBlocksEqual(await store.getPublishedBlocks(start, limit), getExpectedBlocks());
|
|
106
159
|
});
|
|
107
160
|
it('returns an empty array if no blocks are found', async ()=>{
|
|
108
|
-
await expect(store.
|
|
161
|
+
await expect(store.getPublishedBlocks(12, 1)).resolves.toEqual([]);
|
|
109
162
|
});
|
|
110
163
|
it('throws an error if limit is invalid', async ()=>{
|
|
111
|
-
await expect(store.
|
|
164
|
+
await expect(store.getPublishedBlocks(1, 0)).rejects.toThrow('Invalid limit: 0');
|
|
112
165
|
});
|
|
113
166
|
it('throws an error if `from` it is out of range', async ()=>{
|
|
114
|
-
await expect(store.
|
|
167
|
+
await expect(store.getPublishedBlocks(INITIAL_L2_BLOCK_NUM - 100, 1)).rejects.toThrow('Invalid start: -99');
|
|
168
|
+
});
|
|
169
|
+
it('throws an error if unexpected initial block number is found', async ()=>{
|
|
170
|
+
await store.addBlocks([
|
|
171
|
+
makePublished(await L2Block.random(21), 31)
|
|
172
|
+
], {
|
|
173
|
+
force: true
|
|
174
|
+
});
|
|
175
|
+
await expect(store.getPublishedBlocks(20, 1)).rejects.toThrow(`mismatch`);
|
|
176
|
+
});
|
|
177
|
+
it('throws an error if a gap is found', async ()=>{
|
|
178
|
+
await store.addBlocks([
|
|
179
|
+
makePublished(await L2Block.random(20), 30),
|
|
180
|
+
makePublished(await L2Block.random(22), 32)
|
|
181
|
+
], {
|
|
182
|
+
force: true
|
|
183
|
+
});
|
|
184
|
+
await expect(store.getPublishedBlocks(20, 2)).rejects.toThrow(`mismatch`);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
describe('getPublishedBlockByHash', ()=>{
|
|
188
|
+
beforeEach(async ()=>{
|
|
189
|
+
await store.addBlocks(blocks);
|
|
190
|
+
});
|
|
191
|
+
it('retrieves a block by its hash', async ()=>{
|
|
192
|
+
const expectedBlock = blocks[5];
|
|
193
|
+
const blockHash = await expectedBlock.block.hash();
|
|
194
|
+
const retrievedBlock = await store.getPublishedBlockByHash(blockHash);
|
|
195
|
+
expect(retrievedBlock).toBeDefined();
|
|
196
|
+
expectBlocksEqual([
|
|
197
|
+
retrievedBlock
|
|
198
|
+
], [
|
|
199
|
+
expectedBlock
|
|
200
|
+
]);
|
|
201
|
+
});
|
|
202
|
+
it('returns undefined for non-existent block hash', async ()=>{
|
|
203
|
+
const nonExistentHash = Fr.random();
|
|
204
|
+
await expect(store.getPublishedBlockByHash(nonExistentHash)).resolves.toBeUndefined();
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
describe('getPublishedBlockByArchive', ()=>{
|
|
208
|
+
beforeEach(async ()=>{
|
|
209
|
+
await store.addBlocks(blocks);
|
|
210
|
+
});
|
|
211
|
+
it('retrieves a block by its archive root', async ()=>{
|
|
212
|
+
const expectedBlock = blocks[3];
|
|
213
|
+
const archive = expectedBlock.block.archive.root;
|
|
214
|
+
const retrievedBlock = await store.getPublishedBlockByArchive(archive);
|
|
215
|
+
expect(retrievedBlock).toBeDefined();
|
|
216
|
+
expectBlocksEqual([
|
|
217
|
+
retrievedBlock
|
|
218
|
+
], [
|
|
219
|
+
expectedBlock
|
|
220
|
+
]);
|
|
221
|
+
});
|
|
222
|
+
it('returns undefined for non-existent archive root', async ()=>{
|
|
223
|
+
const nonExistentArchive = Fr.random();
|
|
224
|
+
await expect(store.getPublishedBlockByArchive(nonExistentArchive)).resolves.toBeUndefined();
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
describe('getBlockHeaderByHash', ()=>{
|
|
228
|
+
beforeEach(async ()=>{
|
|
229
|
+
await store.addBlocks(blocks);
|
|
230
|
+
});
|
|
231
|
+
it('retrieves a block header by its hash', async ()=>{
|
|
232
|
+
const expectedBlock = blocks[7];
|
|
233
|
+
const blockHash = await expectedBlock.block.hash();
|
|
234
|
+
const retrievedHeader = await store.getBlockHeaderByHash(blockHash);
|
|
235
|
+
expect(retrievedHeader).toBeDefined();
|
|
236
|
+
expect(retrievedHeader.equals(expectedBlock.block.getBlockHeader())).toBe(true);
|
|
237
|
+
});
|
|
238
|
+
it('returns undefined for non-existent block hash', async ()=>{
|
|
239
|
+
const nonExistentHash = Fr.random();
|
|
240
|
+
await expect(store.getBlockHeaderByHash(nonExistentHash)).resolves.toBeUndefined();
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
describe('getBlockHeaderByArchive', ()=>{
|
|
244
|
+
beforeEach(async ()=>{
|
|
245
|
+
await store.addBlocks(blocks);
|
|
246
|
+
});
|
|
247
|
+
it('retrieves a block header by its archive root', async ()=>{
|
|
248
|
+
const expectedBlock = blocks[2];
|
|
249
|
+
const archive = expectedBlock.block.archive.root;
|
|
250
|
+
const retrievedHeader = await store.getBlockHeaderByArchive(archive);
|
|
251
|
+
expect(retrievedHeader).toBeDefined();
|
|
252
|
+
expect(retrievedHeader.equals(expectedBlock.block.getBlockHeader())).toBe(true);
|
|
253
|
+
});
|
|
254
|
+
it('returns undefined for non-existent archive root', async ()=>{
|
|
255
|
+
const nonExistentArchive = Fr.random();
|
|
256
|
+
await expect(store.getBlockHeaderByArchive(nonExistentArchive)).resolves.toBeUndefined();
|
|
115
257
|
});
|
|
116
258
|
});
|
|
117
259
|
describe('getSyncedL2BlockNumber', ()=>{
|
|
@@ -120,7 +262,7 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
120
262
|
});
|
|
121
263
|
it("returns the most recently added block's number", async ()=>{
|
|
122
264
|
await store.addBlocks(blocks);
|
|
123
|
-
await expect(store.getSynchedL2BlockNumber()).resolves.toEqual(blocks.at(-1).
|
|
265
|
+
await expect(store.getSynchedL2BlockNumber()).resolves.toEqual(blocks.at(-1).block.number);
|
|
124
266
|
});
|
|
125
267
|
});
|
|
126
268
|
describe('getSynchPoint', ()=>{
|
|
@@ -138,21 +280,52 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
138
280
|
});
|
|
139
281
|
});
|
|
140
282
|
it('returns the L1 block number that most recently added messages from inbox', async ()=>{
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
283
|
+
const l1BlockHash = Buffer32.random();
|
|
284
|
+
const l1BlockNumber = 10n;
|
|
285
|
+
await store.setMessageSynchedL1Block({
|
|
286
|
+
l1BlockNumber: 5n,
|
|
287
|
+
l1BlockHash: Buffer32.random()
|
|
146
288
|
});
|
|
289
|
+
await store.addL1ToL2Messages([
|
|
290
|
+
makeInboxMessage(Buffer16.ZERO, {
|
|
291
|
+
l1BlockNumber,
|
|
292
|
+
l1BlockHash
|
|
293
|
+
})
|
|
294
|
+
]);
|
|
147
295
|
await expect(store.getSynchPoint()).resolves.toEqual({
|
|
148
296
|
blocksSynchedTo: undefined,
|
|
149
|
-
messagesSynchedTo:
|
|
297
|
+
messagesSynchedTo: {
|
|
298
|
+
l1BlockHash,
|
|
299
|
+
l1BlockNumber
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
it('returns the latest syncpoint if latest message is behind', async ()=>{
|
|
304
|
+
const l1BlockHash = Buffer32.random();
|
|
305
|
+
const l1BlockNumber = 10n;
|
|
306
|
+
await store.setMessageSynchedL1Block({
|
|
307
|
+
l1BlockNumber,
|
|
308
|
+
l1BlockHash
|
|
309
|
+
});
|
|
310
|
+
const msg = makeInboxMessage(Buffer16.ZERO, {
|
|
311
|
+
l1BlockNumber: 5n,
|
|
312
|
+
l1BlockHash: Buffer32.random()
|
|
313
|
+
});
|
|
314
|
+
await store.addL1ToL2Messages([
|
|
315
|
+
msg
|
|
316
|
+
]);
|
|
317
|
+
await expect(store.getSynchPoint()).resolves.toEqual({
|
|
318
|
+
blocksSynchedTo: undefined,
|
|
319
|
+
messagesSynchedTo: {
|
|
320
|
+
l1BlockHash,
|
|
321
|
+
l1BlockNumber
|
|
322
|
+
}
|
|
150
323
|
});
|
|
151
324
|
});
|
|
152
325
|
});
|
|
153
326
|
describe('addLogs', ()=>{
|
|
154
327
|
it('adds private & public logs', async ()=>{
|
|
155
|
-
const block = blocks[0].
|
|
328
|
+
const block = blocks[0].block;
|
|
156
329
|
await expect(store.addLogs([
|
|
157
330
|
block
|
|
158
331
|
])).resolves.toEqual(true);
|
|
@@ -160,7 +333,7 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
160
333
|
});
|
|
161
334
|
describe('deleteLogs', ()=>{
|
|
162
335
|
it('deletes private & public logs', async ()=>{
|
|
163
|
-
const block = blocks[0].
|
|
336
|
+
const block = blocks[0].block;
|
|
164
337
|
await store.addBlocks([
|
|
165
338
|
blocks[0]
|
|
166
339
|
]);
|
|
@@ -183,7 +356,7 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
183
356
|
});
|
|
184
357
|
describe('getPrivateLogs', ()=>{
|
|
185
358
|
it('gets added private logs', async ()=>{
|
|
186
|
-
const block = blocks[0].
|
|
359
|
+
const block = blocks[0].block;
|
|
187
360
|
await store.addBlocks([
|
|
188
361
|
blocks[0]
|
|
189
362
|
]);
|
|
@@ -196,29 +369,55 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
196
369
|
});
|
|
197
370
|
describe('getTxEffect', ()=>{
|
|
198
371
|
beforeEach(async ()=>{
|
|
199
|
-
await store.addLogs(blocks.map((b)=>b.
|
|
372
|
+
await store.addLogs(blocks.map((b)=>b.block));
|
|
200
373
|
await store.addBlocks(blocks);
|
|
201
374
|
});
|
|
202
375
|
it.each([
|
|
203
|
-
()=>
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
376
|
+
()=>({
|
|
377
|
+
data: blocks[0].block.body.txEffects[0],
|
|
378
|
+
block: blocks[0].block,
|
|
379
|
+
txIndexInBlock: 0
|
|
380
|
+
}),
|
|
381
|
+
()=>({
|
|
382
|
+
data: blocks[9].block.body.txEffects[3],
|
|
383
|
+
block: blocks[9].block,
|
|
384
|
+
txIndexInBlock: 3
|
|
385
|
+
}),
|
|
386
|
+
()=>({
|
|
387
|
+
data: blocks[3].block.body.txEffects[1],
|
|
388
|
+
block: blocks[3].block,
|
|
389
|
+
txIndexInBlock: 1
|
|
390
|
+
}),
|
|
391
|
+
()=>({
|
|
392
|
+
data: blocks[5].block.body.txEffects[2],
|
|
393
|
+
block: blocks[5].block,
|
|
394
|
+
txIndexInBlock: 2
|
|
395
|
+
}),
|
|
396
|
+
()=>({
|
|
397
|
+
data: blocks[1].block.body.txEffects[0],
|
|
398
|
+
block: blocks[1].block,
|
|
399
|
+
txIndexInBlock: 0
|
|
400
|
+
})
|
|
208
401
|
])('retrieves a previously stored transaction', async (getExpectedTx)=>{
|
|
209
|
-
const
|
|
210
|
-
const
|
|
402
|
+
const { data, block, txIndexInBlock } = getExpectedTx();
|
|
403
|
+
const expectedTx = {
|
|
404
|
+
data,
|
|
405
|
+
l2BlockNumber: block.number,
|
|
406
|
+
l2BlockHash: L2BlockHash.fromField(await block.hash()),
|
|
407
|
+
txIndexInBlock
|
|
408
|
+
};
|
|
409
|
+
const actualTx = await store.getTxEffect(data.txHash);
|
|
211
410
|
expect(actualTx).toEqual(expectedTx);
|
|
212
411
|
});
|
|
213
412
|
it('returns undefined if tx is not found', async ()=>{
|
|
214
413
|
await expect(store.getTxEffect(TxHash.random())).resolves.toBeUndefined();
|
|
215
414
|
});
|
|
216
415
|
it.each([
|
|
217
|
-
()=>wrapInBlock(blocks[0].
|
|
218
|
-
()=>wrapInBlock(blocks[9].
|
|
219
|
-
()=>wrapInBlock(blocks[3].
|
|
220
|
-
()=>wrapInBlock(blocks[5].
|
|
221
|
-
()=>wrapInBlock(blocks[1].
|
|
416
|
+
()=>wrapInBlock(blocks[0].block.body.txEffects[0], blocks[0].block),
|
|
417
|
+
()=>wrapInBlock(blocks[9].block.body.txEffects[3], blocks[9].block),
|
|
418
|
+
()=>wrapInBlock(blocks[3].block.body.txEffects[1], blocks[3].block),
|
|
419
|
+
()=>wrapInBlock(blocks[5].block.body.txEffects[2], blocks[5].block),
|
|
420
|
+
()=>wrapInBlock(blocks[1].block.body.txEffects[0], blocks[1].block)
|
|
222
421
|
])('tries to retrieves a previously stored transaction after deleted', async (getExpectedTx)=>{
|
|
223
422
|
await store.unwindBlocks(blocks.length, blocks.length);
|
|
224
423
|
const expectedTx = await getExpectedTx();
|
|
@@ -228,42 +427,245 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
228
427
|
it('returns undefined if tx is not found', async ()=>{
|
|
229
428
|
await expect(store.getTxEffect(TxHash.random())).resolves.toBeUndefined();
|
|
230
429
|
});
|
|
430
|
+
it('does not fail if the block is unwound while requesting a tx', async ()=>{
|
|
431
|
+
const expectedTx = await wrapInBlock(blocks[1].block.body.txEffects[0], blocks[1].block);
|
|
432
|
+
let done = false;
|
|
433
|
+
void (async ()=>{
|
|
434
|
+
while(!done){
|
|
435
|
+
void store.getTxEffect(expectedTx.data.txHash);
|
|
436
|
+
await sleep(1);
|
|
437
|
+
}
|
|
438
|
+
})();
|
|
439
|
+
await store.unwindBlocks(blocks.length, blocks.length);
|
|
440
|
+
done = true;
|
|
441
|
+
expect(await store.getTxEffect(expectedTx.data.txHash)).toEqual(undefined);
|
|
442
|
+
});
|
|
231
443
|
});
|
|
232
444
|
describe('L1 to L2 Messages', ()=>{
|
|
233
|
-
const
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
await store.addL1ToL2Messages(
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
445
|
+
const initialL2BlockNumber = 13;
|
|
446
|
+
const checkMessages = async (msgs)=>{
|
|
447
|
+
expect(await store.getLastL1ToL2Message()).toEqual(msgs.at(-1));
|
|
448
|
+
expect(await toArray(store.iterateL1ToL2Messages())).toEqual(msgs);
|
|
449
|
+
expect(await store.getTotalL1ToL2MessageCount()).toEqual(BigInt(msgs.length));
|
|
450
|
+
};
|
|
451
|
+
const makeInboxMessagesWithFullBlocks = (blockCount, opts = {})=>makeInboxMessages(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * blockCount, {
|
|
452
|
+
overrideFn: (msg, i)=>{
|
|
453
|
+
const l2BlockNumber = (opts.initialL2BlockNumber ?? initialL2BlockNumber) + Math.floor(i / NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
454
|
+
const index = InboxLeaf.smallestIndexFromL2Block(l2BlockNumber) + BigInt(i % NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
455
|
+
return {
|
|
456
|
+
...msg,
|
|
457
|
+
l2BlockNumber,
|
|
458
|
+
index
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
it('stores first message ever', async ()=>{
|
|
463
|
+
const msg = makeInboxMessage(Buffer16.ZERO, {
|
|
464
|
+
index: 0n,
|
|
465
|
+
l2BlockNumber: 1
|
|
466
|
+
});
|
|
467
|
+
await store.addL1ToL2Messages([
|
|
468
|
+
msg
|
|
469
|
+
]);
|
|
470
|
+
await checkMessages([
|
|
471
|
+
msg
|
|
472
|
+
]);
|
|
473
|
+
expect(await store.getL1ToL2Messages(1)).toEqual([
|
|
474
|
+
msg.leaf
|
|
475
|
+
]);
|
|
476
|
+
});
|
|
477
|
+
it('stores single message', async ()=>{
|
|
478
|
+
const msg = makeInboxMessage(Buffer16.ZERO, {
|
|
479
|
+
l2BlockNumber: 2
|
|
480
|
+
});
|
|
481
|
+
await store.addL1ToL2Messages([
|
|
482
|
+
msg
|
|
483
|
+
]);
|
|
484
|
+
await checkMessages([
|
|
485
|
+
msg
|
|
486
|
+
]);
|
|
487
|
+
expect(await store.getL1ToL2Messages(2)).toEqual([
|
|
488
|
+
msg.leaf
|
|
489
|
+
]);
|
|
490
|
+
});
|
|
491
|
+
it('stores and returns messages across different blocks', async ()=>{
|
|
492
|
+
const msgs = makeInboxMessages(5, {
|
|
493
|
+
initialL2BlockNumber
|
|
494
|
+
});
|
|
495
|
+
await store.addL1ToL2Messages(msgs);
|
|
496
|
+
await checkMessages(msgs);
|
|
497
|
+
expect(await store.getL1ToL2Messages(initialL2BlockNumber + 2)).toEqual([
|
|
498
|
+
msgs[2]
|
|
499
|
+
].map((m)=>m.leaf));
|
|
500
|
+
});
|
|
501
|
+
it('stores the same messages again', async ()=>{
|
|
502
|
+
const msgs = makeInboxMessages(5, {
|
|
503
|
+
initialL2BlockNumber
|
|
504
|
+
});
|
|
505
|
+
await store.addL1ToL2Messages(msgs);
|
|
506
|
+
await store.addL1ToL2Messages(msgs.slice(2));
|
|
507
|
+
await checkMessages(msgs);
|
|
508
|
+
});
|
|
509
|
+
it('stores and returns messages across different blocks with gaps', async ()=>{
|
|
510
|
+
const msgs1 = makeInboxMessages(3, {
|
|
511
|
+
initialL2BlockNumber: 1
|
|
512
|
+
});
|
|
513
|
+
const msgs2 = makeInboxMessages(3, {
|
|
514
|
+
initialL2BlockNumber: 20,
|
|
515
|
+
initialHash: msgs1.at(-1).rollingHash
|
|
516
|
+
});
|
|
517
|
+
await store.addL1ToL2Messages(msgs1);
|
|
518
|
+
await store.addL1ToL2Messages(msgs2);
|
|
519
|
+
await checkMessages([
|
|
520
|
+
...msgs1,
|
|
521
|
+
...msgs2
|
|
522
|
+
]);
|
|
523
|
+
expect(await store.getL1ToL2Messages(1)).toEqual([
|
|
524
|
+
msgs1[0].leaf
|
|
525
|
+
]);
|
|
526
|
+
expect(await store.getL1ToL2Messages(4)).toEqual([]);
|
|
527
|
+
expect(await store.getL1ToL2Messages(20)).toEqual([
|
|
528
|
+
msgs2[0].leaf
|
|
529
|
+
]);
|
|
530
|
+
expect(await store.getL1ToL2Messages(24)).toEqual([]);
|
|
531
|
+
});
|
|
532
|
+
it('stores and returns messages with block numbers larger than a byte', async ()=>{
|
|
533
|
+
const msgs = makeInboxMessages(5, {
|
|
534
|
+
initialL2BlockNumber: 1000
|
|
535
|
+
});
|
|
536
|
+
await store.addL1ToL2Messages(msgs);
|
|
537
|
+
await checkMessages(msgs);
|
|
538
|
+
expect(await store.getL1ToL2Messages(1002)).toEqual([
|
|
539
|
+
msgs[2]
|
|
540
|
+
].map((m)=>m.leaf));
|
|
541
|
+
});
|
|
542
|
+
it('stores and returns multiple messages per block', async ()=>{
|
|
543
|
+
const msgs = makeInboxMessagesWithFullBlocks(4);
|
|
544
|
+
await store.addL1ToL2Messages(msgs);
|
|
545
|
+
await checkMessages(msgs);
|
|
546
|
+
const blockMessages = await store.getL1ToL2Messages(initialL2BlockNumber + 1);
|
|
547
|
+
expect(blockMessages).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
548
|
+
expect(blockMessages).toEqual(msgs.slice(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2).map((m)=>m.leaf));
|
|
549
|
+
});
|
|
550
|
+
it('stores messages in multiple operations', async ()=>{
|
|
551
|
+
const msgs = makeInboxMessages(20, {
|
|
552
|
+
initialL2BlockNumber
|
|
553
|
+
});
|
|
554
|
+
await store.addL1ToL2Messages(msgs.slice(0, 10));
|
|
555
|
+
await store.addL1ToL2Messages(msgs.slice(10, 20));
|
|
556
|
+
expect(await store.getL1ToL2Messages(initialL2BlockNumber + 2)).toEqual([
|
|
557
|
+
msgs[2]
|
|
558
|
+
].map((m)=>m.leaf));
|
|
559
|
+
expect(await store.getL1ToL2Messages(initialL2BlockNumber + 12)).toEqual([
|
|
560
|
+
msgs[12]
|
|
561
|
+
].map((m)=>m.leaf));
|
|
562
|
+
await checkMessages(msgs);
|
|
563
|
+
});
|
|
564
|
+
it('iterates over messages from start index', async ()=>{
|
|
565
|
+
const msgs = makeInboxMessages(10, {
|
|
566
|
+
initialL2BlockNumber
|
|
567
|
+
});
|
|
568
|
+
await store.addL1ToL2Messages(msgs);
|
|
569
|
+
const iterated = await toArray(store.iterateL1ToL2Messages({
|
|
570
|
+
start: msgs[3].index
|
|
571
|
+
}));
|
|
572
|
+
expect(iterated).toEqual(msgs.slice(3));
|
|
573
|
+
});
|
|
574
|
+
it('iterates over messages in reverse', async ()=>{
|
|
575
|
+
const msgs = makeInboxMessages(10, {
|
|
576
|
+
initialL2BlockNumber
|
|
577
|
+
});
|
|
578
|
+
await store.addL1ToL2Messages(msgs);
|
|
579
|
+
const iterated = await toArray(store.iterateL1ToL2Messages({
|
|
580
|
+
reverse: true,
|
|
581
|
+
end: msgs[3].index
|
|
582
|
+
}));
|
|
583
|
+
expect(iterated).toEqual(msgs.slice(0, 4).reverse());
|
|
584
|
+
});
|
|
585
|
+
it('throws if messages are added out of order', async ()=>{
|
|
586
|
+
const msgs = makeInboxMessages(5, {
|
|
587
|
+
overrideFn: (msg, i)=>({
|
|
588
|
+
...msg,
|
|
589
|
+
index: BigInt(10 - i)
|
|
590
|
+
})
|
|
591
|
+
});
|
|
592
|
+
await expect(store.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError);
|
|
593
|
+
});
|
|
594
|
+
it('throws if block number for the first message is out of order', async ()=>{
|
|
595
|
+
const msgs = makeInboxMessages(4, {
|
|
596
|
+
initialL2BlockNumber
|
|
597
|
+
});
|
|
598
|
+
msgs[2].l2BlockNumber = initialL2BlockNumber - 1;
|
|
599
|
+
await store.addL1ToL2Messages(msgs.slice(0, 2));
|
|
600
|
+
await expect(store.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError);
|
|
601
|
+
});
|
|
602
|
+
it('throws if rolling hash is not correct', async ()=>{
|
|
603
|
+
const msgs = makeInboxMessages(5);
|
|
604
|
+
msgs[1].rollingHash = Buffer16.random();
|
|
605
|
+
await expect(store.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError);
|
|
606
|
+
});
|
|
607
|
+
it('throws if rolling hash for first message is not correct', async ()=>{
|
|
608
|
+
const msgs = makeInboxMessages(4);
|
|
609
|
+
msgs[2].rollingHash = Buffer16.random();
|
|
610
|
+
await store.addL1ToL2Messages(msgs.slice(0, 2));
|
|
611
|
+
await expect(store.addL1ToL2Messages(msgs.slice(2, 4))).rejects.toThrow(MessageStoreError);
|
|
612
|
+
});
|
|
613
|
+
it('throws if index is not in the correct range', async ()=>{
|
|
614
|
+
const msgs = makeInboxMessages(5, {
|
|
615
|
+
initialL2BlockNumber
|
|
616
|
+
});
|
|
617
|
+
msgs.at(-1).index += 100n;
|
|
618
|
+
await expect(store.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError);
|
|
619
|
+
});
|
|
620
|
+
it('throws if first index in block has gaps', async ()=>{
|
|
621
|
+
const msgs = makeInboxMessages(4, {
|
|
622
|
+
initialL2BlockNumber
|
|
623
|
+
});
|
|
624
|
+
msgs[2].index++;
|
|
625
|
+
await expect(store.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError);
|
|
626
|
+
});
|
|
627
|
+
it('throws if index does not follow previous one', async ()=>{
|
|
628
|
+
const msgs = makeInboxMessages(2, {
|
|
629
|
+
initialL2BlockNumber,
|
|
630
|
+
overrideFn: (msg, i)=>({
|
|
631
|
+
...msg,
|
|
632
|
+
l2BlockNumber: 2,
|
|
633
|
+
index: BigInt(i + NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2)
|
|
634
|
+
})
|
|
635
|
+
});
|
|
636
|
+
msgs[1].index++;
|
|
637
|
+
await expect(store.addL1ToL2Messages(msgs)).rejects.toThrow(MessageStoreError);
|
|
638
|
+
});
|
|
639
|
+
it('removes messages up to the given block number', async ()=>{
|
|
640
|
+
const msgs = makeInboxMessagesWithFullBlocks(4, {
|
|
641
|
+
initialL2BlockNumber: 1
|
|
642
|
+
});
|
|
643
|
+
await store.addL1ToL2Messages(msgs);
|
|
644
|
+
await checkMessages(msgs);
|
|
645
|
+
expect(await store.getL1ToL2Messages(1)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
646
|
+
expect(await store.getL1ToL2Messages(2)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
647
|
+
expect(await store.getL1ToL2Messages(3)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
648
|
+
expect(await store.getL1ToL2Messages(4)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
649
|
+
await store.rollbackL1ToL2MessagesToL2Block(2);
|
|
650
|
+
expect(await store.getL1ToL2Messages(1)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
651
|
+
expect(await store.getL1ToL2Messages(2)).toHaveLength(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
652
|
+
expect(await store.getL1ToL2Messages(3)).toHaveLength(0);
|
|
653
|
+
expect(await store.getL1ToL2Messages(4)).toHaveLength(0);
|
|
654
|
+
await checkMessages(msgs.slice(0, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 2));
|
|
655
|
+
});
|
|
656
|
+
it('removes messages starting with the given index', async ()=>{
|
|
657
|
+
const msgs = makeInboxMessagesWithFullBlocks(4, {
|
|
658
|
+
initialL2BlockNumber: 1
|
|
659
|
+
});
|
|
660
|
+
await store.addL1ToL2Messages(msgs);
|
|
661
|
+
await store.removeL1ToL2Messages(msgs[13].index);
|
|
662
|
+
await checkMessages(msgs.slice(0, 13));
|
|
262
663
|
});
|
|
263
664
|
});
|
|
264
665
|
describe('contractInstances', ()=>{
|
|
265
666
|
let contractInstance;
|
|
266
667
|
const blockNum = 10;
|
|
668
|
+
const timestamp = 3600n;
|
|
267
669
|
beforeEach(async ()=>{
|
|
268
670
|
const classId = Fr.random();
|
|
269
671
|
const randomInstance = await SerializableContractInstance.random({
|
|
@@ -279,16 +681,103 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
279
681
|
], blockNum);
|
|
280
682
|
});
|
|
281
683
|
it('returns previously stored contract instances', async ()=>{
|
|
282
|
-
await expect(store.getContractInstance(contractInstance.address)).resolves.toMatchObject(contractInstance);
|
|
684
|
+
await expect(store.getContractInstance(contractInstance.address, timestamp)).resolves.toMatchObject(contractInstance);
|
|
283
685
|
});
|
|
284
686
|
it('returns undefined if contract instance is not found', async ()=>{
|
|
285
|
-
await expect(store.getContractInstance(await AztecAddress.random())).resolves.toBeUndefined();
|
|
687
|
+
await expect(store.getContractInstance(await AztecAddress.random(), timestamp)).resolves.toBeUndefined();
|
|
286
688
|
});
|
|
287
689
|
it('returns undefined if previously stored contract instances was deleted', async ()=>{
|
|
288
690
|
await store.deleteContractInstances([
|
|
289
691
|
contractInstance
|
|
290
692
|
], blockNum);
|
|
291
|
-
await expect(store.getContractInstance(contractInstance.address)).resolves.toBeUndefined();
|
|
693
|
+
await expect(store.getContractInstance(contractInstance.address, timestamp)).resolves.toBeUndefined();
|
|
694
|
+
});
|
|
695
|
+
});
|
|
696
|
+
describe('contractInstanceUpdates', ()=>{
|
|
697
|
+
let contractInstance;
|
|
698
|
+
let classId;
|
|
699
|
+
let nextClassId;
|
|
700
|
+
const timestampOfChange = 3600n;
|
|
701
|
+
beforeEach(async ()=>{
|
|
702
|
+
classId = Fr.random();
|
|
703
|
+
nextClassId = Fr.random();
|
|
704
|
+
const randomInstance = await SerializableContractInstance.random({
|
|
705
|
+
currentContractClassId: classId,
|
|
706
|
+
originalContractClassId: classId
|
|
707
|
+
});
|
|
708
|
+
contractInstance = {
|
|
709
|
+
...randomInstance,
|
|
710
|
+
address: await AztecAddress.random()
|
|
711
|
+
};
|
|
712
|
+
await store.addContractInstances([
|
|
713
|
+
contractInstance
|
|
714
|
+
], 1);
|
|
715
|
+
await store.addContractInstanceUpdates([
|
|
716
|
+
{
|
|
717
|
+
prevContractClassId: classId,
|
|
718
|
+
newContractClassId: nextClassId,
|
|
719
|
+
timestampOfChange,
|
|
720
|
+
address: contractInstance.address
|
|
721
|
+
}
|
|
722
|
+
], timestampOfChange - 1n);
|
|
723
|
+
});
|
|
724
|
+
it('gets the correct current class id for a contract not updated yet', async ()=>{
|
|
725
|
+
const fetchedInstance = await store.getContractInstance(contractInstance.address, timestampOfChange - 1n);
|
|
726
|
+
expect(fetchedInstance?.originalContractClassId).toEqual(classId);
|
|
727
|
+
expect(fetchedInstance?.currentContractClassId).toEqual(classId);
|
|
728
|
+
});
|
|
729
|
+
it('gets the correct current class id for a contract that has just been updated', async ()=>{
|
|
730
|
+
const fetchedInstance = await store.getContractInstance(contractInstance.address, timestampOfChange);
|
|
731
|
+
expect(fetchedInstance?.originalContractClassId).toEqual(classId);
|
|
732
|
+
expect(fetchedInstance?.currentContractClassId).toEqual(nextClassId);
|
|
733
|
+
});
|
|
734
|
+
it('gets the correct current class id for a contract that was updated in the past', async ()=>{
|
|
735
|
+
const fetchedInstance = await store.getContractInstance(contractInstance.address, timestampOfChange + 1n);
|
|
736
|
+
expect(fetchedInstance?.originalContractClassId).toEqual(classId);
|
|
737
|
+
expect(fetchedInstance?.currentContractClassId).toEqual(nextClassId);
|
|
738
|
+
});
|
|
739
|
+
it('ignores updates for the wrong contract', async ()=>{
|
|
740
|
+
const otherClassId = Fr.random();
|
|
741
|
+
const randomInstance = await SerializableContractInstance.random({
|
|
742
|
+
currentContractClassId: otherClassId,
|
|
743
|
+
originalContractClassId: otherClassId
|
|
744
|
+
});
|
|
745
|
+
const otherContractInstance = {
|
|
746
|
+
...randomInstance,
|
|
747
|
+
address: await AztecAddress.random()
|
|
748
|
+
};
|
|
749
|
+
await store.addContractInstances([
|
|
750
|
+
otherContractInstance
|
|
751
|
+
], 1);
|
|
752
|
+
const fetchedInstance = await store.getContractInstance(otherContractInstance.address, timestampOfChange + 1n);
|
|
753
|
+
expect(fetchedInstance?.originalContractClassId).toEqual(otherClassId);
|
|
754
|
+
expect(fetchedInstance?.currentContractClassId).toEqual(otherClassId);
|
|
755
|
+
});
|
|
756
|
+
it('bounds its search to the right contract if more than than one update exists', async ()=>{
|
|
757
|
+
const otherClassId = Fr.random();
|
|
758
|
+
const otherNextClassId = Fr.random();
|
|
759
|
+
const randomInstance = await SerializableContractInstance.random({
|
|
760
|
+
currentContractClassId: otherClassId,
|
|
761
|
+
originalContractClassId: otherNextClassId
|
|
762
|
+
});
|
|
763
|
+
const otherContractInstance = {
|
|
764
|
+
...randomInstance,
|
|
765
|
+
address: await AztecAddress.random()
|
|
766
|
+
};
|
|
767
|
+
await store.addContractInstances([
|
|
768
|
+
otherContractInstance
|
|
769
|
+
], 1);
|
|
770
|
+
await store.addContractInstanceUpdates([
|
|
771
|
+
{
|
|
772
|
+
prevContractClassId: otherClassId,
|
|
773
|
+
newContractClassId: otherNextClassId,
|
|
774
|
+
timestampOfChange,
|
|
775
|
+
address: otherContractInstance.address
|
|
776
|
+
}
|
|
777
|
+
], timestampOfChange - 1n);
|
|
778
|
+
const fetchedInstance = await store.getContractInstance(contractInstance.address, timestampOfChange + 1n);
|
|
779
|
+
expect(fetchedInstance?.originalContractClassId).toEqual(classId);
|
|
780
|
+
expect(fetchedInstance?.currentContractClassId).toEqual(nextClassId);
|
|
292
781
|
});
|
|
293
782
|
});
|
|
294
783
|
describe('contractClasses', ()=>{
|
|
@@ -338,18 +827,18 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
338
827
|
const stored = await store.getContractClass(contractClass.id);
|
|
339
828
|
expect(stored?.privateFunctions).toEqual(fns);
|
|
340
829
|
});
|
|
341
|
-
it('adds new
|
|
342
|
-
const fns = times(3,
|
|
830
|
+
it('adds new utility functions', async ()=>{
|
|
831
|
+
const fns = times(3, makeUtilityFunctionWithMembershipProof);
|
|
343
832
|
await store.addFunctions(contractClass.id, [], fns);
|
|
344
833
|
const stored = await store.getContractClass(contractClass.id);
|
|
345
|
-
expect(stored?.
|
|
834
|
+
expect(stored?.utilityFunctions).toEqual(fns);
|
|
346
835
|
});
|
|
347
|
-
it('does not duplicate
|
|
348
|
-
const fns = times(3,
|
|
836
|
+
it('does not duplicate utility functions', async ()=>{
|
|
837
|
+
const fns = times(3, makeUtilityFunctionWithMembershipProof);
|
|
349
838
|
await store.addFunctions(contractClass.id, [], fns.slice(0, 1));
|
|
350
839
|
await store.addFunctions(contractClass.id, [], fns);
|
|
351
840
|
const stored = await store.getContractClass(contractClass.id);
|
|
352
|
-
expect(stored?.
|
|
841
|
+
expect(stored?.utilityFunctions).toEqual(fns);
|
|
353
842
|
});
|
|
354
843
|
});
|
|
355
844
|
describe('getLogsByTags', ()=>{
|
|
@@ -358,27 +847,17 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
358
847
|
const numPrivateLogsPerTx = 3;
|
|
359
848
|
const numPublicLogsPerTx = 2;
|
|
360
849
|
let blocks;
|
|
361
|
-
const makeTag = (blockNumber, txIndex, logIndex, isPublic = false)=>
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
...times(PRIVATE_LOG_SIZE_IN_FIELDS - 1, (i)=>new Fr(tag.toNumber() + i))
|
|
373
|
-
]);
|
|
374
|
-
// The tag lives in field 1, not 0, of a public log
|
|
375
|
-
// See extractTaggedLogsFromPublic and noir-projects/aztec-nr/aztec/src/macros/notes/mod.nr -> emit_log
|
|
376
|
-
const makePublicLog = (tag)=>PublicLog.fromFields([
|
|
377
|
-
AztecAddress.fromNumber(1).toField(),
|
|
378
|
-
makeLengthsField(2, PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 3),
|
|
379
|
-
tag,
|
|
380
|
-
...times(PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 1, (i)=>new Fr(tag.toNumber() + i))
|
|
381
|
-
]);
|
|
850
|
+
const makeTag = (blockNumber, txIndex, logIndex, isPublic = false)=>blockNumber === 1 && txIndex === 0 && logIndex === 0 ? Fr.ZERO // Shared tag
|
|
851
|
+
: new Fr((blockNumber * 100 + txIndex * 10 + logIndex) * (isPublic ? 123 : 1));
|
|
852
|
+
const makePrivateLog = (tag)=>PrivateLog.from({
|
|
853
|
+
fields: makeTuple(PRIVATE_LOG_SIZE_IN_FIELDS, (i)=>!i ? tag : new Fr(tag.toNumber() + i)),
|
|
854
|
+
emittedLength: PRIVATE_LOG_SIZE_IN_FIELDS
|
|
855
|
+
});
|
|
856
|
+
const makePublicLog = (tag)=>PublicLog.from({
|
|
857
|
+
contractAddress: AztecAddress.fromNumber(1),
|
|
858
|
+
// Arbitrary length
|
|
859
|
+
fields: new Array(10).fill(null).map((_, i)=>!i ? tag : new Fr(tag.toNumber() + i))
|
|
860
|
+
});
|
|
382
861
|
const mockPrivateLogs = (blockNumber, txIndex)=>{
|
|
383
862
|
return times(numPrivateLogsPerTx, (logIndex)=>{
|
|
384
863
|
const tag = makeTag(blockNumber, txIndex, logIndex);
|
|
@@ -393,66 +872,67 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
393
872
|
};
|
|
394
873
|
const mockBlockWithLogs = async (blockNumber)=>{
|
|
395
874
|
const block = await L2Block.random(blockNumber);
|
|
396
|
-
block.header.globalVariables.blockNumber =
|
|
875
|
+
block.header.globalVariables.blockNumber = blockNumber;
|
|
397
876
|
block.body.txEffects = await timesParallel(numTxsPerBlock, async (txIndex)=>{
|
|
398
877
|
const txEffect = await TxEffect.random();
|
|
399
878
|
txEffect.privateLogs = mockPrivateLogs(blockNumber, txIndex);
|
|
400
879
|
txEffect.publicLogs = mockPublicLogs(blockNumber, txIndex);
|
|
401
880
|
return txEffect;
|
|
402
881
|
});
|
|
403
|
-
return {
|
|
404
|
-
|
|
882
|
+
return PublishedL2Block.fromFields({
|
|
883
|
+
block: block,
|
|
884
|
+
attestations: times(3, CommitteeAttestation.random),
|
|
405
885
|
l1: {
|
|
406
886
|
blockNumber: BigInt(blockNumber),
|
|
407
|
-
blockHash:
|
|
887
|
+
blockHash: makeBlockHash(blockNumber),
|
|
408
888
|
timestamp: BigInt(blockNumber)
|
|
409
889
|
}
|
|
410
|
-
};
|
|
890
|
+
});
|
|
411
891
|
};
|
|
412
892
|
beforeEach(async ()=>{
|
|
413
|
-
blocks = await timesParallel(numBlocks, (index)=>mockBlockWithLogs(index));
|
|
893
|
+
blocks = await timesParallel(numBlocks, (index)=>mockBlockWithLogs(index + 1));
|
|
414
894
|
await store.addBlocks(blocks);
|
|
415
|
-
await store.addLogs(blocks.map((b)=>b.
|
|
895
|
+
await store.addLogs(blocks.map((b)=>b.block));
|
|
416
896
|
});
|
|
417
897
|
it('is possible to batch request private logs via tags', async ()=>{
|
|
418
898
|
const tags = [
|
|
419
|
-
makeTag(
|
|
420
|
-
makeTag(
|
|
899
|
+
makeTag(2, 1, 2),
|
|
900
|
+
makeTag(1, 2, 0)
|
|
421
901
|
];
|
|
422
902
|
const logsByTags = await store.getLogsByTags(tags);
|
|
423
903
|
expect(logsByTags).toEqual([
|
|
424
904
|
[
|
|
425
905
|
expect.objectContaining({
|
|
426
|
-
blockNumber:
|
|
427
|
-
|
|
906
|
+
blockNumber: 2,
|
|
907
|
+
log: makePrivateLog(tags[0]),
|
|
428
908
|
isFromPublic: false
|
|
429
909
|
})
|
|
430
910
|
],
|
|
431
911
|
[
|
|
432
912
|
expect.objectContaining({
|
|
433
|
-
blockNumber:
|
|
434
|
-
|
|
913
|
+
blockNumber: 1,
|
|
914
|
+
log: makePrivateLog(tags[1]),
|
|
435
915
|
isFromPublic: false
|
|
436
916
|
})
|
|
437
917
|
]
|
|
438
918
|
]);
|
|
439
919
|
});
|
|
440
920
|
it('is possible to batch request all logs (private and public) via tags', async ()=>{
|
|
441
|
-
// Tag(
|
|
921
|
+
// Tag(1, 0, 0) is shared with the first private log and the first public log.
|
|
442
922
|
const tags = [
|
|
443
|
-
makeTag(
|
|
923
|
+
makeTag(1, 0, 0)
|
|
444
924
|
];
|
|
445
925
|
const logsByTags = await store.getLogsByTags(tags);
|
|
446
926
|
expect(logsByTags).toEqual([
|
|
447
927
|
[
|
|
448
928
|
expect.objectContaining({
|
|
449
|
-
blockNumber:
|
|
450
|
-
|
|
929
|
+
blockNumber: 1,
|
|
930
|
+
log: makePrivateLog(tags[0]),
|
|
451
931
|
isFromPublic: false
|
|
452
932
|
}),
|
|
453
933
|
expect.objectContaining({
|
|
454
|
-
blockNumber:
|
|
455
|
-
|
|
934
|
+
blockNumber: 1,
|
|
935
|
+
log: makePublicLog(tags[0]),
|
|
456
936
|
isFromPublic: true
|
|
457
937
|
})
|
|
458
938
|
]
|
|
@@ -465,26 +945,26 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
465
945
|
// Create a block containing logs that have the same tag as the blocks before.
|
|
466
946
|
const newBlockNumber = numBlocks;
|
|
467
947
|
const newBlock = await mockBlockWithLogs(newBlockNumber);
|
|
468
|
-
const newLog = newBlock.
|
|
948
|
+
const newLog = newBlock.block.body.txEffects[1].privateLogs[1];
|
|
469
949
|
newLog.fields[0] = tags[0];
|
|
470
|
-
newBlock.
|
|
950
|
+
newBlock.block.body.txEffects[1].privateLogs[1] = newLog;
|
|
471
951
|
await store.addBlocks([
|
|
472
952
|
newBlock
|
|
473
953
|
]);
|
|
474
954
|
await store.addLogs([
|
|
475
|
-
newBlock.
|
|
955
|
+
newBlock.block
|
|
476
956
|
]);
|
|
477
957
|
const logsByTags = await store.getLogsByTags(tags);
|
|
478
958
|
expect(logsByTags).toEqual([
|
|
479
959
|
[
|
|
480
960
|
expect.objectContaining({
|
|
481
961
|
blockNumber: 1,
|
|
482
|
-
|
|
962
|
+
log: makePrivateLog(tags[0]),
|
|
483
963
|
isFromPublic: false
|
|
484
964
|
}),
|
|
485
965
|
expect.objectContaining({
|
|
486
966
|
blockNumber: newBlockNumber,
|
|
487
|
-
|
|
967
|
+
log: newLog,
|
|
488
968
|
isFromPublic: false
|
|
489
969
|
})
|
|
490
970
|
]
|
|
@@ -501,46 +981,12 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
501
981
|
[
|
|
502
982
|
expect.objectContaining({
|
|
503
983
|
blockNumber: 1,
|
|
504
|
-
|
|
984
|
+
log: makePrivateLog(tags[1]),
|
|
505
985
|
isFromPublic: false
|
|
506
986
|
})
|
|
507
987
|
]
|
|
508
988
|
]);
|
|
509
989
|
});
|
|
510
|
-
it('is not possible to add public logs by tag if they are invalid', async ()=>{
|
|
511
|
-
const tag = makeTag(99, 88, 77);
|
|
512
|
-
const invalidLogs = [
|
|
513
|
-
PublicLog.fromFields([
|
|
514
|
-
AztecAddress.fromNumber(1).toField(),
|
|
515
|
-
makeLengthsField(2, 3),
|
|
516
|
-
tag,
|
|
517
|
-
...times(PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 1, (i)=>new Fr(tag.toNumber() + i))
|
|
518
|
-
]),
|
|
519
|
-
PublicLog.fromFields([
|
|
520
|
-
AztecAddress.fromNumber(1).toField(),
|
|
521
|
-
makeLengthsField(2, PUBLIC_LOG_DATA_SIZE_IN_FIELDS),
|
|
522
|
-
tag,
|
|
523
|
-
...times(PUBLIC_LOG_DATA_SIZE_IN_FIELDS - 1, (i)=>new Fr(tag.toNumber() + i))
|
|
524
|
-
])
|
|
525
|
-
];
|
|
526
|
-
// Create a block containing these invalid logs
|
|
527
|
-
const newBlockNumber = numBlocks;
|
|
528
|
-
const newBlock = await mockBlockWithLogs(newBlockNumber);
|
|
529
|
-
newBlock.data.body.txEffects[0].publicLogs = invalidLogs;
|
|
530
|
-
await store.addBlocks([
|
|
531
|
-
newBlock
|
|
532
|
-
]);
|
|
533
|
-
await store.addLogs([
|
|
534
|
-
newBlock.data
|
|
535
|
-
]);
|
|
536
|
-
const logsByTags = await store.getLogsByTags([
|
|
537
|
-
tag
|
|
538
|
-
]);
|
|
539
|
-
// Neither of the logs should have been added:
|
|
540
|
-
expect(logsByTags).toEqual([
|
|
541
|
-
[]
|
|
542
|
-
]);
|
|
543
|
-
});
|
|
544
990
|
});
|
|
545
991
|
describe('getPublicLogs', ()=>{
|
|
546
992
|
const txsPerBlock = 4;
|
|
@@ -549,25 +995,26 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
549
995
|
const numBlocks = 10;
|
|
550
996
|
let blocks;
|
|
551
997
|
beforeEach(async ()=>{
|
|
552
|
-
blocks = await timesParallel(numBlocks, async (index)=>({
|
|
553
|
-
|
|
998
|
+
blocks = await timesParallel(numBlocks, async (index)=>PublishedL2Block.fromFields({
|
|
999
|
+
block: await L2Block.random(index + 1, txsPerBlock, numPublicFunctionCalls, numPublicLogs),
|
|
554
1000
|
l1: {
|
|
555
1001
|
blockNumber: BigInt(index),
|
|
556
|
-
blockHash:
|
|
1002
|
+
blockHash: makeBlockHash(index),
|
|
557
1003
|
timestamp: BigInt(index)
|
|
558
|
-
}
|
|
1004
|
+
},
|
|
1005
|
+
attestations: times(3, CommitteeAttestation.random)
|
|
559
1006
|
}));
|
|
560
1007
|
await store.addBlocks(blocks);
|
|
561
|
-
await store.addLogs(blocks.map((b)=>b.
|
|
1008
|
+
await store.addLogs(blocks.map((b)=>b.block));
|
|
562
1009
|
});
|
|
563
1010
|
it('no logs returned if deleted ("txHash" filter param is respected variant)', async ()=>{
|
|
564
1011
|
// get random tx
|
|
565
1012
|
const targetBlockIndex = randomInt(numBlocks);
|
|
566
1013
|
const targetTxIndex = randomInt(txsPerBlock);
|
|
567
|
-
const targetTxHash = blocks[targetBlockIndex].
|
|
1014
|
+
const targetTxHash = blocks[targetBlockIndex].block.body.txEffects[targetTxIndex].txHash;
|
|
568
1015
|
await Promise.all([
|
|
569
1016
|
store.unwindBlocks(blocks.length, blocks.length),
|
|
570
|
-
store.deleteLogs(blocks.map((b)=>b.
|
|
1017
|
+
store.deleteLogs(blocks.map((b)=>b.block))
|
|
571
1018
|
]);
|
|
572
1019
|
const response = await store.getPublicLogs({
|
|
573
1020
|
txHash: targetTxHash
|
|
@@ -580,7 +1027,7 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
580
1027
|
// get random tx
|
|
581
1028
|
const targetBlockIndex = randomInt(numBlocks);
|
|
582
1029
|
const targetTxIndex = randomInt(txsPerBlock);
|
|
583
|
-
const targetTxHash = blocks[targetBlockIndex].
|
|
1030
|
+
const targetTxHash = blocks[targetBlockIndex].block.body.txEffects[targetTxIndex].txHash;
|
|
584
1031
|
const response = await store.getPublicLogs({
|
|
585
1032
|
txHash: targetTxHash
|
|
586
1033
|
});
|
|
@@ -617,7 +1064,7 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
617
1064
|
const targetBlockIndex = randomInt(numBlocks);
|
|
618
1065
|
const targetTxIndex = randomInt(txsPerBlock);
|
|
619
1066
|
const targetLogIndex = randomInt(numPublicLogs * numPublicFunctionCalls);
|
|
620
|
-
const targetContractAddress = blocks[targetBlockIndex].
|
|
1067
|
+
const targetContractAddress = blocks[targetBlockIndex].block.body.txEffects[targetTxIndex].publicLogs[targetLogIndex].contractAddress;
|
|
621
1068
|
const response = await store.getPublicLogs({
|
|
622
1069
|
contractAddress: targetContractAddress
|
|
623
1070
|
});
|
|
@@ -740,54 +1187,102 @@ import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
|
740
1187
|
}
|
|
741
1188
|
});
|
|
742
1189
|
});
|
|
743
|
-
describe('
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
beforeEach(async ()=>{
|
|
748
|
-
blocks = await timesParallel(numBlocks, (index)=>L2Block.random(index + 1, 1));
|
|
749
|
-
blocks.forEach((block, blockIndex)=>{
|
|
750
|
-
nullifiersPerBlock.set(blockIndex, block.body.txEffects.flatMap((txEffect)=>txEffect.nullifiers));
|
|
751
|
-
});
|
|
1190
|
+
describe('pendingChainValidationStatus', ()=>{
|
|
1191
|
+
it('should return undefined when no status is set', async ()=>{
|
|
1192
|
+
const status = await store.getPendingChainValidationStatus();
|
|
1193
|
+
expect(status).toBeUndefined();
|
|
752
1194
|
});
|
|
753
|
-
it('
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
const
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
const
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
1195
|
+
it('should store and retrieve a valid validation status', async ()=>{
|
|
1196
|
+
const validStatus = {
|
|
1197
|
+
valid: true
|
|
1198
|
+
};
|
|
1199
|
+
await store.setPendingChainValidationStatus(validStatus);
|
|
1200
|
+
const retrievedStatus = await store.getPendingChainValidationStatus();
|
|
1201
|
+
expect(retrievedStatus).toEqual(validStatus);
|
|
1202
|
+
});
|
|
1203
|
+
it('should store and retrieve an invalid validation status with insufficient attestations', async ()=>{
|
|
1204
|
+
const invalidStatus = {
|
|
1205
|
+
valid: false,
|
|
1206
|
+
block: randomBlockInfo(1),
|
|
1207
|
+
committee: [
|
|
1208
|
+
EthAddress.random(),
|
|
1209
|
+
EthAddress.random()
|
|
1210
|
+
],
|
|
1211
|
+
epoch: EpochNumber(123),
|
|
1212
|
+
seed: 456n,
|
|
1213
|
+
attestors: [
|
|
1214
|
+
EthAddress.random()
|
|
1215
|
+
],
|
|
1216
|
+
attestations: [
|
|
1217
|
+
CommitteeAttestation.random()
|
|
1218
|
+
],
|
|
1219
|
+
reason: 'insufficient-attestations'
|
|
1220
|
+
};
|
|
1221
|
+
await store.setPendingChainValidationStatus(invalidStatus);
|
|
1222
|
+
const retrievedStatus = await store.getPendingChainValidationStatus();
|
|
1223
|
+
expect(retrievedStatus).toEqual(invalidStatus);
|
|
1224
|
+
});
|
|
1225
|
+
it('should store and retrieve an invalid validation status with invalid attestation', async ()=>{
|
|
1226
|
+
const invalidStatus = {
|
|
1227
|
+
valid: false,
|
|
1228
|
+
block: randomBlockInfo(2),
|
|
1229
|
+
committee: [
|
|
1230
|
+
EthAddress.random()
|
|
1231
|
+
],
|
|
1232
|
+
attestors: [
|
|
1233
|
+
EthAddress.random()
|
|
1234
|
+
],
|
|
1235
|
+
epoch: EpochNumber(789),
|
|
1236
|
+
seed: 101n,
|
|
1237
|
+
attestations: [
|
|
1238
|
+
CommitteeAttestation.random()
|
|
1239
|
+
],
|
|
1240
|
+
reason: 'invalid-attestation',
|
|
1241
|
+
invalidIndex: 5
|
|
1242
|
+
};
|
|
1243
|
+
await store.setPendingChainValidationStatus(invalidStatus);
|
|
1244
|
+
const retrievedStatus = await store.getPendingChainValidationStatus();
|
|
1245
|
+
expect(retrievedStatus).toEqual(invalidStatus);
|
|
1246
|
+
});
|
|
1247
|
+
it('should overwrite existing status when setting a new one', async ()=>{
|
|
1248
|
+
const firstStatus = {
|
|
1249
|
+
valid: true
|
|
1250
|
+
};
|
|
1251
|
+
const secondStatus = {
|
|
1252
|
+
valid: false,
|
|
1253
|
+
block: randomBlockInfo(3),
|
|
1254
|
+
committee: [
|
|
1255
|
+
EthAddress.random()
|
|
1256
|
+
],
|
|
1257
|
+
epoch: EpochNumber(999),
|
|
1258
|
+
seed: 888n,
|
|
1259
|
+
attestors: [
|
|
1260
|
+
EthAddress.random()
|
|
1261
|
+
],
|
|
1262
|
+
attestations: [
|
|
1263
|
+
CommitteeAttestation.random()
|
|
1264
|
+
],
|
|
1265
|
+
reason: 'insufficient-attestations'
|
|
1266
|
+
};
|
|
1267
|
+
await store.setPendingChainValidationStatus(firstStatus);
|
|
1268
|
+
await store.setPendingChainValidationStatus(secondStatus);
|
|
1269
|
+
const retrievedStatus = await store.getPendingChainValidationStatus();
|
|
1270
|
+
expect(retrievedStatus).toEqual(secondStatus);
|
|
1271
|
+
});
|
|
1272
|
+
it('should handle empty committee and attestations arrays', async ()=>{
|
|
1273
|
+
const statusWithEmptyArrays = {
|
|
1274
|
+
valid: false,
|
|
1275
|
+
block: randomBlockInfo(4),
|
|
1276
|
+
committee: [],
|
|
1277
|
+
epoch: EpochNumber(0),
|
|
1278
|
+
seed: 0n,
|
|
1279
|
+
attestors: [],
|
|
1280
|
+
attestations: [],
|
|
1281
|
+
reason: 'insufficient-attestations'
|
|
1282
|
+
};
|
|
1283
|
+
await store.setPendingChainValidationStatus(statusWithEmptyArrays);
|
|
1284
|
+
const retrievedStatus = await store.getPendingChainValidationStatus();
|
|
1285
|
+
expect(retrievedStatus).toEqual(statusWithEmptyArrays);
|
|
791
1286
|
});
|
|
792
1287
|
});
|
|
793
1288
|
});
|