@aztec/validator-client 0.0.1-commit.3895657bc → 0.0.1-commit.3e3d0c9cd
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dest/block_proposal_handler.d.ts +3 -2
- package/dest/block_proposal_handler.d.ts.map +1 -1
- package/dest/block_proposal_handler.js +60 -5
- package/dest/checkpoint_builder.d.ts +2 -1
- package/dest/checkpoint_builder.d.ts.map +1 -1
- package/dest/checkpoint_builder.js +52 -30
- package/dest/duties/validation_service.js +1 -1
- package/dest/key_store/ha_key_store.js +1 -1
- package/dest/validator.d.ts +1 -1
- package/dest/validator.d.ts.map +1 -1
- package/dest/validator.js +3 -3
- package/package.json +19 -19
- package/src/block_proposal_handler.ts +75 -5
- package/src/checkpoint_builder.ts +60 -38
- package/src/duties/validation_service.ts +1 -1
- package/src/key_store/ha_key_store.ts +1 -1
- package/src/validator.ts +5 -4
package/README.md
CHANGED
|
@@ -239,11 +239,11 @@ L1 enforces gas and blob capacity per checkpoint. The node enforces these during
|
|
|
239
239
|
|
|
240
240
|
Per-block budgets prevent one block from consuming the entire checkpoint budget.
|
|
241
241
|
|
|
242
|
-
**Proposer**: `computeBlockLimits()` derives budgets at startup as `min(checkpointLimit, ceil(checkpointLimit / maxBlocks * multiplier))`, where `maxBlocks` comes from the timetable and `multiplier` defaults to 2. The multiplier greater than 1 allows early blocks to use more than their even share of the checkpoint budget, since different blocks hit different limit dimensions (L2 gas, DA gas, blob fields) — a strict even split would waste capacity. Operators can override via `SEQ_MAX_L2_BLOCK_GAS` / `SEQ_MAX_DA_BLOCK_GAS` / `SEQ_MAX_TX_PER_BLOCK` (capped at checkpoint limits). Per-block TX limits follow the same derivation pattern when `SEQ_MAX_TX_PER_CHECKPOINT` is set.
|
|
242
|
+
**Proposer**: `computeBlockLimits()` derives budgets at startup as `min(checkpointLimit, ceil(checkpointLimit / maxBlocks * multiplier))`, where `maxBlocks` comes from the timetable and `multiplier` defaults to 1.2. The multiplier greater than 1 allows early blocks to use more than their even share of the checkpoint budget, since different blocks hit different limit dimensions (L2 gas, DA gas, blob fields) — a strict even split would waste capacity. Operators can override via `SEQ_MAX_L2_BLOCK_GAS` / `SEQ_MAX_DA_BLOCK_GAS` / `SEQ_MAX_TX_PER_BLOCK` (capped at checkpoint limits). Per-block TX limits follow the same derivation pattern when `SEQ_MAX_TX_PER_CHECKPOINT` is set.
|
|
243
243
|
|
|
244
244
|
**Validator**: Optionally enforces per-block limits via `VALIDATOR_MAX_L2_BLOCK_GAS`, `VALIDATOR_MAX_DA_BLOCK_GAS`, and `VALIDATOR_MAX_TX_PER_BLOCK`. When set, these are passed to `buildBlock` during re-execution and to `validateCheckpoint` for final validation. When unset, no per-block limit is enforced for that dimension (checkpoint-level protocol limits still apply). These are independent of the `SEQ_` vars so operators can tune proposer and validation limits separately.
|
|
245
245
|
|
|
246
|
-
**Checkpoint-level capping**: `CheckpointBuilder.capLimitsByCheckpointBudgets()` always runs before tx processing, capping per-block limits by `checkpointBudget - sum(used by prior blocks)
|
|
246
|
+
**Checkpoint-level capping**: `CheckpointBuilder.capLimitsByCheckpointBudgets()` always runs before tx processing, capping per-block limits by the remaining checkpoint budget. When `SEQ_REDISTRIBUTE_CHECKPOINT_BUDGET` is enabled (default: true), the remaining budget is distributed evenly across remaining blocks with the multiplier applied: `min(perBlockLimit, ceil(remainingBudget / remainingBlocks * multiplier), remainingBudget)`. This prevents early blocks from consuming the entire checkpoint budget, producing smoother distribution. When disabled, each block can consume up to the full remaining budget, ie caps by `checkpointBudget - sum(used by prior blocks)`. This applies to all four dimensions (L2 gas, DA gas, blob fields, transaction count). Validators always cap by the total remaining.
|
|
247
247
|
|
|
248
248
|
### Per-transaction enforcement
|
|
249
249
|
|
|
@@ -259,7 +259,8 @@ Per-block budgets prevent one block from consuming the entire checkpoint budget.
|
|
|
259
259
|
| `SEQ_MAX_DA_BLOCK_GAS` | *auto* | Per-block DA gas. Auto-derived from checkpoint DA limit / maxBlocks * multiplier. |
|
|
260
260
|
| `SEQ_MAX_TX_PER_BLOCK` | *none* | Per-block tx count. If `SEQ_MAX_TX_PER_CHECKPOINT` is set and per-block is not, derived as `ceil(checkpointLimit / maxBlocks * multiplier)`. |
|
|
261
261
|
| `SEQ_MAX_TX_PER_CHECKPOINT` | *none* | Total txs across all blocks in a checkpoint. When set, per-block tx limit is derived from it (unless explicitly overridden) and checkpoint-level capping is enforced. |
|
|
262
|
-
| `SEQ_PER_BLOCK_ALLOCATION_MULTIPLIER` | 2 | Multiplier for per-block budget computation. |
|
|
262
|
+
| `SEQ_PER_BLOCK_ALLOCATION_MULTIPLIER` | 1.2 | Multiplier for per-block budget computation. |
|
|
263
|
+
| `SEQ_REDISTRIBUTE_CHECKPOINT_BUDGET` | true | Redistribute remaining checkpoint budget evenly across remaining blocks instead of allowing one block to consume it all. |
|
|
263
264
|
| `VALIDATOR_MAX_L2_BLOCK_GAS` | *none* | Per-block L2 gas limit for validation. Proposals exceeding this are rejected. |
|
|
264
265
|
| `VALIDATOR_MAX_DA_BLOCK_GAS` | *none* | Per-block DA gas limit for validation. Proposals exceeding this are rejected. |
|
|
265
266
|
| `VALIDATOR_MAX_TX_PER_BLOCK` | *none* | Per-block tx count limit for validation. Proposals exceeding this are rejected. |
|
|
@@ -12,7 +12,7 @@ import type { FailedTx, Tx } from '@aztec/stdlib/tx';
|
|
|
12
12
|
import { type TelemetryClient, type Tracer } from '@aztec/telemetry-client';
|
|
13
13
|
import type { FullNodeCheckpointsBuilder } from './checkpoint_builder.js';
|
|
14
14
|
import type { ValidatorMetrics } from './metrics.js';
|
|
15
|
-
export type BlockProposalValidationFailureReason = 'invalid_proposal' | 'parent_block_not_found' | 'parent_block_wrong_slot' | 'in_hash_mismatch' | 'global_variables_mismatch' | 'block_number_already_exists' | 'txs_not_available' | 'state_mismatch' | 'failed_txs' | 'timeout' | 'unknown_error';
|
|
15
|
+
export type BlockProposalValidationFailureReason = 'invalid_proposal' | 'parent_block_not_found' | 'block_source_not_synced' | 'parent_block_wrong_slot' | 'in_hash_mismatch' | 'global_variables_mismatch' | 'block_number_already_exists' | 'txs_not_available' | 'state_mismatch' | 'failed_txs' | 'initial_state_mismatch' | 'timeout' | 'unknown_error';
|
|
16
16
|
type ReexecuteTransactionsResult = {
|
|
17
17
|
block: L2Block;
|
|
18
18
|
failedTxs: FailedTx[];
|
|
@@ -56,8 +56,9 @@ export declare class BlockProposalHandler {
|
|
|
56
56
|
*/
|
|
57
57
|
private validateNonFirstBlockInCheckpoint;
|
|
58
58
|
private getReexecutionDeadline;
|
|
59
|
+
private waitForBlockSourceSync;
|
|
59
60
|
private getReexecuteFailureReason;
|
|
60
61
|
reexecuteTransactions(proposal: BlockProposal, blockNumber: BlockNumber, checkpointNumber: CheckpointNumber, txs: Tx[], l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[]): Promise<ReexecuteTransactionsResult>;
|
|
61
62
|
}
|
|
62
63
|
export {};
|
|
63
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
64
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tfcHJvcG9zYWxfaGFuZGxlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Jsb2NrX3Byb3Bvc2FsX2hhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBYyxNQUFNLGlDQUFpQyxDQUFDO0FBRTVGLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUlwRCxPQUFPLEVBQUUsWUFBWSxFQUFTLE1BQU0seUJBQXlCLENBQUM7QUFDOUQsT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLFlBQVksQ0FBQztBQUM5QyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNuRSxPQUFPLEtBQUssRUFBYSxPQUFPLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRzFGLE9BQU8sS0FBSyxFQUFFLFdBQVcsRUFBRSx5QkFBeUIsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3RILE9BQU8sRUFBRSxLQUFLLG1CQUFtQixFQUFtQyxNQUFNLHlCQUF5QixDQUFDO0FBQ3BHLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXZELE9BQU8sS0FBSyxFQUE2QixRQUFRLEVBQUUsRUFBRSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFRaEYsT0FBTyxFQUFFLEtBQUssZUFBZSxFQUFFLEtBQUssTUFBTSxFQUFzQixNQUFNLHlCQUF5QixDQUFDO0FBRWhHLE9BQU8sS0FBSyxFQUFFLDBCQUEwQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDMUUsT0FBTyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFckQsTUFBTSxNQUFNLG9DQUFvQyxHQUM1QyxrQkFBa0IsR0FDbEIsd0JBQXdCLEdBQ3hCLHlCQUF5QixHQUN6Qix5QkFBeUIsR0FDekIsa0JBQWtCLEdBQ2xCLDJCQUEyQixHQUMzQiw2QkFBNkIsR0FDN0IsbUJBQW1CLEdBQ25CLGdCQUFnQixHQUNoQixZQUFZLEdBQ1osd0JBQXdCLEdBQ3hCLFNBQVMsR0FDVCxlQUFlLENBQUM7QUFFcEIsS0FBSywyQkFBMkIsR0FBRztJQUNqQyxLQUFLLEVBQUUsT0FBTyxDQUFDO0lBQ2YsU0FBUyxFQUFFLFFBQVEsRUFBRSxDQUFDO0lBQ3RCLGlCQUFpQixFQUFFLE1BQU0sQ0FBQztJQUMxQixhQUFhLEVBQUUsTUFBTSxDQUFDO0NBQ3ZCLENBQUM7QUFFRixNQUFNLE1BQU0sb0NBQW9DLEdBQUc7SUFDakQsT0FBTyxFQUFFLElBQUksQ0FBQztJQUNkLFdBQVcsRUFBRSxXQUFXLENBQUM7SUFDekIsaUJBQWlCLENBQUMsRUFBRSwyQkFBMkIsQ0FBQztDQUNqRCxDQUFDO0FBRUYsTUFBTSxNQUFNLG9DQUFvQyxHQUFHO0lBQ2pELE9BQU8sRUFBRSxLQUFLLENBQUM7SUFDZixNQUFNLEVBQUUsb0NBQW9DLENBQUM7SUFDN0MsV0FBVyxDQUFDLEVBQUUsV0FBVyxDQUFDO0lBQzFCLGlCQUFpQixDQUFDLEVBQUUsMkJBQTJCLENBQUM7Q0FDakQsQ0FBQztBQUVGLE1BQU0sTUFBTSw2QkFBNkIsR0FBRyxvQ0FBb0MsR0FBRyxvQ0FBb0MsQ0FBQztBQU14SCxxQkFBYSxvQkFBb0I7SUFJN0IsT0FBTyxDQUFDLGtCQUFrQjtJQUMxQixPQUFPLENBQUMsVUFBVTtJQUNsQixPQUFPLENBQUMsV0FBVztJQUNuQixPQUFPLENBQUMsbUJBQW1CO0lBQzNCLE9BQU8sQ0FBQyxVQUFVO0lBQ2xCLE9BQU8sQ0FBQyxzQkFBc0I7SUFDOUIsT0FBTyxDQUFDLFVBQVU7SUFDbEIsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsT0FBTyxDQUFDO0lBQ2hCLE9BQU8sQ0FBQyxZQUFZO0lBRXBCLE9BQU8sQ0FBQyxHQUFHO0lBZGIsU0FBZ0IsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUUvQixZQUNVLGtCQUFrQixFQUFFLDBCQUEwQixFQUM5QyxVQUFVLEVBQUUsc0JBQXNCLEVBQ2xDLFdBQVcsRUFBRSxhQUFhLEdBQUcsV0FBVyxFQUN4QyxtQkFBbUIsRUFBRSxtQkFBbUIsRUFDeEMsVUFBVSxFQUFFLFdBQVcsRUFDdkIsc0JBQXNCLEVBQUUsc0JBQXNCLEVBQzlDLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLE1BQU0sRUFBRSx5QkFBeUIsRUFDakMsT0FBTyxDQUFDLDhCQUFrQixFQUMxQixZQUFZLEdBQUUsWUFBaUMsRUFDdkQsU0FBUyxHQUFFLGVBQXNDLEVBQ3pDLEdBQUcseUNBQW1ELEVBTS9EO0lBRUQsUUFBUSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUUsZUFBZSxFQUFFLE9BQU8sR0FBRyxvQkFBb0IsQ0FnQ3ZFO0lBRUssbUJBQW1CLENBQ3ZCLFFBQVEsRUFBRSxhQUFhLEVBQ3ZCLGNBQWMsRUFBRSxNQUFNLEVBQ3RCLGVBQWUsRUFBRSxPQUFPLEdBQ3ZCLE9BQU8sQ0FBQyw2QkFBNkIsQ0FBQyxDQXlKeEM7WUFFYSxjQUFjO0lBb0M1QixPQUFPLENBQUMsdUJBQXVCO0lBMEMvQjs7OztPQUlHO0lBQ0gsT0FBTyxDQUFDLGlDQUFpQztJQTRFekMsT0FBTyxDQUFDLHNCQUFzQjtZQU1oQixzQkFBc0I7SUFtQ3BDLE9BQU8sQ0FBQyx5QkFBeUI7SUFjM0IscUJBQXFCLENBQ3pCLFFBQVEsRUFBRSxhQUFhLEVBQ3ZCLFdBQVcsRUFBRSxXQUFXLEVBQ3hCLGdCQUFnQixFQUFFLGdCQUFnQixFQUNsQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQ1QsY0FBYyxFQUFFLEVBQUUsRUFBRSxFQUNwQiwyQkFBMkIsRUFBRSxFQUFFLEVBQUUsR0FDaEMsT0FBTyxDQUFDLDJCQUEyQixDQUFDLENBaUh0QztDQUNGIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block_proposal_handler.d.ts","sourceRoot":"","sources":["../src/block_proposal_handler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAc,MAAM,iCAAiC,CAAC;AAE5F,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAIpD,OAAO,EAAE,YAAY,EAAS,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,KAAK,EAAa,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAG1F,OAAO,KAAK,EAAE,WAAW,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACtH,OAAO,EAAE,KAAK,mBAAmB,EAAmC,MAAM,yBAAyB,CAAC;AACpG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"block_proposal_handler.d.ts","sourceRoot":"","sources":["../src/block_proposal_handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -74,7 +74,8 @@ import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
|
74
74
|
import { getEpochAtSlot, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
75
75
|
import { Gas } from '@aztec/stdlib/gas';
|
|
76
76
|
import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
|
|
77
|
-
import {
|
|
77
|
+
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
78
|
+
import { ReExFailedTxsError, ReExInitialStateMismatchError, ReExStateMismatchError, ReExTimeoutError, TransactionsNotAvailableError } from '@aztec/stdlib/validators';
|
|
78
79
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
79
80
|
export class BlockProposalHandler {
|
|
80
81
|
checkpointsBuilder;
|
|
@@ -153,7 +154,9 @@ export class BlockProposalHandler {
|
|
|
153
154
|
}
|
|
154
155
|
const proposalInfo = {
|
|
155
156
|
...proposal.toBlockInfo(),
|
|
156
|
-
proposer: proposer.toString()
|
|
157
|
+
proposer: proposer.toString(),
|
|
158
|
+
blockNumber: undefined,
|
|
159
|
+
checkpointNumber: undefined
|
|
157
160
|
};
|
|
158
161
|
this.log.info(`Processing proposal for slot ${slotNumber}`, {
|
|
159
162
|
...proposalInfo,
|
|
@@ -169,7 +172,22 @@ export class BlockProposalHandler {
|
|
|
169
172
|
reason: 'invalid_proposal'
|
|
170
173
|
};
|
|
171
174
|
}
|
|
172
|
-
//
|
|
175
|
+
// Ensure the block source is synced before checking for existing blocks,
|
|
176
|
+
// since a pending checkpoint prune may remove blocks we'd otherwise find.
|
|
177
|
+
// This affects mostly the block_number_already_exists check, since a pending
|
|
178
|
+
// checkpoint prune could remove a block that would conflict with this proposal.
|
|
179
|
+
// TODO(@Maddiaa0): This may break staggered slots.
|
|
180
|
+
const blockSourceSync = await this.waitForBlockSourceSync(slotNumber);
|
|
181
|
+
if (!blockSourceSync) {
|
|
182
|
+
this.log.warn(`Block source is not synced, skipping processing`, proposalInfo);
|
|
183
|
+
return {
|
|
184
|
+
isValid: false,
|
|
185
|
+
reason: 'block_source_not_synced'
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
// Check that the parent proposal is a block we know, otherwise reexecution would fail.
|
|
189
|
+
// If we don't find it immediately, we keep retrying for a while; it may be we still
|
|
190
|
+
// need to process other block proposals to get to it.
|
|
173
191
|
const parentBlock = await this.getParentBlock(proposal);
|
|
174
192
|
if (parentBlock === undefined) {
|
|
175
193
|
this.log.warn(`Parent block for proposal not found, skipping processing`, proposalInfo);
|
|
@@ -192,6 +210,7 @@ export class BlockProposalHandler {
|
|
|
192
210
|
}
|
|
193
211
|
// Compute the block number based on the parent block
|
|
194
212
|
const blockNumber = parentBlock === 'genesis' ? BlockNumber(INITIAL_L2_BLOCK_NUM) : BlockNumber(parentBlock.header.getBlockNumber() + 1);
|
|
213
|
+
proposalInfo.blockNumber = blockNumber;
|
|
195
214
|
// Check that this block number does not exist already
|
|
196
215
|
const existingBlock = await this.blockSource.getBlockHeader(blockNumber);
|
|
197
216
|
if (existingBlock) {
|
|
@@ -208,7 +227,7 @@ export class BlockProposalHandler {
|
|
|
208
227
|
pinnedPeer: proposalSender,
|
|
209
228
|
deadline: this.getReexecutionDeadline(slotNumber, config)
|
|
210
229
|
});
|
|
211
|
-
// If reexecution is disabled, bail. We
|
|
230
|
+
// If reexecution is disabled, bail. We were just interested in triggering tx collection.
|
|
212
231
|
if (!shouldReexecute) {
|
|
213
232
|
this.log.info(`Received valid block ${blockNumber} proposal at index ${proposal.indexWithinCheckpoint} on slot ${slotNumber}`, proposalInfo);
|
|
214
233
|
return {
|
|
@@ -226,6 +245,7 @@ export class BlockProposalHandler {
|
|
|
226
245
|
};
|
|
227
246
|
}
|
|
228
247
|
const checkpointNumber = checkpointResult.checkpointNumber;
|
|
248
|
+
proposalInfo.checkpointNumber = checkpointNumber;
|
|
229
249
|
// Check that I have the same set of l1ToL2Messages as the proposal
|
|
230
250
|
const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber);
|
|
231
251
|
const computedInHash = computeInHashFromL1ToL2Messages(l1ToL2Messages);
|
|
@@ -444,8 +464,37 @@ export class BlockProposalHandler {
|
|
|
444
464
|
const nextSlotTimestampSeconds = Number(getTimestampForSlot(SlotNumber(slot + 1), config));
|
|
445
465
|
return new Date(nextSlotTimestampSeconds * 1000);
|
|
446
466
|
}
|
|
467
|
+
/** Waits for the block source to sync L1 data up to at least the slot before the given one. */ async waitForBlockSourceSync(slot) {
|
|
468
|
+
const deadline = this.getReexecutionDeadline(slot, this.checkpointsBuilder.getConfig());
|
|
469
|
+
const timeoutMs = deadline.getTime() - this.dateProvider.now();
|
|
470
|
+
if (slot === 0) {
|
|
471
|
+
return true;
|
|
472
|
+
}
|
|
473
|
+
// Make a quick check before triggering an archiver sync
|
|
474
|
+
const syncedSlot = await this.blockSource.getSyncedL2SlotNumber();
|
|
475
|
+
if (syncedSlot !== undefined && syncedSlot + 1 >= slot) {
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
try {
|
|
479
|
+
// Trigger an immediate sync of the block source, and wait until it reports being synced to the required slot
|
|
480
|
+
return await retryUntil(async ()=>{
|
|
481
|
+
await this.blockSource.syncImmediate();
|
|
482
|
+
const syncedSlot = await this.blockSource.getSyncedL2SlotNumber();
|
|
483
|
+
return syncedSlot !== undefined && syncedSlot + 1 >= slot;
|
|
484
|
+
}, 'wait for block source sync', timeoutMs / 1000, 0.5);
|
|
485
|
+
} catch (err) {
|
|
486
|
+
if (err instanceof TimeoutError) {
|
|
487
|
+
this.log.warn(`Timed out waiting for block source to sync to slot ${slot}`);
|
|
488
|
+
return false;
|
|
489
|
+
} else {
|
|
490
|
+
throw err;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
447
494
|
getReexecuteFailureReason(err) {
|
|
448
|
-
if (err instanceof
|
|
495
|
+
if (err instanceof ReExInitialStateMismatchError) {
|
|
496
|
+
return 'initial_state_mismatch';
|
|
497
|
+
} else if (err instanceof ReExStateMismatchError) {
|
|
449
498
|
return 'state_mismatch';
|
|
450
499
|
} else if (err instanceof ReExFailedTxsError) {
|
|
451
500
|
return 'failed_txs';
|
|
@@ -479,6 +528,12 @@ export class BlockProposalHandler {
|
|
|
479
528
|
const parentBlockNumber = BlockNumber(blockNumber - 1);
|
|
480
529
|
await this.worldState.syncImmediate(parentBlockNumber);
|
|
481
530
|
const fork = _ts_add_disposable_resource(env, await this.worldState.fork(parentBlockNumber), true);
|
|
531
|
+
// Verify the fork's archive root matches the proposal's expected last archive.
|
|
532
|
+
// If they don't match, our world state synced to a different chain and reexecution would fail.
|
|
533
|
+
const forkArchiveRoot = new Fr((await fork.getTreeInfo(MerkleTreeId.ARCHIVE)).root);
|
|
534
|
+
if (!forkArchiveRoot.equals(proposal.blockHeader.lastArchive.root)) {
|
|
535
|
+
throw new ReExInitialStateMismatchError(proposal.blockHeader.lastArchive.root, forkArchiveRoot);
|
|
536
|
+
}
|
|
482
537
|
// Build checkpoint constants from proposal (excludes blockNumber which is per-block)
|
|
483
538
|
const constants = {
|
|
484
539
|
chainId: new Fr(config.l1ChainId),
|
|
@@ -34,6 +34,7 @@ export declare class CheckpointBuilder implements ICheckpointBlockBuilder {
|
|
|
34
34
|
*/
|
|
35
35
|
buildBlock(pendingTxs: Iterable<Tx> | AsyncIterable<Tx>, blockNumber: BlockNumber, timestamp: bigint, opts?: PublicProcessorLimits & {
|
|
36
36
|
expectedEndState?: StateReference;
|
|
37
|
+
minValidTxs?: number;
|
|
37
38
|
}): Promise<BuildBlockInCheckpointResult>;
|
|
38
39
|
/** Completes the checkpoint and returns it. */
|
|
39
40
|
completeCheckpoint(): Promise<Checkpoint>;
|
|
@@ -73,4 +74,4 @@ export declare class FullNodeCheckpointsBuilder implements ICheckpointsBuilder {
|
|
|
73
74
|
/** Returns a fork of the world state at the given block number. */
|
|
74
75
|
getFork(blockNumber: BlockNumber): Promise<MerkleTreeWriteOperations>;
|
|
75
76
|
}
|
|
76
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
77
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludF9idWlsZGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY2hlY2twb2ludF9idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVoRixPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDcEQsT0FBTyxFQUFlLEtBQUssY0FBYyxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBRXZGLE9BQU8sRUFBRSxZQUFZLEVBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUVoRSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMxRSxPQUFPLEVBR0wsZUFBZSxFQUVoQixNQUFNLHlCQUF5QixDQUFDO0FBQ2pDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdEQsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRSxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRXJFLE9BQU8sRUFDTCxLQUFLLDRCQUE0QixFQUNqQyxLQUFLLDBCQUEwQixFQUUvQixLQUFLLHVCQUF1QixFQUM1QixLQUFLLG1CQUFtQixFQUV4QixLQUFLLHlCQUF5QixFQUM5QixLQUFLLHFCQUFxQixFQUMxQixLQUFLLHNCQUFzQixFQUM1QixNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxLQUFLLGFBQWEsRUFBcUIsTUFBTSxvQkFBb0IsQ0FBQztBQUUzRSxPQUFPLEVBQUUsS0FBSyx5QkFBeUIsRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLEVBQUUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxLQUFL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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpoint_builder.d.ts","sourceRoot":"","sources":["../src/checkpoint_builder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEhF,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AAEvF,OAAO,EAAE,YAAY,EAAW,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAGL,eAAe,EAEhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,0BAA0B,EAE/B,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,
|
|
1
|
+
{"version":3,"file":"checkpoint_builder.d.ts","sourceRoot":"","sources":["../src/checkpoint_builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,11 +8,12 @@ import { createTxValidatorForBlockBuilding, getDefaultAllowedSetupFunctions } fr
|
|
|
8
8
|
import { LightweightCheckpointBuilder } from '@aztec/prover-client/light';
|
|
9
9
|
import { GuardedMerkleTreeOperations, PublicContractsDB, PublicProcessor, createPublicTxSimulatorForBlockBuilding } from '@aztec/simulator/server';
|
|
10
10
|
import { Gas } from '@aztec/stdlib/gas';
|
|
11
|
-
import { FullNodeBlockBuilderConfigKeys,
|
|
11
|
+
import { FullNodeBlockBuilderConfigKeys, InsufficientValidTxsError } from '@aztec/stdlib/interfaces/server';
|
|
12
12
|
import { NullDebugLogStore } from '@aztec/stdlib/logs';
|
|
13
13
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
14
14
|
import { GlobalVariables } from '@aztec/stdlib/tx';
|
|
15
15
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
16
|
+
import { ForkCheckpoint } from '@aztec/world-state';
|
|
16
17
|
/**
|
|
17
18
|
* Builder for a single checkpoint. Handles building blocks within the checkpoint
|
|
18
19
|
* and completing it.
|
|
@@ -69,28 +70,40 @@ import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
|
69
70
|
...opts,
|
|
70
71
|
...this.capLimitsByCheckpointBudgets(opts)
|
|
71
72
|
};
|
|
72
|
-
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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;
|
|
77
106
|
}
|
|
78
|
-
// Add block to checkpoint
|
|
79
|
-
const { block } = await this.checkpointBuilder.addBlock(globalVariables, processedTxs, {
|
|
80
|
-
expectedEndState: opts.expectedEndState
|
|
81
|
-
});
|
|
82
|
-
this.log.debug('Built block within checkpoint', {
|
|
83
|
-
header: block.header.toInspect(),
|
|
84
|
-
processedTxs: processedTxs.map((tx)=>tx.hash.toString()),
|
|
85
|
-
failedTxs: failedTxs.map((tx)=>tx.tx.txHash.toString())
|
|
86
|
-
});
|
|
87
|
-
return {
|
|
88
|
-
block,
|
|
89
|
-
publicProcessorDuration,
|
|
90
|
-
numTxs: processedTxs.length,
|
|
91
|
-
failedTxs,
|
|
92
|
-
usedTxs
|
|
93
|
-
};
|
|
94
107
|
}
|
|
95
108
|
/** Completes the checkpoint and returns it. */ async completeCheckpoint() {
|
|
96
109
|
const checkpoint = await this.checkpointBuilder.completeCheckpoint();
|
|
@@ -124,18 +137,27 @@ import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
|
124
137
|
const isFirstBlock = existingBlocks.length === 0;
|
|
125
138
|
const blockEndOverhead = getNumBlockEndBlobFields(isFirstBlock);
|
|
126
139
|
const maxBlobFieldsForTxs = totalBlobCapacity - usedBlobFields - blockEndOverhead;
|
|
127
|
-
//
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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)
|
|
134
155
|
let cappedMaxTransactions;
|
|
135
156
|
if (this.config.maxTxsPerCheckpoint !== undefined) {
|
|
136
157
|
const usedTxs = sum(existingBlocks.map((b)=>b.body.txEffects.length));
|
|
137
158
|
const remainingTxs = Math.max(0, this.config.maxTxsPerCheckpoint - usedTxs);
|
|
138
|
-
|
|
159
|
+
const fairShareTxs = redistribute ? Math.ceil(remainingTxs / remainingBlocks * multiplier) : Infinity;
|
|
160
|
+
cappedMaxTransactions = Math.min(opts.maxTransactions ?? Infinity, fairShareTxs, remainingTxs);
|
|
139
161
|
} else {
|
|
140
162
|
cappedMaxTransactions = opts.maxTransactions;
|
|
141
163
|
}
|
|
@@ -105,7 +105,7 @@ export class ValidationService {
|
|
|
105
105
|
} else {
|
|
106
106
|
const error = result.reason;
|
|
107
107
|
if (error instanceof DutyAlreadySignedError || error instanceof SlashingProtectionError) {
|
|
108
|
-
this.log.
|
|
108
|
+
this.log.verbose(`Attestation for slot ${proposal.slotNumber} by ${attestors[i]} already signed by another High-Availability node`);
|
|
109
109
|
// Continue with remaining attestors
|
|
110
110
|
} else {
|
|
111
111
|
throw error;
|
|
@@ -184,7 +184,7 @@ import { hashTypedData } from 'viem';
|
|
|
184
184
|
return;
|
|
185
185
|
}
|
|
186
186
|
if (error instanceof SlashingProtectionError) {
|
|
187
|
-
this.log.
|
|
187
|
+
this.log.info(`Duty already signed by another node with different payload`, {
|
|
188
188
|
dutyType: context.dutyType,
|
|
189
189
|
slot: context.slot,
|
|
190
190
|
existingMessageHash: error.existingMessageHash,
|
package/dest/validator.d.ts
CHANGED
|
@@ -120,4 +120,4 @@ export declare class ValidatorClient extends ValidatorClient_base implements Val
|
|
|
120
120
|
private handleAuthRequest;
|
|
121
121
|
}
|
|
122
122
|
export {};
|
|
123
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
123
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9yLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdmFsaWRhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFckUsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFckQsT0FBTyxFQUNMLFdBQVcsRUFDWCxnQkFBZ0IsRUFFaEIscUJBQXFCLEVBQ3JCLFVBQVUsRUFDWCxNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUVwRCxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNoRSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsS0FBSyxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sdUJBQXVCLENBQUM7QUFJaEYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzVELE9BQU8sS0FBSyxFQUFtRCxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRS9GLE9BQU8sRUFBb0MsS0FBSyxPQUFPLEVBQUUsS0FBSyxjQUFjLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyRyxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNoRSxPQUFPLEtBQUssRUFBRSwrQkFBK0IsRUFBVyxXQUFXLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHaEgsT0FBTyxLQUFLLEVBQ1YscUNBQXFDLEVBQ3JDLFdBQVcsRUFDWCxTQUFTLEVBQ1QseUJBQXlCLEVBQ3pCLHNCQUFzQixFQUN2QixN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
|
package/dest/validator.d.ts.map
CHANGED
|
@@ -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
|
@@ -237,7 +237,7 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
237
237
|
}
|
|
238
238
|
// Ignore proposals from ourselves (may happen in HA setups)
|
|
239
239
|
if (this.getValidatorAddresses().some((addr)=>addr.equals(proposer))) {
|
|
240
|
-
this.log.
|
|
240
|
+
this.log.debug(`Ignoring block proposal from self for slot ${slotNumber}`, {
|
|
241
241
|
proposer: proposer.toString(),
|
|
242
242
|
slotNumber
|
|
243
243
|
});
|
|
@@ -261,8 +261,8 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
261
261
|
const shouldReexecute = fishermanMode || slashBroadcastedInvalidBlockPenalty > 0n && validatorReexecute || partOfCommittee && validatorReexecute || alwaysReexecuteBlockProposals || this.blobClient.canUpload();
|
|
262
262
|
const validationResult = await this.blockProposalHandler.handleBlockProposal(proposal, proposalSender, !!shouldReexecute && !escapeHatchOpen);
|
|
263
263
|
if (!validationResult.isValid) {
|
|
264
|
-
this.log.warn(`Block proposal validation failed: ${validationResult.reason}`, proposalInfo);
|
|
265
264
|
const reason = validationResult.reason || 'unknown';
|
|
265
|
+
this.log.warn(`Block proposal validation failed: ${reason}`, proposalInfo);
|
|
266
266
|
// Classify failure reason: bad proposal vs node issue
|
|
267
267
|
const badProposalReasons = [
|
|
268
268
|
'invalid_proposal',
|
|
@@ -316,7 +316,7 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
316
316
|
}
|
|
317
317
|
// Ignore proposals from ourselves (may happen in HA setups)
|
|
318
318
|
if (this.getValidatorAddresses().some((addr)=>addr.equals(proposer))) {
|
|
319
|
-
this.log.
|
|
319
|
+
this.log.debug(`Ignoring block proposal from self for slot ${slotNumber}`, {
|
|
320
320
|
proposer: proposer.toString(),
|
|
321
321
|
slotNumber
|
|
322
322
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/validator-client",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.3e3d0c9cd",
|
|
4
4
|
"main": "dest/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -64,30 +64,30 @@
|
|
|
64
64
|
]
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@aztec/blob-client": "0.0.1-commit.
|
|
68
|
-
"@aztec/blob-lib": "0.0.1-commit.
|
|
69
|
-
"@aztec/constants": "0.0.1-commit.
|
|
70
|
-
"@aztec/epoch-cache": "0.0.1-commit.
|
|
71
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
72
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
73
|
-
"@aztec/node-keystore": "0.0.1-commit.
|
|
74
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
75
|
-
"@aztec/p2p": "0.0.1-commit.
|
|
76
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
77
|
-
"@aztec/prover-client": "0.0.1-commit.
|
|
78
|
-
"@aztec/simulator": "0.0.1-commit.
|
|
79
|
-
"@aztec/slasher": "0.0.1-commit.
|
|
80
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
81
|
-
"@aztec/telemetry-client": "0.0.1-commit.
|
|
82
|
-
"@aztec/validator-ha-signer": "0.0.1-commit.
|
|
67
|
+
"@aztec/blob-client": "0.0.1-commit.3e3d0c9cd",
|
|
68
|
+
"@aztec/blob-lib": "0.0.1-commit.3e3d0c9cd",
|
|
69
|
+
"@aztec/constants": "0.0.1-commit.3e3d0c9cd",
|
|
70
|
+
"@aztec/epoch-cache": "0.0.1-commit.3e3d0c9cd",
|
|
71
|
+
"@aztec/ethereum": "0.0.1-commit.3e3d0c9cd",
|
|
72
|
+
"@aztec/foundation": "0.0.1-commit.3e3d0c9cd",
|
|
73
|
+
"@aztec/node-keystore": "0.0.1-commit.3e3d0c9cd",
|
|
74
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.3e3d0c9cd",
|
|
75
|
+
"@aztec/p2p": "0.0.1-commit.3e3d0c9cd",
|
|
76
|
+
"@aztec/protocol-contracts": "0.0.1-commit.3e3d0c9cd",
|
|
77
|
+
"@aztec/prover-client": "0.0.1-commit.3e3d0c9cd",
|
|
78
|
+
"@aztec/simulator": "0.0.1-commit.3e3d0c9cd",
|
|
79
|
+
"@aztec/slasher": "0.0.1-commit.3e3d0c9cd",
|
|
80
|
+
"@aztec/stdlib": "0.0.1-commit.3e3d0c9cd",
|
|
81
|
+
"@aztec/telemetry-client": "0.0.1-commit.3e3d0c9cd",
|
|
82
|
+
"@aztec/validator-ha-signer": "0.0.1-commit.3e3d0c9cd",
|
|
83
83
|
"koa": "^2.16.1",
|
|
84
84
|
"koa-router": "^13.1.1",
|
|
85
85
|
"tslib": "^2.4.0",
|
|
86
86
|
"viem": "npm:@aztec/viem@2.38.2"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
|
-
"@aztec/archiver": "0.0.1-commit.
|
|
90
|
-
"@aztec/world-state": "0.0.1-commit.
|
|
89
|
+
"@aztec/archiver": "0.0.1-commit.3e3d0c9cd",
|
|
90
|
+
"@aztec/world-state": "0.0.1-commit.3e3d0c9cd",
|
|
91
91
|
"@electric-sql/pglite": "^0.3.14",
|
|
92
92
|
"@jest/globals": "^30.0.0",
|
|
93
93
|
"@types/jest": "^30.0.0",
|
|
@@ -15,9 +15,11 @@ import { Gas } from '@aztec/stdlib/gas';
|
|
|
15
15
|
import type { ITxProvider, ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
16
16
|
import { type L1ToL2MessageSource, computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
|
|
17
17
|
import type { BlockProposal } from '@aztec/stdlib/p2p';
|
|
18
|
+
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
18
19
|
import type { CheckpointGlobalVariables, FailedTx, Tx } from '@aztec/stdlib/tx';
|
|
19
20
|
import {
|
|
20
21
|
ReExFailedTxsError,
|
|
22
|
+
ReExInitialStateMismatchError,
|
|
21
23
|
ReExStateMismatchError,
|
|
22
24
|
ReExTimeoutError,
|
|
23
25
|
TransactionsNotAvailableError,
|
|
@@ -30,6 +32,7 @@ import type { ValidatorMetrics } from './metrics.js';
|
|
|
30
32
|
export type BlockProposalValidationFailureReason =
|
|
31
33
|
| 'invalid_proposal'
|
|
32
34
|
| 'parent_block_not_found'
|
|
35
|
+
| 'block_source_not_synced'
|
|
33
36
|
| 'parent_block_wrong_slot'
|
|
34
37
|
| 'in_hash_mismatch'
|
|
35
38
|
| 'global_variables_mismatch'
|
|
@@ -37,6 +40,7 @@ export type BlockProposalValidationFailureReason =
|
|
|
37
40
|
| 'txs_not_available'
|
|
38
41
|
| 'state_mismatch'
|
|
39
42
|
| 'failed_txs'
|
|
43
|
+
| 'initial_state_mismatch'
|
|
40
44
|
| 'timeout'
|
|
41
45
|
| 'unknown_error';
|
|
42
46
|
|
|
@@ -138,7 +142,13 @@ export class BlockProposalHandler {
|
|
|
138
142
|
return { isValid: false, reason: 'invalid_proposal' };
|
|
139
143
|
}
|
|
140
144
|
|
|
141
|
-
const proposalInfo = {
|
|
145
|
+
const proposalInfo = {
|
|
146
|
+
...proposal.toBlockInfo(),
|
|
147
|
+
proposer: proposer.toString(),
|
|
148
|
+
blockNumber: undefined as BlockNumber | undefined,
|
|
149
|
+
checkpointNumber: undefined as CheckpointNumber | undefined,
|
|
150
|
+
};
|
|
151
|
+
|
|
142
152
|
this.log.info(`Processing proposal for slot ${slotNumber}`, {
|
|
143
153
|
...proposalInfo,
|
|
144
154
|
txHashes: proposal.txHashes.map(t => t.toString()),
|
|
@@ -152,7 +162,20 @@ export class BlockProposalHandler {
|
|
|
152
162
|
return { isValid: false, reason: 'invalid_proposal' };
|
|
153
163
|
}
|
|
154
164
|
|
|
155
|
-
//
|
|
165
|
+
// Ensure the block source is synced before checking for existing blocks,
|
|
166
|
+
// since a pending checkpoint prune may remove blocks we'd otherwise find.
|
|
167
|
+
// This affects mostly the block_number_already_exists check, since a pending
|
|
168
|
+
// checkpoint prune could remove a block that would conflict with this proposal.
|
|
169
|
+
// TODO(@Maddiaa0): This may break staggered slots.
|
|
170
|
+
const blockSourceSync = await this.waitForBlockSourceSync(slotNumber);
|
|
171
|
+
if (!blockSourceSync) {
|
|
172
|
+
this.log.warn(`Block source is not synced, skipping processing`, proposalInfo);
|
|
173
|
+
return { isValid: false, reason: 'block_source_not_synced' };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Check that the parent proposal is a block we know, otherwise reexecution would fail.
|
|
177
|
+
// If we don't find it immediately, we keep retrying for a while; it may be we still
|
|
178
|
+
// need to process other block proposals to get to it.
|
|
156
179
|
const parentBlock = await this.getParentBlock(proposal);
|
|
157
180
|
if (parentBlock === undefined) {
|
|
158
181
|
this.log.warn(`Parent block for proposal not found, skipping processing`, proposalInfo);
|
|
@@ -174,6 +197,7 @@ export class BlockProposalHandler {
|
|
|
174
197
|
parentBlock === 'genesis'
|
|
175
198
|
? BlockNumber(INITIAL_L2_BLOCK_NUM)
|
|
176
199
|
: BlockNumber(parentBlock.header.getBlockNumber() + 1);
|
|
200
|
+
proposalInfo.blockNumber = blockNumber;
|
|
177
201
|
|
|
178
202
|
// Check that this block number does not exist already
|
|
179
203
|
const existingBlock = await this.blockSource.getBlockHeader(blockNumber);
|
|
@@ -189,7 +213,7 @@ export class BlockProposalHandler {
|
|
|
189
213
|
deadline: this.getReexecutionDeadline(slotNumber, config),
|
|
190
214
|
});
|
|
191
215
|
|
|
192
|
-
// If reexecution is disabled, bail. We
|
|
216
|
+
// If reexecution is disabled, bail. We were just interested in triggering tx collection.
|
|
193
217
|
if (!shouldReexecute) {
|
|
194
218
|
this.log.info(
|
|
195
219
|
`Received valid block ${blockNumber} proposal at index ${proposal.indexWithinCheckpoint} on slot ${slotNumber}`,
|
|
@@ -204,6 +228,7 @@ export class BlockProposalHandler {
|
|
|
204
228
|
return { isValid: false, blockNumber, reason: checkpointResult.reason };
|
|
205
229
|
}
|
|
206
230
|
const checkpointNumber = checkpointResult.checkpointNumber;
|
|
231
|
+
proposalInfo.checkpointNumber = checkpointNumber;
|
|
207
232
|
|
|
208
233
|
// Check that I have the same set of l1ToL2Messages as the proposal
|
|
209
234
|
const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber);
|
|
@@ -425,8 +450,46 @@ export class BlockProposalHandler {
|
|
|
425
450
|
return new Date(nextSlotTimestampSeconds * 1000);
|
|
426
451
|
}
|
|
427
452
|
|
|
428
|
-
|
|
429
|
-
|
|
453
|
+
/** Waits for the block source to sync L1 data up to at least the slot before the given one. */
|
|
454
|
+
private async waitForBlockSourceSync(slot: SlotNumber): Promise<boolean> {
|
|
455
|
+
const deadline = this.getReexecutionDeadline(slot, this.checkpointsBuilder.getConfig());
|
|
456
|
+
const timeoutMs = deadline.getTime() - this.dateProvider.now();
|
|
457
|
+
if (slot === 0) {
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// Make a quick check before triggering an archiver sync
|
|
462
|
+
const syncedSlot = await this.blockSource.getSyncedL2SlotNumber();
|
|
463
|
+
if (syncedSlot !== undefined && syncedSlot + 1 >= slot) {
|
|
464
|
+
return true;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
try {
|
|
468
|
+
// Trigger an immediate sync of the block source, and wait until it reports being synced to the required slot
|
|
469
|
+
return await retryUntil(
|
|
470
|
+
async () => {
|
|
471
|
+
await this.blockSource.syncImmediate();
|
|
472
|
+
const syncedSlot = await this.blockSource.getSyncedL2SlotNumber();
|
|
473
|
+
return syncedSlot !== undefined && syncedSlot + 1 >= slot;
|
|
474
|
+
},
|
|
475
|
+
'wait for block source sync',
|
|
476
|
+
timeoutMs / 1000,
|
|
477
|
+
0.5,
|
|
478
|
+
);
|
|
479
|
+
} catch (err) {
|
|
480
|
+
if (err instanceof TimeoutError) {
|
|
481
|
+
this.log.warn(`Timed out waiting for block source to sync to slot ${slot}`);
|
|
482
|
+
return false;
|
|
483
|
+
} else {
|
|
484
|
+
throw err;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
private getReexecuteFailureReason(err: any): BlockProposalValidationFailureReason {
|
|
490
|
+
if (err instanceof ReExInitialStateMismatchError) {
|
|
491
|
+
return 'initial_state_mismatch';
|
|
492
|
+
} else if (err instanceof ReExStateMismatchError) {
|
|
430
493
|
return 'state_mismatch';
|
|
431
494
|
} else if (err instanceof ReExFailedTxsError) {
|
|
432
495
|
return 'failed_txs';
|
|
@@ -467,6 +530,13 @@ export class BlockProposalHandler {
|
|
|
467
530
|
await this.worldState.syncImmediate(parentBlockNumber);
|
|
468
531
|
await using fork = await this.worldState.fork(parentBlockNumber);
|
|
469
532
|
|
|
533
|
+
// Verify the fork's archive root matches the proposal's expected last archive.
|
|
534
|
+
// If they don't match, our world state synced to a different chain and reexecution would fail.
|
|
535
|
+
const forkArchiveRoot = new Fr((await fork.getTreeInfo(MerkleTreeId.ARCHIVE)).root);
|
|
536
|
+
if (!forkArchiveRoot.equals(proposal.blockHeader.lastArchive.root)) {
|
|
537
|
+
throw new ReExInitialStateMismatchError(proposal.blockHeader.lastArchive.root, forkArchiveRoot);
|
|
538
|
+
}
|
|
539
|
+
|
|
470
540
|
// Build checkpoint constants from proposal (excludes blockNumber which is per-block)
|
|
471
541
|
const constants: CheckpointGlobalVariables = {
|
|
472
542
|
chainId: new Fr(config.l1ChainId),
|
|
@@ -25,8 +25,8 @@ import {
|
|
|
25
25
|
FullNodeBlockBuilderConfigKeys,
|
|
26
26
|
type ICheckpointBlockBuilder,
|
|
27
27
|
type ICheckpointsBuilder,
|
|
28
|
+
InsufficientValidTxsError,
|
|
28
29
|
type MerkleTreeWriteOperations,
|
|
29
|
-
NoValidTxsError,
|
|
30
30
|
type PublicProcessorLimits,
|
|
31
31
|
type WorldStateSynchronizer,
|
|
32
32
|
} from '@aztec/stdlib/interfaces/server';
|
|
@@ -34,6 +34,7 @@ import { type DebugLogStore, NullDebugLogStore } from '@aztec/stdlib/logs';
|
|
|
34
34
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
35
35
|
import { type CheckpointGlobalVariables, GlobalVariables, StateReference, Tx } from '@aztec/stdlib/tx';
|
|
36
36
|
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
37
|
+
import { ForkCheckpoint } from '@aztec/world-state';
|
|
37
38
|
|
|
38
39
|
// Re-export for backward compatibility
|
|
39
40
|
export type { BuildBlockInCheckpointResult } from '@aztec/stdlib/interfaces/server';
|
|
@@ -73,7 +74,7 @@ export class CheckpointBuilder implements ICheckpointBlockBuilder {
|
|
|
73
74
|
pendingTxs: Iterable<Tx> | AsyncIterable<Tx>,
|
|
74
75
|
blockNumber: BlockNumber,
|
|
75
76
|
timestamp: bigint,
|
|
76
|
-
opts: PublicProcessorLimits & { expectedEndState?: StateReference } = {},
|
|
77
|
+
opts: PublicProcessorLimits & { expectedEndState?: StateReference; minValidTxs?: number } = {},
|
|
77
78
|
): Promise<BuildBlockInCheckpointResult> {
|
|
78
79
|
const slot = this.checkpointBuilder.constants.slotNumber;
|
|
79
80
|
|
|
@@ -103,34 +104,47 @@ export class CheckpointBuilder implements ICheckpointBlockBuilder {
|
|
|
103
104
|
...this.capLimitsByCheckpointBudgets(opts),
|
|
104
105
|
};
|
|
105
106
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
);
|
|
107
|
+
// We execute all merkle tree operations on a world state fork checkpoint
|
|
108
|
+
// This enables us to discard all modifications in the event that we fail to successfully process sufficient transactions
|
|
109
|
+
const forkCheckpoint = await ForkCheckpoint.new(this.fork);
|
|
109
110
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
try {
|
|
112
|
+
const [publicProcessorDuration, [processedTxs, failedTxs, usedTxs]] = await elapsed(() =>
|
|
113
|
+
processor.process(pendingTxs, cappedOpts, validator),
|
|
114
|
+
);
|
|
115
|
+
// Throw before updating state if we don't have enough valid txs
|
|
116
|
+
const minValidTxs = opts.minValidTxs ?? 0;
|
|
117
|
+
if (processedTxs.length < minValidTxs) {
|
|
118
|
+
throw new InsufficientValidTxsError(processedTxs.length, minValidTxs, failedTxs);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Commit the fork checkpoint
|
|
122
|
+
await forkCheckpoint.commit();
|
|
123
|
+
|
|
124
|
+
// Add block to checkpoint
|
|
125
|
+
const { block } = await this.checkpointBuilder.addBlock(globalVariables, processedTxs, {
|
|
126
|
+
expectedEndState: opts.expectedEndState,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
this.log.debug('Built block within checkpoint', {
|
|
130
|
+
header: block.header.toInspect(),
|
|
131
|
+
processedTxs: processedTxs.map(tx => tx.hash.toString()),
|
|
132
|
+
failedTxs: failedTxs.map(tx => tx.tx.txHash.toString()),
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
block,
|
|
137
|
+
publicProcessorDuration,
|
|
138
|
+
numTxs: processedTxs.length,
|
|
139
|
+
failedTxs,
|
|
140
|
+
usedTxs,
|
|
141
|
+
};
|
|
142
|
+
} catch (err) {
|
|
143
|
+
// If we reached the point of committing the checkpoint, this does nothing
|
|
144
|
+
// Otherwise it reverts any changes made to the fork for this failed block
|
|
145
|
+
await forkCheckpoint.revert();
|
|
146
|
+
throw err;
|
|
114
147
|
}
|
|
115
|
-
|
|
116
|
-
// Add block to checkpoint
|
|
117
|
-
const { block } = await this.checkpointBuilder.addBlock(globalVariables, processedTxs, {
|
|
118
|
-
expectedEndState: opts.expectedEndState,
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
this.log.debug('Built block within checkpoint', {
|
|
122
|
-
header: block.header.toInspect(),
|
|
123
|
-
processedTxs: processedTxs.map(tx => tx.hash.toString()),
|
|
124
|
-
failedTxs: failedTxs.map(tx => tx.tx.txHash.toString()),
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
block,
|
|
129
|
-
publicProcessorDuration,
|
|
130
|
-
numTxs: processedTxs.length,
|
|
131
|
-
failedTxs,
|
|
132
|
-
usedTxs,
|
|
133
|
-
};
|
|
134
148
|
}
|
|
135
149
|
|
|
136
150
|
/** Completes the checkpoint and returns it. */
|
|
@@ -178,23 +192,31 @@ export class CheckpointBuilder implements ICheckpointBlockBuilder {
|
|
|
178
192
|
const blockEndOverhead = getNumBlockEndBlobFields(isFirstBlock);
|
|
179
193
|
const maxBlobFieldsForTxs = totalBlobCapacity - usedBlobFields - blockEndOverhead;
|
|
180
194
|
|
|
181
|
-
//
|
|
182
|
-
|
|
195
|
+
// When redistributeCheckpointBudget is enabled (default), compute a fair share of remaining budget
|
|
196
|
+
// across remaining blocks scaled by the multiplier, instead of letting one block consume it all.
|
|
197
|
+
const redistribute = this.config.redistributeCheckpointBudget !== false;
|
|
198
|
+
const remainingBlocks = Math.max(1, (this.config.maxBlocksPerCheckpoint ?? 1) - existingBlocks.length);
|
|
199
|
+
const multiplier = this.config.perBlockAllocationMultiplier ?? 1.2;
|
|
200
|
+
|
|
201
|
+
// Cap L2 gas by remaining checkpoint mana (with fair share when redistributing)
|
|
202
|
+
const fairShareL2 = redistribute ? Math.ceil((remainingMana / remainingBlocks) * multiplier) : Infinity;
|
|
203
|
+
const cappedL2Gas = Math.min(opts.maxBlockGas?.l2Gas ?? Infinity, fairShareL2, remainingMana);
|
|
183
204
|
|
|
184
|
-
// Cap DA gas by remaining checkpoint DA gas budget
|
|
185
|
-
const
|
|
205
|
+
// Cap DA gas by remaining checkpoint DA gas budget (with fair share when redistributing)
|
|
206
|
+
const fairShareDA = redistribute ? Math.ceil((remainingDAGas / remainingBlocks) * multiplier) : Infinity;
|
|
207
|
+
const cappedDAGas = Math.min(opts.maxBlockGas?.daGas ?? remainingDAGas, fairShareDA, remainingDAGas);
|
|
186
208
|
|
|
187
|
-
// Cap blob fields by remaining checkpoint blob capacity
|
|
188
|
-
const
|
|
189
|
-
|
|
209
|
+
// Cap blob fields by remaining checkpoint blob capacity (with fair share when redistributing)
|
|
210
|
+
const fairShareBlobs = redistribute ? Math.ceil((maxBlobFieldsForTxs / remainingBlocks) * multiplier) : Infinity;
|
|
211
|
+
const cappedBlobFields = Math.min(opts.maxBlobFields ?? Infinity, fairShareBlobs, maxBlobFieldsForTxs);
|
|
190
212
|
|
|
191
|
-
// Cap transaction count by remaining checkpoint tx budget
|
|
213
|
+
// Cap transaction count by remaining checkpoint tx budget (with fair share when redistributing)
|
|
192
214
|
let cappedMaxTransactions: number | undefined;
|
|
193
215
|
if (this.config.maxTxsPerCheckpoint !== undefined) {
|
|
194
216
|
const usedTxs = sum(existingBlocks.map(b => b.body.txEffects.length));
|
|
195
217
|
const remainingTxs = Math.max(0, this.config.maxTxsPerCheckpoint - usedTxs);
|
|
196
|
-
|
|
197
|
-
|
|
218
|
+
const fairShareTxs = redistribute ? Math.ceil((remainingTxs / remainingBlocks) * multiplier) : Infinity;
|
|
219
|
+
cappedMaxTransactions = Math.min(opts.maxTransactions ?? Infinity, fairShareTxs, remainingTxs);
|
|
198
220
|
} else {
|
|
199
221
|
cappedMaxTransactions = opts.maxTransactions;
|
|
200
222
|
}
|
|
@@ -177,7 +177,7 @@ export class ValidationService {
|
|
|
177
177
|
} else {
|
|
178
178
|
const error = result.reason;
|
|
179
179
|
if (error instanceof DutyAlreadySignedError || error instanceof SlashingProtectionError) {
|
|
180
|
-
this.log.
|
|
180
|
+
this.log.verbose(
|
|
181
181
|
`Attestation for slot ${proposal.slotNumber} by ${attestors[i]} already signed by another High-Availability node`,
|
|
182
182
|
);
|
|
183
183
|
// Continue with remaining attestors
|
|
@@ -240,7 +240,7 @@ export class HAKeyStore implements ExtendedValidatorKeyStore {
|
|
|
240
240
|
}
|
|
241
241
|
|
|
242
242
|
if (error instanceof SlashingProtectionError) {
|
|
243
|
-
this.log.
|
|
243
|
+
this.log.info(`Duty already signed by another node with different payload`, {
|
|
244
244
|
dutyType: context.dutyType,
|
|
245
245
|
slot: context.slot,
|
|
246
246
|
existingMessageHash: error.existingMessageHash,
|
package/src/validator.ts
CHANGED
|
@@ -380,7 +380,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
|
|
|
380
380
|
|
|
381
381
|
// Ignore proposals from ourselves (may happen in HA setups)
|
|
382
382
|
if (this.getValidatorAddresses().some(addr => addr.equals(proposer))) {
|
|
383
|
-
this.log.
|
|
383
|
+
this.log.debug(`Ignoring block proposal from self for slot ${slotNumber}`, {
|
|
384
384
|
proposer: proposer.toString(),
|
|
385
385
|
slotNumber,
|
|
386
386
|
});
|
|
@@ -416,9 +416,10 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
|
|
|
416
416
|
);
|
|
417
417
|
|
|
418
418
|
if (!validationResult.isValid) {
|
|
419
|
-
this.log.warn(`Block proposal validation failed: ${validationResult.reason}`, proposalInfo);
|
|
420
|
-
|
|
421
419
|
const reason = validationResult.reason || 'unknown';
|
|
420
|
+
|
|
421
|
+
this.log.warn(`Block proposal validation failed: ${reason}`, proposalInfo);
|
|
422
|
+
|
|
422
423
|
// Classify failure reason: bad proposal vs node issue
|
|
423
424
|
const badProposalReasons: BlockProposalValidationFailureReason[] = [
|
|
424
425
|
'invalid_proposal',
|
|
@@ -490,7 +491,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
|
|
|
490
491
|
|
|
491
492
|
// Ignore proposals from ourselves (may happen in HA setups)
|
|
492
493
|
if (this.getValidatorAddresses().some(addr => addr.equals(proposer))) {
|
|
493
|
-
this.log.
|
|
494
|
+
this.log.debug(`Ignoring block proposal from self for slot ${slotNumber}`, {
|
|
494
495
|
proposer: proposer.toString(),
|
|
495
496
|
slotNumber,
|
|
496
497
|
});
|