@aztec/validator-client 0.0.1-commit.f504929 → 0.0.1-commit.f81dbcf
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 +42 -0
- package/dest/block_proposal_handler.d.ts +4 -3
- package/dest/block_proposal_handler.d.ts.map +1 -1
- package/dest/block_proposal_handler.js +106 -30
- package/dest/checkpoint_builder.d.ts +9 -1
- package/dest/checkpoint_builder.d.ts.map +1 -1
- package/dest/checkpoint_builder.js +85 -27
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +21 -1
- package/dest/duties/validation_service.d.ts +1 -1
- package/dest/duties/validation_service.d.ts.map +1 -1
- package/dest/duties/validation_service.js +3 -9
- package/dest/factory.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 +23 -11
- package/package.json +19 -19
- package/src/block_proposal_handler.ts +128 -37
- package/src/checkpoint_builder.ts +107 -34
- package/src/config.ts +21 -1
- package/src/duties/validation_service.ts +3 -9
- package/src/factory.ts +1 -1
- package/src/key_store/ha_key_store.ts +1 -1
- package/src/validator.ts +22 -8
package/README.md
CHANGED
|
@@ -223,6 +223,48 @@ This is useful for monitoring network health without participating in consensus.
|
|
|
223
223
|
- `createCheckpointProposal(...)` → `CheckpointProposal`: Signs checkpoint proposal
|
|
224
224
|
- `attestToCheckpointProposal(proposal, attestors)` → `CheckpointAttestation[]`: Creates attestations for given addresses
|
|
225
225
|
|
|
226
|
+
## Block Building Limits
|
|
227
|
+
|
|
228
|
+
L1 enforces gas and blob capacity per checkpoint. The node enforces these during block building to avoid L1 rejection. Three dimensions are metered: L2 gas (mana), DA gas, and blob fields. DA gas maps to blob fields today (`daGas = blobFields * 32`) but both are tracked independently.
|
|
229
|
+
|
|
230
|
+
### Checkpoint limits
|
|
231
|
+
|
|
232
|
+
| Dimension | Source | Budget |
|
|
233
|
+
| --- | --- | --- |
|
|
234
|
+
| L2 gas (mana) | `rollup.getManaLimit()` | Fetched from L1 at startup |
|
|
235
|
+
| DA gas | `MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT` | 786,432 (6 blobs × 4096 fields × 32 gas/field) |
|
|
236
|
+
| Blob fields | `BLOBS_PER_CHECKPOINT × FIELDS_PER_BLOB` | 24,576 minus checkpoint/block-end overhead |
|
|
237
|
+
|
|
238
|
+
### Per-block budgets
|
|
239
|
+
|
|
240
|
+
Per-block budgets prevent one block from consuming the entire checkpoint budget.
|
|
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.
|
|
243
|
+
|
|
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
|
+
|
|
246
|
+
**Checkpoint-level capping**: `CheckpointBuilder.capLimitsByCheckpointBudgets()` always runs before tx processing, capping per-block limits by `checkpointBudget - sum(used by prior blocks)` for all three gas dimensions and for transaction count (when `SEQ_MAX_TX_PER_CHECKPOINT` is set). This applies to both proposer and validator paths.
|
|
247
|
+
|
|
248
|
+
### Per-transaction enforcement
|
|
249
|
+
|
|
250
|
+
**Mempool entry** (`GasLimitsValidator`): L2 gas must be ≤ `MAX_PROCESSABLE_L2_GAS` (6,540,000) and ≥ fixed minimums.
|
|
251
|
+
|
|
252
|
+
**Block building** (`PublicProcessor.process`): Before processing, txs are skipped if their estimated blob fields or gas limits would exceed the block budget. After processing, actual values are checked and the tx is reverted if limits are exceeded.
|
|
253
|
+
|
|
254
|
+
### Gas limit configuration
|
|
255
|
+
|
|
256
|
+
| Variable | Default | Description |
|
|
257
|
+
| --- | --- | --- |
|
|
258
|
+
| `SEQ_MAX_L2_BLOCK_GAS` | *auto* | Per-block L2 gas. Auto-derived from `rollupManaLimit / maxBlocks * multiplier`. |
|
|
259
|
+
| `SEQ_MAX_DA_BLOCK_GAS` | *auto* | Per-block DA gas. Auto-derived from checkpoint DA limit / maxBlocks * multiplier. |
|
|
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
|
+
| `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. |
|
|
263
|
+
| `VALIDATOR_MAX_L2_BLOCK_GAS` | *none* | Per-block L2 gas limit for validation. Proposals exceeding this are rejected. |
|
|
264
|
+
| `VALIDATOR_MAX_DA_BLOCK_GAS` | *none* | Per-block DA gas limit for validation. Proposals exceeding this are rejected. |
|
|
265
|
+
| `VALIDATOR_MAX_TX_PER_BLOCK` | *none* | Per-block tx count limit for validation. Proposals exceeding this are rejected. |
|
|
266
|
+
| `VALIDATOR_MAX_TX_PER_CHECKPOINT` | *none* | Per-checkpoint tx count limit for validation. Proposals exceeding this are rejected. |
|
|
267
|
+
|
|
226
268
|
## Testing Patterns
|
|
227
269
|
|
|
228
270
|
### Common Mocks
|
|
@@ -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[];
|
|
@@ -45,7 +45,7 @@ export declare class BlockProposalHandler {
|
|
|
45
45
|
private log;
|
|
46
46
|
readonly tracer: Tracer;
|
|
47
47
|
constructor(checkpointsBuilder: FullNodeCheckpointsBuilder, worldState: WorldStateSynchronizer, blockSource: L2BlockSource & L2BlockSink, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: ITxProvider, blockProposalValidator: BlockProposalValidator, epochCache: EpochCache, config: ValidatorClientFullConfig, metrics?: ValidatorMetrics | undefined, dateProvider?: DateProvider, telemetry?: TelemetryClient, log?: import("@aztec/foundation/log").Logger);
|
|
48
|
-
|
|
48
|
+
register(p2pClient: P2P, shouldReexecute: boolean): BlockProposalHandler;
|
|
49
49
|
handleBlockProposal(proposal: BlockProposal, proposalSender: PeerId, shouldReexecute: boolean): Promise<BlockProposalValidationResult>;
|
|
50
50
|
private getParentBlock;
|
|
51
51
|
private computeCheckpointNumber;
|
|
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tfcHJvcG9zYWxfaGFuZGxlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Jsb2NrX3Byb3Bvc2FsX2hhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBYyxNQUFNLGlDQUFpQyxDQUFDO0FBRTVGLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUlwRCxPQUFPLEVBQUUsWUFBWSxFQUFTLE1BQU0seUJBQXlCLENBQUM7QUFDOUQsT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLFlBQVksQ0FBQztBQUM5QyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNuRSxPQUFPLEtBQUssRUFBYSxPQUFPLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRzFGLE9BQU8sS0FBSyxFQUFFLFdBQVcsRUFBRSx5QkFBeUIsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3RILE9BQU8sRUFBRSxLQUFLLG1CQUFtQixFQUFtQyxNQUFNLHlCQUF5QixDQUFDO0FBQ3BHLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXZELE9BQU8sS0FBSyxFQUE2QixRQUFRLEVBQUUsRUFBRSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFRaEYsT0FBTyxFQUFFLEtBQUssZUFBZSxFQUFFLEtBQUssTUFBTSxFQUFzQixNQUFNLHlCQUF5QixDQUFDO0FBRWhHLE9BQU8sS0FBSyxFQUFFLDBCQUEwQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDMUUsT0FBTyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFckQsTUFBTSxNQUFN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
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"block_proposal_handler.d.ts","sourceRoot":"","sources":["../src/block_proposal_handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -65,14 +65,17 @@ function _ts_dispose_resources(env) {
|
|
|
65
65
|
}
|
|
66
66
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
67
67
|
import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
68
|
+
import { pick } from '@aztec/foundation/collection';
|
|
68
69
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
69
70
|
import { TimeoutError } from '@aztec/foundation/error';
|
|
70
71
|
import { createLogger } from '@aztec/foundation/log';
|
|
71
72
|
import { retryUntil } from '@aztec/foundation/retry';
|
|
72
73
|
import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
73
74
|
import { getEpochAtSlot, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
75
|
+
import { Gas } from '@aztec/stdlib/gas';
|
|
74
76
|
import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
|
|
75
|
-
import {
|
|
77
|
+
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
78
|
+
import { ReExFailedTxsError, ReExInitialStateMismatchError, ReExStateMismatchError, ReExTimeoutError, TransactionsNotAvailableError } from '@aztec/stdlib/validators';
|
|
76
79
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
77
80
|
export class BlockProposalHandler {
|
|
78
81
|
checkpointsBuilder;
|
|
@@ -104,23 +107,27 @@ export class BlockProposalHandler {
|
|
|
104
107
|
}
|
|
105
108
|
this.tracer = telemetry.getTracer('BlockProposalHandler');
|
|
106
109
|
}
|
|
107
|
-
|
|
108
|
-
// Non-validator handler that re-executes for monitoring but does not attest.
|
|
110
|
+
register(p2pClient, shouldReexecute) {
|
|
111
|
+
// Non-validator handler that processes or re-executes for monitoring but does not attest.
|
|
109
112
|
// Returns boolean indicating whether the proposal was valid.
|
|
110
113
|
const handler = async (proposal, proposalSender)=>{
|
|
111
114
|
try {
|
|
112
|
-
const
|
|
115
|
+
const { slotNumber, blockNumber } = proposal;
|
|
116
|
+
const result = await this.handleBlockProposal(proposal, proposalSender, shouldReexecute);
|
|
113
117
|
if (result.isValid) {
|
|
114
|
-
this.log.info(`Non-validator
|
|
118
|
+
this.log.info(`Non-validator block proposal ${blockNumber} at slot ${slotNumber} handled`, {
|
|
115
119
|
blockNumber: result.blockNumber,
|
|
120
|
+
slotNumber,
|
|
116
121
|
reexecutionTimeMs: result.reexecutionResult?.reexecutionTimeMs,
|
|
117
122
|
totalManaUsed: result.reexecutionResult?.totalManaUsed,
|
|
118
|
-
numTxs: result.reexecutionResult?.block?.body?.txEffects?.length ?? 0
|
|
123
|
+
numTxs: result.reexecutionResult?.block?.body?.txEffects?.length ?? 0,
|
|
124
|
+
reexecuted: shouldReexecute
|
|
119
125
|
});
|
|
120
126
|
return true;
|
|
121
127
|
} else {
|
|
122
|
-
this.log.warn(`Non-validator
|
|
128
|
+
this.log.warn(`Non-validator block proposal ${blockNumber} at slot ${slotNumber} failed processing with ${result.reason}`, {
|
|
123
129
|
blockNumber: result.blockNumber,
|
|
130
|
+
slotNumber,
|
|
124
131
|
reason: result.reason
|
|
125
132
|
});
|
|
126
133
|
return false;
|
|
@@ -147,7 +154,9 @@ export class BlockProposalHandler {
|
|
|
147
154
|
}
|
|
148
155
|
const proposalInfo = {
|
|
149
156
|
...proposal.toBlockInfo(),
|
|
150
|
-
proposer: proposer.toString()
|
|
157
|
+
proposer: proposer.toString(),
|
|
158
|
+
blockNumber: undefined,
|
|
159
|
+
checkpointNumber: undefined
|
|
151
160
|
};
|
|
152
161
|
this.log.info(`Processing proposal for slot ${slotNumber}`, {
|
|
153
162
|
...proposalInfo,
|
|
@@ -163,7 +172,22 @@ export class BlockProposalHandler {
|
|
|
163
172
|
reason: 'invalid_proposal'
|
|
164
173
|
};
|
|
165
174
|
}
|
|
166
|
-
//
|
|
175
|
+
// Ensure the block source is synced before checking for existing blocks,
|
|
176
|
+
// since a pending checkpoint prune may remove blocks we'd otherwise find.
|
|
177
|
+
// This affects mostly the block_number_already_exists check, since a pending
|
|
178
|
+
// checkpoint prune could remove a block that would conflict with this proposal.
|
|
179
|
+
// 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.
|
|
167
191
|
const parentBlock = await this.getParentBlock(proposal);
|
|
168
192
|
if (parentBlock === undefined) {
|
|
169
193
|
this.log.warn(`Parent block for proposal not found, skipping processing`, proposalInfo);
|
|
@@ -186,6 +210,7 @@ export class BlockProposalHandler {
|
|
|
186
210
|
}
|
|
187
211
|
// Compute the block number based on the parent block
|
|
188
212
|
const blockNumber = parentBlock === 'genesis' ? BlockNumber(INITIAL_L2_BLOCK_NUM) : BlockNumber(parentBlock.header.getBlockNumber() + 1);
|
|
213
|
+
proposalInfo.blockNumber = blockNumber;
|
|
189
214
|
// Check that this block number does not exist already
|
|
190
215
|
const existingBlock = await this.blockSource.getBlockHeader(blockNumber);
|
|
191
216
|
if (existingBlock) {
|
|
@@ -202,6 +227,14 @@ export class BlockProposalHandler {
|
|
|
202
227
|
pinnedPeer: proposalSender,
|
|
203
228
|
deadline: this.getReexecutionDeadline(slotNumber, config)
|
|
204
229
|
});
|
|
230
|
+
// If reexecution is disabled, bail. We were just interested in triggering tx collection.
|
|
231
|
+
if (!shouldReexecute) {
|
|
232
|
+
this.log.info(`Received valid block ${blockNumber} proposal at index ${proposal.indexWithinCheckpoint} on slot ${slotNumber}`, proposalInfo);
|
|
233
|
+
return {
|
|
234
|
+
isValid: true,
|
|
235
|
+
blockNumber
|
|
236
|
+
};
|
|
237
|
+
}
|
|
205
238
|
// Compute the checkpoint number for this block and validate checkpoint consistency
|
|
206
239
|
const checkpointResult = this.computeCheckpointNumber(proposal, parentBlock, proposalInfo);
|
|
207
240
|
if (checkpointResult.reason) {
|
|
@@ -212,6 +245,7 @@ export class BlockProposalHandler {
|
|
|
212
245
|
};
|
|
213
246
|
}
|
|
214
247
|
const checkpointNumber = checkpointResult.checkpointNumber;
|
|
248
|
+
proposalInfo.checkpointNumber = checkpointNumber;
|
|
215
249
|
// Check that I have the same set of l1ToL2Messages as the proposal
|
|
216
250
|
const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber);
|
|
217
251
|
const computedInHash = computeInHashFromL1ToL2Messages(l1ToL2Messages);
|
|
@@ -240,31 +274,32 @@ export class BlockProposalHandler {
|
|
|
240
274
|
reason: 'txs_not_available'
|
|
241
275
|
};
|
|
242
276
|
}
|
|
277
|
+
// Collect the out hashes of all the checkpoints before this one in the same epoch
|
|
278
|
+
const epoch = getEpochAtSlot(slotNumber, this.epochCache.getL1Constants());
|
|
279
|
+
const previousCheckpointOutHashes = (await this.blockSource.getCheckpointsDataForEpoch(epoch)).filter((c)=>c.checkpointNumber < checkpointNumber).map((c)=>c.checkpointOutHash);
|
|
243
280
|
// Try re-executing the transactions in the proposal if needed
|
|
244
281
|
let reexecutionResult;
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
blockNumber,
|
|
258
|
-
reason,
|
|
259
|
-
reexecutionResult
|
|
260
|
-
};
|
|
261
|
-
}
|
|
282
|
+
try {
|
|
283
|
+
this.log.verbose(`Re-executing transactions in the proposal`, proposalInfo);
|
|
284
|
+
reexecutionResult = await this.reexecuteTransactions(proposal, blockNumber, checkpointNumber, txs, l1ToL2Messages, previousCheckpointOutHashes);
|
|
285
|
+
} catch (error) {
|
|
286
|
+
this.log.error(`Error reexecuting txs while processing block proposal`, error, proposalInfo);
|
|
287
|
+
const reason = this.getReexecuteFailureReason(error);
|
|
288
|
+
return {
|
|
289
|
+
isValid: false,
|
|
290
|
+
blockNumber,
|
|
291
|
+
reason,
|
|
292
|
+
reexecutionResult
|
|
293
|
+
};
|
|
262
294
|
}
|
|
263
295
|
// If we succeeded, push this block into the archiver (unless disabled)
|
|
264
296
|
if (reexecutionResult?.block && this.config.skipPushProposedBlocksToArchiver === false) {
|
|
265
297
|
await this.blockSource.addBlock(reexecutionResult?.block);
|
|
266
298
|
}
|
|
267
|
-
this.log.info(`Successfully
|
|
299
|
+
this.log.info(`Successfully re-executed block ${blockNumber} proposal at index ${proposal.indexWithinCheckpoint} on slot ${slotNumber}`, {
|
|
300
|
+
...proposalInfo,
|
|
301
|
+
...pick(reexecutionResult, 'reexecutionTimeMs', 'totalManaUsed')
|
|
302
|
+
});
|
|
268
303
|
return {
|
|
269
304
|
isValid: true,
|
|
270
305
|
blockNumber,
|
|
@@ -429,8 +464,39 @@ export class BlockProposalHandler {
|
|
|
429
464
|
const nextSlotTimestampSeconds = Number(getTimestampForSlot(SlotNumber(slot + 1), config));
|
|
430
465
|
return new Date(nextSlotTimestampSeconds * 1000);
|
|
431
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
|
+
}
|
|
432
494
|
getReexecuteFailureReason(err) {
|
|
433
|
-
if (err instanceof
|
|
495
|
+
if (err instanceof TransactionsNotAvailableError) {
|
|
496
|
+
return 'txs_not_available';
|
|
497
|
+
} else if (err instanceof ReExInitialStateMismatchError) {
|
|
498
|
+
return 'initial_state_mismatch';
|
|
499
|
+
} else if (err instanceof ReExStateMismatchError) {
|
|
434
500
|
return 'state_mismatch';
|
|
435
501
|
} else if (err instanceof ReExFailedTxsError) {
|
|
436
502
|
return 'failed_txs';
|
|
@@ -464,6 +530,12 @@ export class BlockProposalHandler {
|
|
|
464
530
|
const parentBlockNumber = BlockNumber(blockNumber - 1);
|
|
465
531
|
await this.worldState.syncImmediate(parentBlockNumber);
|
|
466
532
|
const fork = _ts_add_disposable_resource(env, await this.worldState.fork(parentBlockNumber), true);
|
|
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
|
+
}
|
|
467
539
|
// Build checkpoint constants from proposal (excludes blockNumber which is per-block)
|
|
468
540
|
const constants = {
|
|
469
541
|
chainId: new Fr(config.l1ChainId),
|
|
@@ -478,16 +550,20 @@ export class BlockProposalHandler {
|
|
|
478
550
|
const checkpointBuilder = await this.checkpointsBuilder.openCheckpoint(checkpointNumber, constants, 0n, l1ToL2Messages, previousCheckpointOutHashes, fork, priorBlocks, this.log.getBindings());
|
|
479
551
|
// Build the new block
|
|
480
552
|
const deadline = this.getReexecutionDeadline(slot, config);
|
|
553
|
+
const maxBlockGas = this.config.validateMaxL2BlockGas !== undefined || this.config.validateMaxDABlockGas !== undefined ? new Gas(this.config.validateMaxDABlockGas ?? Infinity, this.config.validateMaxL2BlockGas ?? Infinity) : undefined;
|
|
481
554
|
const result = await checkpointBuilder.buildBlock(txs, blockNumber, blockHeader.globalVariables.timestamp, {
|
|
482
555
|
deadline,
|
|
483
|
-
expectedEndState: blockHeader.state
|
|
556
|
+
expectedEndState: blockHeader.state,
|
|
557
|
+
maxTransactions: this.config.validateMaxTxsPerBlock,
|
|
558
|
+
maxBlockGas
|
|
484
559
|
});
|
|
485
560
|
const { block, failedTxs } = result;
|
|
486
561
|
const numFailedTxs = failedTxs.length;
|
|
487
|
-
this.log.verbose(`
|
|
562
|
+
this.log.verbose(`Block proposal ${blockNumber} at slot ${slot} transaction re-execution complete`, {
|
|
488
563
|
numFailedTxs,
|
|
489
564
|
numProposalTxs: txHashes.length,
|
|
490
565
|
numProcessedTxs: block.body.txEffects.length,
|
|
566
|
+
blockNumber,
|
|
491
567
|
slot
|
|
492
568
|
});
|
|
493
569
|
if (numFailedTxs > 0) {
|
|
@@ -30,14 +30,22 @@ export declare class CheckpointBuilder implements ICheckpointBlockBuilder {
|
|
|
30
30
|
getConstantData(): CheckpointGlobalVariables;
|
|
31
31
|
/**
|
|
32
32
|
* Builds a single block within this checkpoint.
|
|
33
|
+
* Automatically caps gas and blob field limits based on checkpoint-level budgets and prior blocks.
|
|
33
34
|
*/
|
|
34
35
|
buildBlock(pendingTxs: Iterable<Tx> | AsyncIterable<Tx>, blockNumber: BlockNumber, timestamp: bigint, opts?: PublicProcessorLimits & {
|
|
35
36
|
expectedEndState?: StateReference;
|
|
37
|
+
minValidTxs?: number;
|
|
36
38
|
}): Promise<BuildBlockInCheckpointResult>;
|
|
37
39
|
/** Completes the checkpoint and returns it. */
|
|
38
40
|
completeCheckpoint(): Promise<Checkpoint>;
|
|
39
41
|
/** Gets the checkpoint currently in progress. */
|
|
40
42
|
getCheckpoint(): Promise<Checkpoint>;
|
|
43
|
+
/**
|
|
44
|
+
* Caps per-block gas and blob field limits by remaining checkpoint-level budgets.
|
|
45
|
+
* Computes remaining L2 gas (mana), DA gas, and blob fields from blocks already added to the checkpoint,
|
|
46
|
+
* then returns opts with maxBlockGas and maxBlobFields capped accordingly.
|
|
47
|
+
*/
|
|
48
|
+
protected capLimitsByCheckpointBudgets(opts: PublicProcessorLimits): Pick<PublicProcessorLimits, 'maxBlockGas' | 'maxBlobFields' | 'maxTransactions'>;
|
|
41
49
|
protected makeBlockBuilderDeps(globalVariables: GlobalVariables, fork: MerkleTreeWriteOperations): Promise<{
|
|
42
50
|
processor: PublicProcessor;
|
|
43
51
|
validator: import("@aztec/stdlib/interfaces/server").PublicProcessorValidator;
|
|
@@ -66,4 +74,4 @@ export declare class FullNodeCheckpointsBuilder implements ICheckpointsBuilder {
|
|
|
66
74
|
/** Returns a fork of the world state at the given block number. */
|
|
67
75
|
getFork(blockNumber: BlockNumber): Promise<MerkleTreeWriteOperations>;
|
|
68
76
|
}
|
|
69
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
77
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludF9idWlsZGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY2hlY2twb2ludF9idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVoRixPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDcEQsT0FBTyxFQUFlLEtBQUssY0FBYyxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBRXZGLE9BQU8sRUFBRSxZQUFZLEVBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUVoRSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMxRSxPQUFPLEVBR0wsZUFBZSxFQUVoQixNQUFNLHlCQUF5QixDQUFDO0FBQ2pDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdEQsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRSxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRXJFLE9BQU8sRUFDTCxLQUFLLDRCQUE0QixFQUNqQyxLQUFLLDBCQUEwQixFQUUvQixLQUFLLHVCQUF1QixFQUM1QixLQUFLLG1CQUFtQixFQUV4QixLQUFLLHlCQUF5QixFQUM5QixLQUFLLHFCQUFxQixFQUMxQixLQUFLLHNCQUFzQixFQUM1QixNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxLQUFLLGFBQWEsRUFBcUIsTUFBTSxvQkFBb0IsQ0FBQztBQUUzRSxPQUFPLEVBQUUsS0FBSyx5QkFBeUIsRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLEVBQUUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxLQUFLLGVBQWUsRUFBc0IsTUFBTSx5QkFBeUIsQ0FBQztBQUluRixZQUFZLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVwRjs7O0dBR0c7QUFDSCxxQkFBYSxpQkFBa0IsWUFBVyx1QkFBdUI7SUFJN0QsT0FBTyxDQUFDLGlCQUFpQjtJQUN6QixPQUFPLENBQUMsSUFBSTtJQUNaLE9BQU8sQ0FBQyxNQUFNO0lBQ2QsT0FBTyxDQUFDLGtCQUFrQjtJQUMxQixPQUFPLENBQUMsWUFBWTtJQUNwQixPQUFPLENBQUMsZUFBZTtJQUV2QixPQUFPLENBQUMsYUFBYTtJQVZ2QixPQUFPLENBQUMsR0FBRyxDQUFTO0lBRXBCLFlBQ1UsaUJBQWlCLEVBQUUsNEJBQTRCLEVBQy9DLElBQUksRUFBRSx5QkFBeUIsRUFDL0IsTUFBTSxFQUFFLDBCQUEwQixFQUNsQyxrQkFBa0IsRUFBRSxrQkFBa0IsRUFDdEMsWUFBWSxFQUFFLFlBQVksRUFDMUIsZUFBZSxFQUFFLGVBQWUsRUFDeEMsUUFBUSxDQUFDLEVBQUUsY0FBYyxFQUNqQixhQUFhLEdBQUUsYUFBdUMsRUFNL0Q7SUFFRCxlQUFlLElBQUkseUJBQXlCLENBRTNDO0lBRUQ7OztPQUdHO0lBQ0csVUFBVSxDQUNkLFVBQVUsRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDLEdBQUcsYUFBYSxDQUFDLEVBQUUsQ0FBQyxFQUM1QyxXQUFXLEVBQUUsV0FBVyxFQUN4QixTQUFTLEVBQUUsTUFBTSxFQUNqQixJQUFJLEdBQUUscUJBQXFCLEdBQUc7UUFBRSxnQkFBZ0IsQ0FBQyxFQUFFLGNBQWMsQ0FBQztRQUFDLFdBQVcsQ0FBQyxFQUFFLE1BQU0sQ0FBQTtLQUFPLEdBQzdGLE9BQU8sQ0FBQyw0QkFBNEIsQ0FBQyxDQXNFdkM7SUFFRCwrQ0FBK0M7SUFDekMsa0JBQWtCLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQVU5QztJQUVELGlEQUFpRDtJQUNqRCxhQUFhLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUVuQztJQUVEOzs7O09BSUc7SUFDSCxTQUFTLENBQUMsNEJBQTRCLENBQ3BDLElBQUksRUFBRSxxQkFBcUIsR0FDMUIsSUFBSSxDQUFDLHFCQUFxQixFQUFFLGFBQWEsR0FBRyxlQUFlLEdBQUcsaUJBQWlCLENBQUMsQ0E4Q2xGO0lBRUQsVUFBZ0Isb0JBQW9CLENBQUMsZUFBZSxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUseUJBQXlCOzs7T0E0Q3JHO0NBQ0Y7QUFFRCxnREFBZ0Q7QUFDaEQscUJBQWEsMEJBQTJCLFlBQVcsbUJBQW1CO0lBSWxFLE9BQU8sQ0FBQyxNQUFNO0lBQ2QsT0FBTyxDQUFDLFVBQVU7SUFDbEIsT0FBTyxDQUFDLGtCQUFrQjtJQUMxQixPQUFPLENBQUMsWUFBWTtJQUNwQixPQUFPLENBQUMsZUFBZTtJQUN2QixPQUFPLENBQUMsYUFBYTtJQVJ2QixPQUFPLENBQUMsR0FBRyxDQUFTO0lBRXBCLFlBQ1UsTUFBTSxFQUFFLDBCQUEwQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxlQUFlLEdBQUcsY0FBYyxDQUFDLEVBQzlGLFVBQVUsRUFBRSxzQkFBc0IsRUFDbEMsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQ3RDLFlBQVksRUFBRSxZQUFZLEVBQzFCLGVBQWUsR0FBRSxlQUFzQyxFQUN2RCxhQUFhLEdBQUUsYUFBdUMsRUFHL0Q7SUFFTSxTQUFTLElBQUksMEJBQTBCLENBRTdDO0lBRU0sWUFBWSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsMEJBQTBCLENBQUMsUUFFOUQ7SUFFRDs7T0FFRztJQUNHLGVBQWUsQ0FDbkIsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQ2xDLFNBQVMsRUFBRSx5QkFBeUIsRUFDcEMscUJBQXFCLEVBQUUsTUFBTSxFQUM3QixjQUFjLEVBQUUsRUFBRSxFQUFFLEVBQ3BCLDJCQUEyQixFQUFFLEVBQUUsRUFBRSxFQUNqQyxJQUFJLEVBQUUseUJBQXlCLEVBQy9CLFFBQVEsQ0FBQyxFQUFFLGNBQWMsR0FDeEIsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBaUM1QjtJQUVEOztPQUVHO0lBQ0csY0FBYyxDQUNsQixnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFDbEMsU0FBUyxFQUFFLHlCQUF5QixFQUNwQyxxQkFBcUIsRUFBRSxNQUFNLEVBQzdCLGNBQWMsRUFBRSxFQUFFLEVBQUUsRUFDcEIsMkJBQTJCLEVBQUUsRUFBRSxFQUFFLEVBQ2pDLElBQUksRUFBRSx5QkFBeUIsRUFDL0IsY0FBYyxHQUFFLE9BQU8sRUFBTyxFQUM5QixRQUFRLENBQUMsRUFBRSxjQUFjLEdBQ3hCLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQStDNUI7SUFFRCxtRUFBbUU7SUFDbkUsT0FBTyxDQUFDLFdBQVcsRUFBRSxXQUFXLEdBQUcsT0FBTyxDQUFDLHlCQUF5QixDQUFDLENBRXBFO0NBQ0YifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpoint_builder.d.ts","sourceRoot":"","sources":["../src/checkpoint_builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"checkpoint_builder.d.ts","sourceRoot":"","sources":["../src/checkpoint_builder.ts"],"names":[],"mappings":"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,EAExB,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,oBAAoB,CAAC;AAE3E,OAAO,EAAE,KAAK,yBAAyB,EAAE,eAAe,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACvG,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAInF,YAAY,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAEpF;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,uBAAuB;IAI7D,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,eAAe;IAEvB,OAAO,CAAC,aAAa;IAVvB,OAAO,CAAC,GAAG,CAAS;IAEpB,YACU,iBAAiB,EAAE,4BAA4B,EAC/C,IAAI,EAAE,yBAAyB,EAC/B,MAAM,EAAE,0BAA0B,EAClC,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,eAAe,EACxC,QAAQ,CAAC,EAAE,cAAc,EACjB,aAAa,GAAE,aAAuC,EAM/D;IAED,eAAe,IAAI,yBAAyB,CAE3C;IAED;;;OAGG;IACG,UAAU,CACd,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC,EAC5C,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,qBAAqB,GAAG;QAAE,gBAAgB,CAAC,EAAE,cAAc,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO,GAC7F,OAAO,CAAC,4BAA4B,CAAC,CAsEvC;IAED,+CAA+C;IACzC,kBAAkB,IAAI,OAAO,CAAC,UAAU,CAAC,CAU9C;IAED,iDAAiD;IACjD,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAEnC;IAED;;;;OAIG;IACH,SAAS,CAAC,4BAA4B,CACpC,IAAI,EAAE,qBAAqB,GAC1B,IAAI,CAAC,qBAAqB,EAAE,aAAa,GAAG,eAAe,GAAG,iBAAiB,CAAC,CA8ClF;IAED,UAAgB,oBAAoB,CAAC,eAAe,EAAE,eAAe,EAAE,IAAI,EAAE,yBAAyB;;;OA4CrG;CACF;AAED,gDAAgD;AAChD,qBAAa,0BAA2B,YAAW,mBAAmB;IAIlE,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,aAAa;IARvB,OAAO,CAAC,GAAG,CAAS;IAEpB,YACU,MAAM,EAAE,0BAA0B,GAAG,IAAI,CAAC,iBAAiB,EAAE,eAAe,GAAG,cAAc,CAAC,EAC9F,UAAU,EAAE,sBAAsB,EAClC,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,YAAY,EAC1B,eAAe,GAAE,eAAsC,EACvD,aAAa,GAAE,aAAuC,EAG/D;IAEM,SAAS,IAAI,0BAA0B,CAE7C;IAEM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,0BAA0B,CAAC,QAE9D;IAED;;OAEG;IACG,eAAe,CACnB,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,yBAAyB,EACpC,qBAAqB,EAAE,MAAM,EAC7B,cAAc,EAAE,EAAE,EAAE,EACpB,2BAA2B,EAAE,EAAE,EAAE,EACjC,IAAI,EAAE,yBAAyB,EAC/B,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAiC5B;IAED;;OAEG;IACG,cAAc,CAClB,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,yBAAyB,EACpC,qBAAqB,EAAE,MAAM,EAC7B,cAAc,EAAE,EAAE,EAAE,EACpB,2BAA2B,EAAE,EAAE,EAAE,EACjC,IAAI,EAAE,yBAAyB,EAC/B,cAAc,GAAE,OAAO,EAAO,EAC9B,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,iBAAiB,CAAC,CA+C5B;IAED,mEAAmE;IACnE,OAAO,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAEpE;CACF"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NUM_CHECKPOINT_END_MARKER_FIELDS, getNumBlockEndBlobFields } from '@aztec/blob-lib/encoding';
|
|
2
|
+
import { BLOBS_PER_CHECKPOINT, FIELDS_PER_BLOB, MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT } from '@aztec/constants';
|
|
3
|
+
import { merge, pick, sum } from '@aztec/foundation/collection';
|
|
2
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
5
|
import { bufferToHex } from '@aztec/foundation/string';
|
|
4
6
|
import { elapsed } from '@aztec/foundation/timer';
|
|
@@ -6,11 +8,12 @@ import { createTxValidatorForBlockBuilding, getDefaultAllowedSetupFunctions } fr
|
|
|
6
8
|
import { LightweightCheckpointBuilder } from '@aztec/prover-client/light';
|
|
7
9
|
import { GuardedMerkleTreeOperations, PublicContractsDB, PublicProcessor, createPublicTxSimulatorForBlockBuilding } from '@aztec/simulator/server';
|
|
8
10
|
import { Gas } from '@aztec/stdlib/gas';
|
|
9
|
-
import { FullNodeBlockBuilderConfigKeys,
|
|
11
|
+
import { FullNodeBlockBuilderConfigKeys, InsufficientValidTxsError } from '@aztec/stdlib/interfaces/server';
|
|
10
12
|
import { NullDebugLogStore } from '@aztec/stdlib/logs';
|
|
11
13
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
12
14
|
import { GlobalVariables } from '@aztec/stdlib/tx';
|
|
13
15
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
16
|
+
import { ForkCheckpoint } from '@aztec/world-state';
|
|
14
17
|
/**
|
|
15
18
|
* Builder for a single checkpoint. Handles building blocks within the checkpoint
|
|
16
19
|
* and completing it.
|
|
@@ -41,6 +44,7 @@ import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
|
41
44
|
}
|
|
42
45
|
/**
|
|
43
46
|
* Builds a single block within this checkpoint.
|
|
47
|
+
* Automatically caps gas and blob field limits based on checkpoint-level budgets and prior blocks.
|
|
44
48
|
*/ async buildBlock(pendingTxs, blockNumber, timestamp, opts = {}) {
|
|
45
49
|
const slot = this.checkpointBuilder.constants.slotNumber;
|
|
46
50
|
this.log.verbose(`Building block ${blockNumber} for slot ${slot} within checkpoint`, {
|
|
@@ -61,32 +65,45 @@ import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
|
61
65
|
gasFees: constants.gasFees
|
|
62
66
|
});
|
|
63
67
|
const { processor, validator } = await this.makeBlockBuilderDeps(globalVariables, this.fork);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
throw new NoValidTxsError(failedTxs);
|
|
69
|
-
}
|
|
70
|
-
// Add block to checkpoint
|
|
71
|
-
const { block } = await this.checkpointBuilder.addBlock(globalVariables, processedTxs, {
|
|
72
|
-
expectedEndState: opts.expectedEndState
|
|
73
|
-
});
|
|
74
|
-
// How much public gas was processed
|
|
75
|
-
const publicGas = processedTxs.reduce((acc, tx)=>acc.add(tx.gasUsed.publicGas), Gas.empty());
|
|
76
|
-
this.log.debug('Built block within checkpoint', {
|
|
77
|
-
header: block.header.toInspect(),
|
|
78
|
-
processedTxs: processedTxs.map((tx)=>tx.hash.toString()),
|
|
79
|
-
failedTxs: failedTxs.map((tx)=>tx.tx.txHash.toString())
|
|
80
|
-
});
|
|
81
|
-
return {
|
|
82
|
-
block,
|
|
83
|
-
publicGas,
|
|
84
|
-
publicProcessorDuration,
|
|
85
|
-
numTxs: processedTxs.length,
|
|
86
|
-
failedTxs,
|
|
87
|
-
usedTxs,
|
|
88
|
-
usedTxBlobFields
|
|
68
|
+
// Cap gas limits amd available blob fields by remaining checkpoint-level budgets
|
|
69
|
+
const cappedOpts = {
|
|
70
|
+
...opts,
|
|
71
|
+
...this.capLimitsByCheckpointBudgets(opts)
|
|
89
72
|
};
|
|
73
|
+
// We execute all merkle tree operations on a world state fork checkpoint
|
|
74
|
+
// This enables us to discard all modifications in the event that we fail to successfully process sufficient transactions
|
|
75
|
+
const forkCheckpoint = await ForkCheckpoint.new(this.fork);
|
|
76
|
+
try {
|
|
77
|
+
const [publicProcessorDuration, [processedTxs, failedTxs, usedTxs]] = await elapsed(()=>processor.process(pendingTxs, cappedOpts, validator));
|
|
78
|
+
// Throw before updating state if we don't have enough valid txs
|
|
79
|
+
const minValidTxs = opts.minValidTxs ?? 0;
|
|
80
|
+
if (processedTxs.length < minValidTxs) {
|
|
81
|
+
throw new InsufficientValidTxsError(processedTxs.length, minValidTxs, failedTxs);
|
|
82
|
+
}
|
|
83
|
+
// Commit the fork checkpoint
|
|
84
|
+
await forkCheckpoint.commit();
|
|
85
|
+
// Add block to checkpoint
|
|
86
|
+
const block = await this.checkpointBuilder.addBlock(globalVariables, processedTxs, {
|
|
87
|
+
expectedEndState: opts.expectedEndState
|
|
88
|
+
});
|
|
89
|
+
this.log.debug('Built block within checkpoint', {
|
|
90
|
+
header: block.header.toInspect(),
|
|
91
|
+
processedTxs: processedTxs.map((tx)=>tx.hash.toString()),
|
|
92
|
+
failedTxs: failedTxs.map((tx)=>tx.tx.txHash.toString())
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
block,
|
|
96
|
+
publicProcessorDuration,
|
|
97
|
+
numTxs: processedTxs.length,
|
|
98
|
+
failedTxs,
|
|
99
|
+
usedTxs
|
|
100
|
+
};
|
|
101
|
+
} catch (err) {
|
|
102
|
+
// If we reached the point of committing the checkpoint, this does nothing
|
|
103
|
+
// Otherwise it reverts any changes made to the fork for this failed block
|
|
104
|
+
await forkCheckpoint.revert();
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
90
107
|
}
|
|
91
108
|
/** Completes the checkpoint and returns it. */ async completeCheckpoint() {
|
|
92
109
|
const checkpoint = await this.checkpointBuilder.completeCheckpoint();
|
|
@@ -100,6 +117,47 @@ import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
|
100
117
|
/** Gets the checkpoint currently in progress. */ getCheckpoint() {
|
|
101
118
|
return this.checkpointBuilder.clone().completeCheckpoint();
|
|
102
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Caps per-block gas and blob field limits by remaining checkpoint-level budgets.
|
|
122
|
+
* Computes remaining L2 gas (mana), DA gas, and blob fields from blocks already added to the checkpoint,
|
|
123
|
+
* then returns opts with maxBlockGas and maxBlobFields capped accordingly.
|
|
124
|
+
*/ capLimitsByCheckpointBudgets(opts) {
|
|
125
|
+
const existingBlocks = this.checkpointBuilder.getBlocks();
|
|
126
|
+
// Remaining L2 gas (mana)
|
|
127
|
+
// IMPORTANT: This assumes mana is computed solely based on L2 gas used in transactions.
|
|
128
|
+
// This may change in the future.
|
|
129
|
+
const usedMana = sum(existingBlocks.map((b)=>b.header.totalManaUsed.toNumber()));
|
|
130
|
+
const remainingMana = this.config.rollupManaLimit - usedMana;
|
|
131
|
+
// Remaining DA gas
|
|
132
|
+
const usedDAGas = sum(existingBlocks.map((b)=>b.computeDAGasUsed())) ?? 0;
|
|
133
|
+
const remainingDAGas = MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT - usedDAGas;
|
|
134
|
+
// Remaining blob fields (block blob fields include both tx data and block-end overhead)
|
|
135
|
+
const usedBlobFields = sum(existingBlocks.map((b)=>b.toBlobFields().length));
|
|
136
|
+
const totalBlobCapacity = BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB - NUM_CHECKPOINT_END_MARKER_FIELDS;
|
|
137
|
+
const isFirstBlock = existingBlocks.length === 0;
|
|
138
|
+
const blockEndOverhead = getNumBlockEndBlobFields(isFirstBlock);
|
|
139
|
+
const maxBlobFieldsForTxs = totalBlobCapacity - usedBlobFields - blockEndOverhead;
|
|
140
|
+
// Cap L2 gas by remaining checkpoint mana
|
|
141
|
+
const cappedL2Gas = Math.min(opts.maxBlockGas?.l2Gas ?? remainingMana, remainingMana);
|
|
142
|
+
// Cap DA gas by remaining checkpoint DA gas budget
|
|
143
|
+
const cappedDAGas = Math.min(opts.maxBlockGas?.daGas ?? remainingDAGas, remainingDAGas);
|
|
144
|
+
// Cap blob fields by remaining checkpoint blob capacity
|
|
145
|
+
const cappedBlobFields = opts.maxBlobFields !== undefined ? Math.min(opts.maxBlobFields, maxBlobFieldsForTxs) : maxBlobFieldsForTxs;
|
|
146
|
+
// Cap transaction count by remaining checkpoint tx budget
|
|
147
|
+
let cappedMaxTransactions;
|
|
148
|
+
if (this.config.maxTxsPerCheckpoint !== undefined) {
|
|
149
|
+
const usedTxs = sum(existingBlocks.map((b)=>b.body.txEffects.length));
|
|
150
|
+
const remainingTxs = Math.max(0, this.config.maxTxsPerCheckpoint - usedTxs);
|
|
151
|
+
cappedMaxTransactions = opts.maxTransactions !== undefined ? Math.min(opts.maxTransactions, remainingTxs) : remainingTxs;
|
|
152
|
+
} else {
|
|
153
|
+
cappedMaxTransactions = opts.maxTransactions;
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
maxBlockGas: new Gas(cappedDAGas, cappedL2Gas),
|
|
157
|
+
maxBlobFields: cappedBlobFields,
|
|
158
|
+
maxTransactions: cappedMaxTransactions
|
|
159
|
+
};
|
|
160
|
+
}
|
|
103
161
|
async makeBlockBuilderDeps(globalVariables, fork) {
|
|
104
162
|
const txPublicSetupAllowList = [
|
|
105
163
|
...await getDefaultAllowedSetupFunctions(),
|
package/dest/config.d.ts
CHANGED
|
@@ -8,4 +8,4 @@ export declare const validatorClientConfigMappings: ConfigMappingsType<Validator
|
|
|
8
8
|
* @returns The validator configuration.
|
|
9
9
|
*/
|
|
10
10
|
export declare function getProverEnvVars(): ValidatorClientConfig;
|
|
11
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxLQUFLLGtCQUFrQixFQUt4QixNQUFNLDBCQUEwQixDQUFDO0FBRWxDLE9BQU8sS0FBSyxFQUFFLHFCQUFxQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFHN0UsWUFBWSxFQUFFLHFCQUFxQixFQUFFLENBQUM7QUFFdEMsZUFBTyxNQUFNLDZCQUE2QixFQUFFLGtCQUFrQixDQUFDLHFCQUFxQixDQXVGbkYsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCx3QkFBZ0IsZ0JBQWdCLElBQUkscUJBQXFCLENBRXhEIn0=
|
package/dest/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAG7E,YAAY,EAAE,qBAAqB,EAAE,CAAC;AAEtC,eAAO,MAAM,6BAA6B,EAAE,kBAAkB,CAAC,qBAAqB,CAuFnF,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,qBAAqB,CAExD"}
|
package/dest/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { booleanConfigHelper, getConfigFromMappings, numberConfigHelper, secretValueConfigHelper } from '@aztec/foundation/config';
|
|
2
2
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
-
import { validatorHASignerConfigMappings } from '@aztec/
|
|
3
|
+
import { validatorHASignerConfigMappings } from '@aztec/validator-ha-signer/config';
|
|
4
4
|
export const validatorClientConfigMappings = {
|
|
5
5
|
validatorPrivateKeys: {
|
|
6
6
|
env: 'VALIDATOR_PRIVATE_KEYS',
|
|
@@ -57,6 +57,26 @@ export const validatorClientConfigMappings = {
|
|
|
57
57
|
description: 'Agree to attest to equivocated checkpoint proposals (for testing purposes only)',
|
|
58
58
|
...booleanConfigHelper(false)
|
|
59
59
|
},
|
|
60
|
+
validateMaxL2BlockGas: {
|
|
61
|
+
env: 'VALIDATOR_MAX_L2_BLOCK_GAS',
|
|
62
|
+
description: 'Maximum L2 block gas for validation. Proposals exceeding this limit are rejected.',
|
|
63
|
+
parseEnv: (val)=>val ? parseInt(val, 10) : undefined
|
|
64
|
+
},
|
|
65
|
+
validateMaxDABlockGas: {
|
|
66
|
+
env: 'VALIDATOR_MAX_DA_BLOCK_GAS',
|
|
67
|
+
description: 'Maximum DA block gas for validation. Proposals exceeding this limit are rejected.',
|
|
68
|
+
parseEnv: (val)=>val ? parseInt(val, 10) : undefined
|
|
69
|
+
},
|
|
70
|
+
validateMaxTxsPerBlock: {
|
|
71
|
+
env: 'VALIDATOR_MAX_TX_PER_BLOCK',
|
|
72
|
+
description: 'Maximum transactions per block for validation. Proposals exceeding this limit are rejected.',
|
|
73
|
+
parseEnv: (val)=>val ? parseInt(val, 10) : undefined
|
|
74
|
+
},
|
|
75
|
+
validateMaxTxsPerCheckpoint: {
|
|
76
|
+
env: 'VALIDATOR_MAX_TX_PER_CHECKPOINT',
|
|
77
|
+
description: 'Maximum transactions per checkpoint for validation. Proposals exceeding this limit are rejected.',
|
|
78
|
+
parseEnv: (val)=>val ? parseInt(val, 10) : undefined
|
|
79
|
+
},
|
|
60
80
|
...validatorHASignerConfigMappings
|
|
61
81
|
};
|
|
62
82
|
/**
|