@aztec/validator-client 3.0.0-nightly.20251024 → 3.0.0-nightly.20251025

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.
@@ -3,24 +3,32 @@ import { DateProvider } from '@aztec/foundation/timer';
3
3
  import type { P2P, PeerId } from '@aztec/p2p';
4
4
  import { TxProvider } from '@aztec/p2p';
5
5
  import { BlockProposalValidator } from '@aztec/p2p/msg_validators';
6
- import type { L2BlockSource } from '@aztec/stdlib/block';
6
+ import type { L2Block, L2BlockSource } from '@aztec/stdlib/block';
7
7
  import type { IFullNodeBlockBuilder, ValidatorClientFullConfig } from '@aztec/stdlib/interfaces/server';
8
8
  import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
9
9
  import { type BlockProposal } from '@aztec/stdlib/p2p';
10
10
  import { type FailedTx, type Tx } from '@aztec/stdlib/tx';
11
11
  import { type TelemetryClient, type Tracer } from '@aztec/telemetry-client';
12
12
  import type { ValidatorMetrics } from './metrics.js';
13
- export type BlockProposalValidationFailureReason = 'invalid_proposal' | 'parent_block_not_found' | 'parent_block_does_not_match' | 'in_hash_mismatch' | 'block_number_already_exists' | 'txs_not_available' | 'state_mismatch' | 'failed_txs' | 'timeout' | 'unknown_error';
14
- export interface BlockProposalValidationResult {
15
- isValid: boolean;
16
- reason?: BlockProposalValidationFailureReason;
17
- reexecutionResult?: {
18
- block: any;
19
- failedTxs: FailedTx[];
20
- reexecutionTimeMs: number;
21
- totalManaUsed: number;
22
- };
23
- }
13
+ export type BlockProposalValidationFailureReason = 'invalid_proposal' | 'parent_block_not_found' | 'parent_block_wrong_slot' | 'in_hash_mismatch' | 'block_number_already_exists' | 'txs_not_available' | 'state_mismatch' | 'failed_txs' | 'timeout' | 'unknown_error';
14
+ type ReexecuteTransactionsResult = {
15
+ block: L2Block;
16
+ failedTxs: FailedTx[];
17
+ reexecutionTimeMs: number;
18
+ totalManaUsed: number;
19
+ };
20
+ export type BlockProposalValidationSuccessResult = {
21
+ isValid: true;
22
+ blockNumber: number;
23
+ reexecutionResult?: ReexecuteTransactionsResult;
24
+ };
25
+ export type BlockProposalValidationFailureResult = {
26
+ isValid: false;
27
+ reason: BlockProposalValidationFailureReason;
28
+ blockNumber?: number;
29
+ reexecutionResult?: ReexecuteTransactionsResult;
30
+ };
31
+ export type BlockProposalValidationResult = BlockProposalValidationSuccessResult | BlockProposalValidationFailureResult;
24
32
  export declare class BlockProposalHandler {
25
33
  private blockBuilder;
26
34
  private blockSource;
@@ -35,13 +43,10 @@ export declare class BlockProposalHandler {
35
43
  constructor(blockBuilder: IFullNodeBlockBuilder, blockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: TxProvider, blockProposalValidator: BlockProposalValidator, config: ValidatorClientFullConfig, metrics?: ValidatorMetrics | undefined, dateProvider?: DateProvider, telemetry?: TelemetryClient, log?: import("@aztec/foundation/log").Logger);
36
44
  registerForReexecution(p2pClient: P2P): BlockProposalHandler;
37
45
  handleBlockProposal(proposal: BlockProposal, proposalSender: PeerId, shouldReexecute: boolean): Promise<BlockProposalValidationResult>;
46
+ private getParentBlock;
38
47
  private getReexecutionDeadline;
39
48
  private getReexecuteFailureReason;
40
- reexecuteTransactions(proposal: BlockProposal, txs: Tx[], l1ToL2Messages: Fr[]): Promise<{
41
- block: any;
42
- failedTxs: FailedTx[];
43
- reexecutionTimeMs: number;
44
- totalManaUsed: number;
45
- }>;
49
+ reexecuteTransactions(proposal: BlockProposal, blockNumber: number, txs: Tx[], l1ToL2Messages: Fr[]): Promise<ReexecuteTransactionsResult>;
46
50
  }
51
+ export {};
47
52
  //# sourceMappingURL=block_proposal_handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"block_proposal_handler.d.ts","sourceRoot":"","sources":["../src/block_proposal_handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAS,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AACxG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,KAAK,aAAa,EAAoB,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,KAAK,QAAQ,EAAmB,KAAK,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAO3E,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,MAAM,EAAsB,MAAM,yBAAyB,CAAC;AAEhG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,MAAM,MAAM,oCAAoC,GAC5C,kBAAkB,GAClB,wBAAwB,GACxB,6BAA6B,GAC7B,kBAAkB,GAClB,6BAA6B,GAC7B,mBAAmB,GACnB,gBAAgB,GAChB,YAAY,GACZ,SAAS,GACT,eAAe,CAAC;AAEpB,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,oCAAoC,CAAC;IAC9C,iBAAiB,CAAC,EAAE;QAClB,KAAK,EAAE,GAAG,CAAC;QACX,SAAS,EAAE,QAAQ,EAAE,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,qBAAa,oBAAoB;IAI7B,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,sBAAsB;IAC9B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,OAAO,CAAC;IAChB,OAAO,CAAC,YAAY;IAEpB,OAAO,CAAC,GAAG;IAZb,SAAgB,MAAM,EAAE,MAAM,CAAC;gBAGrB,YAAY,EAAE,qBAAqB,EACnC,WAAW,EAAE,aAAa,EAC1B,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,UAAU,EACtB,sBAAsB,EAAE,sBAAsB,EAC9C,MAAM,EAAE,yBAAyB,EACjC,OAAO,CAAC,EAAE,gBAAgB,YAAA,EAC1B,YAAY,GAAE,YAAiC,EACvD,SAAS,GAAE,eAAsC,EACzC,GAAG,yCAAmD;IAKhE,sBAAsB,CAAC,SAAS,EAAE,GAAG,GAAG,oBAAoB;IA2BtD,mBAAmB,CACvB,QAAQ,EAAE,aAAa,EACvB,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,OAAO,GACvB,OAAO,CAAC,6BAA6B,CAAC;IA+GzC,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,yBAAyB;IAY3B,qBAAqB,CACzB,QAAQ,EAAE,aAAa,EACvB,GAAG,EAAE,EAAE,EAAE,EACT,cAAc,EAAE,EAAE,EAAE,GACnB,OAAO,CAAC;QACT,KAAK,EAAE,GAAG,CAAC;QACX,SAAS,EAAE,QAAQ,EAAE,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CA8EH"}
1
+ {"version":3,"file":"block_proposal_handler.d.ts","sourceRoot":"","sources":["../src/block_proposal_handler.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
2
+ import { TimeoutError } from '@aztec/foundation/error';
2
3
  import { Fr } from '@aztec/foundation/fields';
3
4
  import { createLogger } from '@aztec/foundation/log';
4
5
  import { retryUntil } from '@aztec/foundation/retry';
@@ -36,16 +37,16 @@ export class BlockProposalHandler {
36
37
  const handler = async (proposal, proposalSender)=>{
37
38
  try {
38
39
  const result = await this.handleBlockProposal(proposal, proposalSender, true);
39
- if (result.isValid && result.reexecutionResult) {
40
+ if (result.isValid) {
40
41
  this.log.info(`Non-validator reexecution completed for slot ${proposal.slotNumber.toBigInt()}`, {
41
- blockNumber: proposal.blockNumber,
42
- reexecutionTimeMs: result.reexecutionResult.reexecutionTimeMs,
43
- totalManaUsed: result.reexecutionResult.totalManaUsed,
44
- numTxs: result.reexecutionResult.block?.body?.txEffects?.length ?? 0
42
+ blockNumber: result.blockNumber,
43
+ reexecutionTimeMs: result.reexecutionResult?.reexecutionTimeMs,
44
+ totalManaUsed: result.reexecutionResult?.totalManaUsed,
45
+ numTxs: result.reexecutionResult?.block?.body?.txEffects?.length ?? 0
45
46
  });
46
47
  } else {
47
48
  this.log.warn(`Non-validator reexecution failed for slot ${proposal.slotNumber.toBigInt()}`, {
48
- blockNumber: proposal.blockNumber,
49
+ blockNumber: result.blockNumber,
49
50
  reason: result.reason
50
51
  });
51
52
  }
@@ -59,8 +60,8 @@ export class BlockProposalHandler {
59
60
  }
60
61
  async handleBlockProposal(proposal, proposalSender, shouldReexecute) {
61
62
  const slotNumber = proposal.slotNumber.toBigInt();
62
- const blockNumber = proposal.blockNumber;
63
63
  const proposer = proposal.getSender();
64
+ const config = this.blockBuilder.getConfig();
64
65
  // Reject proposals with invalid signatures
65
66
  if (!proposer) {
66
67
  this.log.warn(`Received proposal with invalid signature for slot ${slotNumber}`);
@@ -87,42 +88,45 @@ export class BlockProposalHandler {
87
88
  reason: 'invalid_proposal'
88
89
  };
89
90
  }
91
+ // Check that the parent proposal is a block we know, otherwise reexecution would fail
92
+ const parentBlockHeader = await this.getParentBlock(proposal);
93
+ if (parentBlockHeader === undefined) {
94
+ this.log.warn(`Parent block for proposal not found, skipping processing`, proposalInfo);
95
+ return {
96
+ isValid: false,
97
+ reason: 'parent_block_not_found'
98
+ };
99
+ }
100
+ // Check that the parent block's slot is less than the proposal's slot (should not happen, but we check anyway)
101
+ if (parentBlockHeader !== 'genesis' && parentBlockHeader.getSlot() >= slotNumber) {
102
+ this.log.warn(`Parent block slot is greater than or equal to proposal slot, skipping processing`, {
103
+ parentBlockSlot: parentBlockHeader.getSlot().toString(),
104
+ proposalSlot: slotNumber.toString(),
105
+ ...proposalInfo
106
+ });
107
+ return {
108
+ isValid: false,
109
+ reason: 'parent_block_wrong_slot'
110
+ };
111
+ }
112
+ // Compute the block number based on the parent block
113
+ const blockNumber = parentBlockHeader === 'genesis' ? INITIAL_L2_BLOCK_NUM : parentBlockHeader.getBlockNumber() + 1;
114
+ // Check that this block number does not exist already
115
+ const existingBlock = await this.blockSource.getBlockHeader(blockNumber);
116
+ if (existingBlock) {
117
+ this.log.warn(`Block number ${blockNumber} already exists, skipping processing`, proposalInfo);
118
+ return {
119
+ isValid: false,
120
+ blockNumber,
121
+ reason: 'block_number_already_exists'
122
+ };
123
+ }
90
124
  // Collect txs from the proposal. We start doing this as early as possible,
91
- // and we do it even if we don't plan to re-execute the txs, so that we have them
92
- // if another node needs them.
93
- const config = this.blockBuilder.getConfig();
94
- const { txs, missingTxs } = await this.txProvider.getTxsForBlockProposal(proposal, {
125
+ // and we do it even if we don't plan to re-execute the txs, so that we have them if another node needs them.
126
+ const { txs, missingTxs } = await this.txProvider.getTxsForBlockProposal(proposal, blockNumber, {
95
127
  pinnedPeer: proposalSender,
96
- deadline: this.getReexecutionDeadline(proposal, config)
128
+ deadline: this.getReexecutionDeadline(slotNumber, config)
97
129
  });
98
- // Check that the parent proposal is a block we know, otherwise reexecution would fail
99
- if (blockNumber > INITIAL_L2_BLOCK_NUM) {
100
- const deadline = this.getReexecutionDeadline(proposal, config);
101
- const currentTime = this.dateProvider.now();
102
- const timeoutDurationMs = deadline.getTime() - currentTime;
103
- const parentBlock = await this.blockSource.getBlock(blockNumber - 1) ?? (timeoutDurationMs <= 0 ? undefined : await retryUntil(async ()=>{
104
- await this.blockSource.syncImmediate();
105
- return await this.blockSource.getBlock(blockNumber - 1);
106
- }, 'Force Archiver Sync', timeoutDurationMs / 1000, 0.5));
107
- if (parentBlock === undefined) {
108
- this.log.warn(`Parent block for ${blockNumber} not found, skipping processing`, proposalInfo);
109
- return {
110
- isValid: false,
111
- reason: 'parent_block_not_found'
112
- };
113
- }
114
- if (!proposal.payload.header.lastArchiveRoot.equals(parentBlock.archive.root)) {
115
- this.log.warn(`Parent block archive root for proposal does not match, skipping processing`, {
116
- proposalLastArchiveRoot: proposal.payload.header.lastArchiveRoot.toString(),
117
- parentBlockArchiveRoot: parentBlock.archive.root.toString(),
118
- ...proposalInfo
119
- });
120
- return {
121
- isValid: false,
122
- reason: 'parent_block_does_not_match'
123
- };
124
- }
125
- }
126
130
  // Check that I have the same set of l1ToL2Messages as the proposal
127
131
  const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(blockNumber);
128
132
  const computedInHash = await computeInHashFromL1ToL2Messages(l1ToL2Messages);
@@ -135,18 +139,10 @@ export class BlockProposalHandler {
135
139
  });
136
140
  return {
137
141
  isValid: false,
142
+ blockNumber,
138
143
  reason: 'in_hash_mismatch'
139
144
  };
140
145
  }
141
- // Check that this block number does not exist already
142
- const existingBlock = await this.blockSource.getBlockHeader(blockNumber);
143
- if (existingBlock) {
144
- this.log.warn(`Block number ${blockNumber} already exists, skipping processing`, proposalInfo);
145
- return {
146
- isValid: false,
147
- reason: 'block_number_already_exists'
148
- };
149
- }
150
146
  // Check that all of the transactions in the proposal are available
151
147
  if (missingTxs.length > 0) {
152
148
  this.log.warn(`Missing ${missingTxs.length} txs to process proposal`, {
@@ -155,6 +151,7 @@ export class BlockProposalHandler {
155
151
  });
156
152
  return {
157
153
  isValid: false,
154
+ blockNumber,
158
155
  reason: 'txs_not_available'
159
156
  };
160
157
  }
@@ -163,12 +160,13 @@ export class BlockProposalHandler {
163
160
  if (shouldReexecute) {
164
161
  try {
165
162
  this.log.verbose(`Re-executing transactions in the proposal`, proposalInfo);
166
- reexecutionResult = await this.reexecuteTransactions(proposal, txs, l1ToL2Messages);
163
+ reexecutionResult = await this.reexecuteTransactions(proposal, blockNumber, txs, l1ToL2Messages);
167
164
  } catch (error) {
168
165
  this.log.error(`Error reexecuting txs while processing block proposal`, error, proposalInfo);
169
166
  const reason = this.getReexecuteFailureReason(error);
170
167
  return {
171
168
  isValid: false,
169
+ blockNumber,
172
170
  reason,
173
171
  reexecutionResult
174
172
  };
@@ -177,11 +175,38 @@ export class BlockProposalHandler {
177
175
  this.log.info(`Successfully processed proposal for slot ${slotNumber}`, proposalInfo);
178
176
  return {
179
177
  isValid: true,
178
+ blockNumber,
180
179
  reexecutionResult
181
180
  };
182
181
  }
183
- getReexecutionDeadline(proposal, config) {
184
- const nextSlotTimestampSeconds = Number(getTimestampForSlot(proposal.slotNumber.toBigInt() + 1n, config));
182
+ async getParentBlock(proposal) {
183
+ const parentArchive = proposal.payload.header.lastArchiveRoot;
184
+ const slot = proposal.slotNumber.toBigInt();
185
+ const config = this.blockBuilder.getConfig();
186
+ const { genesisArchiveRoot } = await this.blockSource.getGenesisValues();
187
+ if (parentArchive.equals(genesisArchiveRoot)) {
188
+ return 'genesis';
189
+ }
190
+ const deadline = this.getReexecutionDeadline(slot, config);
191
+ const currentTime = this.dateProvider.now();
192
+ const timeoutDurationMs = deadline.getTime() - currentTime;
193
+ try {
194
+ 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));
195
+ } catch (err) {
196
+ if (err instanceof TimeoutError) {
197
+ this.log.debug(`Timed out getting parent block by archive root`, {
198
+ parentArchive
199
+ });
200
+ } else {
201
+ this.log.error('Error getting parent block by archive root', err, {
202
+ parentArchive
203
+ });
204
+ }
205
+ return undefined;
206
+ }
207
+ }
208
+ getReexecutionDeadline(slot, config) {
209
+ const nextSlotTimestampSeconds = Number(getTimestampForSlot(slot + 1n, config));
185
210
  const msNeededForPropagationAndPublishing = this.config.validatorReexecuteDeadlineMs;
186
211
  return new Date(nextSlotTimestampSeconds * 1000 - msNeededForPropagationAndPublishing);
187
212
  }
@@ -192,11 +217,11 @@ export class BlockProposalHandler {
192
217
  return 'failed_txs';
193
218
  } else if (err instanceof ReExTimeoutError) {
194
219
  return 'timeout';
195
- } else if (err instanceof Error) {
220
+ } else {
196
221
  return 'unknown_error';
197
222
  }
198
223
  }
199
- async reexecuteTransactions(proposal, txs, l1ToL2Messages) {
224
+ async reexecuteTransactions(proposal, blockNumber, txs, l1ToL2Messages) {
200
225
  const { header } = proposal.payload;
201
226
  const { txHashes } = proposal;
202
227
  // If we do not have all of the transactions, then we should fail
@@ -214,13 +239,13 @@ export class BlockProposalHandler {
214
239
  coinbase: proposal.payload.header.coinbase,
215
240
  feeRecipient: proposal.payload.header.feeRecipient,
216
241
  gasFees: proposal.payload.header.gasFees,
217
- blockNumber: proposal.blockNumber,
242
+ blockNumber,
218
243
  timestamp: header.timestamp,
219
244
  chainId: new Fr(config.l1ChainId),
220
245
  version: new Fr(config.rollupVersion)
221
246
  });
222
247
  const { block, failedTxs } = await this.blockBuilder.buildBlock(txs, l1ToL2Messages, globalVariables, {
223
- deadline: this.getReexecutionDeadline(proposal, config)
248
+ deadline: this.getReexecutionDeadline(proposal.payload.header.slotNumber.toBigInt(), config)
224
249
  });
225
250
  const numFailedTxs = failedTxs.length;
226
251
  const slot = proposal.slotNumber.toBigInt();
@@ -13,7 +13,6 @@ export declare class ValidationService {
13
13
  /**
14
14
  * Create a block proposal with the given header, archive, and transactions
15
15
  *
16
- * @param blockNumber - The block number this proposal is for
17
16
  * @param header - The block header
18
17
  * @param archive - The archive of the current block
19
18
  * @param txs - TxHash[] ordered list of transactions
@@ -21,7 +20,7 @@ export declare class ValidationService {
21
20
  *
22
21
  * @returns A block proposal signing the above information (not the current implementation!!!)
23
22
  */
24
- createBlockProposal(blockNumber: number, header: CheckpointHeader, archive: Fr, stateReference: StateReference, txs: Tx[], proposerAttesterAddress: EthAddress | undefined, options: BlockProposalOptions): Promise<BlockProposal>;
23
+ createBlockProposal(header: CheckpointHeader, archive: Fr, stateReference: StateReference, txs: Tx[], proposerAttesterAddress: EthAddress | undefined, options: BlockProposalOptions): Promise<BlockProposal>;
25
24
  /**
26
25
  * Attest with selection of validators to the given block proposal, constructed by the current sequencer
27
26
  *
@@ -1 +1 @@
1
- {"version":3,"file":"validation_service.d.ts","sourceRoot":"","sources":["../../src/duties/validation_service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAG9C,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,KAAK,oBAAoB,EAG1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,GAAG;gBADH,QAAQ,EAAE,iBAAiB,EAC3B,GAAG,yCAA+C;IAG5D;;;;;;;;;;OAUG;IACG,mBAAmB,CACvB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,EAAE,EACX,cAAc,EAAE,cAAc,EAC9B,GAAG,EAAE,EAAE,EAAE,EACT,uBAAuB,EAAE,UAAU,GAAG,SAAS,EAC/C,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,aAAa,CAAC;IA2BzB;;;;;;;;;OASG;IACG,gBAAgB,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAU/F,0BAA0B,CAC9B,sBAAsB,EAAE,+BAA+B,EACvD,QAAQ,EAAE,UAAU,GACnB,OAAO,CAAC,SAAS,CAAC;CAMtB"}
1
+ {"version":3,"file":"validation_service.d.ts","sourceRoot":"","sources":["../../src/duties/validation_service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAG9C,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,KAAK,oBAAoB,EAG1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,GAAG;gBADH,QAAQ,EAAE,iBAAiB,EAC3B,GAAG,yCAA+C;IAG5D;;;;;;;;;OASG;IACG,mBAAmB,CACvB,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,EAAE,EACX,cAAc,EAAE,cAAc,EAC9B,GAAG,EAAE,EAAE,EAAE,EACT,uBAAuB,EAAE,UAAU,GAAG,SAAS,EAC/C,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,aAAa,CAAC;IA0BzB;;;;;;;;;OASG;IACG,gBAAgB,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAU/F,0BAA0B,CAC9B,sBAAsB,EAAE,+BAA+B,EACvD,QAAQ,EAAE,UAAU,GACnB,OAAO,CAAC,SAAS,CAAC;CAMtB"}
@@ -14,14 +14,13 @@ export class ValidationService {
14
14
  /**
15
15
  * Create a block proposal with the given header, archive, and transactions
16
16
  *
17
- * @param blockNumber - The block number this proposal is for
18
17
  * @param header - The block header
19
18
  * @param archive - The archive of the current block
20
19
  * @param txs - TxHash[] ordered list of transactions
21
20
  * @param options - Block proposal options (including broadcastInvalidBlockProposal for testing)
22
21
  *
23
22
  * @returns A block proposal signing the above information (not the current implementation!!!)
24
- */ async createBlockProposal(blockNumber, header, archive, stateReference, txs, proposerAttesterAddress, options) {
23
+ */ async createBlockProposal(header, archive, stateReference, txs, proposerAttesterAddress, options) {
25
24
  let payloadSigner;
26
25
  if (proposerAttesterAddress !== undefined) {
27
26
  payloadSigner = (payload)=>this.keyStore.signMessageWithAddress(proposerAttesterAddress, payload);
@@ -35,9 +34,9 @@ export class ValidationService {
35
34
  // For testing: corrupt the state reference to trigger state_mismatch validation failure
36
35
  if (options.broadcastInvalidBlockProposal) {
37
36
  unfreeze(stateReference.partial).noteHashTree = AppendOnlyTreeSnapshot.random();
38
- this.log.warn(`Creating INVALID block proposal for block ${blockNumber} at slot ${header.slotNumber.toBigInt()}`);
37
+ this.log.warn(`Creating INVALID block proposal for slot ${header.slotNumber.toBigInt()}`);
39
38
  }
40
- return BlockProposal.createProposalFromSigner(blockNumber, new ConsensusPayload(header, archive, stateReference), txHashes, options.publishFullTxs ? txs : undefined, payloadSigner);
39
+ return BlockProposal.createProposalFromSigner(new ConsensusPayload(header, archive, stateReference), txHashes, options.publishFullTxs ? txs : undefined, payloadSigner);
41
40
  }
42
41
  /**
43
42
  * Attest with selection of validators to the given block proposal, constructed by the current sequencer
@@ -51,7 +50,7 @@ export class ValidationService {
51
50
  */ async attestToProposal(proposal, attestors) {
52
51
  const buf = Buffer32.fromBuffer(keccak256(proposal.payload.getPayloadToSign(SignatureDomainSeparator.blockAttestation)));
53
52
  const signatures = await Promise.all(attestors.map((attestor)=>this.keyStore.signMessageWithAddress(attestor, buf)));
54
- return signatures.map((sig)=>new BlockAttestation(proposal.blockNumber, proposal.payload, sig, proposal.signature));
53
+ return signatures.map((sig)=>new BlockAttestation(proposal.payload, sig, proposal.signature));
55
54
  }
56
55
  async signAttestationsAndSigners(attestationsAndSigners, proposer) {
57
56
  const buf = Buffer32.fromBuffer(keccak256(attestationsAndSigners.getPayloadToSign(SignatureDomainSeparator.attestationsAndSigners)));
@@ -44,7 +44,7 @@ export declare class ValidatorClient extends ValidatorClient_base implements Val
44
44
  static new(config: ValidatorClientFullConfig, blockBuilder: IFullNodeBlockBuilder, epochCache: EpochCache, p2pClient: P2P, blockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: TxProvider, keyStoreManager: KeystoreManager, dateProvider?: DateProvider, telemetry?: TelemetryClient): ValidatorClient;
45
45
  getValidatorAddresses(): EthAddress[];
46
46
  getBlockProposalHandler(): BlockProposalHandler;
47
- reExecuteTransactions(proposal: BlockProposal, txs: any[], l1ToL2Messages: Fr[]): Promise<any>;
47
+ reExecuteTransactions(proposal: BlockProposal, blockNumber: number, txs: any[], l1ToL2Messages: Fr[]): Promise<any>;
48
48
  signWithAddress(addr: EthAddress, msg: TypedDataDefinition): Promise<Signature>;
49
49
  getCoinbaseForAttestor(attestor: EthAddress): EthAddress;
50
50
  getFeeRecipientForAttestor(attestor: EthAddress): AztecAddress;
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
package/dest/validator.js CHANGED
@@ -108,8 +108,8 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
108
108
  return this.blockProposalHandler;
109
109
  }
110
110
  // Proxy method for backwards compatibility with tests
111
- reExecuteTransactions(proposal, txs, l1ToL2Messages) {
112
- return this.blockProposalHandler.reexecuteTransactions(proposal, txs, l1ToL2Messages);
111
+ reExecuteTransactions(proposal, blockNumber, txs, l1ToL2Messages) {
112
+ return this.blockProposalHandler.reexecuteTransactions(proposal, blockNumber, txs, l1ToL2Messages);
113
113
  }
114
114
  signWithAddress(addr, msg) {
115
115
  return this.keyStore.signTypedDataWithAddress(addr, msg);
@@ -174,7 +174,7 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
174
174
  ...proposal.toBlockInfo(),
175
175
  proposer: proposer.toString()
176
176
  };
177
- this.log.info(`Received proposal for block ${proposal.blockNumber} at slot ${slotNumber}`, {
177
+ this.log.info(`Received proposal for slot ${slotNumber}`, {
178
178
  ...proposalInfo,
179
179
  txHashes: proposal.txHashes.map((t)=>t.toString())
180
180
  });
@@ -194,7 +194,7 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
194
194
  'state_mismatch',
195
195
  'failed_txs',
196
196
  'in_hash_mismatch',
197
- 'parent_block_does_not_match'
197
+ 'parent_block_wrong_slot'
198
198
  ];
199
199
  if (badProposalReasons.includes(reason)) {
200
200
  this.metrics.incFailedAttestationsBadProposal(1, reason);
@@ -216,7 +216,7 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
216
216
  return undefined;
217
217
  }
218
218
  // Provided all of the above checks pass, we can attest to the proposal
219
- this.log.info(`Attesting to proposal for block ${proposal.blockNumber} at slot ${slotNumber}`, proposalInfo);
219
+ this.log.info(`Attesting to proposal for slot ${slotNumber}`, proposalInfo);
220
220
  this.metrics.incSuccessfulAttestations(inCommittee.length);
221
221
  // If the above function does not throw an error, then we can attest to the proposal
222
222
  return this.createBlockAttestationsFromProposal(proposal, inCommittee);
@@ -248,7 +248,7 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
248
248
  this.log.verbose(`Already made a proposal for the same slot, skipping proposal`);
249
249
  return Promise.resolve(undefined);
250
250
  }
251
- const newProposal = await this.validationService.createBlockProposal(blockNumber, header, archive, stateReference, txs, proposerAddress, {
251
+ const newProposal = await this.validationService.createBlockProposal(header, archive, stateReference, txs, proposerAddress, {
252
252
  ...options,
253
253
  broadcastInvalidBlockProposal: this.config.broadcastInvalidBlockProposal
254
254
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/validator-client",
3
- "version": "3.0.0-nightly.20251024",
3
+ "version": "3.0.0-nightly.20251025",
4
4
  "main": "dest/index.js",
5
5
  "type": "module",
6
6
  "exports": {
@@ -64,16 +64,16 @@
64
64
  ]
65
65
  },
66
66
  "dependencies": {
67
- "@aztec/constants": "3.0.0-nightly.20251024",
68
- "@aztec/epoch-cache": "3.0.0-nightly.20251024",
69
- "@aztec/ethereum": "3.0.0-nightly.20251024",
70
- "@aztec/foundation": "3.0.0-nightly.20251024",
71
- "@aztec/node-keystore": "3.0.0-nightly.20251024",
72
- "@aztec/p2p": "3.0.0-nightly.20251024",
73
- "@aztec/prover-client": "3.0.0-nightly.20251024",
74
- "@aztec/slasher": "3.0.0-nightly.20251024",
75
- "@aztec/stdlib": "3.0.0-nightly.20251024",
76
- "@aztec/telemetry-client": "3.0.0-nightly.20251024",
67
+ "@aztec/constants": "3.0.0-nightly.20251025",
68
+ "@aztec/epoch-cache": "3.0.0-nightly.20251025",
69
+ "@aztec/ethereum": "3.0.0-nightly.20251025",
70
+ "@aztec/foundation": "3.0.0-nightly.20251025",
71
+ "@aztec/node-keystore": "3.0.0-nightly.20251025",
72
+ "@aztec/p2p": "3.0.0-nightly.20251025",
73
+ "@aztec/prover-client": "3.0.0-nightly.20251025",
74
+ "@aztec/slasher": "3.0.0-nightly.20251025",
75
+ "@aztec/stdlib": "3.0.0-nightly.20251025",
76
+ "@aztec/telemetry-client": "3.0.0-nightly.20251025",
77
77
  "koa": "^2.16.1",
78
78
  "koa-router": "^13.1.1",
79
79
  "tslib": "^2.4.0",
@@ -1,4 +1,5 @@
1
1
  import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
2
+ import { TimeoutError } from '@aztec/foundation/error';
2
3
  import { Fr } from '@aztec/foundation/fields';
3
4
  import { createLogger } from '@aztec/foundation/log';
4
5
  import { retryUntil } from '@aztec/foundation/retry';
@@ -7,12 +8,12 @@ import type { P2P, PeerId } from '@aztec/p2p';
7
8
  import { TxProvider } from '@aztec/p2p';
8
9
  import { BlockProposalValidator } from '@aztec/p2p/msg_validators';
9
10
  import { computeInHashFromL1ToL2Messages } from '@aztec/prover-client/helpers';
10
- import type { L2BlockSource } from '@aztec/stdlib/block';
11
+ import type { L2Block, L2BlockSource } from '@aztec/stdlib/block';
11
12
  import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
12
13
  import type { IFullNodeBlockBuilder, ValidatorClientFullConfig } from '@aztec/stdlib/interfaces/server';
13
14
  import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
14
15
  import { type BlockProposal, ConsensusPayload } from '@aztec/stdlib/p2p';
15
- import { type FailedTx, GlobalVariables, type Tx } from '@aztec/stdlib/tx';
16
+ import { BlockHeader, type FailedTx, GlobalVariables, type Tx } from '@aztec/stdlib/tx';
16
17
  import {
17
18
  ReExFailedTxsError,
18
19
  ReExStateMismatchError,
@@ -26,7 +27,7 @@ import type { ValidatorMetrics } from './metrics.js';
26
27
  export type BlockProposalValidationFailureReason =
27
28
  | 'invalid_proposal'
28
29
  | 'parent_block_not_found'
29
- | 'parent_block_does_not_match'
30
+ | 'parent_block_wrong_slot'
30
31
  | 'in_hash_mismatch'
31
32
  | 'block_number_already_exists'
32
33
  | 'txs_not_available'
@@ -35,16 +36,27 @@ export type BlockProposalValidationFailureReason =
35
36
  | 'timeout'
36
37
  | 'unknown_error';
37
38
 
38
- export interface BlockProposalValidationResult {
39
- isValid: boolean;
40
- reason?: BlockProposalValidationFailureReason;
41
- reexecutionResult?: {
42
- block: any;
43
- failedTxs: FailedTx[];
44
- reexecutionTimeMs: number;
45
- totalManaUsed: number;
46
- };
47
- }
39
+ type ReexecuteTransactionsResult = {
40
+ block: L2Block;
41
+ failedTxs: FailedTx[];
42
+ reexecutionTimeMs: number;
43
+ totalManaUsed: number;
44
+ };
45
+
46
+ export type BlockProposalValidationSuccessResult = {
47
+ isValid: true;
48
+ blockNumber: number;
49
+ reexecutionResult?: ReexecuteTransactionsResult;
50
+ };
51
+
52
+ export type BlockProposalValidationFailureResult = {
53
+ isValid: false;
54
+ reason: BlockProposalValidationFailureReason;
55
+ blockNumber?: number;
56
+ reexecutionResult?: ReexecuteTransactionsResult;
57
+ };
58
+
59
+ export type BlockProposalValidationResult = BlockProposalValidationSuccessResult | BlockProposalValidationFailureResult;
48
60
 
49
61
  export class BlockProposalHandler {
50
62
  public readonly tracer: Tracer;
@@ -68,16 +80,16 @@ export class BlockProposalHandler {
68
80
  const handler = async (proposal: BlockProposal, proposalSender: PeerId) => {
69
81
  try {
70
82
  const result = await this.handleBlockProposal(proposal, proposalSender, true);
71
- if (result.isValid && result.reexecutionResult) {
83
+ if (result.isValid) {
72
84
  this.log.info(`Non-validator reexecution completed for slot ${proposal.slotNumber.toBigInt()}`, {
73
- blockNumber: proposal.blockNumber,
74
- reexecutionTimeMs: result.reexecutionResult.reexecutionTimeMs,
75
- totalManaUsed: result.reexecutionResult.totalManaUsed,
76
- numTxs: result.reexecutionResult.block?.body?.txEffects?.length ?? 0,
85
+ blockNumber: result.blockNumber,
86
+ reexecutionTimeMs: result.reexecutionResult?.reexecutionTimeMs,
87
+ totalManaUsed: result.reexecutionResult?.totalManaUsed,
88
+ numTxs: result.reexecutionResult?.block?.body?.txEffects?.length ?? 0,
77
89
  });
78
90
  } else {
79
91
  this.log.warn(`Non-validator reexecution failed for slot ${proposal.slotNumber.toBigInt()}`, {
80
- blockNumber: proposal.blockNumber,
92
+ blockNumber: result.blockNumber,
81
93
  reason: result.reason,
82
94
  });
83
95
  }
@@ -97,8 +109,8 @@ export class BlockProposalHandler {
97
109
  shouldReexecute: boolean,
98
110
  ): Promise<BlockProposalValidationResult> {
99
111
  const slotNumber = proposal.slotNumber.toBigInt();
100
- const blockNumber = proposal.blockNumber;
101
112
  const proposer = proposal.getSender();
113
+ const config = this.blockBuilder.getConfig();
102
114
 
103
115
  // Reject proposals with invalid signatures
104
116
  if (!proposer) {
@@ -120,49 +132,40 @@ export class BlockProposalHandler {
120
132
  return { isValid: false, reason: 'invalid_proposal' };
121
133
  }
122
134
 
123
- // Collect txs from the proposal. We start doing this as early as possible,
124
- // and we do it even if we don't plan to re-execute the txs, so that we have them
125
- // if another node needs them.
126
- const config = this.blockBuilder.getConfig();
127
- const { txs, missingTxs } = await this.txProvider.getTxsForBlockProposal(proposal, {
128
- pinnedPeer: proposalSender,
129
- deadline: this.getReexecutionDeadline(proposal, config),
130
- });
131
-
132
135
  // Check that the parent proposal is a block we know, otherwise reexecution would fail
133
- if (blockNumber > INITIAL_L2_BLOCK_NUM) {
134
- const deadline = this.getReexecutionDeadline(proposal, config);
135
- const currentTime = this.dateProvider.now();
136
- const timeoutDurationMs = deadline.getTime() - currentTime;
137
- const parentBlock =
138
- (await this.blockSource.getBlock(blockNumber - 1)) ??
139
- (timeoutDurationMs <= 0
140
- ? undefined
141
- : await retryUntil(
142
- async () => {
143
- await this.blockSource.syncImmediate();
144
- return await this.blockSource.getBlock(blockNumber - 1);
145
- },
146
- 'Force Archiver Sync',
147
- timeoutDurationMs / 1000,
148
- 0.5,
149
- ));
136
+ const parentBlockHeader = await this.getParentBlock(proposal);
137
+ if (parentBlockHeader === undefined) {
138
+ this.log.warn(`Parent block for proposal not found, skipping processing`, proposalInfo);
139
+ return { isValid: false, reason: 'parent_block_not_found' };
140
+ }
150
141
 
151
- if (parentBlock === undefined) {
152
- this.log.warn(`Parent block for ${blockNumber} not found, skipping processing`, proposalInfo);
153
- return { isValid: false, reason: 'parent_block_not_found' };
154
- }
142
+ // Check that the parent block's slot is less than the proposal's slot (should not happen, but we check anyway)
143
+ if (parentBlockHeader !== 'genesis' && parentBlockHeader.getSlot() >= slotNumber) {
144
+ this.log.warn(`Parent block slot is greater than or equal to proposal slot, skipping processing`, {
145
+ parentBlockSlot: parentBlockHeader.getSlot().toString(),
146
+ proposalSlot: slotNumber.toString(),
147
+ ...proposalInfo,
148
+ });
149
+ return { isValid: false, reason: 'parent_block_wrong_slot' };
150
+ }
155
151
 
156
- if (!proposal.payload.header.lastArchiveRoot.equals(parentBlock.archive.root)) {
157
- this.log.warn(`Parent block archive root for proposal does not match, skipping processing`, {
158
- proposalLastArchiveRoot: proposal.payload.header.lastArchiveRoot.toString(),
159
- parentBlockArchiveRoot: parentBlock.archive.root.toString(),
160
- ...proposalInfo,
161
- });
162
- return { isValid: false, reason: 'parent_block_does_not_match' };
163
- }
152
+ // Compute the block number based on the parent block
153
+ const blockNumber = parentBlockHeader === 'genesis' ? INITIAL_L2_BLOCK_NUM : parentBlockHeader.getBlockNumber() + 1;
154
+
155
+ // Check that this block number does not exist already
156
+ const existingBlock = await this.blockSource.getBlockHeader(blockNumber);
157
+ if (existingBlock) {
158
+ this.log.warn(`Block number ${blockNumber} already exists, skipping processing`, proposalInfo);
159
+ return { isValid: false, blockNumber, reason: 'block_number_already_exists' };
164
160
  }
165
161
 
162
+ // Collect txs from the proposal. We start doing this as early as possible,
163
+ // and we do it even if we don't plan to re-execute the txs, so that we have them if another node needs them.
164
+ const { txs, missingTxs } = await this.txProvider.getTxsForBlockProposal(proposal, blockNumber, {
165
+ pinnedPeer: proposalSender,
166
+ deadline: this.getReexecutionDeadline(slotNumber, config),
167
+ });
168
+
166
169
  // Check that I have the same set of l1ToL2Messages as the proposal
167
170
  const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(blockNumber);
168
171
  const computedInHash = await computeInHashFromL1ToL2Messages(l1ToL2Messages);
@@ -173,20 +176,13 @@ export class BlockProposalHandler {
173
176
  computedInHash: computedInHash.toString(),
174
177
  ...proposalInfo,
175
178
  });
176
- return { isValid: false, reason: 'in_hash_mismatch' };
177
- }
178
-
179
- // Check that this block number does not exist already
180
- const existingBlock = await this.blockSource.getBlockHeader(blockNumber);
181
- if (existingBlock) {
182
- this.log.warn(`Block number ${blockNumber} already exists, skipping processing`, proposalInfo);
183
- return { isValid: false, reason: 'block_number_already_exists' };
179
+ return { isValid: false, blockNumber, reason: 'in_hash_mismatch' };
184
180
  }
185
181
 
186
182
  // Check that all of the transactions in the proposal are available
187
183
  if (missingTxs.length > 0) {
188
184
  this.log.warn(`Missing ${missingTxs.length} txs to process proposal`, { ...proposalInfo, missingTxs });
189
- return { isValid: false, reason: 'txs_not_available' };
185
+ return { isValid: false, blockNumber, reason: 'txs_not_available' };
190
186
  }
191
187
 
192
188
  // Try re-executing the transactions in the proposal if needed
@@ -194,23 +190,57 @@ export class BlockProposalHandler {
194
190
  if (shouldReexecute) {
195
191
  try {
196
192
  this.log.verbose(`Re-executing transactions in the proposal`, proposalInfo);
197
- reexecutionResult = await this.reexecuteTransactions(proposal, txs, l1ToL2Messages);
193
+ reexecutionResult = await this.reexecuteTransactions(proposal, blockNumber, txs, l1ToL2Messages);
198
194
  } catch (error) {
199
195
  this.log.error(`Error reexecuting txs while processing block proposal`, error, proposalInfo);
200
196
  const reason = this.getReexecuteFailureReason(error);
201
- return { isValid: false, reason, reexecutionResult };
197
+ return { isValid: false, blockNumber, reason, reexecutionResult };
202
198
  }
203
199
  }
204
200
 
205
201
  this.log.info(`Successfully processed proposal for slot ${slotNumber}`, proposalInfo);
206
- return { isValid: true, reexecutionResult };
202
+ return { isValid: true, blockNumber, reexecutionResult };
207
203
  }
208
204
 
209
- private getReexecutionDeadline(
210
- proposal: BlockProposal,
211
- config: { l1GenesisTime: bigint; slotDuration: number },
212
- ): Date {
213
- const nextSlotTimestampSeconds = Number(getTimestampForSlot(proposal.slotNumber.toBigInt() + 1n, config));
205
+ private async getParentBlock(proposal: BlockProposal): Promise<'genesis' | BlockHeader | undefined> {
206
+ const parentArchive = proposal.payload.header.lastArchiveRoot;
207
+ const slot = proposal.slotNumber.toBigInt();
208
+ const config = this.blockBuilder.getConfig();
209
+ const { genesisArchiveRoot } = await this.blockSource.getGenesisValues();
210
+
211
+ if (parentArchive.equals(genesisArchiveRoot)) {
212
+ return 'genesis';
213
+ }
214
+
215
+ const deadline = this.getReexecutionDeadline(slot, config);
216
+ const currentTime = this.dateProvider.now();
217
+ const timeoutDurationMs = deadline.getTime() - currentTime;
218
+
219
+ try {
220
+ return (
221
+ (await this.blockSource.getBlockHeaderByArchive(parentArchive)) ??
222
+ (timeoutDurationMs <= 0
223
+ ? undefined
224
+ : await retryUntil(
225
+ () =>
226
+ this.blockSource.syncImmediate().then(() => this.blockSource.getBlockHeaderByArchive(parentArchive)),
227
+ 'force archiver sync',
228
+ timeoutDurationMs / 1000,
229
+ 0.5,
230
+ ))
231
+ );
232
+ } catch (err) {
233
+ if (err instanceof TimeoutError) {
234
+ this.log.debug(`Timed out getting parent block by archive root`, { parentArchive });
235
+ } else {
236
+ this.log.error('Error getting parent block by archive root', err, { parentArchive });
237
+ }
238
+ return undefined;
239
+ }
240
+ }
241
+
242
+ private getReexecutionDeadline(slot: bigint, config: { l1GenesisTime: bigint; slotDuration: number }): Date {
243
+ const nextSlotTimestampSeconds = Number(getTimestampForSlot(slot + 1n, config));
214
244
  const msNeededForPropagationAndPublishing = this.config.validatorReexecuteDeadlineMs;
215
245
  return new Date(nextSlotTimestampSeconds * 1000 - msNeededForPropagationAndPublishing);
216
246
  }
@@ -222,21 +252,17 @@ export class BlockProposalHandler {
222
252
  return 'failed_txs';
223
253
  } else if (err instanceof ReExTimeoutError) {
224
254
  return 'timeout';
225
- } else if (err instanceof Error) {
255
+ } else {
226
256
  return 'unknown_error';
227
257
  }
228
258
  }
229
259
 
230
260
  async reexecuteTransactions(
231
261
  proposal: BlockProposal,
262
+ blockNumber: number,
232
263
  txs: Tx[],
233
264
  l1ToL2Messages: Fr[],
234
- ): Promise<{
235
- block: any;
236
- failedTxs: FailedTx[];
237
- reexecutionTimeMs: number;
238
- totalManaUsed: number;
239
- }> {
265
+ ): Promise<ReexecuteTransactionsResult> {
240
266
  const { header } = proposal.payload;
241
267
  const { txHashes } = proposal;
242
268
 
@@ -257,14 +283,14 @@ export class BlockProposalHandler {
257
283
  coinbase: proposal.payload.header.coinbase, // set arbitrarily by the proposer
258
284
  feeRecipient: proposal.payload.header.feeRecipient, // set arbitrarily by the proposer
259
285
  gasFees: proposal.payload.header.gasFees, // validated by the rollup contract
260
- blockNumber: proposal.blockNumber, // checked blockNumber-1 exists in archiver but blockNumber doesnt
286
+ blockNumber, // computed from the parent block and checked it does not exist in archiver
261
287
  timestamp: header.timestamp, // checked in the rollup contract against the slot number
262
288
  chainId: new Fr(config.l1ChainId),
263
289
  version: new Fr(config.rollupVersion),
264
290
  });
265
291
 
266
292
  const { block, failedTxs } = await this.blockBuilder.buildBlock(txs, l1ToL2Messages, globalVariables, {
267
- deadline: this.getReexecutionDeadline(proposal, config),
293
+ deadline: this.getReexecutionDeadline(proposal.payload.header.slotNumber.toBigInt(), config),
268
294
  });
269
295
 
270
296
  const numFailedTxs = failedTxs.length;
@@ -28,7 +28,6 @@ export class ValidationService {
28
28
  /**
29
29
  * Create a block proposal with the given header, archive, and transactions
30
30
  *
31
- * @param blockNumber - The block number this proposal is for
32
31
  * @param header - The block header
33
32
  * @param archive - The archive of the current block
34
33
  * @param txs - TxHash[] ordered list of transactions
@@ -37,7 +36,6 @@ export class ValidationService {
37
36
  * @returns A block proposal signing the above information (not the current implementation!!!)
38
37
  */
39
38
  async createBlockProposal(
40
- blockNumber: number,
41
39
  header: CheckpointHeader,
42
40
  archive: Fr,
43
41
  stateReference: StateReference,
@@ -59,11 +57,10 @@ export class ValidationService {
59
57
  // For testing: corrupt the state reference to trigger state_mismatch validation failure
60
58
  if (options.broadcastInvalidBlockProposal) {
61
59
  unfreeze(stateReference.partial).noteHashTree = AppendOnlyTreeSnapshot.random();
62
- this.log.warn(`Creating INVALID block proposal for block ${blockNumber} at slot ${header.slotNumber.toBigInt()}`);
60
+ this.log.warn(`Creating INVALID block proposal for slot ${header.slotNumber.toBigInt()}`);
63
61
  }
64
62
 
65
63
  return BlockProposal.createProposalFromSigner(
66
- blockNumber,
67
64
  new ConsensusPayload(header, archive, stateReference),
68
65
  txHashes,
69
66
  options.publishFullTxs ? txs : undefined,
@@ -88,7 +85,7 @@ export class ValidationService {
88
85
  const signatures = await Promise.all(
89
86
  attestors.map(attestor => this.keyStore.signMessageWithAddress(attestor, buf)),
90
87
  );
91
- return signatures.map(sig => new BlockAttestation(proposal.blockNumber, proposal.payload, sig, proposal.signature));
88
+ return signatures.map(sig => new BlockAttestation(proposal.payload, sig, proposal.signature));
92
89
  }
93
90
 
94
91
  async signAttestationsAndSigners(
package/src/validator.ts CHANGED
@@ -184,8 +184,13 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
184
184
  }
185
185
 
186
186
  // Proxy method for backwards compatibility with tests
187
- public reExecuteTransactions(proposal: BlockProposal, txs: any[], l1ToL2Messages: Fr[]): Promise<any> {
188
- return this.blockProposalHandler.reexecuteTransactions(proposal, txs, l1ToL2Messages);
187
+ public reExecuteTransactions(
188
+ proposal: BlockProposal,
189
+ blockNumber: number,
190
+ txs: any[],
191
+ l1ToL2Messages: Fr[],
192
+ ): Promise<any> {
193
+ return this.blockProposalHandler.reexecuteTransactions(proposal, blockNumber, txs, l1ToL2Messages);
189
194
  }
190
195
 
191
196
  public signWithAddress(addr: EthAddress, msg: TypedDataDefinition) {
@@ -268,7 +273,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
268
273
  const partOfCommittee = inCommittee.length > 0;
269
274
 
270
275
  const proposalInfo = { ...proposal.toBlockInfo(), proposer: proposer.toString() };
271
- this.log.info(`Received proposal for block ${proposal.blockNumber} at slot ${slotNumber}`, {
276
+ this.log.info(`Received proposal for slot ${slotNumber}`, {
272
277
  ...proposalInfo,
273
278
  txHashes: proposal.txHashes.map(t => t.toString()),
274
279
  });
@@ -299,7 +304,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
299
304
  'state_mismatch',
300
305
  'failed_txs',
301
306
  'in_hash_mismatch',
302
- 'parent_block_does_not_match',
307
+ 'parent_block_wrong_slot',
303
308
  ];
304
309
 
305
310
  if (badProposalReasons.includes(reason as BlockProposalValidationFailureReason)) {
@@ -329,7 +334,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
329
334
  }
330
335
 
331
336
  // Provided all of the above checks pass, we can attest to the proposal
332
- this.log.info(`Attesting to proposal for block ${proposal.blockNumber} at slot ${slotNumber}`, proposalInfo);
337
+ this.log.info(`Attesting to proposal for slot ${slotNumber}`, proposalInfo);
333
338
  this.metrics.incSuccessfulAttestations(inCommittee.length);
334
339
 
335
340
  // If the above function does not throw an error, then we can attest to the proposal
@@ -378,7 +383,6 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
378
383
  }
379
384
 
380
385
  const newProposal = await this.validationService.createBlockProposal(
381
- blockNumber,
382
386
  header,
383
387
  archive,
384
388
  stateReference,