@aztec/validator-client 0.0.1-commit.6d3c34e → 0.0.1-commit.7035c9bd6
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 +94 -24
- package/dest/block_proposal_handler.d.ts +12 -11
- package/dest/block_proposal_handler.d.ts.map +1 -1
- package/dest/block_proposal_handler.js +140 -77
- package/dest/checkpoint_builder.d.ts +35 -26
- package/dest/checkpoint_builder.d.ts.map +1 -1
- package/dest/checkpoint_builder.js +144 -48
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +33 -14
- package/dest/duties/validation_service.d.ts +20 -7
- package/dest/duties/validation_service.d.ts.map +1 -1
- package/dest/duties/validation_service.js +69 -22
- package/dest/factory.d.ts +4 -2
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +4 -3
- package/dest/index.d.ts +1 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +0 -1
- package/dest/key_store/ha_key_store.d.ts +99 -0
- package/dest/key_store/ha_key_store.d.ts.map +1 -0
- package/dest/key_store/ha_key_store.js +208 -0
- package/dest/key_store/index.d.ts +2 -1
- package/dest/key_store/index.d.ts.map +1 -1
- package/dest/key_store/index.js +1 -0
- package/dest/key_store/interface.d.ts +36 -6
- package/dest/key_store/interface.d.ts.map +1 -1
- package/dest/key_store/local_key_store.d.ts +10 -5
- package/dest/key_store/local_key_store.d.ts.map +1 -1
- package/dest/key_store/local_key_store.js +8 -4
- package/dest/key_store/node_keystore_adapter.d.ts +18 -5
- package/dest/key_store/node_keystore_adapter.d.ts.map +1 -1
- package/dest/key_store/node_keystore_adapter.js +18 -4
- package/dest/key_store/web3signer_key_store.d.ts +10 -5
- package/dest/key_store/web3signer_key_store.d.ts.map +1 -1
- package/dest/key_store/web3signer_key_store.js +8 -4
- package/dest/metrics.d.ts +12 -3
- package/dest/metrics.d.ts.map +1 -1
- package/dest/metrics.js +46 -5
- package/dest/validator.d.ts +45 -18
- package/dest/validator.d.ts.map +1 -1
- package/dest/validator.js +276 -107
- package/package.json +21 -17
- package/src/block_proposal_handler.ts +171 -95
- package/src/checkpoint_builder.ts +211 -61
- package/src/config.ts +32 -13
- package/src/duties/validation_service.ts +94 -25
- package/src/factory.ts +5 -0
- package/src/index.ts +0 -1
- package/src/key_store/ha_key_store.ts +269 -0
- package/src/key_store/index.ts +1 -0
- package/src/key_store/interface.ts +44 -5
- package/src/key_store/local_key_store.ts +13 -4
- package/src/key_store/node_keystore_adapter.ts +27 -4
- package/src/key_store/web3signer_key_store.ts +17 -4
- package/src/metrics.ts +63 -6
- package/src/validator.ts +354 -130
- package/dest/tx_validator/index.d.ts +0 -3
- package/dest/tx_validator/index.d.ts.map +0 -1
- package/dest/tx_validator/index.js +0 -2
- package/dest/tx_validator/nullifier_cache.d.ts +0 -14
- package/dest/tx_validator/nullifier_cache.d.ts.map +0 -1
- package/dest/tx_validator/nullifier_cache.js +0 -24
- package/dest/tx_validator/tx_validator_factory.d.ts +0 -18
- package/dest/tx_validator/tx_validator_factory.d.ts.map +0 -1
- package/dest/tx_validator/tx_validator_factory.js +0 -53
- package/src/tx_validator/index.ts +0 -2
- package/src/tx_validator/nullifier_cache.ts +0 -30
- package/src/tx_validator/tx_validator_factory.ts +0 -133
|
@@ -65,14 +65,17 @@ function _ts_dispose_resources(env) {
|
|
|
65
65
|
}
|
|
66
66
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
67
67
|
import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
68
|
+
import { pick } from '@aztec/foundation/collection';
|
|
68
69
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
69
70
|
import { TimeoutError } from '@aztec/foundation/error';
|
|
70
71
|
import { createLogger } from '@aztec/foundation/log';
|
|
71
72
|
import { retryUntil } from '@aztec/foundation/retry';
|
|
72
73
|
import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
73
|
-
import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
74
|
+
import { getEpochAtSlot, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
75
|
+
import { Gas } from '@aztec/stdlib/gas';
|
|
74
76
|
import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
|
|
75
|
-
import {
|
|
77
|
+
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
78
|
+
import { ReExFailedTxsError, ReExInitialStateMismatchError, ReExStateMismatchError, ReExTimeoutError, TransactionsNotAvailableError } from '@aztec/stdlib/validators';
|
|
76
79
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
77
80
|
export class BlockProposalHandler {
|
|
78
81
|
checkpointsBuilder;
|
|
@@ -81,18 +84,20 @@ export class BlockProposalHandler {
|
|
|
81
84
|
l1ToL2MessageSource;
|
|
82
85
|
txProvider;
|
|
83
86
|
blockProposalValidator;
|
|
87
|
+
epochCache;
|
|
84
88
|
config;
|
|
85
89
|
metrics;
|
|
86
90
|
dateProvider;
|
|
87
91
|
log;
|
|
88
92
|
tracer;
|
|
89
|
-
constructor(checkpointsBuilder, worldState, blockSource, l1ToL2MessageSource, txProvider, blockProposalValidator, config, metrics, dateProvider = new DateProvider(), telemetry = getTelemetryClient(), log = createLogger('validator:block-proposal-handler')){
|
|
93
|
+
constructor(checkpointsBuilder, worldState, blockSource, l1ToL2MessageSource, txProvider, blockProposalValidator, epochCache, config, metrics, dateProvider = new DateProvider(), telemetry = getTelemetryClient(), log = createLogger('validator:block-proposal-handler')){
|
|
90
94
|
this.checkpointsBuilder = checkpointsBuilder;
|
|
91
95
|
this.worldState = worldState;
|
|
92
96
|
this.blockSource = blockSource;
|
|
93
97
|
this.l1ToL2MessageSource = l1ToL2MessageSource;
|
|
94
98
|
this.txProvider = txProvider;
|
|
95
99
|
this.blockProposalValidator = blockProposalValidator;
|
|
100
|
+
this.epochCache = epochCache;
|
|
96
101
|
this.config = config;
|
|
97
102
|
this.metrics = metrics;
|
|
98
103
|
this.dateProvider = dateProvider;
|
|
@@ -102,23 +107,27 @@ export class BlockProposalHandler {
|
|
|
102
107
|
}
|
|
103
108
|
this.tracer = telemetry.getTracer('BlockProposalHandler');
|
|
104
109
|
}
|
|
105
|
-
|
|
106
|
-
// Non-validator handler that re-executes for monitoring but does not attest.
|
|
110
|
+
register(p2pClient, shouldReexecute) {
|
|
111
|
+
// Non-validator handler that processes or re-executes for monitoring but does not attest.
|
|
107
112
|
// Returns boolean indicating whether the proposal was valid.
|
|
108
113
|
const handler = async (proposal, proposalSender)=>{
|
|
109
114
|
try {
|
|
110
|
-
const
|
|
115
|
+
const { slotNumber, blockNumber } = proposal;
|
|
116
|
+
const result = await this.handleBlockProposal(proposal, proposalSender, shouldReexecute);
|
|
111
117
|
if (result.isValid) {
|
|
112
|
-
this.log.info(`Non-validator
|
|
118
|
+
this.log.info(`Non-validator block proposal ${blockNumber} at slot ${slotNumber} handled`, {
|
|
113
119
|
blockNumber: result.blockNumber,
|
|
120
|
+
slotNumber,
|
|
114
121
|
reexecutionTimeMs: result.reexecutionResult?.reexecutionTimeMs,
|
|
115
122
|
totalManaUsed: result.reexecutionResult?.totalManaUsed,
|
|
116
|
-
numTxs: result.reexecutionResult?.block?.body?.txEffects?.length ?? 0
|
|
123
|
+
numTxs: result.reexecutionResult?.block?.body?.txEffects?.length ?? 0,
|
|
124
|
+
reexecuted: shouldReexecute
|
|
117
125
|
});
|
|
118
126
|
return true;
|
|
119
127
|
} else {
|
|
120
|
-
this.log.warn(`Non-validator
|
|
128
|
+
this.log.warn(`Non-validator block proposal ${blockNumber} at slot ${slotNumber} failed processing with ${result.reason}`, {
|
|
121
129
|
blockNumber: result.blockNumber,
|
|
130
|
+
slotNumber,
|
|
122
131
|
reason: result.reason
|
|
123
132
|
});
|
|
124
133
|
return false;
|
|
@@ -145,7 +154,9 @@ export class BlockProposalHandler {
|
|
|
145
154
|
}
|
|
146
155
|
const proposalInfo = {
|
|
147
156
|
...proposal.toBlockInfo(),
|
|
148
|
-
proposer: proposer.toString()
|
|
157
|
+
proposer: proposer.toString(),
|
|
158
|
+
blockNumber: undefined,
|
|
159
|
+
checkpointNumber: undefined
|
|
149
160
|
};
|
|
150
161
|
this.log.info(`Processing proposal for slot ${slotNumber}`, {
|
|
151
162
|
...proposalInfo,
|
|
@@ -153,27 +164,46 @@ export class BlockProposalHandler {
|
|
|
153
164
|
});
|
|
154
165
|
// Check that the proposal is from the current proposer, or the next proposer
|
|
155
166
|
// This should have been handled by the p2p layer, but we double check here out of caution
|
|
156
|
-
const
|
|
157
|
-
if (
|
|
167
|
+
const validationResult = await this.blockProposalValidator.validate(proposal);
|
|
168
|
+
if (validationResult.result !== 'accept') {
|
|
158
169
|
this.log.warn(`Proposal is not valid, skipping processing`, proposalInfo);
|
|
159
170
|
return {
|
|
160
171
|
isValid: false,
|
|
161
172
|
reason: 'invalid_proposal'
|
|
162
173
|
};
|
|
163
174
|
}
|
|
164
|
-
//
|
|
165
|
-
|
|
166
|
-
|
|
175
|
+
// Ensure the block source is synced before checking for existing blocks,
|
|
176
|
+
// since a pending checkpoint prune may remove blocks we'd otherwise find.
|
|
177
|
+
// This affects mostly the block_number_already_exists check, since a pending
|
|
178
|
+
// checkpoint prune could remove a block that would conflict with this proposal.
|
|
179
|
+
// When pipelining is enabled, the proposer builds ahead of L1 submission, so the
|
|
180
|
+
// block source won't have synced to the proposed slot yet. Skip the sync wait to
|
|
181
|
+
// avoid eating into the attestation window.
|
|
182
|
+
if (!this.epochCache.isProposerPipeliningEnabled()) {
|
|
183
|
+
const blockSourceSync = await this.waitForBlockSourceSync(slotNumber);
|
|
184
|
+
if (!blockSourceSync) {
|
|
185
|
+
this.log.warn(`Block source is not synced, skipping processing`, proposalInfo);
|
|
186
|
+
return {
|
|
187
|
+
isValid: false,
|
|
188
|
+
reason: 'block_source_not_synced'
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Check that the parent proposal is a block we know, otherwise reexecution would fail.
|
|
193
|
+
// If we don't find it immediately, we keep retrying for a while; it may be we still
|
|
194
|
+
// need to process other block proposals to get to it.
|
|
195
|
+
const parentBlock = await this.getParentBlock(proposal);
|
|
196
|
+
if (parentBlock === undefined) {
|
|
167
197
|
this.log.warn(`Parent block for proposal not found, skipping processing`, proposalInfo);
|
|
168
198
|
return {
|
|
169
199
|
isValid: false,
|
|
170
200
|
reason: 'parent_block_not_found'
|
|
171
201
|
};
|
|
172
202
|
}
|
|
173
|
-
// Check that the parent block's slot is
|
|
174
|
-
if (
|
|
175
|
-
this.log.warn(`Parent block slot is greater than
|
|
176
|
-
parentBlockSlot:
|
|
203
|
+
// Check that the parent block's slot is not greater than the proposal's slot.
|
|
204
|
+
if (parentBlock !== 'genesis' && parentBlock.header.getSlot() > slotNumber) {
|
|
205
|
+
this.log.warn(`Parent block slot is greater than proposal slot, skipping processing`, {
|
|
206
|
+
parentBlockSlot: parentBlock.header.getSlot().toString(),
|
|
177
207
|
proposalSlot: slotNumber.toString(),
|
|
178
208
|
...proposalInfo
|
|
179
209
|
});
|
|
@@ -183,7 +213,8 @@ export class BlockProposalHandler {
|
|
|
183
213
|
};
|
|
184
214
|
}
|
|
185
215
|
// Compute the block number based on the parent block
|
|
186
|
-
const blockNumber =
|
|
216
|
+
const blockNumber = parentBlock === 'genesis' ? BlockNumber(INITIAL_L2_BLOCK_NUM) : BlockNumber(parentBlock.header.getBlockNumber() + 1);
|
|
217
|
+
proposalInfo.blockNumber = blockNumber;
|
|
187
218
|
// Check that this block number does not exist already
|
|
188
219
|
const existingBlock = await this.blockSource.getBlockHeader(blockNumber);
|
|
189
220
|
if (existingBlock) {
|
|
@@ -200,8 +231,16 @@ export class BlockProposalHandler {
|
|
|
200
231
|
pinnedPeer: proposalSender,
|
|
201
232
|
deadline: this.getReexecutionDeadline(slotNumber, config)
|
|
202
233
|
});
|
|
234
|
+
// If reexecution is disabled, bail. We were just interested in triggering tx collection.
|
|
235
|
+
if (!shouldReexecute) {
|
|
236
|
+
this.log.info(`Received valid block ${blockNumber} proposal at index ${proposal.indexWithinCheckpoint} on slot ${slotNumber}`, proposalInfo);
|
|
237
|
+
return {
|
|
238
|
+
isValid: true,
|
|
239
|
+
blockNumber
|
|
240
|
+
};
|
|
241
|
+
}
|
|
203
242
|
// Compute the checkpoint number for this block and validate checkpoint consistency
|
|
204
|
-
const checkpointResult =
|
|
243
|
+
const checkpointResult = this.computeCheckpointNumber(proposal, parentBlock, proposalInfo);
|
|
205
244
|
if (checkpointResult.reason) {
|
|
206
245
|
return {
|
|
207
246
|
isValid: false,
|
|
@@ -210,6 +249,7 @@ export class BlockProposalHandler {
|
|
|
210
249
|
};
|
|
211
250
|
}
|
|
212
251
|
const checkpointNumber = checkpointResult.checkpointNumber;
|
|
252
|
+
proposalInfo.checkpointNumber = checkpointNumber;
|
|
213
253
|
// Check that I have the same set of l1ToL2Messages as the proposal
|
|
214
254
|
const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber);
|
|
215
255
|
const computedInHash = computeInHashFromL1ToL2Messages(l1ToL2Messages);
|
|
@@ -238,29 +278,32 @@ export class BlockProposalHandler {
|
|
|
238
278
|
reason: 'txs_not_available'
|
|
239
279
|
};
|
|
240
280
|
}
|
|
281
|
+
// Collect the out hashes of all the checkpoints before this one in the same epoch
|
|
282
|
+
const epoch = getEpochAtSlot(slotNumber, this.epochCache.getL1Constants());
|
|
283
|
+
const previousCheckpointOutHashes = (await this.blockSource.getCheckpointsDataForEpoch(epoch)).filter((c)=>c.checkpointNumber < checkpointNumber).map((c)=>c.checkpointOutHash);
|
|
241
284
|
// Try re-executing the transactions in the proposal if needed
|
|
242
285
|
let reexecutionResult;
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
};
|
|
256
|
-
}
|
|
286
|
+
try {
|
|
287
|
+
this.log.verbose(`Re-executing transactions in the proposal`, proposalInfo);
|
|
288
|
+
reexecutionResult = await this.reexecuteTransactions(proposal, blockNumber, checkpointNumber, txs, l1ToL2Messages, previousCheckpointOutHashes);
|
|
289
|
+
} catch (error) {
|
|
290
|
+
this.log.error(`Error reexecuting txs while processing block proposal`, error, proposalInfo);
|
|
291
|
+
const reason = this.getReexecuteFailureReason(error);
|
|
292
|
+
return {
|
|
293
|
+
isValid: false,
|
|
294
|
+
blockNumber,
|
|
295
|
+
reason,
|
|
296
|
+
reexecutionResult
|
|
297
|
+
};
|
|
257
298
|
}
|
|
258
299
|
// If we succeeded, push this block into the archiver (unless disabled)
|
|
259
|
-
// TODO(palla/mbps): Change default to false once block sync is stable.
|
|
260
300
|
if (reexecutionResult?.block && this.config.skipPushProposedBlocksToArchiver === false) {
|
|
261
301
|
await this.blockSource.addBlock(reexecutionResult?.block);
|
|
262
302
|
}
|
|
263
|
-
this.log.info(`Successfully
|
|
303
|
+
this.log.info(`Successfully re-executed block ${blockNumber} proposal at index ${proposal.indexWithinCheckpoint} on slot ${slotNumber}`, {
|
|
304
|
+
...proposalInfo,
|
|
305
|
+
...pick(reexecutionResult, 'reexecutionTimeMs', 'totalManaUsed')
|
|
306
|
+
});
|
|
264
307
|
return {
|
|
265
308
|
isValid: true,
|
|
266
309
|
blockNumber,
|
|
@@ -279,7 +322,7 @@ export class BlockProposalHandler {
|
|
|
279
322
|
const currentTime = this.dateProvider.now();
|
|
280
323
|
const timeoutDurationMs = deadline.getTime() - currentTime;
|
|
281
324
|
try {
|
|
282
|
-
return await this.blockSource.
|
|
325
|
+
return await this.blockSource.getBlockDataByArchive(parentArchive) ?? (timeoutDurationMs <= 0 ? undefined : await retryUntil(()=>this.blockSource.syncImmediate().then(()=>this.blockSource.getBlockDataByArchive(parentArchive)), 'force archiver sync', timeoutDurationMs / 1000, 0.5));
|
|
283
326
|
} catch (err) {
|
|
284
327
|
if (err instanceof TimeoutError) {
|
|
285
328
|
this.log.debug(`Timed out getting parent block by archive root`, {
|
|
@@ -293,8 +336,8 @@ export class BlockProposalHandler {
|
|
|
293
336
|
return undefined;
|
|
294
337
|
}
|
|
295
338
|
}
|
|
296
|
-
|
|
297
|
-
if (
|
|
339
|
+
computeCheckpointNumber(proposal, parentBlock, proposalInfo) {
|
|
340
|
+
if (parentBlock === 'genesis') {
|
|
298
341
|
// First block is in checkpoint 1
|
|
299
342
|
if (proposal.indexWithinCheckpoint !== 0) {
|
|
300
343
|
this.log.warn(`First block proposal has non-zero indexWithinCheckpoint`, proposalInfo);
|
|
@@ -306,20 +349,9 @@ export class BlockProposalHandler {
|
|
|
306
349
|
checkpointNumber: CheckpointNumber.INITIAL
|
|
307
350
|
};
|
|
308
351
|
}
|
|
309
|
-
// Get the parent block to find its checkpoint number
|
|
310
|
-
// TODO(palla/mbps): The block header should include the checkpoint number to avoid this lookup,
|
|
311
|
-
// or at least the L2BlockSource should return a different struct that includes it.
|
|
312
|
-
const parentBlockNumber = parentBlockHeader.getBlockNumber();
|
|
313
|
-
const parentBlock = await this.blockSource.getL2BlockNew(parentBlockNumber);
|
|
314
|
-
if (!parentBlock) {
|
|
315
|
-
this.log.warn(`Parent block ${parentBlockNumber} not found in archiver`, proposalInfo);
|
|
316
|
-
return {
|
|
317
|
-
reason: 'invalid_proposal'
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
352
|
if (proposal.indexWithinCheckpoint === 0) {
|
|
321
353
|
// If this is the first block in a new checkpoint, increment the checkpoint number
|
|
322
|
-
if (!(proposal.blockHeader.getSlot() >
|
|
354
|
+
if (!(proposal.blockHeader.getSlot() > parentBlock.header.getSlot())) {
|
|
323
355
|
this.log.warn(`Slot should be greater than parent block slot for first block in checkpoint`, proposalInfo);
|
|
324
356
|
return {
|
|
325
357
|
reason: 'invalid_proposal'
|
|
@@ -336,7 +368,7 @@ export class BlockProposalHandler {
|
|
|
336
368
|
reason: 'invalid_proposal'
|
|
337
369
|
};
|
|
338
370
|
}
|
|
339
|
-
if (proposal.blockHeader.getSlot() !==
|
|
371
|
+
if (proposal.blockHeader.getSlot() !== parentBlock.header.getSlot()) {
|
|
340
372
|
this.log.warn(`Slot should be equal to parent block slot for non-first block in checkpoint`, proposalInfo);
|
|
341
373
|
return {
|
|
342
374
|
reason: 'invalid_proposal'
|
|
@@ -434,26 +466,41 @@ export class BlockProposalHandler {
|
|
|
434
466
|
}
|
|
435
467
|
getReexecutionDeadline(slot, config) {
|
|
436
468
|
const nextSlotTimestampSeconds = Number(getTimestampForSlot(SlotNumber(slot + 1), config));
|
|
437
|
-
|
|
438
|
-
return new Date(nextSlotTimestampSeconds * 1000 - msNeededForPropagationAndPublishing);
|
|
469
|
+
return new Date(nextSlotTimestampSeconds * 1000);
|
|
439
470
|
}
|
|
440
|
-
/**
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
471
|
+
/** Waits for the block source to sync L1 data up to at least the slot before the given one. */ async waitForBlockSourceSync(slot) {
|
|
472
|
+
const deadline = this.getReexecutionDeadline(slot, this.checkpointsBuilder.getConfig());
|
|
473
|
+
const timeoutMs = deadline.getTime() - this.dateProvider.now();
|
|
474
|
+
if (slot === 0) {
|
|
475
|
+
return true;
|
|
476
|
+
}
|
|
477
|
+
// Make a quick check before triggering an archiver sync
|
|
478
|
+
const syncedSlot = await this.blockSource.getSyncedL2SlotNumber();
|
|
479
|
+
if (syncedSlot !== undefined && syncedSlot + 1 >= slot) {
|
|
480
|
+
return true;
|
|
481
|
+
}
|
|
482
|
+
try {
|
|
483
|
+
// Trigger an immediate sync of the block source, and wait until it reports being synced to the required slot
|
|
484
|
+
return await retryUntil(async ()=>{
|
|
485
|
+
await this.blockSource.syncImmediate();
|
|
486
|
+
const syncedSlot = await this.blockSource.getSyncedL2SlotNumber();
|
|
487
|
+
return syncedSlot !== undefined && syncedSlot + 1 >= slot;
|
|
488
|
+
}, 'wait for block source sync', timeoutMs / 1000, 0.5);
|
|
489
|
+
} catch (err) {
|
|
490
|
+
if (err instanceof TimeoutError) {
|
|
491
|
+
this.log.warn(`Timed out waiting for block source to sync to slot ${slot}`);
|
|
492
|
+
return false;
|
|
493
|
+
} else {
|
|
494
|
+
throw err;
|
|
449
495
|
}
|
|
450
|
-
blocks.unshift(block);
|
|
451
|
-
currentBlockNumber = BlockNumber(currentBlockNumber - 1);
|
|
452
496
|
}
|
|
453
|
-
return blocks;
|
|
454
497
|
}
|
|
455
498
|
getReexecuteFailureReason(err) {
|
|
456
|
-
if (err instanceof
|
|
499
|
+
if (err instanceof TransactionsNotAvailableError) {
|
|
500
|
+
return 'txs_not_available';
|
|
501
|
+
} else if (err instanceof ReExInitialStateMismatchError) {
|
|
502
|
+
return 'initial_state_mismatch';
|
|
503
|
+
} else if (err instanceof ReExStateMismatchError) {
|
|
457
504
|
return 'state_mismatch';
|
|
458
505
|
} else if (err instanceof ReExFailedTxsError) {
|
|
459
506
|
return 'failed_txs';
|
|
@@ -463,7 +510,7 @@ export class BlockProposalHandler {
|
|
|
463
510
|
return 'unknown_error';
|
|
464
511
|
}
|
|
465
512
|
}
|
|
466
|
-
async reexecuteTransactions(proposal, blockNumber, checkpointNumber, txs, l1ToL2Messages) {
|
|
513
|
+
async reexecuteTransactions(proposal, blockNumber, checkpointNumber, txs, l1ToL2Messages, previousCheckpointOutHashes) {
|
|
467
514
|
const env = {
|
|
468
515
|
stack: [],
|
|
469
516
|
error: void 0,
|
|
@@ -480,34 +527,49 @@ export class BlockProposalHandler {
|
|
|
480
527
|
const timer = new Timer();
|
|
481
528
|
const slot = proposal.slotNumber;
|
|
482
529
|
const config = this.checkpointsBuilder.getConfig();
|
|
483
|
-
// Get prior blocks in this checkpoint (same slot
|
|
484
|
-
const
|
|
530
|
+
// Get prior blocks in this checkpoint (same slot before current block)
|
|
531
|
+
const allBlocksInSlot = await this.blockSource.getBlocksForSlot(slot);
|
|
532
|
+
const priorBlocks = allBlocksInSlot.filter((b)=>b.number < blockNumber && b.header.getSlot() === slot);
|
|
485
533
|
// Fork before the block to be built
|
|
486
534
|
const parentBlockNumber = BlockNumber(blockNumber - 1);
|
|
487
|
-
|
|
488
|
-
|
|
535
|
+
await this.worldState.syncImmediate(parentBlockNumber);
|
|
536
|
+
const fork = _ts_add_disposable_resource(env, await this.worldState.fork(parentBlockNumber), true);
|
|
537
|
+
// Verify the fork's archive root matches the proposal's expected last archive.
|
|
538
|
+
// If they don't match, our world state synced to a different chain and reexecution would fail.
|
|
539
|
+
const forkArchiveRoot = new Fr((await fork.getTreeInfo(MerkleTreeId.ARCHIVE)).root);
|
|
540
|
+
if (!forkArchiveRoot.equals(proposal.blockHeader.lastArchive.root)) {
|
|
541
|
+
throw new ReExInitialStateMismatchError(proposal.blockHeader.lastArchive.root, forkArchiveRoot);
|
|
542
|
+
}
|
|
543
|
+
// Build checkpoint constants from proposal (excludes blockNumber which is per-block)
|
|
489
544
|
const constants = {
|
|
490
545
|
chainId: new Fr(config.l1ChainId),
|
|
491
546
|
version: new Fr(config.rollupVersion),
|
|
492
547
|
slotNumber: slot,
|
|
548
|
+
timestamp: blockHeader.globalVariables.timestamp,
|
|
493
549
|
coinbase: blockHeader.globalVariables.coinbase,
|
|
494
550
|
feeRecipient: blockHeader.globalVariables.feeRecipient,
|
|
495
551
|
gasFees: blockHeader.globalVariables.gasFees
|
|
496
552
|
};
|
|
497
553
|
// Create checkpoint builder with prior blocks
|
|
498
|
-
const checkpointBuilder = await this.checkpointsBuilder.openCheckpoint(checkpointNumber, constants, l1ToL2Messages, fork, priorBlocks);
|
|
554
|
+
const checkpointBuilder = await this.checkpointsBuilder.openCheckpoint(checkpointNumber, constants, 0n, l1ToL2Messages, previousCheckpointOutHashes, fork, priorBlocks, this.log.getBindings());
|
|
499
555
|
// Build the new block
|
|
500
556
|
const deadline = this.getReexecutionDeadline(slot, config);
|
|
557
|
+
const maxBlockGas = this.config.validateMaxL2BlockGas !== undefined || this.config.validateMaxDABlockGas !== undefined ? new Gas(this.config.validateMaxDABlockGas ?? Infinity, this.config.validateMaxL2BlockGas ?? Infinity) : undefined;
|
|
501
558
|
const result = await checkpointBuilder.buildBlock(txs, blockNumber, blockHeader.globalVariables.timestamp, {
|
|
559
|
+
isBuildingProposal: false,
|
|
560
|
+
minValidTxs: 0,
|
|
502
561
|
deadline,
|
|
503
|
-
expectedEndState: blockHeader.state
|
|
562
|
+
expectedEndState: blockHeader.state,
|
|
563
|
+
maxTransactions: this.config.validateMaxTxsPerBlock,
|
|
564
|
+
maxBlockGas
|
|
504
565
|
});
|
|
505
566
|
const { block, failedTxs } = result;
|
|
506
567
|
const numFailedTxs = failedTxs.length;
|
|
507
|
-
this.log.verbose(`
|
|
568
|
+
this.log.verbose(`Block proposal ${blockNumber} at slot ${slot} transaction re-execution complete`, {
|
|
508
569
|
numFailedTxs,
|
|
509
570
|
numProposalTxs: txHashes.length,
|
|
510
571
|
numProcessedTxs: block.body.txEffects.length,
|
|
572
|
+
blockNumber,
|
|
511
573
|
slot
|
|
512
574
|
});
|
|
513
575
|
if (numFailedTxs > 0) {
|
|
@@ -545,7 +607,8 @@ export class BlockProposalHandler {
|
|
|
545
607
|
env.error = e;
|
|
546
608
|
env.hasError = true;
|
|
547
609
|
} finally{
|
|
548
|
-
_ts_dispose_resources(env);
|
|
610
|
+
const result = _ts_dispose_resources(env);
|
|
611
|
+
if (result) await result;
|
|
549
612
|
}
|
|
550
613
|
}
|
|
551
614
|
}
|
|
@@ -1,70 +1,79 @@
|
|
|
1
1
|
import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
|
-
import {
|
|
3
|
+
import { type LoggerBindings } from '@aztec/foundation/log';
|
|
4
|
+
import { DateProvider } from '@aztec/foundation/timer';
|
|
4
5
|
import { LightweightCheckpointBuilder } from '@aztec/prover-client/light';
|
|
5
|
-
import { PublicProcessor } from '@aztec/simulator/server';
|
|
6
|
-
import {
|
|
6
|
+
import { PublicContractsDB, PublicProcessor } from '@aztec/simulator/server';
|
|
7
|
+
import { L2Block } from '@aztec/stdlib/block';
|
|
7
8
|
import { Checkpoint } from '@aztec/stdlib/checkpoint';
|
|
8
9
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
9
|
-
import {
|
|
10
|
-
import { type FullNodeBlockBuilderConfig, type MerkleTreeWriteOperations, type PublicProcessorLimits } from '@aztec/stdlib/interfaces/server';
|
|
11
|
-
import { type
|
|
10
|
+
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
11
|
+
import { type BlockBuilderOptions, type BuildBlockInCheckpointResult, type FullNodeBlockBuilderConfig, type ICheckpointBlockBuilder, type ICheckpointsBuilder, type MerkleTreeWriteOperations, type PublicProcessorLimits, type WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
12
|
+
import { type DebugLogStore } from '@aztec/stdlib/logs';
|
|
13
|
+
import { type CheckpointGlobalVariables, GlobalVariables, StateReference, Tx } from '@aztec/stdlib/tx';
|
|
12
14
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
13
|
-
export
|
|
14
|
-
block: L2BlockNew;
|
|
15
|
-
publicGas: Gas;
|
|
16
|
-
publicProcessorDuration: number;
|
|
17
|
-
numTxs: number;
|
|
18
|
-
failedTxs: FailedTx[];
|
|
19
|
-
blockBuildingTimer: Timer;
|
|
20
|
-
usedTxs: Tx[];
|
|
21
|
-
}
|
|
15
|
+
export type { BuildBlockInCheckpointResult } from '@aztec/stdlib/interfaces/server';
|
|
22
16
|
/**
|
|
23
17
|
* Builder for a single checkpoint. Handles building blocks within the checkpoint
|
|
24
18
|
* and completing it.
|
|
25
19
|
*/
|
|
26
|
-
export declare class CheckpointBuilder {
|
|
20
|
+
export declare class CheckpointBuilder implements ICheckpointBlockBuilder {
|
|
27
21
|
private checkpointBuilder;
|
|
28
22
|
private fork;
|
|
29
23
|
private config;
|
|
30
24
|
private contractDataSource;
|
|
31
25
|
private dateProvider;
|
|
32
26
|
private telemetryClient;
|
|
33
|
-
|
|
27
|
+
private debugLogStore;
|
|
28
|
+
private log;
|
|
29
|
+
/** Persistent contracts DB shared across all blocks in this checkpoint. */
|
|
30
|
+
protected contractsDB: PublicContractsDB;
|
|
31
|
+
constructor(checkpointBuilder: LightweightCheckpointBuilder, fork: MerkleTreeWriteOperations, config: FullNodeBlockBuilderConfig, contractDataSource: ContractDataSource, dateProvider: DateProvider, telemetryClient: TelemetryClient, bindings?: LoggerBindings, debugLogStore?: DebugLogStore);
|
|
34
32
|
getConstantData(): CheckpointGlobalVariables;
|
|
35
33
|
/**
|
|
36
34
|
* Builds a single block within this checkpoint.
|
|
35
|
+
* Automatically caps gas and blob field limits based on checkpoint-level budgets and prior blocks.
|
|
37
36
|
*/
|
|
38
|
-
buildBlock(pendingTxs: Iterable<Tx> | AsyncIterable<Tx>, blockNumber: BlockNumber, timestamp: bigint, opts:
|
|
37
|
+
buildBlock(pendingTxs: Iterable<Tx> | AsyncIterable<Tx>, blockNumber: BlockNumber, timestamp: bigint, opts: BlockBuilderOptions & {
|
|
39
38
|
expectedEndState?: StateReference;
|
|
40
39
|
}): Promise<BuildBlockInCheckpointResult>;
|
|
41
40
|
/** Completes the checkpoint and returns it. */
|
|
42
41
|
completeCheckpoint(): Promise<Checkpoint>;
|
|
43
42
|
/** Gets the checkpoint currently in progress. */
|
|
44
43
|
getCheckpoint(): Promise<Checkpoint>;
|
|
44
|
+
/**
|
|
45
|
+
* Caps per-block gas and blob field limits by remaining checkpoint-level budgets.
|
|
46
|
+
* When building a proposal (isBuildingProposal=true), computes a fair share of remaining budget
|
|
47
|
+
* across remaining blocks scaled by the multiplier. When validating, only caps by per-block limit
|
|
48
|
+
* and remaining checkpoint budget (no redistribution or multiplier).
|
|
49
|
+
*/
|
|
50
|
+
protected capLimitsByCheckpointBudgets(opts: BlockBuilderOptions): Pick<PublicProcessorLimits, 'maxBlockGas' | 'maxBlobFields' | 'maxTransactions'>;
|
|
45
51
|
protected makeBlockBuilderDeps(globalVariables: GlobalVariables, fork: MerkleTreeWriteOperations): Promise<{
|
|
46
52
|
processor: PublicProcessor;
|
|
47
53
|
validator: import("@aztec/stdlib/interfaces/server").PublicProcessorValidator;
|
|
48
54
|
}>;
|
|
49
55
|
}
|
|
50
|
-
/**
|
|
51
|
-
|
|
52
|
-
*/
|
|
53
|
-
export declare class FullNodeCheckpointsBuilder {
|
|
56
|
+
/** Factory for creating checkpoint builders. */
|
|
57
|
+
export declare class FullNodeCheckpointsBuilder implements ICheckpointsBuilder {
|
|
54
58
|
private config;
|
|
59
|
+
private worldState;
|
|
55
60
|
private contractDataSource;
|
|
56
61
|
private dateProvider;
|
|
57
62
|
private telemetryClient;
|
|
58
|
-
|
|
63
|
+
private debugLogStore;
|
|
64
|
+
private log;
|
|
65
|
+
constructor(config: FullNodeBlockBuilderConfig & Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration'>, worldState: WorldStateSynchronizer, contractDataSource: ContractDataSource, dateProvider: DateProvider, telemetryClient?: TelemetryClient, debugLogStore?: DebugLogStore);
|
|
59
66
|
getConfig(): FullNodeBlockBuilderConfig;
|
|
60
67
|
updateConfig(config: Partial<FullNodeBlockBuilderConfig>): void;
|
|
61
68
|
/**
|
|
62
69
|
* Starts a new checkpoint and returns a CheckpointBuilder to build blocks within it.
|
|
63
70
|
*/
|
|
64
|
-
startCheckpoint(checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, l1ToL2Messages: Fr[], fork: MerkleTreeWriteOperations): Promise<CheckpointBuilder>;
|
|
71
|
+
startCheckpoint(checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, feeAssetPriceModifier: bigint, l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[], fork: MerkleTreeWriteOperations, bindings?: LoggerBindings): Promise<CheckpointBuilder>;
|
|
65
72
|
/**
|
|
66
73
|
* Opens a checkpoint, either starting fresh or resuming from existing blocks.
|
|
67
74
|
*/
|
|
68
|
-
openCheckpoint(checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, l1ToL2Messages: Fr[], fork: MerkleTreeWriteOperations, existingBlocks?:
|
|
75
|
+
openCheckpoint(checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, feeAssetPriceModifier: bigint, l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[], fork: MerkleTreeWriteOperations, existingBlocks?: L2Block[], bindings?: LoggerBindings): Promise<CheckpointBuilder>;
|
|
76
|
+
/** Returns a fork of the world state at the given block number. */
|
|
77
|
+
getFork(blockNumber: BlockNumber): Promise<MerkleTreeWriteOperations>;
|
|
69
78
|
}
|
|
70
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
79
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludF9idWlsZGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY2hlY2twb2ludF9idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVoRixPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDcEQsT0FBTyxFQUFlLEtBQUssY0FBYyxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBRXZGLE9BQU8sRUFBRSxZQUFZLEVBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUVoRSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMxRSxPQUFPLEVBRUwsaUJBQWlCLEVBQ2pCLGVBQWUsRUFFaEIsTUFBTSx5QkFBeUIsQ0FBQztBQUNqQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakUsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUVyRSxPQUFPLEVBQ0wsS0FBSyxtQkFBbUIsRUFDeEIsS0FBSyw0QkFBNEIsRUFDakMsS0FBSywwQkFBMEIsRUFFL0IsS0FBSyx1QkFBdUIsRUFDNUIsS0FBSyxtQkFBbUIsRUFFeEIsS0FBSyx5QkFBeUIsRUFDOUIsS0FBSyxxQkFBcUIsRUFDMUIsS0FBSyxzQkFBc0IsRUFDNUIsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLEVBQUUsS0FBSyxhQUFhLEVBQXFCLE1BQU0sb0JBQW9CLENBQUM7QUFFM0UsT0FBTyxFQUFFLEtBQUsseUJBQXlCLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN2RyxPQUFPLEVBQUUsS0FBSyxlQUFlLEVBQXNCLE1BQU0seUJBQXlCLENBQUM7QUFJbkYsWUFBWSxFQUFFLDRCQUE0QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFcEY7OztHQUdHO0FBQ0gscUJBQWEsaUJBQWtCLFlBQVcsdUJBQXVCO0lBTzdELE9BQU8sQ0FBQyxpQkFBaUI7SUFDekIsT0FBTyxDQUFDLElBQUk7SUFDWixPQUFPLENBQUMsTUFBTTtJQUNkLE9BQU8sQ0FBQyxrQkFBa0I7SUFDMUIsT0FBTyxDQUFDLFlBQVk7SUFDcEIsT0FBTyxDQUFDLGVBQWU7SUFFdkIsT0FBTyxDQUFDLGFBQWE7SUFidkIsT0FBTyxDQUFDLEdBQUcsQ0FBUztJQUVwQiwyRUFBMkU7SUFDM0UsU0FBUyxDQUFDLFdBQVcsRUFBRSxpQkFBaUIsQ0FBQztJQUV6QyxZQUNVLGlCQUFpQixFQUFFLDRCQUE0QixFQUMvQyxJQUFJLEVBQUUseUJBQXlCLEVBQy9CLE1BQU0sRUFBRSwwQkFBMEIsRUFDbEMsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQ3RDLFlBQVksRUFBRSxZQUFZLEVBQzFCLGVBQWUsRUFBRSxlQUFlLEVBQ3hDLFFBQVEsQ0FBQyxFQUFFLGNBQWMsRUFDakIsYUFBYSxHQUFFLGFBQXVDLEVBTy9EO0lBRUQsZUFBZSxJQUFJLHlCQUF5QixDQUUzQztJQUVEOzs7T0FHRztJQUNHLFVBQVUsQ0FDZCxVQUFVLEVBQUUsUUFBUSxDQUFDLEVBQUUsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxFQUFFLENBQUMsRUFDNUMsV0FBVyxFQUFFLFdBQVcsRUFDeEIsU0FBUyxFQUFFLE1BQU0sRUFDakIsSUFBSSxFQUFFLG1CQUFtQixHQUFHO1FBQUUsZ0JBQWdCLENBQUMsRUFBRSxjQUFjLENBQUE7S0FBRSxHQUNoRSxPQUFPLENBQUMsNEJBQTRCLENBQUMsQ0E2RXZDO0lBRUQsK0NBQStDO0lBQ3pDLGtCQUFrQixJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FVOUM7SUFFRCxpREFBaUQ7SUFDakQsYUFBYSxJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FFbkM7SUFFRDs7Ozs7T0FLRztJQUNILFNBQVMsQ0FBQyw0QkFBNEIsQ0FDcEMsSUFBSSxFQUFFLG1CQUFtQixHQUN4QixJQUFJLENBQUMscUJBQXFCLEVBQUUsYUFBYSxHQUFHLGVBQWUsR0FBRyxpQkFBaUIsQ0FBQyxDQThDbEY7SUFFRCxVQUFnQixvQkFBb0IsQ0FBQyxlQUFlLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSx5QkFBeUI7OztPQTRDckc7Q0FDRjtBQUVELGdEQUFnRDtBQUNoRCxxQkFBYSwwQkFBMkIsWUFBVyxtQkFBbUI7SUFJbEUsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsVUFBVTtJQUNsQixPQUFPLENBQUMsa0JBQWtCO0lBQzFCLE9BQU8sQ0FBQyxZQUFZO0lBQ3BCLE9BQU8sQ0FBQyxlQUFlO0lBQ3ZCLE9BQU8sQ0FBQyxhQUFhO0lBUnZCLE9BQU8sQ0FBQyxHQUFHLENBQVM7SUFFcEIsWUFDVSxNQUFNLEVBQUUsMEJBQTBCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLGVBQWUsR0FBRyxjQUFjLENBQUMsRUFDOUYsVUFBVSxFQUFFLHNCQUFzQixFQUNsQyxrQkFBa0IsRUFBRSxrQkFBa0IsRUFDdEMsWUFBWSxFQUFFLFlBQVksRUFDMUIsZUFBZSxHQUFFLGVBQXNDLEVBQ3ZELGFBQWEsR0FBRSxhQUF1QyxFQUcvRDtJQUVNLFNBQVMsSUFBSSwwQkFBMEIsQ0FFN0M7SUFFTSxZQUFZLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQywwQkFBMEIsQ0FBQyxRQUU5RDtJQUVEOztPQUVHO0lBQ0csZUFBZSxDQUNuQixnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFDbEMsU0FBUyxFQUFFLHlCQUF5QixFQUNwQyxxQkFBcUIsRUFBRSxNQUFNLEVBQzdCLGNBQWMsRUFBRSxFQUFFLEVBQUUsRUFDcEIsMkJBQTJCLEVBQUUsRUFBRSxFQUFFLEVBQ2pDLElBQUksRUFBRSx5QkFBeUIsRUFDL0IsUUFBUSxDQUFDLEVBQUUsY0FBYyxHQUN4QixPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FpQzVCO0lBRUQ7O09BRUc7SUFDRyxjQUFjLENBQ2xCLGdCQUFnQixFQUFFLGdCQUFnQixFQUNsQyxTQUFTLEVBQUUseUJBQXlCLEVBQ3BDLHFCQUFxQixFQUFFLE1BQU0sRUFDN0IsY0FBYyxFQUFFLEVBQUUsRUFBRSxFQUNwQiwyQkFBMkIsRUFBRSxFQUFFLEVBQUUsRUFDakMsSUFBSSxFQUFFLHlCQUF5QixFQUMvQixjQUFjLEdBQUUsT0FBTyxFQUFPLEVBQzlCLFFBQVEsQ0FBQyxFQUFFLGNBQWMsR0FDeEIsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBK0M1QjtJQUVELG1FQUFtRTtJQUNuRSxPQUFPLENBQUMsV0FBVyxFQUFFLFdBQVcsR0FBRyxPQUFPLENBQUMseUJBQXlCLENBQUMsQ0FFcEU7Q0FDRiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpoint_builder.d.ts","sourceRoot":"","sources":["../src/checkpoint_builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"checkpoint_builder.d.ts","sourceRoot":"","sources":["../src/checkpoint_builder.ts"],"names":[],"mappings":"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"}
|