@aztec/validator-client 0.0.1-commit.1142ef1 → 0.0.1-commit.125b3452

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.
Files changed (69) hide show
  1. package/README.md +96 -24
  2. package/dest/block_proposal_handler.d.ts +12 -11
  3. package/dest/block_proposal_handler.d.ts.map +1 -1
  4. package/dest/block_proposal_handler.js +132 -77
  5. package/dest/checkpoint_builder.d.ts +32 -25
  6. package/dest/checkpoint_builder.d.ts.map +1 -1
  7. package/dest/checkpoint_builder.js +144 -49
  8. package/dest/config.d.ts +1 -1
  9. package/dest/config.d.ts.map +1 -1
  10. package/dest/config.js +33 -14
  11. package/dest/duties/validation_service.d.ts +20 -7
  12. package/dest/duties/validation_service.d.ts.map +1 -1
  13. package/dest/duties/validation_service.js +69 -22
  14. package/dest/factory.d.ts +2 -2
  15. package/dest/factory.d.ts.map +1 -1
  16. package/dest/factory.js +3 -2
  17. package/dest/index.d.ts +1 -2
  18. package/dest/index.d.ts.map +1 -1
  19. package/dest/index.js +0 -1
  20. package/dest/key_store/ha_key_store.d.ts +99 -0
  21. package/dest/key_store/ha_key_store.d.ts.map +1 -0
  22. package/dest/key_store/ha_key_store.js +208 -0
  23. package/dest/key_store/index.d.ts +2 -1
  24. package/dest/key_store/index.d.ts.map +1 -1
  25. package/dest/key_store/index.js +1 -0
  26. package/dest/key_store/interface.d.ts +36 -6
  27. package/dest/key_store/interface.d.ts.map +1 -1
  28. package/dest/key_store/local_key_store.d.ts +10 -5
  29. package/dest/key_store/local_key_store.d.ts.map +1 -1
  30. package/dest/key_store/local_key_store.js +8 -4
  31. package/dest/key_store/node_keystore_adapter.d.ts +18 -5
  32. package/dest/key_store/node_keystore_adapter.d.ts.map +1 -1
  33. package/dest/key_store/node_keystore_adapter.js +18 -4
  34. package/dest/key_store/web3signer_key_store.d.ts +10 -5
  35. package/dest/key_store/web3signer_key_store.d.ts.map +1 -1
  36. package/dest/key_store/web3signer_key_store.js +8 -4
  37. package/dest/metrics.d.ts +12 -3
  38. package/dest/metrics.d.ts.map +1 -1
  39. package/dest/metrics.js +46 -5
  40. package/dest/validator.d.ts +45 -18
  41. package/dest/validator.d.ts.map +1 -1
  42. package/dest/validator.js +263 -99
  43. package/package.json +21 -17
  44. package/src/block_proposal_handler.ts +163 -95
  45. package/src/checkpoint_builder.ts +206 -61
  46. package/src/config.ts +32 -13
  47. package/src/duties/validation_service.ts +94 -25
  48. package/src/factory.ts +2 -0
  49. package/src/index.ts +0 -1
  50. package/src/key_store/ha_key_store.ts +269 -0
  51. package/src/key_store/index.ts +1 -0
  52. package/src/key_store/interface.ts +44 -5
  53. package/src/key_store/local_key_store.ts +13 -4
  54. package/src/key_store/node_keystore_adapter.ts +27 -4
  55. package/src/key_store/web3signer_key_store.ts +17 -4
  56. package/src/metrics.ts +63 -6
  57. package/src/validator.ts +329 -118
  58. package/dest/tx_validator/index.d.ts +0 -3
  59. package/dest/tx_validator/index.d.ts.map +0 -1
  60. package/dest/tx_validator/index.js +0 -2
  61. package/dest/tx_validator/nullifier_cache.d.ts +0 -14
  62. package/dest/tx_validator/nullifier_cache.d.ts.map +0 -1
  63. package/dest/tx_validator/nullifier_cache.js +0 -24
  64. package/dest/tx_validator/tx_validator_factory.d.ts +0 -18
  65. package/dest/tx_validator/tx_validator_factory.d.ts.map +0 -1
  66. package/dest/tx_validator/tx_validator_factory.js +0 -53
  67. package/src/tx_validator/index.ts +0 -2
  68. package/src/tx_validator/nullifier_cache.ts +0 -30
  69. 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 { ReExFailedTxsError, ReExStateMismatchError, ReExTimeoutError, TransactionsNotAvailableError } from '@aztec/stdlib/validators';
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
- registerForReexecution(p2pClient) {
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 result = await this.handleBlockProposal(proposal, proposalSender, true);
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 reexecution completed for slot ${proposal.slotNumber}`, {
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 reexecution failed for slot ${proposal.slotNumber}`, {
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,42 @@ 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 invalidProposal = await this.blockProposalValidator.validate(proposal);
157
- if (invalidProposal) {
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
- // Check that the parent proposal is a block we know, otherwise reexecution would fail
165
- const parentBlockHeader = await this.getParentBlock(proposal);
166
- if (parentBlockHeader === undefined) {
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
+ // TODO(@Maddiaa0): This may break staggered slots.
180
+ const blockSourceSync = await this.waitForBlockSourceSync(slotNumber);
181
+ if (!blockSourceSync) {
182
+ this.log.warn(`Block source is not synced, skipping processing`, proposalInfo);
183
+ return {
184
+ isValid: false,
185
+ reason: 'block_source_not_synced'
186
+ };
187
+ }
188
+ // Check that the parent proposal is a block we know, otherwise reexecution would fail.
189
+ // If we don't find it immediately, we keep retrying for a while; it may be we still
190
+ // need to process other block proposals to get to it.
191
+ const parentBlock = await this.getParentBlock(proposal);
192
+ if (parentBlock === undefined) {
167
193
  this.log.warn(`Parent block for proposal not found, skipping processing`, proposalInfo);
168
194
  return {
169
195
  isValid: false,
170
196
  reason: 'parent_block_not_found'
171
197
  };
172
198
  }
173
- // Check that the parent block's slot is less than the proposal's slot (should not happen, but we check anyway)
174
- if (parentBlockHeader !== 'genesis' && parentBlockHeader.getSlot() >= slotNumber) {
175
- this.log.warn(`Parent block slot is greater than or equal to proposal slot, skipping processing`, {
176
- parentBlockSlot: parentBlockHeader.getSlot().toString(),
199
+ // Check that the parent block's slot is not greater than the proposal's slot.
200
+ if (parentBlock !== 'genesis' && parentBlock.header.getSlot() > slotNumber) {
201
+ this.log.warn(`Parent block slot is greater than proposal slot, skipping processing`, {
202
+ parentBlockSlot: parentBlock.header.getSlot().toString(),
177
203
  proposalSlot: slotNumber.toString(),
178
204
  ...proposalInfo
179
205
  });
@@ -183,7 +209,8 @@ export class BlockProposalHandler {
183
209
  };
184
210
  }
185
211
  // Compute the block number based on the parent block
186
- const blockNumber = parentBlockHeader === 'genesis' ? BlockNumber(INITIAL_L2_BLOCK_NUM) : BlockNumber(parentBlockHeader.getBlockNumber() + 1);
212
+ const blockNumber = parentBlock === 'genesis' ? BlockNumber(INITIAL_L2_BLOCK_NUM) : BlockNumber(parentBlock.header.getBlockNumber() + 1);
213
+ proposalInfo.blockNumber = blockNumber;
187
214
  // Check that this block number does not exist already
188
215
  const existingBlock = await this.blockSource.getBlockHeader(blockNumber);
189
216
  if (existingBlock) {
@@ -200,8 +227,16 @@ export class BlockProposalHandler {
200
227
  pinnedPeer: proposalSender,
201
228
  deadline: this.getReexecutionDeadline(slotNumber, config)
202
229
  });
230
+ // If reexecution is disabled, bail. We were just interested in triggering tx collection.
231
+ if (!shouldReexecute) {
232
+ this.log.info(`Received valid block ${blockNumber} proposal at index ${proposal.indexWithinCheckpoint} on slot ${slotNumber}`, proposalInfo);
233
+ return {
234
+ isValid: true,
235
+ blockNumber
236
+ };
237
+ }
203
238
  // Compute the checkpoint number for this block and validate checkpoint consistency
204
- const checkpointResult = await this.computeCheckpointNumber(proposal, parentBlockHeader, proposalInfo);
239
+ const checkpointResult = this.computeCheckpointNumber(proposal, parentBlock, proposalInfo);
205
240
  if (checkpointResult.reason) {
206
241
  return {
207
242
  isValid: false,
@@ -210,6 +245,7 @@ export class BlockProposalHandler {
210
245
  };
211
246
  }
212
247
  const checkpointNumber = checkpointResult.checkpointNumber;
248
+ proposalInfo.checkpointNumber = checkpointNumber;
213
249
  // Check that I have the same set of l1ToL2Messages as the proposal
214
250
  const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber);
215
251
  const computedInHash = computeInHashFromL1ToL2Messages(l1ToL2Messages);
@@ -238,29 +274,32 @@ export class BlockProposalHandler {
238
274
  reason: 'txs_not_available'
239
275
  };
240
276
  }
277
+ // Collect the out hashes of all the checkpoints before this one in the same epoch
278
+ const epoch = getEpochAtSlot(slotNumber, this.epochCache.getL1Constants());
279
+ const previousCheckpointOutHashes = (await this.blockSource.getCheckpointsDataForEpoch(epoch)).filter((c)=>c.checkpointNumber < checkpointNumber).map((c)=>c.checkpointOutHash);
241
280
  // Try re-executing the transactions in the proposal if needed
242
281
  let reexecutionResult;
243
- if (shouldReexecute) {
244
- try {
245
- this.log.verbose(`Re-executing transactions in the proposal`, proposalInfo);
246
- reexecutionResult = await this.reexecuteTransactions(proposal, blockNumber, checkpointNumber, txs, l1ToL2Messages);
247
- } catch (error) {
248
- this.log.error(`Error reexecuting txs while processing block proposal`, error, proposalInfo);
249
- const reason = this.getReexecuteFailureReason(error);
250
- return {
251
- isValid: false,
252
- blockNumber,
253
- reason,
254
- reexecutionResult
255
- };
256
- }
282
+ try {
283
+ this.log.verbose(`Re-executing transactions in the proposal`, proposalInfo);
284
+ reexecutionResult = await this.reexecuteTransactions(proposal, blockNumber, checkpointNumber, txs, l1ToL2Messages, previousCheckpointOutHashes);
285
+ } catch (error) {
286
+ this.log.error(`Error reexecuting txs while processing block proposal`, error, proposalInfo);
287
+ const reason = this.getReexecuteFailureReason(error);
288
+ return {
289
+ isValid: false,
290
+ blockNumber,
291
+ reason,
292
+ reexecutionResult
293
+ };
257
294
  }
258
295
  // 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
296
  if (reexecutionResult?.block && this.config.skipPushProposedBlocksToArchiver === false) {
261
297
  await this.blockSource.addBlock(reexecutionResult?.block);
262
298
  }
263
- this.log.info(`Successfully processed block ${blockNumber} proposal at index ${proposal.indexWithinCheckpoint} on slot ${slotNumber}`, proposalInfo);
299
+ this.log.info(`Successfully re-executed block ${blockNumber} proposal at index ${proposal.indexWithinCheckpoint} on slot ${slotNumber}`, {
300
+ ...proposalInfo,
301
+ ...pick(reexecutionResult, 'reexecutionTimeMs', 'totalManaUsed')
302
+ });
264
303
  return {
265
304
  isValid: true,
266
305
  blockNumber,
@@ -279,7 +318,7 @@ export class BlockProposalHandler {
279
318
  const currentTime = this.dateProvider.now();
280
319
  const timeoutDurationMs = deadline.getTime() - currentTime;
281
320
  try {
282
- return await this.blockSource.getBlockHeaderByArchive(parentArchive) ?? (timeoutDurationMs <= 0 ? undefined : await retryUntil(()=>this.blockSource.syncImmediate().then(()=>this.blockSource.getBlockHeaderByArchive(parentArchive)), 'force archiver sync', timeoutDurationMs / 1000, 0.5));
321
+ 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
322
  } catch (err) {
284
323
  if (err instanceof TimeoutError) {
285
324
  this.log.debug(`Timed out getting parent block by archive root`, {
@@ -293,8 +332,8 @@ export class BlockProposalHandler {
293
332
  return undefined;
294
333
  }
295
334
  }
296
- async computeCheckpointNumber(proposal, parentBlockHeader, proposalInfo) {
297
- if (parentBlockHeader === 'genesis') {
335
+ computeCheckpointNumber(proposal, parentBlock, proposalInfo) {
336
+ if (parentBlock === 'genesis') {
298
337
  // First block is in checkpoint 1
299
338
  if (proposal.indexWithinCheckpoint !== 0) {
300
339
  this.log.warn(`First block proposal has non-zero indexWithinCheckpoint`, proposalInfo);
@@ -306,20 +345,9 @@ export class BlockProposalHandler {
306
345
  checkpointNumber: CheckpointNumber.INITIAL
307
346
  };
308
347
  }
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
348
  if (proposal.indexWithinCheckpoint === 0) {
321
349
  // If this is the first block in a new checkpoint, increment the checkpoint number
322
- if (!(proposal.blockHeader.getSlot() > parentBlockHeader.getSlot())) {
350
+ if (!(proposal.blockHeader.getSlot() > parentBlock.header.getSlot())) {
323
351
  this.log.warn(`Slot should be greater than parent block slot for first block in checkpoint`, proposalInfo);
324
352
  return {
325
353
  reason: 'invalid_proposal'
@@ -336,7 +364,7 @@ export class BlockProposalHandler {
336
364
  reason: 'invalid_proposal'
337
365
  };
338
366
  }
339
- if (proposal.blockHeader.getSlot() !== parentBlockHeader.getSlot()) {
367
+ if (proposal.blockHeader.getSlot() !== parentBlock.header.getSlot()) {
340
368
  this.log.warn(`Slot should be equal to parent block slot for non-first block in checkpoint`, proposalInfo);
341
369
  return {
342
370
  reason: 'invalid_proposal'
@@ -434,26 +462,39 @@ export class BlockProposalHandler {
434
462
  }
435
463
  getReexecutionDeadline(slot, config) {
436
464
  const nextSlotTimestampSeconds = Number(getTimestampForSlot(SlotNumber(slot + 1), config));
437
- const msNeededForPropagationAndPublishing = this.config.validatorReexecuteDeadlineMs;
438
- return new Date(nextSlotTimestampSeconds * 1000 - msNeededForPropagationAndPublishing);
465
+ return new Date(nextSlotTimestampSeconds * 1000);
439
466
  }
440
- /**
441
- * Gets all prior blocks in the same checkpoint (same slot and checkpoint number) up to but not including upToBlockNumber.
442
- */ async getBlocksInCheckpoint(slot, upToBlockNumber, checkpointNumber) {
443
- const blocks = [];
444
- let currentBlockNumber = BlockNumber(upToBlockNumber - 1);
445
- while(currentBlockNumber >= INITIAL_L2_BLOCK_NUM){
446
- const block = await this.blockSource.getL2BlockNew(currentBlockNumber);
447
- if (!block || block.header.getSlot() !== slot || block.checkpointNumber !== checkpointNumber) {
448
- break;
467
+ /** Waits for the block source to sync L1 data up to at least the slot before the given one. */ async waitForBlockSourceSync(slot) {
468
+ const deadline = this.getReexecutionDeadline(slot, this.checkpointsBuilder.getConfig());
469
+ const timeoutMs = deadline.getTime() - this.dateProvider.now();
470
+ if (slot === 0) {
471
+ return true;
472
+ }
473
+ // Make a quick check before triggering an archiver sync
474
+ const syncedSlot = await this.blockSource.getSyncedL2SlotNumber();
475
+ if (syncedSlot !== undefined && syncedSlot + 1 >= slot) {
476
+ return true;
477
+ }
478
+ try {
479
+ // Trigger an immediate sync of the block source, and wait until it reports being synced to the required slot
480
+ return await retryUntil(async ()=>{
481
+ await this.blockSource.syncImmediate();
482
+ const syncedSlot = await this.blockSource.getSyncedL2SlotNumber();
483
+ return syncedSlot !== undefined && syncedSlot + 1 >= slot;
484
+ }, 'wait for block source sync', timeoutMs / 1000, 0.5);
485
+ } catch (err) {
486
+ if (err instanceof TimeoutError) {
487
+ this.log.warn(`Timed out waiting for block source to sync to slot ${slot}`);
488
+ return false;
489
+ } else {
490
+ throw err;
449
491
  }
450
- blocks.unshift(block);
451
- currentBlockNumber = BlockNumber(currentBlockNumber - 1);
452
492
  }
453
- return blocks;
454
493
  }
455
494
  getReexecuteFailureReason(err) {
456
- if (err instanceof ReExStateMismatchError) {
495
+ if (err instanceof ReExInitialStateMismatchError) {
496
+ return 'initial_state_mismatch';
497
+ } else if (err instanceof ReExStateMismatchError) {
457
498
  return 'state_mismatch';
458
499
  } else if (err instanceof ReExFailedTxsError) {
459
500
  return 'failed_txs';
@@ -463,7 +504,7 @@ export class BlockProposalHandler {
463
504
  return 'unknown_error';
464
505
  }
465
506
  }
466
- async reexecuteTransactions(proposal, blockNumber, checkpointNumber, txs, l1ToL2Messages) {
507
+ async reexecuteTransactions(proposal, blockNumber, checkpointNumber, txs, l1ToL2Messages, previousCheckpointOutHashes) {
467
508
  const env = {
468
509
  stack: [],
469
510
  error: void 0,
@@ -480,34 +521,47 @@ export class BlockProposalHandler {
480
521
  const timer = new Timer();
481
522
  const slot = proposal.slotNumber;
482
523
  const config = this.checkpointsBuilder.getConfig();
483
- // Get prior blocks in this checkpoint (same slot and checkpoint number)
484
- const priorBlocks = await this.getBlocksInCheckpoint(slot, blockNumber, checkpointNumber);
524
+ // Get prior blocks in this checkpoint (same slot before current block)
525
+ const allBlocksInSlot = await this.blockSource.getBlocksForSlot(slot);
526
+ const priorBlocks = allBlocksInSlot.filter((b)=>b.number < blockNumber && b.header.getSlot() === slot);
485
527
  // Fork before the block to be built
486
528
  const parentBlockNumber = BlockNumber(blockNumber - 1);
487
- const fork = _ts_add_disposable_resource(env, await this.worldState.fork(parentBlockNumber), false);
488
- // Build checkpoint constants from proposal (excludes blockNumber and timestamp which are per-block)
529
+ await this.worldState.syncImmediate(parentBlockNumber);
530
+ const fork = _ts_add_disposable_resource(env, await this.worldState.fork(parentBlockNumber), true);
531
+ // Verify the fork's archive root matches the proposal's expected last archive.
532
+ // If they don't match, our world state synced to a different chain and reexecution would fail.
533
+ const forkArchiveRoot = new Fr((await fork.getTreeInfo(MerkleTreeId.ARCHIVE)).root);
534
+ if (!forkArchiveRoot.equals(proposal.blockHeader.lastArchive.root)) {
535
+ throw new ReExInitialStateMismatchError(proposal.blockHeader.lastArchive.root, forkArchiveRoot);
536
+ }
537
+ // Build checkpoint constants from proposal (excludes blockNumber which is per-block)
489
538
  const constants = {
490
539
  chainId: new Fr(config.l1ChainId),
491
540
  version: new Fr(config.rollupVersion),
492
541
  slotNumber: slot,
542
+ timestamp: blockHeader.globalVariables.timestamp,
493
543
  coinbase: blockHeader.globalVariables.coinbase,
494
544
  feeRecipient: blockHeader.globalVariables.feeRecipient,
495
545
  gasFees: blockHeader.globalVariables.gasFees
496
546
  };
497
547
  // Create checkpoint builder with prior blocks
498
- const checkpointBuilder = await this.checkpointsBuilder.openCheckpoint(checkpointNumber, constants, l1ToL2Messages, fork, priorBlocks);
548
+ const checkpointBuilder = await this.checkpointsBuilder.openCheckpoint(checkpointNumber, constants, 0n, l1ToL2Messages, previousCheckpointOutHashes, fork, priorBlocks, this.log.getBindings());
499
549
  // Build the new block
500
550
  const deadline = this.getReexecutionDeadline(slot, config);
551
+ const maxBlockGas = this.config.validateMaxL2BlockGas !== undefined || this.config.validateMaxDABlockGas !== undefined ? new Gas(this.config.validateMaxDABlockGas ?? Infinity, this.config.validateMaxL2BlockGas ?? Infinity) : undefined;
501
552
  const result = await checkpointBuilder.buildBlock(txs, blockNumber, blockHeader.globalVariables.timestamp, {
502
553
  deadline,
503
- expectedEndState: blockHeader.state
554
+ expectedEndState: blockHeader.state,
555
+ maxTransactions: this.config.validateMaxTxsPerBlock,
556
+ maxBlockGas
504
557
  });
505
558
  const { block, failedTxs } = result;
506
559
  const numFailedTxs = failedTxs.length;
507
- this.log.verbose(`Transaction re-execution complete for slot ${slot}`, {
560
+ this.log.verbose(`Block proposal ${blockNumber} at slot ${slot} transaction re-execution complete`, {
508
561
  numFailedTxs,
509
562
  numProposalTxs: txHashes.length,
510
563
  numProcessedTxs: block.body.txEffects.length,
564
+ blockNumber,
511
565
  slot
512
566
  });
513
567
  if (numFailedTxs > 0) {
@@ -545,7 +599,8 @@ export class BlockProposalHandler {
545
599
  env.error = e;
546
600
  env.hasError = true;
547
601
  } finally{
548
- _ts_dispose_resources(env);
602
+ const result = _ts_dispose_resources(env);
603
+ if (result) await result;
549
604
  }
550
605
  }
551
606
  }
@@ -1,70 +1,77 @@
1
1
  import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
2
2
  import { Fr } from '@aztec/foundation/curves/bn254';
3
- import { DateProvider, Timer } from '@aztec/foundation/timer';
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
6
  import { PublicProcessor } from '@aztec/simulator/server';
6
- import { L2BlockNew } from '@aztec/stdlib/block';
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 { Gas } from '@aztec/stdlib/gas';
10
- import { type FullNodeBlockBuilderConfig, type MerkleTreeWriteOperations, type PublicProcessorLimits } from '@aztec/stdlib/interfaces/server';
11
- import { type CheckpointGlobalVariables, type FailedTx, GlobalVariables, StateReference, Tx } from '@aztec/stdlib/tx';
10
+ import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
11
+ import { 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 interface BuildBlockInCheckpointResult {
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
- constructor(checkpointBuilder: LightweightCheckpointBuilder, fork: MerkleTreeWriteOperations, config: FullNodeBlockBuilderConfig, contractDataSource: ContractDataSource, dateProvider: DateProvider, telemetryClient: TelemetryClient);
27
+ private debugLogStore;
28
+ private log;
29
+ constructor(checkpointBuilder: LightweightCheckpointBuilder, fork: MerkleTreeWriteOperations, config: FullNodeBlockBuilderConfig, contractDataSource: ContractDataSource, dateProvider: DateProvider, telemetryClient: TelemetryClient, bindings?: LoggerBindings, debugLogStore?: DebugLogStore);
34
30
  getConstantData(): CheckpointGlobalVariables;
35
31
  /**
36
32
  * Builds a single block within this checkpoint.
33
+ * Automatically caps gas and blob field limits based on checkpoint-level budgets and prior blocks.
37
34
  */
38
- buildBlock(pendingTxs: Iterable<Tx> | AsyncIterable<Tx>, blockNumber: BlockNumber, timestamp: bigint, opts: PublicProcessorLimits & {
35
+ buildBlock(pendingTxs: Iterable<Tx> | AsyncIterable<Tx>, blockNumber: BlockNumber, timestamp: bigint, opts?: PublicProcessorLimits & {
39
36
  expectedEndState?: StateReference;
37
+ minValidTxs?: number;
40
38
  }): Promise<BuildBlockInCheckpointResult>;
41
39
  /** Completes the checkpoint and returns it. */
42
40
  completeCheckpoint(): Promise<Checkpoint>;
43
41
  /** Gets the checkpoint currently in progress. */
44
42
  getCheckpoint(): Promise<Checkpoint>;
43
+ /**
44
+ * Caps per-block gas and blob field limits by remaining checkpoint-level budgets.
45
+ * Computes remaining L2 gas (mana), DA gas, and blob fields from blocks already added to the checkpoint,
46
+ * then returns opts with maxBlockGas and maxBlobFields capped accordingly.
47
+ */
48
+ protected capLimitsByCheckpointBudgets(opts: PublicProcessorLimits): Pick<PublicProcessorLimits, 'maxBlockGas' | 'maxBlobFields' | 'maxTransactions'>;
45
49
  protected makeBlockBuilderDeps(globalVariables: GlobalVariables, fork: MerkleTreeWriteOperations): Promise<{
46
50
  processor: PublicProcessor;
47
51
  validator: import("@aztec/stdlib/interfaces/server").PublicProcessorValidator;
48
52
  }>;
49
53
  }
50
- /**
51
- * Factory for creating checkpoint builders.
52
- */
53
- export declare class FullNodeCheckpointsBuilder {
54
+ /** Factory for creating checkpoint builders. */
55
+ export declare class FullNodeCheckpointsBuilder implements ICheckpointsBuilder {
54
56
  private config;
57
+ private worldState;
55
58
  private contractDataSource;
56
59
  private dateProvider;
57
60
  private telemetryClient;
58
- constructor(config: FullNodeBlockBuilderConfig, contractDataSource: ContractDataSource, dateProvider: DateProvider, telemetryClient?: TelemetryClient);
61
+ private debugLogStore;
62
+ private log;
63
+ constructor(config: FullNodeBlockBuilderConfig & Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration'>, worldState: WorldStateSynchronizer, contractDataSource: ContractDataSource, dateProvider: DateProvider, telemetryClient?: TelemetryClient, debugLogStore?: DebugLogStore);
59
64
  getConfig(): FullNodeBlockBuilderConfig;
60
65
  updateConfig(config: Partial<FullNodeBlockBuilderConfig>): void;
61
66
  /**
62
67
  * Starts a new checkpoint and returns a CheckpointBuilder to build blocks within it.
63
68
  */
64
- startCheckpoint(checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, l1ToL2Messages: Fr[], fork: MerkleTreeWriteOperations): Promise<CheckpointBuilder>;
69
+ startCheckpoint(checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, feeAssetPriceModifier: bigint, l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[], fork: MerkleTreeWriteOperations, bindings?: LoggerBindings): Promise<CheckpointBuilder>;
65
70
  /**
66
71
  * Opens a checkpoint, either starting fresh or resuming from existing blocks.
67
72
  */
68
- openCheckpoint(checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, l1ToL2Messages: Fr[], fork: MerkleTreeWriteOperations, existingBlocks?: L2BlockNew[]): Promise<CheckpointBuilder>;
73
+ openCheckpoint(checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, feeAssetPriceModifier: bigint, l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[], fork: MerkleTreeWriteOperations, existingBlocks?: L2Block[], bindings?: LoggerBindings): Promise<CheckpointBuilder>;
74
+ /** Returns a fork of the world state at the given block number. */
75
+ getFork(blockNumber: BlockNumber): Promise<MerkleTreeWriteOperations>;
69
76
  }
70
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludF9idWlsZGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY2hlY2twb2ludF9idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVoRixPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFHcEQsT0FBTyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUV2RSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMxRSxPQUFPLEVBR0wsZUFBZSxFQUVoQixNQUFNLHlCQUF5QixDQUFDO0FBQ2pDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdEQsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRSxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDeEMsT0FBTyxFQUNMLEtBQUssMEJBQTBCLEVBRS9CLEtBQUsseUJBQXlCLEVBQzlCLEtBQUsscUJBQXFCLEVBQzNCLE1BQU0saUNBQWlDLENBQUM7QUFFekMsT0FBTyxFQUFFLEtBQUsseUJBQXlCLEVBQUUsS0FBSyxRQUFRLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN0SCxPQUFPLEVBQUUsS0FBSyxlQUFlLEVBQXNCLE1BQU0seUJBQXlCLENBQUM7QUFNbkYsTUFBTSxXQUFXLDRCQUE0QjtJQUMzQyxLQUFLLEVBQUUsVUFBVSxDQUFDO0lBQ2xCLFNBQVMsRUFBRSxHQUFHLENBQUM7SUFDZix1QkFBdUIsRUFBRSxNQUFNLENBQUM7SUFDaEMsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUNmLFNBQVMsRUFBRSxRQUFRLEVBQUUsQ0FBQztJQUN0QixrQkFBa0IsRUFBRSxLQUFLLENBQUM7SUFDMUIsT0FBTyxFQUFFLEVBQUUsRUFBRSxDQUFDO0NBQ2Y7QUFFRDs7O0dBR0c7QUFDSCxxQkFBYSxpQkFBaUI7SUFFMUIsT0FBTyxDQUFDLGlCQUFpQjtJQUN6QixPQUFPLENBQUMsSUFBSTtJQUNaLE9BQU8sQ0FBQyxNQUFNO0lBQ2QsT0FBTyxDQUFDLGtCQUFrQjtJQUMxQixPQUFPLENBQUMsWUFBWTtJQUNwQixPQUFPLENBQUMsZUFBZTtJQU56QixZQUNVLGlCQUFpQixFQUFFLDRCQUE0QixFQUMvQyxJQUFJLEVBQUUseUJBQXlCLEVBQy9CLE1BQU0sRUFBRSwwQkFBMEIsRUFDbEMsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQ3RDLFlBQVksRUFBRSxZQUFZLEVBQzFCLGVBQWUsRUFBRSxlQUFlLEVBQ3RDO0lBRUosZUFBZSxJQUFJLHlCQUF5QixDQUUzQztJQUVEOztPQUVHO0lBQ0csVUFBVSxDQUNkLFVBQVUsRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDLEdBQUcsYUFBYSxDQUFDLEVBQUUsQ0FBQyxFQUM1QyxXQUFXLEVBQUUsV0FBVyxFQUN4QixTQUFTLEVBQUUsTUFBTSxFQUNqQixJQUFJLEVBQUUscUJBQXFCLEdBQUc7UUFBRSxnQkFBZ0IsQ0FBQyxFQUFFLGNBQWMsQ0FBQTtLQUFFLEdBQ2xFLE9BQU8sQ0FBQyw0QkFBNEIsQ0FBQyxDQTBDdkM7SUFFRCwrQ0FBK0M7SUFDekMsa0JBQWtCLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQVU5QztJQUVELGlEQUFpRDtJQUNqRCxhQUFhLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUVuQztJQUVELFVBQWdCLG9CQUFvQixDQUFDLGVBQWUsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLHlCQUF5Qjs7O09Ba0NyRztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxxQkFBYSwwQkFBMEI7SUFFbkMsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsa0JBQWtCO0lBQzFCLE9BQU8sQ0FBQyxZQUFZO0lBQ3BCLE9BQU8sQ0FBQyxlQUFlO0lBSnpCLFlBQ1UsTUFBTSxFQUFFLDBCQUEwQixFQUNsQyxrQkFBa0IsRUFBRSxrQkFBa0IsRUFDdEMsWUFBWSxFQUFFLFlBQVksRUFDMUIsZUFBZSxHQUFFLGVBQXNDLEVBQzdEO0lBRUcsU0FBUyxJQUFJLDBCQUEwQixDQUU3QztJQUVNLFlBQVksQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLDBCQUEwQixDQUFDLFFBRTlEO0lBRUQ7O09BRUc7SUFDRyxlQUFlLENBQ25CLGdCQUFnQixFQUFFLGdCQUFnQixFQUNsQyxTQUFTLEVBQUUseUJBQXlCLEVBQ3BDLGNBQWMsRUFBRSxFQUFFLEVBQUUsRUFDcEIsSUFBSSxFQUFFLHlCQUF5QixHQUM5QixPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0EyQjVCO0lBRUQ7O09BRUc7SUFDRyxjQUFjLENBQ2xCLGdCQUFnQixFQUFFLGdCQUFnQixFQUNsQyxTQUFTLEVBQUUseUJBQXlCLEVBQ3BDLGNBQWMsRUFBRSxFQUFFLEVBQUUsRUFDcEIsSUFBSSxFQUFFLHlCQUF5QixFQUMvQixjQUFjLEdBQUUsVUFBVSxFQUFPLEdBQ2hDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQWlDNUI7Q0FDRiJ9
77
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludF9idWlsZGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY2hlY2twb2ludF9idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVoRixPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDcEQsT0FBTyxFQUFlLEtBQUssY0FBYyxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBRXZGLE9BQU8sRUFBRSxZQUFZLEVBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUVoRSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMxRSxPQUFPLEVBR0wsZUFBZSxFQUVoQixNQUFNLHlCQUF5QixDQUFDO0FBQ2pDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdEQsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRSxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRXJFLE9BQU8sRUFDTCxLQUFLLDRCQUE0QixFQUNqQyxLQUFLLDBCQUEwQixFQUUvQixLQUFLLHVCQUF1QixFQUM1QixLQUFLLG1CQUFtQixFQUV4QixLQUFLLHlCQUF5QixFQUM5QixLQUFLLHFCQUFxQixFQUMxQixLQUFLLHNCQUFzQixFQUM1QixNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxLQUFLLGFBQWEsRUFBcUIsTUFBTSxvQkFBb0IsQ0FBQztBQUUzRSxPQUFPLEVBQUUsS0FBSyx5QkFBeUIsRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLEVBQUUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxLQUFL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
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoint_builder.d.ts","sourceRoot":"","sources":["../src/checkpoint_builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"checkpoint_builder.d.ts","sourceRoot":"","sources":["../src/checkpoint_builder.ts"],"names":[],"mappings":"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"}