@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
@@ -1,17 +1,19 @@
1
- import { merge, pick } from '@aztec/foundation/collection';
1
+ import { NUM_CHECKPOINT_END_MARKER_FIELDS, getNumBlockEndBlobFields } from '@aztec/blob-lib/encoding';
2
+ import { BLOBS_PER_CHECKPOINT, FIELDS_PER_BLOB, MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT } from '@aztec/constants';
3
+ import { merge, pick, sum } from '@aztec/foundation/collection';
2
4
  import { createLogger } from '@aztec/foundation/log';
3
5
  import { bufferToHex } from '@aztec/foundation/string';
4
- import { Timer, elapsed } from '@aztec/foundation/timer';
5
- import { getDefaultAllowedSetupFunctions } from '@aztec/p2p/msg_validators';
6
+ import { elapsed } from '@aztec/foundation/timer';
7
+ import { createTxValidatorForBlockBuilding, getDefaultAllowedSetupFunctions } from '@aztec/p2p/msg_validators';
6
8
  import { LightweightCheckpointBuilder } from '@aztec/prover-client/light';
7
9
  import { GuardedMerkleTreeOperations, PublicContractsDB, PublicProcessor, createPublicTxSimulatorForBlockBuilding } from '@aztec/simulator/server';
8
10
  import { Gas } from '@aztec/stdlib/gas';
9
- import { FullNodeBlockBuilderConfigKeys } from '@aztec/stdlib/interfaces/server';
11
+ import { FullNodeBlockBuilderConfigKeys, InsufficientValidTxsError } from '@aztec/stdlib/interfaces/server';
12
+ import { NullDebugLogStore } from '@aztec/stdlib/logs';
10
13
  import { MerkleTreeId } from '@aztec/stdlib/trees';
11
14
  import { GlobalVariables } from '@aztec/stdlib/tx';
12
15
  import { getTelemetryClient } from '@aztec/telemetry-client';
