@aztec/archiver 0.56.0 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dest/archiver/archiver.d.ts +23 -20
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +353 -103
- package/dest/archiver/archiver_store.d.ts +39 -9
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +75 -18
- package/dest/archiver/config.js +6 -6
- package/dest/archiver/data_retrieval.d.ts +2 -3
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +21 -20
- package/dest/archiver/epoch_helpers.d.ts +15 -0
- package/dest/archiver/epoch_helpers.d.ts.map +1 -0
- package/dest/archiver/epoch_helpers.js +23 -0
- package/dest/archiver/kv_archiver_store/block_store.d.ts +20 -1
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +62 -5
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +2 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.js +11 -4
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +1 -0
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.js +4 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +29 -9
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +57 -17
- package/dest/archiver/kv_archiver_store/log_store.d.ts +4 -5
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +18 -14
- package/dest/archiver/kv_archiver_store/message_store.d.ts +1 -0
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +10 -3
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +1 -0
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +4 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +23 -22
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +129 -69
- package/dest/index.js +2 -1
- package/dest/test/index.d.ts +2 -0
- package/dest/test/index.d.ts.map +1 -0
- package/dest/test/index.js +2 -0
- package/dest/test/mock_l2_block_source.d.ts +73 -0
- package/dest/test/mock_l2_block_source.d.ts.map +1 -0
- package/dest/test/mock_l2_block_source.js +134 -0
- package/package.json +15 -11
- package/src/archiver/archiver.ts +457 -149
- package/src/archiver/archiver_store.ts +44 -16
- package/src/archiver/archiver_store_test_suite.ts +91 -52
- package/src/archiver/config.ts +5 -5
- package/src/archiver/data_retrieval.ts +23 -24
- package/src/archiver/epoch_helpers.ts +26 -0
- package/src/archiver/kv_archiver_store/block_store.ts +70 -2
- package/src/archiver/kv_archiver_store/contract_class_store.ts +18 -5
- package/src/archiver/kv_archiver_store/contract_instance_store.ts +4 -0
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +65 -24
- package/src/archiver/kv_archiver_store/log_store.ts +18 -18
- package/src/archiver/kv_archiver_store/message_store.ts +9 -0
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +4 -0
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +149 -80
- package/src/index.ts +1 -0
- package/src/test/index.ts +1 -0
- package/src/test/mock_l2_block_source.ts +165 -0
- package/dest/archiver/kv_archiver_store/proven_store.d.ts +0 -14
- package/dest/archiver/kv_archiver_store/proven_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/proven_store.js +0 -30
- package/src/archiver/kv_archiver_store/proven_store.ts +0 -34
|
@@ -19,6 +19,10 @@ export class ContractInstanceStore {
|
|
|
19
19
|
);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
deleteContractInstance(contractInstance: ContractInstanceWithAddress): Promise<void> {
|
|
23
|
+
return this.#contractInstances.delete(contractInstance.address.toString());
|
|
24
|
+
}
|
|
25
|
+
|
|
22
26
|
getContractInstance(address: AztecAddress): ContractInstanceWithAddress | undefined {
|
|
23
27
|
const contractInstance = this.#contractInstances.get(address.toString());
|
|
24
28
|
return contractInstance && SerializableContractInstance.fromBuffer(contractInstance).withAddress(address);
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type EncryptedL2BlockL2Logs,
|
|
3
|
-
type EncryptedNoteL2BlockL2Logs,
|
|
4
2
|
type FromLogType,
|
|
5
3
|
type GetUnencryptedLogsResponse,
|
|
6
4
|
type InboxLeaf,
|
|
@@ -11,9 +9,8 @@ import {
|
|
|
11
9
|
type TxEffect,
|
|
12
10
|
type TxHash,
|
|
13
11
|
type TxReceipt,
|
|
14
|
-
type UnencryptedL2BlockL2Logs,
|
|
15
12
|
} from '@aztec/circuit-types';
|
|
16
|
-
import { type Fr } from '@aztec/circuits.js';
|
|
13
|
+
import { type Fr, type Header } from '@aztec/circuits.js';
|
|
17
14
|
import { type ContractArtifact } from '@aztec/foundation/abi';
|
|
18
15
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
19
16
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
@@ -26,7 +23,7 @@ import {
|
|
|
26
23
|
} from '@aztec/types/contracts';
|
|
27
24
|
|
|
28
25
|
import { type ArchiverDataStore, type ArchiverL1SynchPoint } from '../archiver_store.js';
|
|
29
|
-
import { type DataRetrieval
|
|
26
|
+
import { type DataRetrieval } from '../structs/data_retrieval.js';
|
|
30
27
|
import { type L1Published } from '../structs/published.js';
|
|
31
28
|
import { BlockStore } from './block_store.js';
|
|
32
29
|
import { ContractArtifactsStore } from './contract_artifacts_store.js';
|
|
@@ -34,14 +31,12 @@ import { ContractClassStore } from './contract_class_store.js';
|
|
|
34
31
|
import { ContractInstanceStore } from './contract_instance_store.js';
|
|
35
32
|
import { LogStore } from './log_store.js';
|
|
36
33
|
import { MessageStore } from './message_store.js';
|
|
37
|
-
import { ProvenStore } from './proven_store.js';
|
|
38
34
|
|
|
39
35
|
/**
|
|
40
36
|
* LMDB implementation of the ArchiverDataStore interface.
|
|
41
37
|
*/
|
|
42
38
|
export class KVArchiverDataStore implements ArchiverDataStore {
|
|
43
39
|
#blockStore: BlockStore;
|
|
44
|
-
#provenStore: ProvenStore;
|
|
45
40
|
#logStore: LogStore;
|
|
46
41
|
#messageStore: MessageStore;
|
|
47
42
|
#contractClassStore: ContractClassStore;
|
|
@@ -52,7 +47,6 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
52
47
|
|
|
53
48
|
constructor(db: AztecKVStore, logsMaxPageSize: number = 1000) {
|
|
54
49
|
this.#blockStore = new BlockStore(db);
|
|
55
|
-
this.#provenStore = new ProvenStore(db);
|
|
56
50
|
this.#logStore = new LogStore(db, this.#blockStore, logsMaxPageSize);
|
|
57
51
|
this.#messageStore = new MessageStore(db);
|
|
58
52
|
this.#contractClassStore = new ContractClassStore(db);
|
|
@@ -80,8 +74,14 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
80
74
|
return Promise.resolve(this.#contractInstanceStore.getContractInstance(address));
|
|
81
75
|
}
|
|
82
76
|
|
|
83
|
-
async addContractClasses(data: ContractClassPublic[],
|
|
84
|
-
return (await Promise.all(data.map(c => this.#contractClassStore.addContractClass(c)))).every(Boolean);
|
|
77
|
+
async addContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
|
|
78
|
+
return (await Promise.all(data.map(c => this.#contractClassStore.addContractClass(c, blockNumber)))).every(Boolean);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async deleteContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
|
|
82
|
+
return (await Promise.all(data.map(c => this.#contractClassStore.deleteContractClasses(c, blockNumber)))).every(
|
|
83
|
+
Boolean,
|
|
84
|
+
);
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
addFunctions(
|
|
@@ -96,6 +96,10 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
96
96
|
return (await Promise.all(data.map(c => this.#contractInstanceStore.addContractInstance(c)))).every(Boolean);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
async deleteContractInstances(data: ContractInstanceWithAddress[], _blockNumber: number): Promise<boolean> {
|
|
100
|
+
return (await Promise.all(data.map(c => this.#contractInstanceStore.deleteContractInstance(c)))).every(Boolean);
|
|
101
|
+
}
|
|
102
|
+
|
|
99
103
|
/**
|
|
100
104
|
* Append new blocks to the store's list.
|
|
101
105
|
* @param blocks - The L2 blocks to be added to the store and the last processed L1 block.
|
|
@@ -105,6 +109,17 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
105
109
|
return this.#blockStore.addBlocks(blocks);
|
|
106
110
|
}
|
|
107
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Unwinds blocks from the database
|
|
114
|
+
* @param from - The tip of the chain, passed for verification purposes,
|
|
115
|
+
* ensuring that we don't end up deleting something we did not intend
|
|
116
|
+
* @param blocksToUnwind - The number of blocks we are to unwind
|
|
117
|
+
* @returns True if the operation is successful
|
|
118
|
+
*/
|
|
119
|
+
unwindBlocks(from: number, blocksToUnwind: number): Promise<boolean> {
|
|
120
|
+
return this.#blockStore.unwindBlocks(from, blocksToUnwind);
|
|
121
|
+
}
|
|
122
|
+
|
|
108
123
|
/**
|
|
109
124
|
* Gets up to `limit` amount of L2 blocks starting from `from`.
|
|
110
125
|
*
|
|
@@ -121,6 +136,22 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
121
136
|
}
|
|
122
137
|
}
|
|
123
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Gets up to `limit` amount of L2 blocks headers starting from `from`.
|
|
141
|
+
*
|
|
142
|
+
* @param start - Number of the first block to return (inclusive).
|
|
143
|
+
* @param limit - The number of blocks to return.
|
|
144
|
+
* @returns The requested L2 blocks
|
|
145
|
+
*/
|
|
146
|
+
getBlockHeaders(start: number, limit: number): Promise<Header[]> {
|
|
147
|
+
try {
|
|
148
|
+
return Promise.resolve(Array.from(this.#blockStore.getBlockHeaders(start, limit)));
|
|
149
|
+
} catch (err) {
|
|
150
|
+
// this function is sync so if any errors are thrown we need to make sure they're passed on as rejected Promises
|
|
151
|
+
return Promise.reject(err);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
124
155
|
/**
|
|
125
156
|
* Gets a tx effect.
|
|
126
157
|
* @param txHash - The txHash of the tx corresponding to the tx effect.
|
|
@@ -141,18 +172,19 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
141
172
|
|
|
142
173
|
/**
|
|
143
174
|
* Append new logs to the store's list.
|
|
144
|
-
* @param
|
|
145
|
-
* @param unencryptedLogs - The type of the logs to be added to the store.
|
|
146
|
-
* @param blockNumber - The block for which to add the logs.
|
|
175
|
+
* @param blocks - The blocks for which to add the logs.
|
|
147
176
|
* @returns True if the operation is successful.
|
|
148
177
|
*/
|
|
149
|
-
addLogs(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
178
|
+
addLogs(blocks: L2Block[]): Promise<boolean> {
|
|
179
|
+
return this.#logStore.addLogs(blocks);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
deleteLogs(blocks: L2Block[]): Promise<boolean> {
|
|
183
|
+
return this.#logStore.deleteLogs(blocks);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
getTotalL1ToL2MessageCount(): Promise<bigint> {
|
|
187
|
+
return Promise.resolve(this.#messageStore.getTotalL1ToL2MessageCount());
|
|
156
188
|
}
|
|
157
189
|
|
|
158
190
|
/**
|
|
@@ -228,11 +260,21 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
228
260
|
}
|
|
229
261
|
|
|
230
262
|
getProvenL2BlockNumber(): Promise<number> {
|
|
231
|
-
return Promise.resolve(this.#
|
|
263
|
+
return Promise.resolve(this.#blockStore.getProvenL2BlockNumber());
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
getProvenL2EpochNumber(): Promise<number | undefined> {
|
|
267
|
+
return Promise.resolve(this.#blockStore.getProvenL2EpochNumber());
|
|
232
268
|
}
|
|
233
269
|
|
|
234
|
-
|
|
235
|
-
|
|
270
|
+
setProvenL2BlockNumber(blockNumber: number) {
|
|
271
|
+
this.#blockStore.setProvenL2BlockNumber(blockNumber);
|
|
272
|
+
return Promise.resolve();
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
setProvenL2EpochNumber(epochNumber: number) {
|
|
276
|
+
this.#blockStore.setProvenL2EpochNumber(epochNumber);
|
|
277
|
+
return Promise.resolve();
|
|
236
278
|
}
|
|
237
279
|
|
|
238
280
|
setBlockSynchedL1BlockNumber(l1BlockNumber: bigint) {
|
|
@@ -252,7 +294,6 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
252
294
|
return Promise.resolve({
|
|
253
295
|
blocksSynchedTo: this.#blockStore.getSynchedL1BlockNumber(),
|
|
254
296
|
messagesSynchedTo: this.#messageStore.getSynchedL1BlockNumber(),
|
|
255
|
-
provenLogsSynchedTo: this.#provenStore.getSynchedL1BlockNumber(),
|
|
256
297
|
});
|
|
257
298
|
}
|
|
258
299
|
}
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
ExtendedUnencryptedL2Log,
|
|
5
5
|
type FromLogType,
|
|
6
6
|
type GetUnencryptedLogsResponse,
|
|
7
|
+
type L2Block,
|
|
7
8
|
type L2BlockL2Logs,
|
|
8
9
|
type LogFilter,
|
|
9
10
|
LogId,
|
|
@@ -37,29 +38,28 @@ export class LogStore {
|
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
40
|
* Append new logs to the store's list.
|
|
40
|
-
* @param
|
|
41
|
-
* @param unencryptedLogs - The type of the logs to be added to the store.
|
|
42
|
-
* @param blockNumber - The block for which to add the logs.
|
|
41
|
+
* @param blocks - The blocks for which to add the logs.
|
|
43
42
|
* @returns True if the operation is successful.
|
|
44
43
|
*/
|
|
45
|
-
addLogs(
|
|
46
|
-
noteEncryptedLogs: EncryptedNoteL2BlockL2Logs | undefined,
|
|
47
|
-
encryptedLogs: EncryptedL2BlockL2Logs | undefined,
|
|
48
|
-
unencryptedLogs: UnencryptedL2BlockL2Logs | undefined,
|
|
49
|
-
blockNumber: number,
|
|
50
|
-
): Promise<boolean> {
|
|
44
|
+
addLogs(blocks: L2Block[]): Promise<boolean> {
|
|
51
45
|
return this.db.transaction(() => {
|
|
52
|
-
|
|
53
|
-
void this.#noteEncryptedLogs.set(
|
|
54
|
-
|
|
46
|
+
blocks.forEach(block => {
|
|
47
|
+
void this.#noteEncryptedLogs.set(block.number, block.body.noteEncryptedLogs.toBuffer());
|
|
48
|
+
void this.#encryptedLogs.set(block.number, block.body.encryptedLogs.toBuffer());
|
|
49
|
+
void this.#unencryptedLogs.set(block.number, block.body.unencryptedLogs.toBuffer());
|
|
50
|
+
});
|
|
55
51
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
return true;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
59
55
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
deleteLogs(blocks: L2Block[]): Promise<boolean> {
|
|
57
|
+
return this.db.transaction(() => {
|
|
58
|
+
blocks.forEach(block => {
|
|
59
|
+
void this.#noteEncryptedLogs.delete(block.number);
|
|
60
|
+
void this.#encryptedLogs.delete(block.number);
|
|
61
|
+
void this.#unencryptedLogs.delete(block.number);
|
|
62
|
+
});
|
|
63
63
|
|
|
64
64
|
return true;
|
|
65
65
|
});
|
|
@@ -17,6 +17,7 @@ export class MessageStore {
|
|
|
17
17
|
#l1ToL2Messages: AztecMap<string, Buffer>;
|
|
18
18
|
#l1ToL2MessageIndices: AztecMap<string, bigint[]>; // We store array of bigints here because there can be duplicate messages
|
|
19
19
|
#lastSynchedL1Block: AztecSingleton<bigint>;
|
|
20
|
+
#totalMessageCount: AztecSingleton<bigint>;
|
|
20
21
|
|
|
21
22
|
#log = createDebugLogger('aztec:archiver:message_store');
|
|
22
23
|
|
|
@@ -26,6 +27,11 @@ export class MessageStore {
|
|
|
26
27
|
this.#l1ToL2Messages = db.openMap('archiver_l1_to_l2_messages');
|
|
27
28
|
this.#l1ToL2MessageIndices = db.openMap('archiver_l1_to_l2_message_indices');
|
|
28
29
|
this.#lastSynchedL1Block = db.openSingleton('archiver_last_l1_block_new_messages');
|
|
30
|
+
this.#totalMessageCount = db.openSingleton('archiver_l1_to_l2_message_count');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
getTotalL1ToL2MessageCount(): bigint {
|
|
34
|
+
return this.#totalMessageCount.get() ?? 0n;
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
/**
|
|
@@ -70,6 +76,9 @@ export class MessageStore {
|
|
|
70
76
|
void this.#l1ToL2MessageIndices.set(message.leaf.toString(), indices);
|
|
71
77
|
}
|
|
72
78
|
|
|
79
|
+
const lastTotalMessageCount = this.getTotalL1ToL2MessageCount();
|
|
80
|
+
void this.#totalMessageCount.set(lastTotalMessageCount + BigInt(messages.retrievedData.length));
|
|
81
|
+
|
|
73
82
|
return true;
|
|
74
83
|
});
|
|
75
84
|
}
|
|
@@ -19,6 +19,10 @@ export class L1ToL2MessageStore {
|
|
|
19
19
|
|
|
20
20
|
constructor() {}
|
|
21
21
|
|
|
22
|
+
getTotalL1ToL2MessageCount(): bigint {
|
|
23
|
+
return BigInt(this.store.size);
|
|
24
|
+
}
|
|
25
|
+
|
|
22
26
|
addMessage(message: InboxLeaf) {
|
|
23
27
|
if (message.index >= this.#l1ToL2MessagesSubtreeSize) {
|
|
24
28
|
throw new Error(`Message index ${message.index} out of subtree range`);
|
|
@@ -15,18 +15,19 @@ import {
|
|
|
15
15
|
TxReceipt,
|
|
16
16
|
type UnencryptedL2BlockL2Logs,
|
|
17
17
|
} from '@aztec/circuit-types';
|
|
18
|
-
import { Fr, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
|
|
18
|
+
import { Fr, type Header, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
|
|
19
19
|
import { type ContractArtifact } from '@aztec/foundation/abi';
|
|
20
20
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
21
21
|
import {
|
|
22
22
|
type ContractClassPublic,
|
|
23
|
+
type ContractClassPublicWithBlockNumber,
|
|
23
24
|
type ContractInstanceWithAddress,
|
|
24
25
|
type ExecutablePrivateFunctionWithMembershipProof,
|
|
25
26
|
type UnconstrainedFunctionWithMembershipProof,
|
|
26
27
|
} from '@aztec/types/contracts';
|
|
27
28
|
|
|
28
29
|
import { type ArchiverDataStore, type ArchiverL1SynchPoint } from '../archiver_store.js';
|
|
29
|
-
import { type DataRetrieval
|
|
30
|
+
import { type DataRetrieval } from '../structs/data_retrieval.js';
|
|
30
31
|
import { type L1Published } from '../structs/published.js';
|
|
31
32
|
import { L1ToL2MessageStore } from './l1_to_l2_message_store.js';
|
|
32
33
|
|
|
@@ -44,23 +45,11 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
44
45
|
*/
|
|
45
46
|
private txEffects: TxEffect[] = [];
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
* An array containing all the encrypted logs that have been fetched so far.
|
|
49
|
-
* Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM).
|
|
50
|
-
*/
|
|
51
|
-
private noteEncryptedLogsPerBlock: EncryptedNoteL2BlockL2Logs[] = [];
|
|
48
|
+
private noteEncryptedLogsPerBlock: Map<number, EncryptedNoteL2BlockL2Logs> = new Map();
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
* An array containing all the encrypted logs that have been fetched so far.
|
|
55
|
-
* Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM).
|
|
56
|
-
*/
|
|
57
|
-
private encryptedLogsPerBlock: EncryptedL2BlockL2Logs[] = [];
|
|
50
|
+
private encryptedLogsPerBlock: Map<number, EncryptedL2BlockL2Logs> = new Map();
|
|
58
51
|
|
|
59
|
-
|
|
60
|
-
* An array containing all the unencrypted logs that have been fetched so far.
|
|
61
|
-
* Note: Index in the "outer" array equals to (corresponding L2 block's number - INITIAL_L2_BLOCK_NUM).
|
|
62
|
-
*/
|
|
63
|
-
private unencryptedLogsPerBlock: UnencryptedL2BlockL2Logs[] = [];
|
|
52
|
+
private unencryptedLogsPerBlock: Map<number, UnencryptedL2BlockL2Logs> = new Map();
|
|
64
53
|
|
|
65
54
|
/**
|
|
66
55
|
* Contains all L1 to L2 messages.
|
|
@@ -69,7 +58,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
69
58
|
|
|
70
59
|
private contractArtifacts: Map<string, ContractArtifact> = new Map();
|
|
71
60
|
|
|
72
|
-
private contractClasses: Map<string,
|
|
61
|
+
private contractClasses: Map<string, ContractClassPublicWithBlockNumber> = new Map();
|
|
73
62
|
|
|
74
63
|
private privateFunctions: Map<string, ExecutablePrivateFunctionWithMembershipProof[]> = new Map();
|
|
75
64
|
|
|
@@ -79,9 +68,9 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
79
68
|
|
|
80
69
|
private lastL1BlockNewBlocks: bigint | undefined = undefined;
|
|
81
70
|
private lastL1BlockNewMessages: bigint | undefined = undefined;
|
|
82
|
-
private lastL1BlockNewProvenLogs: bigint | undefined = undefined;
|
|
83
71
|
|
|
84
72
|
private lastProvenL2BlockNumber: number = 0;
|
|
73
|
+
private lastProvenL2EpochNumber: number = 0;
|
|
85
74
|
|
|
86
75
|
constructor(
|
|
87
76
|
/** The max number of logs that can be obtained in 1 "getUnencryptedLogs" call. */
|
|
@@ -129,9 +118,24 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
129
118
|
return Promise.resolve(true);
|
|
130
119
|
}
|
|
131
120
|
|
|
132
|
-
public addContractClasses(data: ContractClassPublic[],
|
|
121
|
+
public addContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
|
|
133
122
|
for (const contractClass of data) {
|
|
134
|
-
this.contractClasses.
|
|
123
|
+
if (!this.contractClasses.has(contractClass.id.toString())) {
|
|
124
|
+
this.contractClasses.set(contractClass.id.toString(), {
|
|
125
|
+
...contractClass,
|
|
126
|
+
l2BlockNumber: blockNumber,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return Promise.resolve(true);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public deleteContractClasses(data: ContractClassPublic[], blockNumber: number): Promise<boolean> {
|
|
134
|
+
for (const contractClass of data) {
|
|
135
|
+
const restored = this.contractClasses.get(contractClass.id.toString());
|
|
136
|
+
if (restored && restored.l2BlockNumber >= blockNumber) {
|
|
137
|
+
this.contractClasses.delete(contractClass.id.toString());
|
|
138
|
+
}
|
|
135
139
|
}
|
|
136
140
|
return Promise.resolve(true);
|
|
137
141
|
}
|
|
@@ -143,6 +147,13 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
143
147
|
return Promise.resolve(true);
|
|
144
148
|
}
|
|
145
149
|
|
|
150
|
+
public deleteContractInstances(data: ContractInstanceWithAddress[], _blockNumber: number): Promise<boolean> {
|
|
151
|
+
for (const contractInstance of data) {
|
|
152
|
+
this.contractInstances.delete(contractInstance.address.toString());
|
|
153
|
+
}
|
|
154
|
+
return Promise.resolve(true);
|
|
155
|
+
}
|
|
156
|
+
|
|
146
157
|
/**
|
|
147
158
|
* Append new blocks to the store's list.
|
|
148
159
|
* @param blocks - The L2 blocks to be added to the store and the last processed L1 block.
|
|
@@ -161,33 +172,58 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
161
172
|
}
|
|
162
173
|
|
|
163
174
|
/**
|
|
164
|
-
*
|
|
165
|
-
* @param
|
|
166
|
-
*
|
|
167
|
-
* @param
|
|
168
|
-
* @returns True if the operation is successful
|
|
175
|
+
* Unwinds blocks from the database
|
|
176
|
+
* @param from - The tip of the chain, passed for verification purposes,
|
|
177
|
+
* ensuring that we don't end up deleting something we did not intend
|
|
178
|
+
* @param blocksToUnwind - The number of blocks we are to unwind
|
|
179
|
+
* @returns True if the operation is successful
|
|
169
180
|
*/
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
blockNumber: number,
|
|
175
|
-
): Promise<boolean> {
|
|
176
|
-
if (noteEncryptedLogs) {
|
|
177
|
-
this.noteEncryptedLogsPerBlock[blockNumber - INITIAL_L2_BLOCK_NUM] = noteEncryptedLogs;
|
|
181
|
+
public async unwindBlocks(from: number, blocksToUnwind: number): Promise<boolean> {
|
|
182
|
+
const last = await this.getSynchedL2BlockNumber();
|
|
183
|
+
if (from != last) {
|
|
184
|
+
throw new Error(`Can only remove the tip`);
|
|
178
185
|
}
|
|
179
186
|
|
|
180
|
-
|
|
181
|
-
|
|
187
|
+
const stopAt = from - blocksToUnwind;
|
|
188
|
+
while ((await this.getSynchedL2BlockNumber()) > stopAt) {
|
|
189
|
+
const block = this.l2Blocks.pop();
|
|
190
|
+
if (block == undefined) {
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
block.data.body.txEffects.forEach(() => this.txEffects.pop());
|
|
182
194
|
}
|
|
183
195
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
196
|
+
return Promise.resolve(true);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Append new logs to the store's list.
|
|
201
|
+
* @param block - The block for which to add the logs.
|
|
202
|
+
* @returns True if the operation is successful.
|
|
203
|
+
*/
|
|
204
|
+
addLogs(blocks: L2Block[]): Promise<boolean> {
|
|
205
|
+
blocks.forEach(block => {
|
|
206
|
+
this.noteEncryptedLogsPerBlock.set(block.number, block.body.noteEncryptedLogs);
|
|
207
|
+
this.encryptedLogsPerBlock.set(block.number, block.body.encryptedLogs);
|
|
208
|
+
this.unencryptedLogsPerBlock.set(block.number, block.body.unencryptedLogs);
|
|
209
|
+
});
|
|
210
|
+
return Promise.resolve(true);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
deleteLogs(blocks: L2Block[]): Promise<boolean> {
|
|
214
|
+
blocks.forEach(block => {
|
|
215
|
+
this.encryptedLogsPerBlock.delete(block.number);
|
|
216
|
+
this.noteEncryptedLogsPerBlock.delete(block.number);
|
|
217
|
+
this.unencryptedLogsPerBlock.delete(block.number);
|
|
218
|
+
});
|
|
187
219
|
|
|
188
220
|
return Promise.resolve(true);
|
|
189
221
|
}
|
|
190
222
|
|
|
223
|
+
getTotalL1ToL2MessageCount(): Promise<bigint> {
|
|
224
|
+
return Promise.resolve(this.l1ToL2Messages.getTotalL1ToL2MessageCount());
|
|
225
|
+
}
|
|
226
|
+
|
|
191
227
|
/**
|
|
192
228
|
* Append L1 to L2 messages to the store.
|
|
193
229
|
* @param messages - The L1 to L2 messages to be added to the store and the last processed L1 block.
|
|
@@ -226,12 +262,15 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
226
262
|
* @remarks When "from" is smaller than genesis block number, blocks from the beginning are returned.
|
|
227
263
|
*/
|
|
228
264
|
public getBlocks(from: number, limit: number): Promise<L1Published<L2Block>[]> {
|
|
229
|
-
// Return an empty array if we are outside of range
|
|
230
265
|
if (limit < 1) {
|
|
231
266
|
return Promise.reject(new Error(`Invalid limit: ${limit}`));
|
|
232
267
|
}
|
|
233
268
|
|
|
234
|
-
|
|
269
|
+
if (from < INITIAL_L2_BLOCK_NUM) {
|
|
270
|
+
return Promise.reject(new Error(`Invalid start: ${from}`));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const fromIndex = from - INITIAL_L2_BLOCK_NUM;
|
|
235
274
|
if (fromIndex >= this.l2Blocks.length) {
|
|
236
275
|
return Promise.resolve([]);
|
|
237
276
|
}
|
|
@@ -240,6 +279,11 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
240
279
|
return Promise.resolve(this.l2Blocks.slice(fromIndex, toIndex));
|
|
241
280
|
}
|
|
242
281
|
|
|
282
|
+
public async getBlockHeaders(from: number, limit: number): Promise<Header[]> {
|
|
283
|
+
const blocks = await this.getBlocks(from, limit);
|
|
284
|
+
return blocks.map(block => block.data.header);
|
|
285
|
+
}
|
|
286
|
+
|
|
243
287
|
/**
|
|
244
288
|
* Gets a tx effect.
|
|
245
289
|
* @param txHash - The txHash of the tx effect.
|
|
@@ -297,9 +341,14 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
297
341
|
logType: TLogType,
|
|
298
342
|
): Promise<L2BlockL2Logs<FromLogType<TLogType>>[]> {
|
|
299
343
|
if (from < INITIAL_L2_BLOCK_NUM || limit < 1) {
|
|
300
|
-
|
|
344
|
+
return Promise.resolve([]);
|
|
301
345
|
}
|
|
302
|
-
|
|
346
|
+
|
|
347
|
+
if (from > this.l2Blocks.length) {
|
|
348
|
+
return Promise.resolve([]);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const logMap = (() => {
|
|
303
352
|
switch (logType) {
|
|
304
353
|
case LogType.ENCRYPTED:
|
|
305
354
|
return this.encryptedLogsPerBlock;
|
|
@@ -309,14 +358,24 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
309
358
|
default:
|
|
310
359
|
return this.unencryptedLogsPerBlock;
|
|
311
360
|
}
|
|
312
|
-
})() as L2BlockL2Logs<FromLogType<TLogType
|
|
361
|
+
})() as Map<number, L2BlockL2Logs<FromLogType<TLogType>>>;
|
|
313
362
|
|
|
314
|
-
|
|
315
|
-
return Promise.resolve([]);
|
|
316
|
-
}
|
|
317
|
-
const startIndex = from - INITIAL_L2_BLOCK_NUM;
|
|
363
|
+
const startIndex = from;
|
|
318
364
|
const endIndex = startIndex + limit;
|
|
319
|
-
|
|
365
|
+
const upper = Math.min(endIndex, this.l2Blocks.length + INITIAL_L2_BLOCK_NUM);
|
|
366
|
+
|
|
367
|
+
const l = [];
|
|
368
|
+
for (let i = startIndex; i < upper; i++) {
|
|
369
|
+
const log = logMap.get(i);
|
|
370
|
+
if (log) {
|
|
371
|
+
l.push(log);
|
|
372
|
+
} else {
|
|
373
|
+
// I hate typescript sometimes
|
|
374
|
+
l.push(undefined as unknown as L2BlockL2Logs<FromLogType<TLogType>>);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return Promise.resolve(l);
|
|
320
379
|
}
|
|
321
380
|
|
|
322
381
|
/**
|
|
@@ -327,37 +386,37 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
327
386
|
*/
|
|
328
387
|
getUnencryptedLogs(filter: LogFilter): Promise<GetUnencryptedLogsResponse> {
|
|
329
388
|
let txHash: TxHash | undefined;
|
|
330
|
-
let
|
|
331
|
-
let
|
|
389
|
+
let fromBlock = 0;
|
|
390
|
+
let toBlock = this.l2Blocks.length + INITIAL_L2_BLOCK_NUM;
|
|
332
391
|
let txIndexInBlock = 0;
|
|
333
392
|
let logIndexInTx = 0;
|
|
334
393
|
|
|
335
394
|
if (filter.afterLog) {
|
|
336
395
|
// Continuation parameter is set --> tx hash is ignored
|
|
337
396
|
if (filter.fromBlock == undefined || filter.fromBlock <= filter.afterLog.blockNumber) {
|
|
338
|
-
|
|
397
|
+
fromBlock = filter.afterLog.blockNumber;
|
|
339
398
|
txIndexInBlock = filter.afterLog.txIndex;
|
|
340
399
|
logIndexInTx = filter.afterLog.logIndex + 1; // We want to start from the next log
|
|
341
400
|
} else {
|
|
342
|
-
|
|
401
|
+
fromBlock = filter.fromBlock;
|
|
343
402
|
}
|
|
344
403
|
} else {
|
|
345
404
|
txHash = filter.txHash;
|
|
346
405
|
|
|
347
406
|
if (filter.fromBlock !== undefined) {
|
|
348
|
-
|
|
407
|
+
fromBlock = filter.fromBlock;
|
|
349
408
|
}
|
|
350
409
|
}
|
|
351
410
|
|
|
352
411
|
if (filter.toBlock !== undefined) {
|
|
353
|
-
|
|
412
|
+
toBlock = filter.toBlock;
|
|
354
413
|
}
|
|
355
414
|
|
|
356
415
|
// Ensure the indices are within block array bounds
|
|
357
|
-
|
|
358
|
-
|
|
416
|
+
fromBlock = Math.max(fromBlock, INITIAL_L2_BLOCK_NUM);
|
|
417
|
+
toBlock = Math.min(toBlock, this.l2Blocks.length + INITIAL_L2_BLOCK_NUM);
|
|
359
418
|
|
|
360
|
-
if (
|
|
419
|
+
if (fromBlock > this.l2Blocks.length || toBlock < fromBlock || toBlock <= 0) {
|
|
361
420
|
return Promise.resolve({
|
|
362
421
|
logs: [],
|
|
363
422
|
maxLogsHit: false,
|
|
@@ -368,27 +427,30 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
368
427
|
|
|
369
428
|
const logs: ExtendedUnencryptedL2Log[] = [];
|
|
370
429
|
|
|
371
|
-
for (;
|
|
372
|
-
const block = this.l2Blocks[
|
|
373
|
-
const blockLogs = this.unencryptedLogsPerBlock
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
for (;
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
430
|
+
for (; fromBlock < toBlock; fromBlock++) {
|
|
431
|
+
const block = this.l2Blocks[fromBlock - INITIAL_L2_BLOCK_NUM];
|
|
432
|
+
const blockLogs = this.unencryptedLogsPerBlock.get(fromBlock);
|
|
433
|
+
|
|
434
|
+
if (blockLogs) {
|
|
435
|
+
for (; txIndexInBlock < blockLogs.txLogs.length; txIndexInBlock++) {
|
|
436
|
+
const txLogs = blockLogs.txLogs[txIndexInBlock].unrollLogs();
|
|
437
|
+
for (; logIndexInTx < txLogs.length; logIndexInTx++) {
|
|
438
|
+
const log = txLogs[logIndexInTx];
|
|
439
|
+
if (
|
|
440
|
+
(!txHash || block.data.body.txEffects[txIndexInBlock].txHash.equals(txHash)) &&
|
|
441
|
+
(!contractAddress || log.contractAddress.equals(contractAddress))
|
|
442
|
+
) {
|
|
443
|
+
logs.push(new ExtendedUnencryptedL2Log(new LogId(block.data.number, txIndexInBlock, logIndexInTx), log));
|
|
444
|
+
if (logs.length === this.maxLogs) {
|
|
445
|
+
return Promise.resolve({
|
|
446
|
+
logs,
|
|
447
|
+
maxLogsHit: true,
|
|
448
|
+
});
|
|
449
|
+
}
|
|
388
450
|
}
|
|
389
451
|
}
|
|
452
|
+
logIndexInTx = 0;
|
|
390
453
|
}
|
|
391
|
-
logIndexInTx = 0;
|
|
392
454
|
}
|
|
393
455
|
txIndexInBlock = 0;
|
|
394
456
|
}
|
|
@@ -414,9 +476,17 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
414
476
|
return Promise.resolve(this.lastProvenL2BlockNumber);
|
|
415
477
|
}
|
|
416
478
|
|
|
417
|
-
public
|
|
418
|
-
this.
|
|
419
|
-
|
|
479
|
+
public getProvenL2EpochNumber(): Promise<number | undefined> {
|
|
480
|
+
return Promise.resolve(this.lastProvenL2EpochNumber);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
public setProvenL2BlockNumber(l2BlockNumber: number): Promise<void> {
|
|
484
|
+
this.lastProvenL2BlockNumber = l2BlockNumber;
|
|
485
|
+
return Promise.resolve();
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
public setProvenL2EpochNumber(l2EpochNumber: number): Promise<void> {
|
|
489
|
+
this.lastProvenL2EpochNumber = l2EpochNumber;
|
|
420
490
|
return Promise.resolve();
|
|
421
491
|
}
|
|
422
492
|
|
|
@@ -434,7 +504,6 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
434
504
|
return Promise.resolve({
|
|
435
505
|
blocksSynchedTo: this.lastL1BlockNewBlocks,
|
|
436
506
|
messagesSynchedTo: this.lastL1BlockNewMessages,
|
|
437
|
-
provenLogsSynchedTo: this.lastL1BlockNewProvenLogs,
|
|
438
507
|
});
|
|
439
508
|
}
|
|
440
509
|
|