@aztec/archiver 0.55.1 → 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 +27 -25
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +391 -169
- package/dest/archiver/archiver_store.d.ts +47 -23
- 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 -42
- package/dest/archiver/config.js +6 -6
- package/dest/archiver/data_retrieval.d.ts +32 -5
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +126 -16
- 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 +22 -3
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +75 -12
- 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 +31 -23
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +65 -38
- 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 +2 -0
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +18 -8
- 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 -39
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +132 -91
- package/dest/index.d.ts +0 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -2
- 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 +531 -248
- package/src/archiver/archiver_store.ts +53 -31
- package/src/archiver/archiver_store_test_suite.ts +93 -81
- package/src/archiver/config.ts +5 -5
- package/src/archiver/data_retrieval.ts +189 -30
- package/src/archiver/epoch_helpers.ts +26 -0
- package/src/archiver/kv_archiver_store/block_store.ts +87 -12
- 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 +74 -47
- package/src/archiver/kv_archiver_store/log_store.ts +18 -18
- package/src/archiver/kv_archiver_store/message_store.ts +18 -5
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +4 -0
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +155 -108
- package/src/index.ts +1 -2
- package/src/test/index.ts +1 -0
- package/src/test/mock_l2_block_source.ts +165 -0
- package/dest/archiver/eth_log_handlers.d.ts +0 -59
- package/dest/archiver/eth_log_handlers.d.ts.map +0 -1
- package/dest/archiver/eth_log_handlers.js +0 -155
- package/dest/archiver/kv_archiver_store/block_body_store.d.ts +0 -34
- package/dest/archiver/kv_archiver_store/block_body_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/block_body_store.js +0 -65
- 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/eth_log_handlers.ts +0 -213
- package/src/archiver/kv_archiver_store/block_body_store.ts +0 -74
- package/src/archiver/kv_archiver_store/proven_store.ts +0 -34
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
var _ArchiverStoreHelper_instances, _ArchiverStoreHelper_log, _ArchiverStoreHelper_updateRegisteredContractClasses, _ArchiverStoreHelper_updateDeployedContractInstances, _ArchiverStoreHelper_storeBroadcastedIndividualFunctions;
|
|
2
|
+
import { __classPrivateFieldGet } from "tslib";
|
|
3
|
+
import { ContractClassRegisteredEvent, ContractInstanceDeployedEvent, PrivateFunctionBroadcastedEvent, UnconstrainedFunctionBroadcastedEvent, isValidPrivateFunctionMembershipProof, isValidUnconstrainedFunctionMembershipProof, } from '@aztec/circuits.js';
|
|
3
4
|
import { createEthereumChain } from '@aztec/ethereum';
|
|
4
|
-
import { compactArray, unique } from '@aztec/foundation/collection';
|
|
5
5
|
import { Fr } from '@aztec/foundation/fields';
|
|
6
6
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
7
7
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
8
8
|
import { Timer } from '@aztec/foundation/timer';
|
|
9
|
-
import { RollupAbi } from '@aztec/l1-artifacts';
|
|
9
|
+
import { InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
10
10
|
import { ClassRegistererAddress } from '@aztec/protocol-contracts/class-registerer';
|
|
11
11
|
import groupBy from 'lodash.groupby';
|
|
12
|
-
import { createPublicClient, getContract, http } from 'viem';
|
|
13
|
-
import { retrieveBlockFromRollup, retrieveL1ToL2Messages
|
|
14
|
-
import {
|
|
12
|
+
import { createPublicClient, getContract, http, } from 'viem';
|
|
13
|
+
import { retrieveBlockFromRollup, retrieveL1ToL2Messages } from './data_retrieval.js';
|
|
14
|
+
import { getEpochNumberAtTimestamp, getSlotAtTimestamp, getSlotRangeForEpoch, getTimestampRangeForEpoch, } from './epoch_helpers.js';
|
|
15
15
|
import { ArchiverInstrumentation } from './instrumentation.js';
|
|
16
16
|
/**
|
|
17
17
|
* Pulls L2 blocks in a non-blocking manner and provides interface for their retrieval.
|
|
@@ -29,16 +29,27 @@ export class Archiver {
|
|
|
29
29
|
* @param store - An archiver data store for storage & retrieval of blocks, encrypted logs & contract data.
|
|
30
30
|
* @param log - A logger.
|
|
31
31
|
*/
|
|
32
|
-
constructor(publicClient, rollupAddress, inboxAddress, registryAddress,
|
|
32
|
+
constructor(publicClient, rollupAddress, inboxAddress, registryAddress, dataStore, pollingIntervalMs, instrumentation, l1constants = EmptyL1RollupConstants, log = createDebugLogger('aztec:archiver')) {
|
|
33
33
|
this.publicClient = publicClient;
|
|
34
34
|
this.rollupAddress = rollupAddress;
|
|
35
35
|
this.inboxAddress = inboxAddress;
|
|
36
36
|
this.registryAddress = registryAddress;
|
|
37
|
-
this.
|
|
37
|
+
this.dataStore = dataStore;
|
|
38
38
|
this.pollingIntervalMs = pollingIntervalMs;
|
|
39
39
|
this.instrumentation = instrumentation;
|
|
40
|
-
this.
|
|
40
|
+
this.l1constants = l1constants;
|
|
41
41
|
this.log = log;
|
|
42
|
+
this.store = new ArchiverStoreHelper(dataStore);
|
|
43
|
+
this.rollup = getContract({
|
|
44
|
+
address: rollupAddress.toString(),
|
|
45
|
+
abi: RollupAbi,
|
|
46
|
+
client: publicClient,
|
|
47
|
+
});
|
|
48
|
+
this.inbox = getContract({
|
|
49
|
+
address: inboxAddress.toString(),
|
|
50
|
+
abi: InboxAbi,
|
|
51
|
+
client: publicClient,
|
|
52
|
+
});
|
|
42
53
|
}
|
|
43
54
|
/**
|
|
44
55
|
* Creates a new instance of the Archiver and blocks until it syncs from chain.
|
|
@@ -59,8 +70,11 @@ export class Archiver {
|
|
|
59
70
|
abi: RollupAbi,
|
|
60
71
|
client: publicClient,
|
|
61
72
|
});
|
|
62
|
-
const l1StartBlock = await
|
|
63
|
-
|
|
73
|
+
const [l1StartBlock, l1GenesisTime] = await Promise.all([
|
|
74
|
+
rollup.read.L1_BLOCK_AT_GENESIS(),
|
|
75
|
+
rollup.read.GENESIS_TIME(),
|
|
76
|
+
]);
|
|
77
|
+
const archiver = new Archiver(publicClient, config.l1Contracts.rollupAddress, config.l1Contracts.inboxAddress, config.l1Contracts.registryAddress, archiverStore, config.archiverPollingIntervalMS ?? 10000, new ArchiverInstrumentation(telemetry), { l1StartBlock, l1GenesisTime });
|
|
64
78
|
await archiver.start(blockUntilSynced);
|
|
65
79
|
return archiver;
|
|
66
80
|
}
|
|
@@ -107,23 +121,9 @@ export class Archiver {
|
|
|
107
121
|
*
|
|
108
122
|
* This code does not handle reorgs.
|
|
109
123
|
*/
|
|
110
|
-
const {
|
|
124
|
+
const { l1StartBlock } = this.l1constants;
|
|
125
|
+
const { blocksSynchedTo = l1StartBlock, messagesSynchedTo = l1StartBlock } = await this.store.getSynchPoint();
|
|
111
126
|
const currentL1BlockNumber = await this.publicClient.getBlockNumber();
|
|
112
|
-
if (currentL1BlockNumber <= blocksSynchedTo &&
|
|
113
|
-
currentL1BlockNumber <= messagesSynchedTo &&
|
|
114
|
-
currentL1BlockNumber <= blockBodiesSynchedTo &&
|
|
115
|
-
currentL1BlockNumber <= provenLogsSynchedTo) {
|
|
116
|
-
// chain hasn't moved forward
|
|
117
|
-
// or it's been rolled back
|
|
118
|
-
this.log.debug(`Nothing to sync`, {
|
|
119
|
-
currentL1BlockNumber,
|
|
120
|
-
blocksSynchedTo,
|
|
121
|
-
messagesSynchedTo,
|
|
122
|
-
provenLogsSynchedTo,
|
|
123
|
-
blockBodiesSynchedTo,
|
|
124
|
-
});
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
127
|
// ********** Ensuring Consistency of data pulled from L1 **********
|
|
128
128
|
/**
|
|
129
129
|
* There are a number of calls in this sync operation to L1 for retrieving
|
|
@@ -142,158 +142,112 @@ export class Archiver {
|
|
|
142
142
|
* in future but for the time being it should give us the guarantees that we need
|
|
143
143
|
*/
|
|
144
144
|
// ********** Events that are processed per L1 block **********
|
|
145
|
+
await this.handleL1ToL2Messages(blockUntilSynced, messagesSynchedTo, currentL1BlockNumber);
|
|
145
146
|
// ********** Events that are processed per L2 block **********
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
// Read all data from chain and then write to our stores at the end
|
|
152
|
-
const nextExpectedL2BlockNum = BigInt((await this.store.getSynchedL2BlockNumber()) + 1);
|
|
153
|
-
this.log.debug(`Retrieving blocks from ${blocksSynchedTo + 1n} to ${currentL1BlockNumber}`);
|
|
154
|
-
const retrievedBlocks = await retrieveBlockFromRollup(this.publicClient, this.rollupAddress, blockUntilSynced, blocksSynchedTo + 1n, currentL1BlockNumber, nextExpectedL2BlockNum);
|
|
155
|
-
// Add the body
|
|
156
|
-
(retrievedBlocks.length ? this.log.verbose : this.log.debug)(`Retrieved ${retrievedBlocks.length || 'no'} new L2 blocks between L1 blocks ${blocksSynchedTo + 1n} and ${currentL1BlockNumber}.`);
|
|
157
|
-
const lastProcessedL1BlockNumber = retrievedBlocks.length > 0 ? retrievedBlocks[retrievedBlocks.length - 1].l1.blockNumber : blocksSynchedTo;
|
|
158
|
-
this.log.debug(`Processing retrieved blocks ${retrievedBlocks
|
|
159
|
-
.map(b => b.data.number)
|
|
160
|
-
.join(',')} with last processed L1 block ${lastProcessedL1BlockNumber}`);
|
|
161
|
-
if (retrievedBlocks.length > 0) {
|
|
162
|
-
await Promise.all(retrievedBlocks.map(block => {
|
|
163
|
-
const noteEncryptedLogs = block.data.body.noteEncryptedLogs;
|
|
164
|
-
const encryptedLogs = block.data.body.encryptedLogs;
|
|
165
|
-
const unencryptedLogs = block.data.body.unencryptedLogs;
|
|
166
|
-
return this.store.addLogs(noteEncryptedLogs, encryptedLogs, unencryptedLogs, block.data.number);
|
|
167
|
-
}));
|
|
168
|
-
// Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them
|
|
169
|
-
await Promise.all(retrievedBlocks.map(async (block) => {
|
|
170
|
-
const blockLogs = block.data.body.txEffects
|
|
171
|
-
.flatMap(txEffect => (txEffect ? [txEffect.unencryptedLogs] : []))
|
|
172
|
-
.flatMap(txLog => txLog.unrollLogs());
|
|
173
|
-
await this.storeRegisteredContractClasses(blockLogs, block.data.number);
|
|
174
|
-
await this.storeDeployedContractInstances(blockLogs, block.data.number);
|
|
175
|
-
await this.storeBroadcastedIndividualFunctions(blockLogs, block.data.number);
|
|
176
|
-
}));
|
|
177
|
-
const timer = new Timer();
|
|
178
|
-
await this.store.addBlockBodies({
|
|
179
|
-
lastProcessedL1BlockNumber: lastProcessedL1BlockNumber,
|
|
180
|
-
retrievedData: retrievedBlocks.map(b => b.data.body),
|
|
181
|
-
});
|
|
182
|
-
await this.store.addBlocks(retrievedBlocks);
|
|
183
|
-
this.instrumentation.processNewBlocks(timer.ms() / retrievedBlocks.length, retrievedBlocks.map(b => b.data));
|
|
184
|
-
const lastL2BlockNumber = retrievedBlocks[retrievedBlocks.length - 1].data.number;
|
|
185
|
-
this.log.verbose(`Processed ${retrievedBlocks.length} new L2 blocks up to ${lastL2BlockNumber}`);
|
|
186
|
-
}
|
|
187
|
-
// Fetch the logs for proven blocks in the block range and update the last proven block number.
|
|
188
|
-
if (currentL1BlockNumber > provenLogsSynchedTo) {
|
|
189
|
-
await this.updateLastProvenL2Block(provenLogsSynchedTo + 1n, currentL1BlockNumber);
|
|
190
|
-
}
|
|
191
|
-
if (retrievedBlocks.length > 0 || blockUntilSynced) {
|
|
192
|
-
(blockUntilSynced ? this.log.info : this.log.verbose)(`Synced to L1 block ${currentL1BlockNumber}`);
|
|
147
|
+
await this.handleL2blocks(blockUntilSynced, blocksSynchedTo, currentL1BlockNumber);
|
|
148
|
+
// Store latest l1 block number and timestamp seen. Used for epoch and slots calculations.
|
|
149
|
+
if (!this.l1BlockNumber || this.l1BlockNumber < currentL1BlockNumber) {
|
|
150
|
+
this.l1Timestamp = await this.publicClient.getBlock({ blockNumber: currentL1BlockNumber }).then(b => b.timestamp);
|
|
151
|
+
this.l1BlockNumber = currentL1BlockNumber;
|
|
193
152
|
}
|
|
194
153
|
}
|
|
195
|
-
async
|
|
196
|
-
|
|
197
|
-
const lastLog = logs[logs.length - 1];
|
|
198
|
-
if (!lastLog) {
|
|
154
|
+
async handleL1ToL2Messages(blockUntilSynced, messagesSynchedTo, currentL1BlockNumber) {
|
|
155
|
+
if (currentL1BlockNumber <= messagesSynchedTo) {
|
|
199
156
|
return;
|
|
200
157
|
}
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
if (provenBlockNumber > currentProvenBlockNumber) {
|
|
208
|
-
// Update the last proven block number
|
|
209
|
-
this.log.verbose(`Updated last proven block number from ${currentProvenBlockNumber} to ${provenBlockNumber}`);
|
|
210
|
-
await this.store.setProvenL2BlockNumber({
|
|
211
|
-
retrievedData: Number(provenBlockNumber),
|
|
212
|
-
lastProcessedL1BlockNumber: lastLog.l1BlockNumber,
|
|
213
|
-
});
|
|
214
|
-
this.instrumentation.updateLastProvenBlock(Number(provenBlockNumber));
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
// We set the last processed L1 block number to the last L1 block number in the range to avoid duplicate processing
|
|
218
|
-
await this.store.setProvenL2BlockNumber({
|
|
219
|
-
retrievedData: Number(currentProvenBlockNumber),
|
|
220
|
-
lastProcessedL1BlockNumber: lastLog.l1BlockNumber,
|
|
221
|
-
});
|
|
158
|
+
const localTotalMessageCount = await this.store.getTotalL1ToL2MessageCount();
|
|
159
|
+
const destinationTotalMessageCount = await this.inbox.read.totalMessagesInserted();
|
|
160
|
+
if (localTotalMessageCount === destinationTotalMessageCount) {
|
|
161
|
+
await this.store.setMessageSynchedL1BlockNumber(currentL1BlockNumber);
|
|
162
|
+
this.log.verbose(`Retrieved no new L1 -> L2 messages between L1 blocks ${messagesSynchedTo + 1n} and ${currentL1BlockNumber}.`);
|
|
163
|
+
return;
|
|
222
164
|
}
|
|
165
|
+
const retrievedL1ToL2Messages = await retrieveL1ToL2Messages(this.inbox, blockUntilSynced, messagesSynchedTo + 1n, currentL1BlockNumber);
|
|
166
|
+
await this.store.addL1ToL2Messages(retrievedL1ToL2Messages);
|
|
167
|
+
this.log.verbose(`Retrieved ${retrievedL1ToL2Messages.retrievedData.length} new L1 -> L2 messages between L1 blocks ${messagesSynchedTo + 1n} and ${currentL1BlockNumber}.`);
|
|
223
168
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
* @param logs - The ProofVerified logs to emit metrics for, as collected from `retrieveL2ProofVerifiedEvents`.
|
|
227
|
-
**/
|
|
228
|
-
async emitProofVerifiedMetrics(logs) {
|
|
229
|
-
if (!logs.length || !this.instrumentation.isEnabled()) {
|
|
169
|
+
async handleL2blocks(blockUntilSynced, blocksSynchedTo, currentL1BlockNumber) {
|
|
170
|
+
if (currentL1BlockNumber <= blocksSynchedTo) {
|
|
230
171
|
return;
|
|
231
172
|
}
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
return undefined;
|
|
173
|
+
const localPendingBlockNumber = BigInt(await this.getBlockNumber());
|
|
174
|
+
const [provenBlockNumber, provenArchive, pendingBlockNumber, pendingArchive, archiveForLocalPendingBlockNumber, provenEpochNumber,] = await this.rollup.read.status([localPendingBlockNumber]);
|
|
175
|
+
const updateProvenBlock = async () => {
|
|
176
|
+
const localBlockForDestinationProvenBlockNumber = await this.getBlock(Number(provenBlockNumber));
|
|
177
|
+
if (localBlockForDestinationProvenBlockNumber &&
|
|
178
|
+
provenArchive === localBlockForDestinationProvenBlockNumber.archive.root.toString()) {
|
|
179
|
+
this.log.info(`Updating the proven block number to ${provenBlockNumber} and epoch to ${provenEpochNumber}`);
|
|
180
|
+
await this.store.setProvenL2BlockNumber(Number(provenBlockNumber));
|
|
181
|
+
// if we are here then we must have a valid proven epoch number
|
|
182
|
+
await this.store.setProvenL2EpochNumber(Number(provenEpochNumber));
|
|
243
183
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const contractClasses = ContractClassRegisteredEvent.fromLogs(allLogs, ClassRegistererAddress).map(e => e.toContractClassPublic());
|
|
253
|
-
if (contractClasses.length > 0) {
|
|
254
|
-
contractClasses.forEach(c => this.log.verbose(`Registering contract class ${c.id.toString()}`));
|
|
255
|
-
await this.store.addContractClasses(contractClasses, blockNum);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Extracts and stores contract instances out of ContractInstanceDeployed events emitted by the canonical deployer contract.
|
|
260
|
-
* @param allLogs - All logs emitted in a bunch of blocks.
|
|
261
|
-
*/
|
|
262
|
-
async storeDeployedContractInstances(allLogs, blockNum) {
|
|
263
|
-
const contractInstances = ContractInstanceDeployedEvent.fromLogs(allLogs).map(e => e.toContractInstance());
|
|
264
|
-
if (contractInstances.length > 0) {
|
|
265
|
-
contractInstances.forEach(c => this.log.verbose(`Storing contract instance at ${c.address.toString()}`));
|
|
266
|
-
await this.store.addContractInstances(contractInstances, blockNum);
|
|
184
|
+
};
|
|
185
|
+
// This is an edge case that we only hit if there are no proposed blocks.
|
|
186
|
+
// If we have 0 blocks locally and there are no blocks onchain there is nothing to do.
|
|
187
|
+
const noBlocks = localPendingBlockNumber === 0n && pendingBlockNumber === 0n;
|
|
188
|
+
if (noBlocks) {
|
|
189
|
+
await this.store.setBlockSynchedL1BlockNumber(currentL1BlockNumber);
|
|
190
|
+
this.log.verbose(`No blocks to retrieve from ${blocksSynchedTo + 1n} to ${currentL1BlockNumber}`);
|
|
191
|
+
return;
|
|
267
192
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
//
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
const contractClassId = Fr.fromString(classIdString);
|
|
276
|
-
const contractClass = await this.store.getContractClass(contractClassId);
|
|
277
|
-
if (!contractClass) {
|
|
278
|
-
this.log.warn(`Skipping broadcasted functions as contract class ${contractClassId.toString()} was not found`);
|
|
279
|
-
continue;
|
|
193
|
+
await updateProvenBlock();
|
|
194
|
+
// Related to the L2 reorgs of the pending chain. We are only interested in actually addressing a reorg if there
|
|
195
|
+
// are any state that could be impacted by it. If we have no blocks, there is no impact.
|
|
196
|
+
if (localPendingBlockNumber > 0) {
|
|
197
|
+
const localPendingBlock = await this.getBlock(Number(localPendingBlockNumber));
|
|
198
|
+
if (localPendingBlock === undefined) {
|
|
199
|
+
throw new Error(`Missing block ${localPendingBlockNumber}`);
|
|
280
200
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
const validUnconstrainedFns = unconstrainedFns.filter(fn => isValidUnconstrainedFunctionMembershipProof(fn, contractClass));
|
|
287
|
-
const validFnCount = validPrivateFns.length + validUnconstrainedFns.length;
|
|
288
|
-
if (validFnCount !== allFns.length) {
|
|
289
|
-
this.log.warn(`Skipping ${allFns.length - validFnCount} invalid functions`);
|
|
201
|
+
const noBlockSinceLast = localPendingBlock && pendingArchive === localPendingBlock.archive.root.toString();
|
|
202
|
+
if (noBlockSinceLast) {
|
|
203
|
+
await this.store.setBlockSynchedL1BlockNumber(currentL1BlockNumber);
|
|
204
|
+
this.log.verbose(`No blocks to retrieve from ${blocksSynchedTo + 1n} to ${currentL1BlockNumber}`);
|
|
205
|
+
return;
|
|
290
206
|
}
|
|
291
|
-
|
|
292
|
-
if (
|
|
293
|
-
|
|
207
|
+
const localPendingBlockInChain = archiveForLocalPendingBlockNumber === localPendingBlock.archive.root.toString();
|
|
208
|
+
if (!localPendingBlockInChain) {
|
|
209
|
+
// If our local pending block tip is not in the chain on L1 a "prune" must have happened
|
|
210
|
+
// or the L1 have reorged.
|
|
211
|
+
// In any case, we have to figure out how far into the past the action will take us.
|
|
212
|
+
// For simplicity here, we will simply rewind until we end in a block that is also on the chain on L1.
|
|
213
|
+
this.log.verbose(`L2 prune have occurred, unwind state`);
|
|
214
|
+
let tipAfterUnwind = localPendingBlockNumber;
|
|
215
|
+
while (true) {
|
|
216
|
+
const candidateBlock = await this.getBlock(Number(tipAfterUnwind));
|
|
217
|
+
if (candidateBlock === undefined) {
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
const archiveAtContract = await this.rollup.read.archiveAt([BigInt(candidateBlock.number)]);
|
|
221
|
+
if (archiveAtContract === candidateBlock.archive.root.toString()) {
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
tipAfterUnwind--;
|
|
225
|
+
}
|
|
226
|
+
const blocksToUnwind = localPendingBlockNumber - tipAfterUnwind;
|
|
227
|
+
this.log.verbose(`Unwinding ${blocksToUnwind} block${blocksToUnwind > 1n ? 's' : ''} from block ${localPendingBlockNumber}`);
|
|
228
|
+
await this.store.unwindBlocks(Number(localPendingBlockNumber), Number(blocksToUnwind));
|
|
294
229
|
}
|
|
295
|
-
await this.store.addFunctions(contractClassId, validPrivateFns, validUnconstrainedFns);
|
|
296
230
|
}
|
|
231
|
+
this.log.debug(`Retrieving blocks from ${blocksSynchedTo + 1n} to ${currentL1BlockNumber}`);
|
|
232
|
+
const retrievedBlocks = await retrieveBlockFromRollup(this.rollup, this.publicClient, blockUntilSynced, blocksSynchedTo + 1n, currentL1BlockNumber, this.log);
|
|
233
|
+
if (retrievedBlocks.length === 0) {
|
|
234
|
+
// We are not calling `setBlockSynchedL1BlockNumber` because it may cause sync issues if based off infura.
|
|
235
|
+
// See further details in earlier comments.
|
|
236
|
+
this.log.verbose(`Retrieved no new blocks from ${blocksSynchedTo + 1n} to ${currentL1BlockNumber}`);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
this.log.debug(`Retrieved ${retrievedBlocks.length} new L2 blocks between L1 blocks ${blocksSynchedTo + 1n} and ${currentL1BlockNumber}.`);
|
|
240
|
+
const lastProcessedL1BlockNumber = retrievedBlocks[retrievedBlocks.length - 1].l1.blockNumber;
|
|
241
|
+
this.log.debug(`Processing retrieved blocks ${retrievedBlocks
|
|
242
|
+
.map(b => b.data.number)
|
|
243
|
+
.join(',')} with last processed L1 block ${lastProcessedL1BlockNumber}`);
|
|
244
|
+
const timer = new Timer();
|
|
245
|
+
await this.store.addBlocks(retrievedBlocks);
|
|
246
|
+
// Important that we update AFTER inserting the blocks.
|
|
247
|
+
await updateProvenBlock();
|
|
248
|
+
this.instrumentation.processNewBlocks(timer.ms() / retrievedBlocks.length, retrievedBlocks.map(b => b.data));
|
|
249
|
+
const lastL2BlockNumber = retrievedBlocks[retrievedBlocks.length - 1].data.number;
|
|
250
|
+
this.log.verbose(`Processed ${retrievedBlocks.length} new L2 blocks up to ${lastL2BlockNumber}`);
|
|
297
251
|
}
|
|
298
252
|
/**
|
|
299
253
|
* Stops the archiver.
|
|
@@ -311,6 +265,58 @@ export class Archiver {
|
|
|
311
265
|
getRegistryAddress() {
|
|
312
266
|
return Promise.resolve(this.registryAddress);
|
|
313
267
|
}
|
|
268
|
+
getL1BlockNumber() {
|
|
269
|
+
const l1BlockNumber = this.l1BlockNumber;
|
|
270
|
+
if (!l1BlockNumber) {
|
|
271
|
+
throw new Error('L1 block number not yet available. Complete an initial sync first.');
|
|
272
|
+
}
|
|
273
|
+
return l1BlockNumber;
|
|
274
|
+
}
|
|
275
|
+
getL1Timestamp() {
|
|
276
|
+
const l1Timestamp = this.l1Timestamp;
|
|
277
|
+
if (!l1Timestamp) {
|
|
278
|
+
throw new Error('L1 timestamp not yet available. Complete an initial sync first.');
|
|
279
|
+
}
|
|
280
|
+
return l1Timestamp;
|
|
281
|
+
}
|
|
282
|
+
getL2SlotNumber() {
|
|
283
|
+
return Promise.resolve(getSlotAtTimestamp(this.getL1Timestamp(), this.l1constants));
|
|
284
|
+
}
|
|
285
|
+
getL2EpochNumber() {
|
|
286
|
+
return Promise.resolve(getEpochNumberAtTimestamp(this.getL1Timestamp(), this.l1constants));
|
|
287
|
+
}
|
|
288
|
+
async getBlocksForEpoch(epochNumber) {
|
|
289
|
+
const [start, end] = getSlotRangeForEpoch(epochNumber);
|
|
290
|
+
const blocks = [];
|
|
291
|
+
// Walk the list of blocks backwards and filter by slots matching the requested epoch.
|
|
292
|
+
// We'll typically ask for blocks for a very recent epoch, so we shouldn't need an index here.
|
|
293
|
+
let block = await this.getBlock(await this.store.getSynchedL2BlockNumber());
|
|
294
|
+
const slot = (b) => b.header.globalVariables.slotNumber.toBigInt();
|
|
295
|
+
while (block && slot(block) >= start) {
|
|
296
|
+
if (slot(block) <= end) {
|
|
297
|
+
blocks.push(block);
|
|
298
|
+
}
|
|
299
|
+
block = await this.getBlock(block.number - 1);
|
|
300
|
+
}
|
|
301
|
+
return blocks.reverse();
|
|
302
|
+
}
|
|
303
|
+
async isEpochComplete(epochNumber) {
|
|
304
|
+
// The epoch is complete if the current L2 block is the last one in the epoch (or later)
|
|
305
|
+
const header = await this.getBlockHeader('latest');
|
|
306
|
+
const slot = header?.globalVariables.slotNumber.toBigInt();
|
|
307
|
+
const [_startSlot, endSlot] = getSlotRangeForEpoch(epochNumber);
|
|
308
|
+
if (slot && slot >= endSlot) {
|
|
309
|
+
return true;
|
|
310
|
+
}
|
|
311
|
+
// If not, the epoch may also be complete if the L2 slot has passed without a block
|
|
312
|
+
// We compute this based on the timestamp for the given epoch and the timestamp of the last L1 block
|
|
313
|
+
const l1Timestamp = this.getL1Timestamp();
|
|
314
|
+
const [_startTimestamp, endTimestamp] = getTimestampRangeForEpoch(epochNumber, this.l1constants);
|
|
315
|
+
// For this computation, we throw in a few extra seconds just for good measure,
|
|
316
|
+
// since we know the next L1 block won't be mined within this range
|
|
317
|
+
const leeway = 3n;
|
|
318
|
+
return l1Timestamp + leeway >= endTimestamp;
|
|
319
|
+
}
|
|
314
320
|
/**
|
|
315
321
|
* Gets up to `limit` amount of L2 blocks starting from `from`.
|
|
316
322
|
* @param from - Number of the first block to return (inclusive).
|
|
@@ -326,7 +332,7 @@ export class Archiver {
|
|
|
326
332
|
}
|
|
327
333
|
/**
|
|
328
334
|
* Gets an l2 block.
|
|
329
|
-
* @param number - The block number to return
|
|
335
|
+
* @param number - The block number to return.
|
|
330
336
|
* @returns The requested L2 block.
|
|
331
337
|
*/
|
|
332
338
|
async getBlock(number) {
|
|
@@ -334,9 +340,19 @@ export class Archiver {
|
|
|
334
340
|
if (number < 0) {
|
|
335
341
|
number = await this.store.getSynchedL2BlockNumber();
|
|
336
342
|
}
|
|
343
|
+
if (number == 0) {
|
|
344
|
+
return undefined;
|
|
345
|
+
}
|
|
337
346
|
const blocks = await this.store.getBlocks(number, 1);
|
|
338
347
|
return blocks.length === 0 ? undefined : blocks[0].data;
|
|
339
348
|
}
|
|
349
|
+
async getBlockHeader(number) {
|
|
350
|
+
if (number === 'latest') {
|
|
351
|
+
number = await this.store.getSynchedL2BlockNumber();
|
|
352
|
+
}
|
|
353
|
+
const headers = await this.store.getBlockHeaders(number, 1);
|
|
354
|
+
return headers.length === 0 ? undefined : headers[0];
|
|
355
|
+
}
|
|
340
356
|
getTxEffect(txHash) {
|
|
341
357
|
return this.store.getTxEffect(txHash);
|
|
342
358
|
}
|
|
@@ -388,9 +404,12 @@ export class Archiver {
|
|
|
388
404
|
getProvenBlockNumber() {
|
|
389
405
|
return this.store.getProvenL2BlockNumber();
|
|
390
406
|
}
|
|
407
|
+
getProvenL2EpochNumber() {
|
|
408
|
+
return this.store.getProvenL2EpochNumber();
|
|
409
|
+
}
|
|
391
410
|
/** Forcefully updates the last proven block number. Use for testing. */
|
|
392
|
-
setProvenBlockNumber(
|
|
393
|
-
return this.store.setProvenL2BlockNumber(
|
|
411
|
+
setProvenBlockNumber(blockNumber) {
|
|
412
|
+
return this.store.setProvenL2BlockNumber(blockNumber);
|
|
394
413
|
}
|
|
395
414
|
getContractClass(id) {
|
|
396
415
|
return this.store.getContractClass(id);
|
|
@@ -425,4 +444,207 @@ export class Archiver {
|
|
|
425
444
|
return this.store.getContractArtifact(address);
|
|
426
445
|
}
|
|
427
446
|
}
|
|
428
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJjaGl2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXJjaGl2ZXIvYXJjaGl2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBZUEsT0FBTyxFQUFFLDRCQUE0QixFQUF5QixNQUFNLG9CQUFvQixDQUFDO0FBQ3pGLE9BQU8sRUFDTCw2QkFBNkIsRUFDN0IsK0JBQStCLEVBQy9CLHFDQUFxQyxFQUNyQyxxQ0FBcUMsRUFDckMsMkNBQTJDLEdBQzVDLE1BQU0sNkJBQTZCLENBQUM7QUFDckMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHdEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUVwRSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDOUMsT0FBTyxFQUFvQixpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzVFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBV3BGLE9BQU8sT0FBTyxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sRUFBcUQsa0JBQWtCLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUloSCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsc0JBQXNCLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNySCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDdkQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFRL0Q7Ozs7R0FJRztBQUNILE1BQU0s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
|
|
447
|
+
var Operation;
|
|
448
|
+
(function (Operation) {
|
|
449
|
+
Operation[Operation["Store"] = 0] = "Store";
|
|
450
|
+
Operation[Operation["Delete"] = 1] = "Delete";
|
|
451
|
+
})(Operation || (Operation = {}));
|
|
452
|
+
/**
|
|
453
|
+
* A helper class that we use to deal with some of the logic needed when adding blocks.
|
|
454
|
+
*
|
|
455
|
+
* I would have preferred to not have this type. But it is useful for handling the logic that any
|
|
456
|
+
* store would need to include otherwise while exposing fewer functions and logic directly to the archiver.
|
|
457
|
+
*/
|
|
458
|
+
class ArchiverStoreHelper {
|
|
459
|
+
constructor(store) {
|
|
460
|
+
_ArchiverStoreHelper_instances.add(this);
|
|
461
|
+
this.store = store;
|
|
462
|
+
_ArchiverStoreHelper_log.set(this, createDebugLogger('aztec:archiver:block-helper'));
|
|
463
|
+
}
|
|
464
|
+
async addBlocks(blocks) {
|
|
465
|
+
return [
|
|
466
|
+
this.store.addLogs(blocks.map(block => block.data)),
|
|
467
|
+
// Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them
|
|
468
|
+
...(await Promise.all(blocks.map(async (block) => {
|
|
469
|
+
const blockLogs = block.data.body.txEffects
|
|
470
|
+
.flatMap(txEffect => (txEffect ? [txEffect.unencryptedLogs] : []))
|
|
471
|
+
.flatMap(txLog => txLog.unrollLogs());
|
|
472
|
+
return (await Promise.all([
|
|
473
|
+
__classPrivateFieldGet(this, _ArchiverStoreHelper_instances, "m", _ArchiverStoreHelper_updateRegisteredContractClasses).call(this, blockLogs, block.data.number, Operation.Store),
|
|
474
|
+
__classPrivateFieldGet(this, _ArchiverStoreHelper_instances, "m", _ArchiverStoreHelper_updateDeployedContractInstances).call(this, blockLogs, block.data.number, Operation.Store),
|
|
475
|
+
__classPrivateFieldGet(this, _ArchiverStoreHelper_instances, "m", _ArchiverStoreHelper_storeBroadcastedIndividualFunctions).call(this, blockLogs, block.data.number),
|
|
476
|
+
])).every(Boolean);
|
|
477
|
+
}))),
|
|
478
|
+
this.store.addBlocks(blocks),
|
|
479
|
+
].every(Boolean);
|
|
480
|
+
}
|
|
481
|
+
async unwindBlocks(from, blocksToUnwind) {
|
|
482
|
+
const last = await this.getSynchedL2BlockNumber();
|
|
483
|
+
if (from != last) {
|
|
484
|
+
throw new Error(`Can only remove from the tip`);
|
|
485
|
+
}
|
|
486
|
+
// from - blocksToUnwind = the new head, so + 1 for what we need to remove
|
|
487
|
+
const blocks = await this.getBlocks(from - blocksToUnwind + 1, blocksToUnwind);
|
|
488
|
+
return [
|
|
489
|
+
// Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them
|
|
490
|
+
...(await Promise.all(blocks.map(async (block) => {
|
|
491
|
+
const blockLogs = block.data.body.txEffects
|
|
492
|
+
.flatMap(txEffect => (txEffect ? [txEffect.unencryptedLogs] : []))
|
|
493
|
+
.flatMap(txLog => txLog.unrollLogs());
|
|
494
|
+
await __classPrivateFieldGet(this, _ArchiverStoreHelper_instances, "m", _ArchiverStoreHelper_updateRegisteredContractClasses).call(this, blockLogs, block.data.number, Operation.Delete);
|
|
495
|
+
await __classPrivateFieldGet(this, _ArchiverStoreHelper_instances, "m", _ArchiverStoreHelper_updateDeployedContractInstances).call(this, blockLogs, block.data.number, Operation.Delete);
|
|
496
|
+
}))),
|
|
497
|
+
this.store.deleteLogs(blocks.map(b => b.data)),
|
|
498
|
+
this.store.unwindBlocks(from, blocksToUnwind),
|
|
499
|
+
].every(Boolean);
|
|
500
|
+
}
|
|
501
|
+
getBlocks(from, limit) {
|
|
502
|
+
return this.store.getBlocks(from, limit);
|
|
503
|
+
}
|
|
504
|
+
getBlockHeaders(from, limit) {
|
|
505
|
+
return this.store.getBlockHeaders(from, limit);
|
|
506
|
+
}
|
|
507
|
+
getTxEffect(txHash) {
|
|
508
|
+
return this.store.getTxEffect(txHash);
|
|
509
|
+
}
|
|
510
|
+
getSettledTxReceipt(txHash) {
|
|
511
|
+
return this.store.getSettledTxReceipt(txHash);
|
|
512
|
+
}
|
|
513
|
+
addL1ToL2Messages(messages) {
|
|
514
|
+
return this.store.addL1ToL2Messages(messages);
|
|
515
|
+
}
|
|
516
|
+
getL1ToL2Messages(blockNumber) {
|
|
517
|
+
return this.store.getL1ToL2Messages(blockNumber);
|
|
518
|
+
}
|
|
519
|
+
getL1ToL2MessageIndex(l1ToL2Message, startIndex) {
|
|
520
|
+
return this.store.getL1ToL2MessageIndex(l1ToL2Message, startIndex);
|
|
521
|
+
}
|
|
522
|
+
getLogs(from, limit, logType) {
|
|
523
|
+
return this.store.getLogs(from, limit, logType);
|
|
524
|
+
}
|
|
525
|
+
getUnencryptedLogs(filter) {
|
|
526
|
+
return this.store.getUnencryptedLogs(filter);
|
|
527
|
+
}
|
|
528
|
+
getSynchedL2BlockNumber() {
|
|
529
|
+
return this.store.getSynchedL2BlockNumber();
|
|
530
|
+
}
|
|
531
|
+
getProvenL2BlockNumber() {
|
|
532
|
+
return this.store.getProvenL2BlockNumber();
|
|
533
|
+
}
|
|
534
|
+
getProvenL2EpochNumber() {
|
|
535
|
+
return this.store.getProvenL2EpochNumber();
|
|
536
|
+
}
|
|
537
|
+
setProvenL2BlockNumber(l2BlockNumber) {
|
|
538
|
+
return this.store.setProvenL2BlockNumber(l2BlockNumber);
|
|
539
|
+
}
|
|
540
|
+
setProvenL2EpochNumber(l2EpochNumber) {
|
|
541
|
+
return this.store.setProvenL2EpochNumber(l2EpochNumber);
|
|
542
|
+
}
|
|
543
|
+
setBlockSynchedL1BlockNumber(l1BlockNumber) {
|
|
544
|
+
return this.store.setBlockSynchedL1BlockNumber(l1BlockNumber);
|
|
545
|
+
}
|
|
546
|
+
setMessageSynchedL1BlockNumber(l1BlockNumber) {
|
|
547
|
+
return this.store.setMessageSynchedL1BlockNumber(l1BlockNumber);
|
|
548
|
+
}
|
|
549
|
+
getSynchPoint() {
|
|
550
|
+
return this.store.getSynchPoint();
|
|
551
|
+
}
|
|
552
|
+
getContractClass(id) {
|
|
553
|
+
return this.store.getContractClass(id);
|
|
554
|
+
}
|
|
555
|
+
getContractInstance(address) {
|
|
556
|
+
return this.store.getContractInstance(address);
|
|
557
|
+
}
|
|
558
|
+
getContractClassIds() {
|
|
559
|
+
return this.store.getContractClassIds();
|
|
560
|
+
}
|
|
561
|
+
addContractArtifact(address, contract) {
|
|
562
|
+
return this.store.addContractArtifact(address, contract);
|
|
563
|
+
}
|
|
564
|
+
getContractArtifact(address) {
|
|
565
|
+
return this.store.getContractArtifact(address);
|
|
566
|
+
}
|
|
567
|
+
getTotalL1ToL2MessageCount() {
|
|
568
|
+
return this.store.getTotalL1ToL2MessageCount();
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
_ArchiverStoreHelper_log = new WeakMap(), _ArchiverStoreHelper_instances = new WeakSet(), _ArchiverStoreHelper_updateRegisteredContractClasses =
|
|
572
|
+
/**
|
|
573
|
+
* Extracts and stores contract classes out of ContractClassRegistered events emitted by the class registerer contract.
|
|
574
|
+
* @param allLogs - All logs emitted in a bunch of blocks.
|
|
575
|
+
*/
|
|
576
|
+
async function _ArchiverStoreHelper_updateRegisteredContractClasses(allLogs, blockNum, operation) {
|
|
577
|
+
const contractClasses = ContractClassRegisteredEvent.fromLogs(allLogs, ClassRegistererAddress).map(e => e.toContractClassPublic());
|
|
578
|
+
if (contractClasses.length > 0) {
|
|
579
|
+
contractClasses.forEach(c => __classPrivateFieldGet(this, _ArchiverStoreHelper_log, "f").verbose(`Registering contract class ${c.id.toString()}`));
|
|
580
|
+
if (operation == Operation.Store) {
|
|
581
|
+
return await this.store.addContractClasses(contractClasses, blockNum);
|
|
582
|
+
}
|
|
583
|
+
else if (operation == Operation.Delete) {
|
|
584
|
+
return await this.store.deleteContractClasses(contractClasses, blockNum);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
return true;
|
|
588
|
+
}, _ArchiverStoreHelper_updateDeployedContractInstances =
|
|
589
|
+
/**
|
|
590
|
+
* Extracts and stores contract instances out of ContractInstanceDeployed events emitted by the canonical deployer contract.
|
|
591
|
+
* @param allLogs - All logs emitted in a bunch of blocks.
|
|
592
|
+
*/
|
|
593
|
+
async function _ArchiverStoreHelper_updateDeployedContractInstances(allLogs, blockNum, operation) {
|
|
594
|
+
const contractInstances = ContractInstanceDeployedEvent.fromLogs(allLogs).map(e => e.toContractInstance());
|
|
595
|
+
if (contractInstances.length > 0) {
|
|
596
|
+
contractInstances.forEach(c => __classPrivateFieldGet(this, _ArchiverStoreHelper_log, "f").verbose(`${Operation[operation]} contract instance at ${c.address.toString()}`));
|
|
597
|
+
if (operation == Operation.Store) {
|
|
598
|
+
return await this.store.addContractInstances(contractInstances, blockNum);
|
|
599
|
+
}
|
|
600
|
+
else if (operation == Operation.Delete) {
|
|
601
|
+
return await this.store.deleteContractInstances(contractInstances, blockNum);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return true;
|
|
605
|
+
}, _ArchiverStoreHelper_storeBroadcastedIndividualFunctions =
|
|
606
|
+
/**
|
|
607
|
+
* Stores the functions that was broadcasted individually
|
|
608
|
+
*
|
|
609
|
+
* @dev Beware that there is not a delete variant of this, since they are added to contract classes
|
|
610
|
+
* and will be deleted as part of the class if needed.
|
|
611
|
+
*
|
|
612
|
+
* @param allLogs - The logs from the block
|
|
613
|
+
* @param _blockNum - The block number
|
|
614
|
+
* @returns
|
|
615
|
+
*/
|
|
616
|
+
async function _ArchiverStoreHelper_storeBroadcastedIndividualFunctions(allLogs, _blockNum) {
|
|
617
|
+
// Filter out private and unconstrained function broadcast events
|
|
618
|
+
const privateFnEvents = PrivateFunctionBroadcastedEvent.fromLogs(allLogs, ClassRegistererAddress);
|
|
619
|
+
const unconstrainedFnEvents = UnconstrainedFunctionBroadcastedEvent.fromLogs(allLogs, ClassRegistererAddress);
|
|
620
|
+
// Group all events by contract class id
|
|
621
|
+
for (const [classIdString, classEvents] of Object.entries(groupBy([...privateFnEvents, ...unconstrainedFnEvents], e => e.contractClassId.toString()))) {
|
|
622
|
+
const contractClassId = Fr.fromString(classIdString);
|
|
623
|
+
const contractClass = await this.getContractClass(contractClassId);
|
|
624
|
+
if (!contractClass) {
|
|
625
|
+
__classPrivateFieldGet(this, _ArchiverStoreHelper_log, "f").warn(`Skipping broadcasted functions as contract class ${contractClassId.toString()} was not found`);
|
|
626
|
+
continue;
|
|
627
|
+
}
|
|
628
|
+
// Split private and unconstrained functions, and filter out invalid ones
|
|
629
|
+
const allFns = classEvents.map(e => e.toFunctionWithMembershipProof());
|
|
630
|
+
const privateFns = allFns.filter((fn) => 'unconstrainedFunctionsArtifactTreeRoot' in fn);
|
|
631
|
+
const unconstrainedFns = allFns.filter((fn) => 'privateFunctionsArtifactTreeRoot' in fn);
|
|
632
|
+
const validPrivateFns = privateFns.filter(fn => isValidPrivateFunctionMembershipProof(fn, contractClass));
|
|
633
|
+
const validUnconstrainedFns = unconstrainedFns.filter(fn => isValidUnconstrainedFunctionMembershipProof(fn, contractClass));
|
|
634
|
+
const validFnCount = validPrivateFns.length + validUnconstrainedFns.length;
|
|
635
|
+
if (validFnCount !== allFns.length) {
|
|
636
|
+
__classPrivateFieldGet(this, _ArchiverStoreHelper_log, "f").warn(`Skipping ${allFns.length - validFnCount} invalid functions`);
|
|
637
|
+
}
|
|
638
|
+
// Store the functions in the contract class in a single operation
|
|
639
|
+
if (validFnCount > 0) {
|
|
640
|
+
__classPrivateFieldGet(this, _ArchiverStoreHelper_log, "f").verbose(`Storing ${validFnCount} functions for contract class ${contractClassId.toString()}`);
|
|
641
|
+
}
|
|
642
|
+
return await this.store.addFunctions(contractClassId, validPrivateFns, validUnconstrainedFns);
|
|
643
|
+
}
|
|
644
|
+
return true;
|
|
645
|
+
};
|
|
646
|
+
const EmptyL1RollupConstants = {
|
|
647
|
+
l1StartBlock: 0n,
|
|
648
|
+
l1GenesisTime: 0n,
|
|
649
|
+
};
|
|
650
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJjaGl2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXJjaGl2ZXIvYXJjaGl2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFnQkEsT0FBTyxFQUNMLDRCQUE0QixFQUM1Qiw2QkFBNkIsRUFHN0IsK0JBQStCLEVBQy9CLHFDQUFxQyxFQUNyQyxxQ0FBcUMsRUFDckMsMkNBQTJDLEdBQzVDLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFJdEQsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzlDLE9BQU8sRUFBb0IsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM1RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDbkUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDMUQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFXcEYsT0FBTyxPQUFPLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxFQUtMLGtCQUFrQixFQUNsQixXQUFXLEVBQ1gsSUFBSSxHQUNMLE1BQU0sTUFBTSxDQUFDO0FBSWQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLHNCQUFzQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEYsT0FBTyxFQUNMLHlCQUF5QixFQUN6QixrQkFBa0IsRUFDbEIsb0JBQW9CLEVBQ3BCLHlCQUF5QixHQUMxQixNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBUy9EOzs7O0dBSUc7QUFDSCxNQUFNLE9BQU8sUUFBUTtJQWNuQjs7Ozs7Ozs7O09BU0c7SUFDSCxZQUNtQixZQUFn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
|