13
- import { createValidatorForBlockBuilding } from './tx_validator/tx_validator_factory.js';
14
- const log = createLogger('checkpoint-builder');
16
+ import { ForkCheckpoint } from '@aztec/world-state';
15
17
  /**
16
18
  * Builder for a single checkpoint. Handles building blocks within the checkpoint
17
19
  * and completing it.
@@ -22,26 +24,34 @@ const log = createLogger('checkpoint-builder');
22
24
  contractDataSource;
23
25
  dateProvider;
24
26
  telemetryClient;
25
- constructor(checkpointBuilder, fork, config, contractDataSource, dateProvider, telemetryClient){
27
+ debugLogStore;
28
+ log;
29
+ constructor(checkpointBuilder, fork, config, contractDataSource, dateProvider, telemetryClient, bindings, debugLogStore = new NullDebugLogStore()){
26
30
  this.checkpointBuilder = checkpointBuilder;
27
31
  this.fork = fork;
28
32
  this.config = config;
29
33
  this.contractDataSource = contractDataSource;
30
34
  this.dateProvider = dateProvider;
31
35
  this.telemetryClient = telemetryClient;
36
+ this.debugLogStore = debugLogStore;
37
+ this.log = createLogger('checkpoint-builder', {
38
+ ...bindings,
39
+ instanceId: `checkpoint-${checkpointBuilder.checkpointNumber}`
40
+ });
32
41
  }
33
42
  getConstantData() {
34
43
  return this.checkpointBuilder.constants;
35
44
  }
36
45
  /**
37
46
  * Builds a single block within this checkpoint.
38
- */ async buildBlock(pendingTxs, blockNumber, timestamp, opts) {
39
- const blockBuildingTimer = new Timer();
47
+ * Automatically caps gas and blob field limits based on checkpoint-level budgets and prior blocks.
48
+ */ async buildBlock(pendingTxs, blockNumber, timestamp, opts = {}) {
40
49
  const slot = this.checkpointBuilder.constants.slotNumber;
41
- log.verbose(`Building block ${blockNumber} for slot ${slot} within checkpoint`, {
50
+ this.log.verbose(`Building block ${blockNumber} for slot ${slot} within checkpoint`, {
42
51
  slot,
43
52
  blockNumber,
44
- ...opts
53
+ ...opts,
54
+ currentTime: new Date(this.dateProvider.now())
45
55
  });
46
56
  const constants = this.checkpointBuilder.constants;
47
57
  const globalVariables = GlobalVariables.from({
@@ -55,28 +65,49 @@ const log = createLogger('checkpoint-builder');
55
65
  gasFees: constants.gasFees
56
66
  });
57
67
  const { processor, validator } = await this.makeBlockBuilderDeps(globalVariables, this.fork);
58
- const [publicProcessorDuration, [processedTxs, failedTxs, usedTxs]] = await elapsed(()=>processor.process(pendingTxs, opts, validator));
59
- // Add block to checkpoint
60
- const block = await this.checkpointBuilder.addBlock(globalVariables, processedTxs, {
61
- expectedEndState: opts.expectedEndState
62
- });
63
- // How much public gas was processed
64
- const publicGas = processedTxs.reduce((acc, tx)=>acc.add(tx.gasUsed.publicGas), Gas.empty());
65
- const res = {
66
- block,
67
- publicGas,
68
- publicProcessorDuration,
69
- numTxs: processedTxs.length,
70
- failedTxs,
71
- blockBuildingTimer,
72
- usedTxs
68
+ // Cap gas limits amd available blob fields by remaining checkpoint-level budgets
69
+ const cappedOpts = {
70
+ ...opts,
71
+ ...this.capLimitsByCheckpointBudgets(opts)
73
72
  };
74
- log.debug('Built block within checkpoint', res.block.header);
75
- return res;
73
+ // We execute all merkle tree operations on a world state fork checkpoint
74
+ // This enables us to discard all modifications in the event that we fail to successfully process sufficient transactions
75
+ const forkCheckpoint = await ForkCheckpoint.new(this.fork);
76
+ try {
77
+ const [publicProcessorDuration, [processedTxs, failedTxs, usedTxs]] = await elapsed(()=>processor.process(pendingTxs, cappedOpts, validator));
78
+ // Throw before updating state if we don't have enough valid txs
79
+ const minValidTxs = opts.minValidTxs ?? 0;
80
+ if (processedTxs.length < minValidTxs) {
81
+ throw new InsufficientValidTxsError(processedTxs.length, minValidTxs, failedTxs);
82
+ }
83
+ // Commit the fork checkpoint
84
+ await forkCheckpoint.commit();
85
+ // Add block to checkpoint
86
+ const { block } = await this.checkpointBuilder.addBlock(globalVariables, processedTxs, {
87
+ expectedEndState: opts.expectedEndState
88
+ });
89
+ this.log.debug('Built block within checkpoint', {
90
+ header: block.header.toInspect(),
91
+ processedTxs: processedTxs.map((tx)=>tx.hash.toString()),
92
+ failedTxs: failedTxs.map((tx)=>tx.tx.txHash.toString())
93
+ });
94
+ return {
95
+ block,
96
+ publicProcessorDuration,
97
+ numTxs: processedTxs.length,
98
+ failedTxs,
99
+ usedTxs
100
+ };
101
+ } catch (err) {
102
+ // If we reached the point of committing the checkpoint, this does nothing
103
+ // Otherwise it reverts any changes made to the fork for this failed block
104
+ await forkCheckpoint.revert();
105
+ throw err;
106
+ }
76
107
  }
77
108
  /** Completes the checkpoint and returns it. */ async completeCheckpoint() {
78
109
  const checkpoint = await this.checkpointBuilder.completeCheckpoint();
79
- log.verbose(`Completed checkpoint ${checkpoint.number}`, {
110
+ this.log.verbose(`Completed checkpoint ${checkpoint.number}`, {
80
111
  checkpointNumber: checkpoint.number,
81
112
  numBlocks: checkpoint.blocks.length,
82
113
  archiveRoot: checkpoint.archive.root.toString()
@@ -86,31 +117,90 @@ const log = createLogger('checkpoint-builder');
86
117
  /** Gets the checkpoint currently in progress. */ getCheckpoint() {
87
118
  return this.checkpointBuilder.clone().completeCheckpoint();
88
119
  }
120
+ /**
121
+ * Caps per-block gas and blob field limits by remaining checkpoint-level budgets.
122
+ * Computes remaining L2 gas (mana), DA gas, and blob fields from blocks already added to the checkpoint,
123
+ * then returns opts with maxBlockGas and maxBlobFields capped accordingly.
124
+ */ capLimitsByCheckpointBudgets(opts) {
125
+ const existingBlocks = this.checkpointBuilder.getBlocks();
126
+ // Remaining L2 gas (mana)
127
+ // IMPORTANT: This assumes mana is computed solely based on L2 gas used in transactions.
128
+ // This may change in the future.
129
+ const usedMana = sum(existingBlocks.map((b)=>b.header.totalManaUsed.toNumber()));
130
+ const remainingMana = this.config.rollupManaLimit - usedMana;
131
+ // Remaining DA gas
132
+ const usedDAGas = sum(existingBlocks.map((b)=>b.computeDAGasUsed())) ?? 0;
133
+ const remainingDAGas = MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT - usedDAGas;
134
+ // Remaining blob fields (block blob fields include both tx data and block-end overhead)
135
+ const usedBlobFields = sum(existingBlocks.map((b)=>b.toBlobFields().length));
136
+ const totalBlobCapacity = BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB - NUM_CHECKPOINT_END_MARKER_FIELDS;
137
+ const isFirstBlock = existingBlocks.length === 0;
138
+ const blockEndOverhead = getNumBlockEndBlobFields(isFirstBlock);
139
+ const maxBlobFieldsForTxs = totalBlobCapacity - usedBlobFields - blockEndOverhead;
140
+ // When redistributeCheckpointBudget is enabled (default), compute a fair share of remaining budget
141
+ // across remaining blocks scaled by the multiplier, instead of letting one block consume it all.
142
+ const redistribute = this.config.redistributeCheckpointBudget !== false;
143
+ const remainingBlocks = Math.max(1, (this.config.maxBlocksPerCheckpoint ?? 1) - existingBlocks.length);
144
+ const multiplier = this.config.perBlockAllocationMultiplier ?? 1.2;
145
+ // Cap L2 gas by remaining checkpoint mana (with fair share when redistributing)
146
+ const fairShareL2 = redistribute ? Math.ceil(remainingMana / remainingBlocks * multiplier) : Infinity;
147
+ const cappedL2Gas = Math.min(opts.maxBlockGas?.l2Gas ?? Infinity, fairShareL2, remainingMana);
148
+ // Cap DA gas by remaining checkpoint DA gas budget (with fair share when redistributing)
149
+ const fairShareDA = redistribute ? Math.ceil(remainingDAGas / remainingBlocks * multiplier) : Infinity;
150
+ const cappedDAGas = Math.min(opts.maxBlockGas?.daGas ?? remainingDAGas, fairShareDA, remainingDAGas);
151
+ // Cap blob fields by remaining checkpoint blob capacity (with fair share when redistributing)
152
+ const fairShareBlobs = redistribute ? Math.ceil(maxBlobFieldsForTxs / remainingBlocks * multiplier) : Infinity;
153
+ const cappedBlobFields = Math.min(opts.maxBlobFields ?? Infinity, fairShareBlobs, maxBlobFieldsForTxs);
154
+ // Cap transaction count by remaining checkpoint tx budget (with fair share when redistributing)
155
+ let cappedMaxTransactions;
156
+ if (this.config.maxTxsPerCheckpoint !== undefined) {
157
+ const usedTxs = sum(existingBlocks.map((b)=>b.body.txEffects.length));
158
+ const remainingTxs = Math.max(0, this.config.maxTxsPerCheckpoint - usedTxs);
159
+ const fairShareTxs = redistribute ? Math.ceil(remainingTxs / remainingBlocks * multiplier) : Infinity;
160
+ cappedMaxTransactions = Math.min(opts.maxTransactions ?? Infinity, fairShareTxs, remainingTxs);
161
+ } else {
162
+ cappedMaxTransactions = opts.maxTransactions;
163
+ }
164
+ return {
165
+ maxBlockGas: new Gas(cappedDAGas, cappedL2Gas),
166
+ maxBlobFields: cappedBlobFields,
167
+ maxTransactions: cappedMaxTransactions
168
+ };
169
+ }
89
170
  async makeBlockBuilderDeps(globalVariables, fork) {
90
- const txPublicSetupAllowList = this.config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
91
- const contractsDB = new PublicContractsDB(this.contractDataSource);
171
+ const txPublicSetupAllowList = [
172
+ ...await getDefaultAllowedSetupFunctions(),
173
+ ...this.config.txPublicSetupAllowListExtend ?? []
174
+ ];
175
+ const contractsDB = new PublicContractsDB(this.contractDataSource, this.log.getBindings());
92
176
  const guardedFork = new GuardedMerkleTreeOperations(fork);
93
- const publicTxSimulator = createPublicTxSimulatorForBlockBuilding(guardedFork, contractsDB, globalVariables, this.telemetryClient);
94
- const processor = new PublicProcessor(globalVariables, guardedFork, contractsDB, publicTxSimulator, this.dateProvider, this.telemetryClient, undefined, this.config);
95
- const validator = createValidatorForBlockBuilding(fork, this.contractDataSource, globalVariables, txPublicSetupAllowList);
177
+ const collectDebugLogs = this.debugLogStore.isEnabled;
178
+ const bindings = this.log.getBindings();
179
+ const publicTxSimulator = createPublicTxSimulatorForBlockBuilding(guardedFork, contractsDB, globalVariables, this.telemetryClient, bindings, collectDebugLogs);
180
+ const processor = new PublicProcessor(globalVariables, guardedFork, contractsDB, publicTxSimulator, this.dateProvider, this.telemetryClient, createLogger('simulator:public-processor', bindings), this.config, this.debugLogStore);
181
+ const validator = createTxValidatorForBlockBuilding(fork, this.contractDataSource, globalVariables, txPublicSetupAllowList, this.log.getBindings());
96
182
  return {
97
183
  processor,
98
184
  validator
99
185
  };
100
186
  }
101
187
  }
102
- /**
103
- * Factory for creating checkpoint builders.
104
- */ export class FullNodeCheckpointsBuilder {
188
+ /** Factory for creating checkpoint builders. */ export class FullNodeCheckpointsBuilder {
105
189
  config;
190
+ worldState;
106
191
  contractDataSource;
107
192
  dateProvider;
108
193
  telemetryClient;
109
- constructor(config, contractDataSource, dateProvider, telemetryClient = getTelemetryClient()){
194
+ debugLogStore;
195
+ log;
196
+ constructor(config, worldState, contractDataSource, dateProvider, telemetryClient = getTelemetryClient(), debugLogStore = new NullDebugLogStore()){
110
197
  this.config = config;
198
+ this.worldState = worldState;
111
199
  this.contractDataSource = contractDataSource;
112
200
  this.dateProvider = dateProvider;
113
201
  this.telemetryClient = telemetryClient;
202
+ this.debugLogStore = debugLogStore;
203
+ this.log = createLogger('checkpoint-builder');
114
204
  }
115
205
  getConfig() {
116
206
  return this.config;
@@ -120,36 +210,41 @@ const log = createLogger('checkpoint-builder');
120
210
  }
121
211
  /**
122
212
  * Starts a new checkpoint and returns a CheckpointBuilder to build blocks within it.
123
- */ async startCheckpoint(checkpointNumber, constants, l1ToL2Messages, fork) {
213
+ */ async startCheckpoint(checkpointNumber, constants, feeAssetPriceModifier, l1ToL2Messages, previousCheckpointOutHashes, fork, bindings) {
124
214
  const stateReference = await fork.getStateReference();
125
215
  const archiveTree = await fork.getTreeInfo(MerkleTreeId.ARCHIVE);
126
- log.verbose(`Building new checkpoint ${checkpointNumber}`, {
216
+ this.log.verbose(`Building new checkpoint ${checkpointNumber}`, {
127
217
  checkpointNumber,
128
218
  msgCount: l1ToL2Messages.length,
129
219
  initialStateReference: stateReference.toInspect(),
130
220
  initialArchiveRoot: bufferToHex(archiveTree.root),
131
- constants
221
+ constants,
222
+ feeAssetPriceModifier
132
223
  });
133
- const lightweightBuilder = await LightweightCheckpointBuilder.startNewCheckpoint(checkpointNumber, constants, l1ToL2Messages, fork);
134
- return new CheckpointBuilder(lightweightBuilder, fork, this.config, this.contractDataSource, this.dateProvider, this.telemetryClient);
224
+ const lightweightBuilder = await LightweightCheckpointBuilder.startNewCheckpoint(checkpointNumber, constants, l1ToL2Messages, previousCheckpointOutHashes, fork, bindings, feeAssetPriceModifier);
225
+ return new CheckpointBuilder(lightweightBuilder, fork, this.config, this.contractDataSource, this.dateProvider, this.telemetryClient, bindings, this.debugLogStore);
135
226
  }
136
227
  /**
137
228
  * Opens a checkpoint, either starting fresh or resuming from existing blocks.
138
- */ async openCheckpoint(checkpointNumber, constants, l1ToL2Messages, fork, existingBlocks = []) {
229
+ */ async openCheckpoint(checkpointNumber, constants, feeAssetPriceModifier, l1ToL2Messages, previousCheckpointOutHashes, fork, existingBlocks = [], bindings) {
139
230
  const stateReference = await fork.getStateReference();
140
231
  const archiveTree = await fork.getTreeInfo(MerkleTreeId.ARCHIVE);
141
232
  if (existingBlocks.length === 0) {
142
- return this.startCheckpoint(checkpointNumber, constants, l1ToL2Messages, fork);
233
+ return this.startCheckpoint(checkpointNumber, constants, feeAssetPriceModifier, l1ToL2Messages, previousCheckpointOutHashes, fork, bindings);
143
234
  }
144
- log.verbose(`Resuming checkpoint ${checkpointNumber} with ${existingBlocks.length} existing blocks`, {
235
+ this.log.verbose(`Resuming checkpoint ${checkpointNumber} with ${existingBlocks.length} existing blocks`, {
145
236
  checkpointNumber,
146
237
  msgCount: l1ToL2Messages.length,
147
238
  existingBlockCount: existingBlocks.length,
148
239
  initialStateReference: stateReference.toInspect(),
149
240
  initialArchiveRoot: bufferToHex(archiveTree.root),
150
- constants
241
+ constants,
242
+ feeAssetPriceModifier
151
243
  });
152
- const lightweightBuilder = await LightweightCheckpointBuilder.resumeCheckpoint(checkpointNumber, constants, l1ToL2Messages, fork, existingBlocks);
153
- return new CheckpointBuilder(lightweightBuilder, fork, this.config, this.contractDataSource, this.dateProvider, this.telemetryClient);
244
+ const lightweightBuilder = await LightweightCheckpointBuilder.resumeCheckpoint(checkpointNumber, constants, feeAssetPriceModifier, l1ToL2Messages, previousCheckpointOutHashes, fork, existingBlocks, bindings);
245
+ return new CheckpointBuilder(lightweightBuilder, fork, this.config, this.contractDataSource, this.dateProvider, this.telemetryClient, bindings, this.debugLogStore);
246
+ }
247
+ /** Returns a fork of the world state at the given block number. */ getFork(blockNumber) {
248
+ return this.worldState.fork(blockNumber);
154
249
  }
155
250
  }
package/dest/config.d.ts CHANGED
@@ -8,4 +8,4 @@ export declare const validatorClientConfigMappings: ConfigMappingsType<Validator
8
8
  * @returns The validator configuration.
9
9
  */
10
10
  export declare function getProverEnvVars(): ValidatorClientConfig;
11
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxLQUFLLGtCQUFrQixFQUt4QixNQUFNLDBCQUEwQixDQUFDO0FBRWxDLE9BQU8sS0FBSyxFQUFFLHFCQUFxQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFN0UsWUFBWSxFQUFFLHFCQUFxQixFQUFFLENBQUM7QUFFdEMsZUFBTyxNQUFNLDZCQUE2QixFQUFFLGtCQUFrQixDQUFDLHFCQUFxQixDQXNFbkYsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCx3QkFBZ0IsZ0JBQWdCLElBQUkscUJBQXFCLENBRXhEIn0=
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxLQUFLLGtCQUFrQixFQUt4QixNQUFNLDBCQUEwQixDQUFDO0FBR2xDLE9BQU8sS0FBSyxFQUFFLHFCQUFxQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFN0UsWUFBWSxFQUFFLHFCQUFxQixFQUFFLENBQUM7QUFFdEMsZUFBTyxNQUFNLDZCQUE2QixFQUFFLGtCQUFrQixDQUFDLHFCQUFxQixDQXdGbkYsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCx3QkFBZ0IsZ0JBQWdCLElBQUkscUJBQXFCLENBRXhEIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAE7E,YAAY,EAAE,qBAAqB,EAAE,CAAC;AAEtC,eAAO,MAAM,6BAA6B,EAAE,kBAAkB,CAAC,qBAAqB,CAsEnF,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,qBAAqB,CAExD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAE7E,YAAY,EAAE,qBAAqB,EAAE,CAAC;AAEtC,eAAO,MAAM,6BAA6B,EAAE,kBAAkB,CAAC,qBAAqB,CAwFnF,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,qBAAqB,CAExD"}
package/dest/config.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { booleanConfigHelper, getConfigFromMappings, numberConfigHelper, secretValueConfigHelper } from '@aztec/foundation/config';
2
2
  import { EthAddress } from '@aztec/foundation/eth-address';
3
+ import { localSignerConfigMappings, validatorHASignerConfigMappings } from '@aztec/stdlib/ha-signing';
3
4
  export const validatorClientConfigMappings = {
4
5
  validatorPrivateKeys: {
5
6
  env: 'VALIDATOR_PRIVATE_KEYS',
@@ -35,31 +36,49 @@ export const validatorClientConfigMappings = {
35
36
  description: 'Re-execute transactions before attesting',
36
37
  ...booleanConfigHelper(true)
37
38
  },
38
- validatorReexecuteDeadlineMs: {
39
- env: 'VALIDATOR_REEXECUTE_DEADLINE_MS',
40
- description: 'Will re-execute until this many milliseconds are left in the slot',
41
- ...numberConfigHelper(6000)
42
- },
43
39
  alwaysReexecuteBlockProposals: {
44
- env: 'ALWAYS_REEXECUTE_BLOCK_PROPOSALS',
45
40
  description: 'Whether to always reexecute block proposals, even for non-validator nodes (useful for monitoring network status).',
46
- ...booleanConfigHelper(false)
41
+ defaultValue: true
47
42
  },
48
43
  fishermanMode: {
49
44
  env: 'FISHERMAN_MODE',
50
45
  description: 'Whether to run in fisherman mode: validates all proposals and attestations but does not broadcast attestations or participate in consensus.',
51
46
  ...booleanConfigHelper(false)
52
47
  },
53
- // TODO(palla/mbps): Change default to false once checkpoint validation is stable
54
48
  skipCheckpointProposalValidation: {
55
- description: 'Skip checkpoint proposal validation and always attest (default: true)',
56
- defaultValue: true
49
+ description: 'Skip checkpoint proposal validation and always attest (default: false)',
50
+ defaultValue: false
57
51
  },
58
- // TODO(palla/mbps): Change default to false once block sync is stable
59
52
  skipPushProposedBlocksToArchiver: {
60
- description: 'Skip pushing re-executed blocks to archiver (default: true)',
61
- defaultValue: true
62
- }
53
+ description: 'Skip pushing re-executed blocks to archiver (default: false)',
54
+ defaultValue: false
55
+ },
56
+ attestToEquivocatedProposals: {
57
+ description: 'Agree to attest to equivocated checkpoint proposals (for testing purposes only)',
58
+ ...booleanConfigHelper(false)
59
+ },
60
+ validateMaxL2BlockGas: {
61
+ env: 'VALIDATOR_MAX_L2_BLOCK_GAS',
62
+ description: 'Maximum L2 block gas for validation. Proposals exceeding this limit are rejected.',
63
+ parseEnv: (val)=>val ? parseInt(val, 10) : undefined
64
+ },
65
+ validateMaxDABlockGas: {
66
+ env: 'VALIDATOR_MAX_DA_BLOCK_GAS',
67
+ description: 'Maximum DA block gas for validation. Proposals exceeding this limit are rejected.',
68
+ parseEnv: (val)=>val ? parseInt(val, 10) : undefined
69
+ },
70
+ validateMaxTxsPerBlock: {
71
+ env: 'VALIDATOR_MAX_TX_PER_BLOCK',
72
+ description: 'Maximum transactions per block for validation. Proposals exceeding this limit are rejected.',
73
+ parseEnv: (val)=>val ? parseInt(val, 10) : undefined
74
+ },
75
+ validateMaxTxsPerCheckpoint: {
76
+ env: 'VALIDATOR_MAX_TX_PER_CHECKPOINT',
77
+ description: 'Maximum transactions per checkpoint for validation. Proposals exceeding this limit are rejected.',
78
+ parseEnv: (val)=>val ? parseInt(val, 10) : undefined
79
+ },
80
+ ...localSignerConfigMappings,
81
+ ...validatorHASignerConfigMappings
63
82
  };
64
83
  /**
65
84
  * Returns the prover configuration from the environment variables.
@@ -1,3 +1,4 @@
1
+ import { BlockNumber, type CheckpointNumber, IndexWithinCheckpoint, type SlotNumber } from '@aztec/foundation/branded-types';
1
2
  import { Fr } from '@aztec/foundation/curves/bn254';
2
3
  import type { EthAddress } from '@aztec/foundation/eth-address';
3
4
  import type { Signature } from '@aztec/foundation/eth-signature';
@@ -15,15 +16,18 @@ export declare class ValidationService {
15
16
  * Create a block proposal with the given header, archive, and transactions
16
17
  *
17
18
  * @param blockHeader - The block header
18
- * @param indexWithinCheckpoint - Index of this block within the checkpoint (0-indexed)
19
+ * @param blockIndexWithinCheckpoint - The block index within checkpoint for HA signing context
19
20
  * @param inHash - Hash of L1 to L2 messages for this checkpoint
20
21
  * @param archive - The archive of the current block
21
- * @param txs - TxHash[] ordered list of transactions
22
+ * @param txs - Ordered list of transactions (Tx[])
23
+ * @param proposerAttesterAddress - The address of the proposer/attester, or undefined
22
24
  * @param options - Block proposal options (including broadcastInvalidBlockProposal for testing)
23
25
  *
24
26
  * @returns A block proposal signing the above information
27
+ * @throws DutyAlreadySignedError if HA signer indicates duty already signed by another node
28
+ * @throws SlashingProtectionError if attempting to sign different data for same slot
25
29
  */
26
- createBlockProposal(blockHeader: BlockHeader, indexWithinCheckpoint: number, inHash: Fr, archive: Fr, txs: Tx[], proposerAttesterAddress: EthAddress | undefined, options: BlockProposalOptions): Promise<BlockProposal>;
30
+ createBlockProposal(blockHeader: BlockHeader, blockIndexWithinCheckpoint: IndexWithinCheckpoint, inHash: Fr, archive: Fr, txs: Tx[], proposerAttesterAddress: EthAddress | undefined, options: BlockProposalOptions): Promise<BlockProposal>;
27
31
  /**
28
32
  * Create a checkpoint proposal with the last block header and checkpoint header
29
33
  *
@@ -35,8 +39,7 @@ export declare class ValidationService {
35
39
  *
36
40
  * @returns A checkpoint proposal signing the above information
37
41
  */
38
- createCheckpointProposal(checkpointHeader: CheckpointHeader, archive: Fr, lastBlockInfo: CreateCheckpointProposalLastBlockData | undefined, proposerAttesterAddress: EthAddress | undefined, options: CheckpointProposalOptions): Promise<CheckpointProposal>;
39
- private getPayloadSigner;
42
+ createCheckpointProposal(checkpointHeader: CheckpointHeader, archive: Fr, feeAssetPriceModifier: bigint, lastBlockInfo: CreateCheckpointProposalLastBlockData | undefined, proposerAttesterAddress: EthAddress | undefined, options: CheckpointProposalOptions): Promise<CheckpointProposal>;
40
43
  /**
41
44
  * Attest with selection of validators to the given checkpoint proposal
42
45
  *
@@ -48,6 +51,16 @@ export declare class ValidationService {
48
51
  * @returns checkpoint attestations
49
52
  */
50
53
  attestToCheckpointProposal(proposal: CheckpointProposalCore, attestors: EthAddress[]): Promise<CheckpointAttestation[]>;
51
- signAttestationsAndSigners(attestationsAndSigners: CommitteeAttestationsAndSigners, proposer: EthAddress): Promise<Signature>;
54
+ /**
55
+ * Sign attestations and signers payload
56
+ * @param attestationsAndSigners - The attestations and signers to sign
57
+ * @param proposer - The proposer address to sign with
58
+ * @param slot - The slot number for HA signing context
59
+ * @param blockNumber - The block or checkpoint number for HA signing context
60
+ * @returns signature
61
+ * @throws DutyAlreadySignedError if already signed by another HA node
62
+ * @throws SlashingProtectionError if attempting to sign different data for same slot
63
+ */
64
+ signAttestationsAndSigners(attestationsAndSigners: CommitteeAttestationsAndSigners, proposer: EthAddress, slot: SlotNumber, blockNumber: BlockNumber | CheckpointNumber): Promise<Signature>;
52
65
  }
53
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbl9zZXJ2aWNlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZHV0aWVzL3ZhbGlkYXRpb25fc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDcEQsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFakUsT0FBTyxLQUFLLEVBQUUsK0JBQStCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMzRSxPQUFPLEtBQUssRUFBRSxxQ0FBcUMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzdGLE9BQU8sRUFDTCxhQUFhLEVBQ2IsS0FBSyxvQkFBb0IsRUFDekIscUJBQXFCLEVBQ3JCLGtCQUFrQixFQUNsQixLQUFLLHNCQUFzQixFQUMzQixLQUFLLHlCQUF5QixFQUcvQixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDN0QsT0FBTyxLQUFLLEVBQUUsV0FBVyxFQUFFLEVBQUUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXhELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFbkUscUJBQWEsaUJBQWlCO0lBRTFCLE9BQU8sQ0FBQyxRQUFRO0lBQ2hCLE9BQU8sQ0FBQyxHQUFHO0lBRmIsWUFDVSxRQUFRLEVBQUUsaUJBQWlCLEVBQzNCLEdBQUcseUNBQStDLEVBQ3hEO0lBRUo7Ozs7Ozs7Ozs7O09BV0c7SUFDSSxtQkFBbUIsQ0FDeEIsV0FBVyxFQUFFLFdBQVcsRUFDeEIscUJBQXFCLEVBQUUsTUFBTSxFQUM3QixNQUFNLEVBQUUsRUFBRSxFQUNWLE9BQU8sRUFBRSxFQUFFLEVBQ1gsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUNULHVCQUF1QixFQUFFLFVBQVUsR0FBRyxTQUFTLEVBQy9DLE9BQU8sRUFBRSxvQkFBb0IsR0FDNUIsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQWtCeEI7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksd0JBQXdCLENBQzdCLGdCQUFnQixFQUFFLGdCQUFnQixFQUNsQyxPQUFPLEVBQUUsRUFBRSxFQUNYLGFBQWEsRUFBRSxxQ0FBcUMsR0FBRyxTQUFTLEVBQ2hFLHVCQUF1QixFQUFFLFVBQVUsR0FBRyxTQUFTLEVBQy9DLE9BQU8sRUFBRSx5QkFBeUIsR0FDakMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBa0I3QjtJQUVELE9BQU8sQ0FBQyxnQkFBZ0I7SUFVeEI7Ozs7Ozs7OztPQVNHO0lBQ0csMEJBQTBCLENBQzlCLFFBQVEsRUFBRSxzQkFBc0IsRUFDaEMsU0FBUyxFQUFFLFVBQVUsRUFBRSxHQUN0QixPQUFPLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxDQVVsQztJQUVLLDBCQUEwQixDQUM5QixzQkFBc0IsRUFBRSwrQkFBK0IsRUFDdkQsUUFBUSxFQUFFLFVBQVUsR0FDbkIsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUtwQjtDQUNGIn0=
66
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbl9zZXJ2aWNlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZHV0aWVzL3ZhbGlkYXRpb25fc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsV0FBVyxFQUNYLEtBQUssZ0JBQWdCLEVBQ3JCLHFCQUFxQixFQUNyQixLQUFLLFVBQVUsRUFDaEIsTUFBTSxpQ0FBaUMsQ0FBQztBQUd6QyxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDcEQsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFakUsT0FBTyxLQUFLLEVBQUUsK0JBQStCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMzRSxPQUFPLEtBQUssRUFBRSxxQ0FBcUMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzdGLE9BQU8sRUFDTCxhQUFhLEVBQ2IsS0FBSyxvQkFBb0IsRUFDekIscUJBQXFCLEVBQ3JCLGtCQUFrQixFQUNsQixLQUFLLHNCQUFzQixFQUMzQixLQUFLLHlCQUF5QixFQUcvQixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDN0QsT0FBTyxLQUFLLEVBQUUsV0FBVyxFQUFFLEVBQUUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBSXhELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFbkUscUJBQWEsaUJBQWlCO0lBRTFCLE9BQU8sQ0FBQyxRQUFRO0lBQ2hCLE9BQU8sQ0FBQyxHQUFHO0lBRmIsWUFDVSxRQUFRLEVBQUUsaUJBQWlCLEVBQzNCLEdBQUcseUNBQStDLEVBQ3hEO0lBRUo7Ozs7Ozs7Ozs7Ozs7O09BY0c7SUFDSSxtQkFBbUIsQ0FDeEIsV0FBVyxFQUFFLFdBQVcsRUFDeEIsMEJBQTBCLEVBQUUscUJBQXFCLEVBQ2pELE1BQU0sRUFBRSxFQUFFLEVBQ1YsT0FBTyxFQUFFLEVBQUUsRUFDWCxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQ1QsdUJBQXVCLEVBQUUsVUFBVSxHQUFHLFNBQVMsRUFDL0MsT0FBTyxFQUFFLG9CQUFvQixHQUM1QixPQUFPLENBQUMsYUFBYSxDQUFDLENBcUJ4QjtJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSx3QkFBd0IsQ0FDN0IsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQ2xDLE9BQU8sRUFBRSxFQUFFLEVBQ1gscUJBQXFCLEVBQUUsTUFBTSxFQUM3QixhQUFhLEVBQUUscUNBQXFDLEdBQUcsU0FBUyxFQUNoRSx1QkFBdUIsRUFBRSxVQUFVLEdBQUcsU0FBUyxFQUMvQyxPQUFPLEVBQUUseUJBQXlCLEdBQ2pDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQTRCN0I7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDRywwQkFBMEIsQ0FDOUIsUUFBUSxFQUFFLHNCQUFzQixFQUNoQyxTQUFTLEVBQUUsVUFBVSxFQUFFLEdBQ3RCLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLENBOENsQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNILDBCQUEwQixDQUN4QixzQkFBc0IsRUFBRSwrQkFBK0IsRUFDdkQsUUFBUSxFQUFFLFVBQVUsRUFDcEIsSUFBSSxFQUFFLFVBQVUsRUFDaEIsV0FBVyxFQUFFLFdBQVcsR0FBRyxnQkFBZ0IsR0FDMUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQVdwQjtDQUNGIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"validation_service.d.ts","sourceRoot":"","sources":["../../src/duties/validation_service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAEjE,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,iCAAiC,CAAC;AAC7F,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EACzB,qBAAqB,EACrB,kBAAkB,EAClB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAG/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,GAAG;IAFb,YACU,QAAQ,EAAE,iBAAiB,EAC3B,GAAG,yCAA+C,EACxD;IAEJ;;;;;;;;;;;OAWG;IACI,mBAAmB,CACxB,WAAW,EAAE,WAAW,EACxB,qBAAqB,EAAE,MAAM,EAC7B,MAAM,EAAE,EAAE,EACV,OAAO,EAAE,EAAE,EACX,GAAG,EAAE,EAAE,EAAE,EACT,uBAAuB,EAAE,UAAU,GAAG,SAAS,EAC/C,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,aAAa,CAAC,CAkBxB;IAED;;;;;;;;;;OAUG;IACI,wBAAwB,CAC7B,gBAAgB,EAAE,gBAAgB,EAClC,OAAO,EAAE,EAAE,EACX,aAAa,EAAE,qCAAqC,GAAG,SAAS,EAChE,uBAAuB,EAAE,UAAU,GAAG,SAAS,EAC/C,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,kBAAkB,CAAC,CAkB7B;IAED,OAAO,CAAC,gBAAgB;IAUxB;;;;;;;;;OASG;IACG,0BAA0B,CAC9B,QAAQ,EAAE,sBAAsB,EAChC,SAAS,EAAE,UAAU,EAAE,GACtB,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAUlC;IAEK,0BAA0B,CAC9B,sBAAsB,EAAE,+BAA+B,EACvD,QAAQ,EAAE,UAAU,GACnB,OAAO,CAAC,SAAS,CAAC,CAKpB;CACF"}
1
+ {"version":3,"file":"validation_service.d.ts","sourceRoot":"","sources":["../../src/duties/validation_service.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,KAAK,gBAAgB,EACrB,qBAAqB,EACrB,KAAK,UAAU,EAChB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAEjE,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,iCAAiC,CAAC;AAC7F,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EACzB,qBAAqB,EACrB,kBAAkB,EAClB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAG/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAIxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,GAAG;IAFb,YACU,QAAQ,EAAE,iBAAiB,EAC3B,GAAG,yCAA+C,EACxD;IAEJ;;;;;;;;;;;;;;OAcG;IACI,mBAAmB,CACxB,WAAW,EAAE,WAAW,EACxB,0BAA0B,EAAE,qBAAqB,EACjD,MAAM,EAAE,EAAE,EACV,OAAO,EAAE,EAAE,EACX,GAAG,EAAE,EAAE,EAAE,EACT,uBAAuB,EAAE,UAAU,GAAG,SAAS,EAC/C,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,aAAa,CAAC,CAqBxB;IAED;;;;;;;;;;OAUG;IACI,wBAAwB,CAC7B,gBAAgB,EAAE,gBAAgB,EAClC,OAAO,EAAE,EAAE,EACX,qBAAqB,EAAE,MAAM,EAC7B,aAAa,EAAE,qCAAqC,GAAG,SAAS,EAChE,uBAAuB,EAAE,UAAU,GAAG,SAAS,EAC/C,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,kBAAkB,CAAC,CA4B7B;IAED;;;;;;;;;OASG;IACG,0BAA0B,CAC9B,QAAQ,EAAE,sBAAsB,EAChC,SAAS,EAAE,UAAU,EAAE,GACtB,OAAO,CAAC,qBAAqB,EAAE,CAAC,CA8ClC;IAED;;;;;;;;;OASG;IACH,0BAA0B,CACxB,sBAAsB,EAAE,+BAA+B,EACvD,QAAQ,EAAE,UAAU,EACpB,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,WAAW,GAAG,gBAAgB,GAC1C,OAAO,CAAC,SAAS,CAAC,CAWpB;CACF"}
@@ -1,8 +1,11 @@
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
1
2
  import { Buffer32 } from '@aztec/foundation/buffer';
2
3
  import { keccak256 } from '@aztec/foundation/crypto/keccak';
3
4
  import { Fr } from '@aztec/foundation/curves/bn254';
4
5
  import { createLogger } from '@aztec/foundation/log';
5
6
  import { BlockProposal, CheckpointAttestation, CheckpointProposal, ConsensusPayload, SignatureDomainSeparator } from '@aztec/stdlib/p2p';
7
+ import { DutyAlreadySignedError, SlashingProtectionError } from '@aztec/validator-ha-signer/errors';
8
+ import { DutyType } from '@aztec/validator-ha-signer/types';
6
9
  export class ValidationService {
7
10
  keyStore;
8
11
  log;
@@ -14,21 +17,26 @@ export class ValidationService {
14
17
  * Create a block proposal with the given header, archive, and transactions
15
18
  *
16
19
  * @param blockHeader - The block header
17
- * @param indexWithinCheckpoint - Index of this block within the checkpoint (0-indexed)
20
+ * @param blockIndexWithinCheckpoint - The block index within checkpoint for HA signing context
18
21
  * @param inHash - Hash of L1 to L2 messages for this checkpoint
19
22
  * @param archive - The archive of the current block
20
- * @param txs - TxHash[] ordered list of transactions
23
+ * @param txs - Ordered list of transactions (Tx[])
24
+ * @param proposerAttesterAddress - The address of the proposer/attester, or undefined
21
25
  * @param options - Block proposal options (including broadcastInvalidBlockProposal for testing)
22
26
  *
23
27
  * @returns A block proposal signing the above information
24
- */ createBlockProposal(blockHeader, indexWithinCheckpoint, inHash, archive, txs, proposerAttesterAddress, options) {
25
- const payloadSigner = this.getPayloadSigner(proposerAttesterAddress);
28
+ * @throws DutyAlreadySignedError if HA signer indicates duty already signed by another node
29
+ * @throws SlashingProtectionError if attempting to sign different data for same slot
30
+ */ createBlockProposal(blockHeader, blockIndexWithinCheckpoint, inHash, archive, txs, proposerAttesterAddress, options) {
26
31
  // For testing: change the new archive to trigger state_mismatch validation failure
27
32
  if (options.broadcastInvalidBlockProposal) {
28
33
  archive = Fr.random();
29
34
  this.log.warn(`Creating INVALID block proposal for slot ${blockHeader.globalVariables.slotNumber}`);
30
35
  }
31
- return BlockProposal.createProposalFromSigner(blockHeader, indexWithinCheckpoint, inHash, archive, txs.map((tx)=>tx.getTxHash()), options.publishFullTxs ? txs : undefined, payloadSigner);
36
+ // Create a signer that uses the appropriate address
37
+ const address = proposerAttesterAddress ?? this.keyStore.getAddress(0);
38
+ const payloadSigner = (payload, context)=>this.keyStore.signMessageWithAddress(address, payload, context);
39
+ return BlockProposal.createProposalFromSigner(blockHeader, blockIndexWithinCheckpoint, inHash, archive, txs.map((tx)=>tx.getTxHash()), options.publishFullTxs ? txs : undefined, payloadSigner);
32
40
  }
33
41
  /**
34
42
  * Create a checkpoint proposal with the last block header and checkpoint header
@@ -40,13 +48,17 @@ export class ValidationService {
40
48
  * @param options - Checkpoint proposal options
41
49
  *
42
50
  * @returns A checkpoint proposal signing the above information
43
- */ createCheckpointProposal(checkpointHeader, archive, lastBlockInfo, proposerAttesterAddress, options) {
44
- const payloadSigner = this.getPayloadSigner(proposerAttesterAddress);
51
+ */ createCheckpointProposal(checkpointHeader, archive, feeAssetPriceModifier, lastBlockInfo, proposerAttesterAddress, options) {
45
52
  // For testing: change the archive to trigger state_mismatch validation failure
46
53
  if (options.broadcastInvalidCheckpointProposal) {
47
54
  archive = Fr.random();
48
55
  this.log.warn(`Creating INVALID checkpoint proposal for slot ${checkpointHeader.slotNumber}`);
49
56
  }
57
+ // Create a signer that takes payload and context, and uses the appropriate address
58
+ const payloadSigner = (payload, context)=>{
59
+ const address = proposerAttesterAddress ?? this.keyStore.getAddress(0);
60
+ return this.keyStore.signMessageWithAddress(address, payload, context);
61
+ };
50
62
  // Last block to include in the proposal
51
63
  const lastBlock = lastBlockInfo && {
52
64
  blockHeader: lastBlockInfo.blockHeader,
@@ -54,16 +66,7 @@ export class ValidationService {
54
66
  txHashes: lastBlockInfo.txs.map((tx)=>tx.getTxHash()),
55
67
  txs: options.publishFullTxs ? lastBlockInfo.txs : undefined
56
68
  };
57
- return CheckpointProposal.createProposalFromSigner(checkpointHeader, archive, lastBlock, payloadSigner);
58
- }
59
- getPayloadSigner(proposerAttesterAddress) {
60
- if (proposerAttesterAddress !== undefined) {
61
- return (payload)=>this.keyStore.signMessageWithAddress(proposerAttesterAddress, payload);
62
- } else {
63
- // if there is no proposer attester address, just use the first signer
64
- const signer = this.keyStore.getAddress(0);
65
- return (payload)=>this.keyStore.signMessageWithAddress(signer, payload);
66
- }
69
+ return CheckpointProposal.createProposalFromSigner(checkpointHeader, archive, feeAssetPriceModifier, lastBlock, payloadSigner);
67
70
  }
68
71
  /**
69
72
  * Attest with selection of validators to the given checkpoint proposal
@@ -76,13 +79,57 @@ export class ValidationService {
76
79
  * @returns checkpoint attestations
77
80
  */ async attestToCheckpointProposal(proposal, attestors) {
78
81
  // Create the attestation payload from the checkpoint proposal
79
- const payload = new ConsensusPayload(proposal.checkpointHeader, proposal.archive);
82
+ const payload = new ConsensusPayload(proposal.checkpointHeader, proposal.archive, proposal.feeAssetPriceModifier);
80
83
  const buf = Buffer32.fromBuffer(keccak256(payload.getPayloadToSign(SignatureDomainSeparator.checkpointAttestation)));
81
- const signatures = await Promise.all(attestors.map((attestor)=>this.keyStore.signMessageWithAddress(attestor, buf)));
82
- return signatures.map((sig)=>new CheckpointAttestation(payload, sig, proposal.signature));
84
+ // TODO(spy/ha): Use checkpointNumber instead of blockNumber once CheckpointHeader includes it.
85
+ // CheckpointProposalCore doesn't have lastBlock info, so use 0 as a proxy.
86
+ // blockNumber is NOT used for the primary key so it's safe to use here.
87
+ // See CheckpointHeader TODO and SigningContext types documentation.
88
+ const blockNumber = BlockNumber(0);
89
+ const context = {
90
+ slot: proposal.slotNumber,
91
+ blockNumber,
92
+ dutyType: DutyType.ATTESTATION
93
+ };
94
+ // Sign each attestor in parallel, catching HA errors per-attestor
95
+ const results = await Promise.allSettled(attestors.map(async (attestor)=>{
96
+ const sig = await this.keyStore.signMessageWithAddress(attestor, buf, context);
97
+ // return new BlockAttestation(proposal.payload, sig, proposal.signature);
98
+ return new CheckpointAttestation(payload, sig, proposal.signature);
99
+ }));
100
+ const attestations = [];
101
+ for(let i = 0; i < results.length; i++){
102
+ const result = results[i];
103
+ if (result.status === 'fulfilled') {
104
+ attestations.push(result.value);
105
+ } else {
106
+ const error = result.reason;
107
+ if (error instanceof DutyAlreadySignedError || error instanceof SlashingProtectionError) {
108
+ this.log.verbose(`Attestation for slot ${proposal.slotNumber} by ${attestors[i]} already signed by another High-Availability node`);
109
+ // Continue with remaining attestors
110
+ } else {
111
+ throw error;
112
+ }
113
+ }
114
+ }
115
+ return attestations;
83
116
  }
84
- async signAttestationsAndSigners(attestationsAndSigners, proposer) {
117
+ /**
118
+ * Sign attestations and signers payload
119
+ * @param attestationsAndSigners - The attestations and signers to sign
120
+ * @param proposer - The proposer address to sign with
121
+ * @param slot - The slot number for HA signing context
122
+ * @param blockNumber - The block or checkpoint number for HA signing context
123
+ * @returns signature
124
+ * @throws DutyAlreadySignedError if already signed by another HA node
125
+ * @throws SlashingProtectionError if attempting to sign different data for same slot
126
+ */ signAttestationsAndSigners(attestationsAndSigners, proposer, slot, blockNumber) {
127
+ const context = {
128
+ slot,
129
+ blockNumber,
130
+ dutyType: DutyType.ATTESTATIONS_AND_SIGNERS
131
+ };
85
132
  const buf = Buffer32.fromBuffer(keccak256(attestationsAndSigners.getPayloadToSign(SignatureDomainSeparator.attestationsAndSigners)));
86
- return await this.keyStore.signMessageWithAddress(proposer, buf);
133
+ return this.keyStore.signMessageWithAddress(proposer, buf, context);
87
134
  }
88
135
  }
package/dest/factory.d.ts CHANGED
@@ -31,5 +31,5 @@ export declare function createValidatorClient(config: ValidatorClientFullConfig,
31
31
  epochCache: EpochCache;
32
32
  keyStoreManager: KeystoreManager | undefined;
33
33
  blobClient: BlobClientInterface;
34
- }): ValidatorClient | undefined;
35
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM1RCxPQUFPLEVBQTBCLEtBQUssU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3BFLE9BQU8sS0FBSyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RSxPQUFPLEtBQUssRUFBRSx5QkFBeUIsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3pHLE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbkUsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFL0QsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDbkUsT0FBTyxLQUFLLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUUxRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFakQsd0JBQWdCLDBCQUEwQixDQUN4QyxNQUFNLEVBQUUseUJBQXlCLEVBQ2pDLElBQUksRUFBRTtJQUNKLGtCQUFrQixFQUFFLDBCQUEwQixDQUFDO0lBQy9DLFVBQVUsRUFBRSxzQkFBc0IsQ0FBQztJQUNuQyxXQUFXLEVBQUUsYUFBYSxHQUFHLFdBQVcsQ0FBQztJQUN6QyxtQkFBbUIsRUFBRSxtQkFBbUIsQ0FBQztJQUN6QyxTQUFTLEVBQUUsU0FBUyxDQUFDO0lBQ3JCLFVBQVUsRUFBRSxVQUFVLENBQUM7SUFDdkIsWUFBWSxFQUFFLFlBQVksQ0FBQztJQUMzQixTQUFTLEVBQUUsZUFBZSxDQUFDO0NBQzVCLHdCQWtCRjtBQUVELHdCQUFnQixxQkFBcUIsQ0FDbkMsTUFBTSxFQUFFLHlCQUF5QixFQUNqQyxJQUFJLEVBQUU7SUFDSixrQkFBa0IsRUFBRSwwQkFBMEIsQ0FBQztJQUMvQyxVQUFVLEVBQUUsc0JBQXNCLENBQUM7SUFDbkMsU0FBUyxFQUFFLFNBQVMsQ0FBQztJQUNyQixXQUFXLEVBQUUsYUFBYSxHQUFHLFdBQVcsQ0FBQztJQUN6QyxtQkFBbUIsRUFBRSxtQkFBbUIsQ0FBQztJQUN6QyxTQUFTLEVBQUUsZUFBZSxDQUFDO0lBQzNCLFlBQVksRUFBRSxZQUFZLENBQUM7SUFDM0IsVUFBVSxFQUFFLFVBQVUsQ0FBQztJQUN2QixlQUFlLEVBQUUsZUFBZSxHQUFHLFNBQVMsQ0FBQztJQUM3QyxVQUFVLEVBQUUsbUJBQW1CLENBQUM7Q0FDakMsK0JBcUJGIn0=
34
+ }): Promise<ValidatorClient> | undefined;
35
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM1RCxPQUFPLEVBQTBCLEtBQUssU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3BFLE9BQU8sS0FBSyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RSxPQUFPLEtBQUssRUFBRSx5QkFBeUIsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3pHLE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbkUsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFL0QsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDbkUsT0FBTyxLQUFLLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUUxRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFakQsd0JBQWdCLDBCQUEwQixDQUN4QyxNQUFNLEVBQUUseUJBQXlCLEVBQ2pDLElBQUksRUFBRTtJQUNKLGtCQUFrQixFQUFFLDBCQUEwQixDQUFDO0lBQy9DLFVBQVUsRUFBRSxzQkFBc0IsQ0FBQztJQUNuQyxXQUFXLEVBQUUsYUFBYSxHQUFHLFdBQVcsQ0FBQztJQUN6QyxtQkFBbUIsRUFBRSxtQkFBbUIsQ0FBQztJQUN6QyxTQUFTLEVBQUUsU0FBUyxDQUFDO0lBQ3JCLFVBQVUsRUFBRSxVQUFVLENBQUM7SUFDdkIsWUFBWSxFQUFFLFlBQVksQ0FBQztJQUMzQixTQUFTLEVBQUUsZUFBZSxDQUFDO0NBQzVCLHdCQW9CRjtBQUVELHdCQUFnQixxQkFBcUIsQ0FDbkMsTUFBTSxFQUFFLHlCQUF5QixFQUNqQyxJQUFJLEVBQUU7SUFDSixrQkFBa0IsRUFBRSwwQkFBMEIsQ0FBQztJQUMvQyxVQUFVLEVBQUUsc0JBQXNCLENBQUM7SUFDbkMsU0FBUyxFQUFFLFNBQVMsQ0FBQztJQUNyQixXQUFXLEVBQUUsYUFBYSxHQUFHLFdBQVcsQ0FBQztJQUN6QyxtQkFBbUIsRUFBRSxtQkFBbUIsQ0FBQztJQUN6QyxTQUFTLEVBQUUsZUFBZSxDQUFDO0lBQzNCLFlBQVksRUFBRSxZQUFZLENBQUM7SUFDM0IsVUFBVSxFQUFFLFVBQVUsQ0FBQztJQUN2QixlQUFlLEVBQUUsZUFBZSxHQUFHLFNBQVMsQ0FBQztJQUM3QyxVQUFVLEVBQUUsbUJBQW1CLENBQUM7Q0FDakMsd0NBcUJGIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAA0B,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,KAAK,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,yBAAyB,EACjC,IAAI,EAAE;IACJ,kBAAkB,EAAE,0BAA0B,CAAC;IAC/C,UAAU,EAAE,sBAAsB,CAAC;IACnC,WAAW,EAAE,aAAa,GAAG,WAAW,CAAC;IACzC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;IAC3B,SAAS,EAAE,eAAe,CAAC;CAC5B,wBAkBF;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,yBAAyB,EACjC,IAAI,EAAE;IACJ,kBAAkB,EAAE,0BAA0B,CAAC;IAC/C,UAAU,EAAE,sBAAsB,CAAC;IACnC,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,aAAa,GAAG,WAAW,CAAC;IACzC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,SAAS,EAAE,eAAe,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,EAAE,UAAU,CAAC;IACvB,eAAe,EAAE,eAAe,GAAG,SAAS,CAAC;IAC7C,UAAU,EAAE,mBAAmB,CAAC;CACjC,+BAqBF"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAA0B,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,KAAK,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,yBAAyB,EACjC,IAAI,EAAE;IACJ,kBAAkB,EAAE,0BAA0B,CAAC;IAC/C,UAAU,EAAE,sBAAsB,CAAC;IACnC,WAAW,EAAE,aAAa,GAAG,WAAW,CAAC;IACzC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;IAC3B,SAAS,EAAE,eAAe,CAAC;CAC5B,wBAoBF;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,yBAAyB,EACjC,IAAI,EAAE;IACJ,kBAAkB,EAAE,0BAA0B,CAAC;IAC/C,UAAU,EAAE,sBAAsB,CAAC;IACnC,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,aAAa,GAAG,WAAW,CAAC;IACzC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,SAAS,EAAE,eAAe,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,EAAE,UAAU,CAAC;IACvB,eAAe,EAAE,eAAe,GAAG,SAAS,CAAC;IAC7C,UAAU,EAAE,mBAAmB,CAAC;CACjC,wCAqBF"}
package/dest/factory.js CHANGED
@@ -5,9 +5,10 @@ import { ValidatorClient } from './validator.js';
5
5
  export function createBlockProposalHandler(config, deps) {
6
6
  const metrics = new ValidatorMetrics(deps.telemetry);
7
7
  const blockProposalValidator = new BlockProposalValidator(deps.epochCache, {
8
- txsPermitted: !config.disableTransactions
8
+ txsPermitted: !config.disableTransactions,
9
+ maxTxsPerBlock: config.validateMaxTxsPerBlock
9
10
  });
10
- return new BlockProposalHandler(deps.checkpointsBuilder, deps.worldState, deps.blockSource, deps.l1ToL2MessageSource, deps.p2pClient.getTxProvider(), blockProposalValidator, config, metrics, deps.dateProvider, deps.telemetry);
11
+ return new BlockProposalHandler(deps.checkpointsBuilder, deps.worldState, deps.blockSource, deps.l1ToL2MessageSource, deps.p2pClient.getTxProvider(), blockProposalValidator, deps.epochCache, config, metrics, deps.dateProvider, deps.telemetry);
11
12
  }
12
13
  export function createValidatorClient(config, deps) {
13
14
  if (config.disableValidator || !deps.keyStoreManager) {