@aztec/validator-client 0.0.1-commit.1bea0213 → 0.0.1-commit.1de2a32
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 +63 -18
- package/dest/block_proposal_handler.d.ts +5 -6
- package/dest/block_proposal_handler.d.ts.map +1 -1
- package/dest/block_proposal_handler.js +66 -60
- package/dest/checkpoint_builder.d.ts +21 -12
- package/dest/checkpoint_builder.d.ts.map +1 -1
- package/dest/checkpoint_builder.js +107 -39
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +28 -4
- package/dest/duties/validation_service.d.ts +2 -2
- package/dest/duties/validation_service.d.ts.map +1 -1
- package/dest/duties/validation_service.js +5 -11
- package/dest/factory.d.ts +1 -1
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +2 -1
- package/dest/index.d.ts +1 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +0 -1
- package/dest/key_store/ha_key_store.d.ts +1 -1
- package/dest/key_store/ha_key_store.d.ts.map +1 -1
- package/dest/key_store/ha_key_store.js +2 -2
- package/dest/metrics.d.ts +12 -3
- package/dest/metrics.d.ts.map +1 -1
- package/dest/metrics.js +46 -5
- package/dest/validator.d.ts +40 -14
- package/dest/validator.d.ts.map +1 -1
- package/dest/validator.js +212 -56
- package/package.json +19 -17
- package/src/block_proposal_handler.ts +81 -81
- package/src/checkpoint_builder.ts +144 -38
- package/src/config.ts +28 -4
- package/src/duties/validation_service.ts +11 -10
- package/src/factory.ts +1 -0
- package/src/index.ts +0 -1
- package/src/key_store/ha_key_store.ts +2 -2
- package/src/metrics.ts +63 -6
- package/src/validator.ts +260 -66
- package/dest/tx_validator/index.d.ts +0 -3
- package/dest/tx_validator/index.d.ts.map +0 -1
- package/dest/tx_validator/index.js +0 -2
- package/dest/tx_validator/nullifier_cache.d.ts +0 -14
- package/dest/tx_validator/nullifier_cache.d.ts.map +0 -1
- package/dest/tx_validator/nullifier_cache.js +0 -24
- package/dest/tx_validator/tx_validator_factory.d.ts +0 -18
- package/dest/tx_validator/tx_validator_factory.d.ts.map +0 -1
- package/dest/tx_validator/tx_validator_factory.js +0 -54
- package/src/tx_validator/index.ts +0 -2
- package/src/tx_validator/nullifier_cache.ts +0 -30
- package/src/tx_validator/tx_validator_factory.ts +0 -135
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.1de2a32",
|
|
4
4
|
"main": "dest/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -64,28 +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.1de2a32",
|
|
68
|
+
"@aztec/blob-lib": "0.0.1-commit.1de2a32",
|
|
69
|
+
"@aztec/constants": "0.0.1-commit.1de2a32",
|
|
70
|
+
"@aztec/epoch-cache": "0.0.1-commit.1de2a32",
|
|
71
|
+
"@aztec/ethereum": "0.0.1-commit.1de2a32",
|
|
72
|
+
"@aztec/foundation": "0.0.1-commit.1de2a32",
|
|
73
|
+
"@aztec/node-keystore": "0.0.1-commit.1de2a32",
|
|
74
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.1de2a32",
|
|
75
|
+
"@aztec/p2p": "0.0.1-commit.1de2a32",
|
|
76
|
+
"@aztec/protocol-contracts": "0.0.1-commit.1de2a32",
|
|
77
|
+
"@aztec/prover-client": "0.0.1-commit.1de2a32",
|
|
78
|
+
"@aztec/simulator": "0.0.1-commit.1de2a32",
|
|
79
|
+
"@aztec/slasher": "0.0.1-commit.1de2a32",
|
|
80
|
+
"@aztec/stdlib": "0.0.1-commit.1de2a32",
|
|
81
|
+
"@aztec/telemetry-client": "0.0.1-commit.1de2a32",
|
|
82
|
+
"@aztec/validator-ha-signer": "0.0.1-commit.1de2a32",
|
|
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.1de2a32",
|
|
90
|
+
"@aztec/world-state": "0.0.1-commit.1de2a32",
|
|
89
91
|
"@electric-sql/pglite": "^0.3.14",
|
|
90
92
|
"@jest/globals": "^30.0.0",
|
|
91
93
|
"@types/jest": "^30.0.0",
|
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
2
2
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
3
3
|
import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
4
|
-
import {
|
|
4
|
+
import { pick } from '@aztec/foundation/collection';
|
|
5
5
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
6
6
|
import { TimeoutError } from '@aztec/foundation/error';
|
|
7
7
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
8
|
import { retryUntil } from '@aztec/foundation/retry';
|
|
9
9
|
import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
10
10
|
import type { P2P, PeerId } from '@aztec/p2p';
|
|
11
|
-
import { TxProvider } from '@aztec/p2p';
|
|
12
11
|
import { BlockProposalValidator } from '@aztec/p2p/msg_validators';
|
|
13
|
-
import type { L2Block, L2BlockSink, L2BlockSource } from '@aztec/stdlib/block';
|
|
12
|
+
import type { BlockData, L2Block, L2BlockSink, L2BlockSource } from '@aztec/stdlib/block';
|
|
14
13
|
import { getEpochAtSlot, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
15
|
-
import
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
computeCheckpointOutHash,
|
|
19
|
-
computeInHashFromL1ToL2Messages,
|
|
20
|
-
} from '@aztec/stdlib/messaging';
|
|
14
|
+
import { Gas } from '@aztec/stdlib/gas';
|
|
15
|
+
import type { ITxProvider, ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
16
|
+
import { type L1ToL2MessageSource, computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
|
|
21
17
|
import type { BlockProposal } from '@aztec/stdlib/p2p';
|
|
22
|
-
import {
|
|
18
|
+
import type { CheckpointGlobalVariables, FailedTx, Tx } from '@aztec/stdlib/tx';
|
|
23
19
|
import {
|
|
24
20
|
ReExFailedTxsError,
|
|
25
21
|
ReExStateMismatchError,
|
|
@@ -78,7 +74,7 @@ export class BlockProposalHandler {
|
|
|
78
74
|
private worldState: WorldStateSynchronizer,
|
|
79
75
|
private blockSource: L2BlockSource & L2BlockSink,
|
|
80
76
|
private l1ToL2MessageSource: L1ToL2MessageSource,
|
|
81
|
-
private txProvider:
|
|
77
|
+
private txProvider: ITxProvider,
|
|
82
78
|
private blockProposalValidator: BlockProposalValidator,
|
|
83
79
|
private epochCache: EpochCache,
|
|
84
80
|
private config: ValidatorClientFullConfig,
|
|
@@ -93,25 +89,28 @@ export class BlockProposalHandler {
|
|
|
93
89
|
this.tracer = telemetry.getTracer('BlockProposalHandler');
|
|
94
90
|
}
|
|
95
91
|
|
|
96
|
-
|
|
97
|
-
// Non-validator handler that re-executes for monitoring but does not attest.
|
|
92
|
+
register(p2pClient: P2P, shouldReexecute: boolean): BlockProposalHandler {
|
|
93
|
+
// Non-validator handler that processes or re-executes for monitoring but does not attest.
|
|
98
94
|
// Returns boolean indicating whether the proposal was valid.
|
|
99
95
|
const handler = async (proposal: BlockProposal, proposalSender: PeerId): Promise<boolean> => {
|
|
100
96
|
try {
|
|
101
|
-
const
|
|
97
|
+
const { slotNumber, blockNumber } = proposal;
|
|
98
|
+
const result = await this.handleBlockProposal(proposal, proposalSender, shouldReexecute);
|
|
102
99
|
if (result.isValid) {
|
|
103
|
-
this.log.info(`Non-validator
|
|
100
|
+
this.log.info(`Non-validator block proposal ${blockNumber} at slot ${slotNumber} handled`, {
|
|
104
101
|
blockNumber: result.blockNumber,
|
|
102
|
+
slotNumber,
|
|
105
103
|
reexecutionTimeMs: result.reexecutionResult?.reexecutionTimeMs,
|
|
106
104
|
totalManaUsed: result.reexecutionResult?.totalManaUsed,
|
|
107
105
|
numTxs: result.reexecutionResult?.block?.body?.txEffects?.length ?? 0,
|
|
106
|
+
reexecuted: shouldReexecute,
|
|
108
107
|
});
|
|
109
108
|
return true;
|
|
110
109
|
} else {
|
|
111
|
-
this.log.warn(
|
|
112
|
-
blockNumber
|
|
113
|
-
reason: result.reason,
|
|
114
|
-
|
|
110
|
+
this.log.warn(
|
|
111
|
+
`Non-validator block proposal ${blockNumber} at slot ${slotNumber} failed processing with ${result.reason}`,
|
|
112
|
+
{ blockNumber: result.blockNumber, slotNumber, reason: result.reason },
|
|
113
|
+
);
|
|
115
114
|
return false;
|
|
116
115
|
}
|
|
117
116
|
} catch (error) {
|
|
@@ -154,16 +153,16 @@ export class BlockProposalHandler {
|
|
|
154
153
|
}
|
|
155
154
|
|
|
156
155
|
// Check that the parent proposal is a block we know, otherwise reexecution would fail
|
|
157
|
-
const
|
|
158
|
-
if (
|
|
156
|
+
const parentBlock = await this.getParentBlock(proposal);
|
|
157
|
+
if (parentBlock === undefined) {
|
|
159
158
|
this.log.warn(`Parent block for proposal not found, skipping processing`, proposalInfo);
|
|
160
159
|
return { isValid: false, reason: 'parent_block_not_found' };
|
|
161
160
|
}
|
|
162
161
|
|
|
163
|
-
// Check that the parent block's slot is
|
|
164
|
-
if (
|
|
165
|
-
this.log.warn(`Parent block slot is greater than
|
|
166
|
-
parentBlockSlot:
|
|
162
|
+
// Check that the parent block's slot is not greater than the proposal's slot.
|
|
163
|
+
if (parentBlock !== 'genesis' && parentBlock.header.getSlot() > slotNumber) {
|
|
164
|
+
this.log.warn(`Parent block slot is greater than proposal slot, skipping processing`, {
|
|
165
|
+
parentBlockSlot: parentBlock.header.getSlot().toString(),
|
|
167
166
|
proposalSlot: slotNumber.toString(),
|
|
168
167
|
...proposalInfo,
|
|
169
168
|
});
|
|
@@ -172,9 +171,9 @@ export class BlockProposalHandler {
|
|
|
172
171
|
|
|
173
172
|
// Compute the block number based on the parent block
|
|
174
173
|
const blockNumber =
|
|
175
|
-
|
|
174
|
+
parentBlock === 'genesis'
|
|
176
175
|
? BlockNumber(INITIAL_L2_BLOCK_NUM)
|
|
177
|
-
: BlockNumber(
|
|
176
|
+
: BlockNumber(parentBlock.header.getBlockNumber() + 1);
|
|
178
177
|
|
|
179
178
|
// Check that this block number does not exist already
|
|
180
179
|
const existingBlock = await this.blockSource.getBlockHeader(blockNumber);
|
|
@@ -190,8 +189,17 @@ export class BlockProposalHandler {
|
|
|
190
189
|
deadline: this.getReexecutionDeadline(slotNumber, config),
|
|
191
190
|
});
|
|
192
191
|
|
|
192
|
+
// If reexecution is disabled, bail. We are just interested in triggering tx collection.
|
|
193
|
+
if (!shouldReexecute) {
|
|
194
|
+
this.log.info(
|
|
195
|
+
`Received valid block ${blockNumber} proposal at index ${proposal.indexWithinCheckpoint} on slot ${slotNumber}`,
|
|
196
|
+
proposalInfo,
|
|
197
|
+
);
|
|
198
|
+
return { isValid: true, blockNumber };
|
|
199
|
+
}
|
|
200
|
+
|
|
193
201
|
// Compute the checkpoint number for this block and validate checkpoint consistency
|
|
194
|
-
const checkpointResult =
|
|
202
|
+
const checkpointResult = this.computeCheckpointNumber(proposal, parentBlock, proposalInfo);
|
|
195
203
|
if (checkpointResult.reason) {
|
|
196
204
|
return { isValid: false, blockNumber, reason: checkpointResult.reason };
|
|
197
205
|
}
|
|
@@ -216,36 +224,28 @@ export class BlockProposalHandler {
|
|
|
216
224
|
return { isValid: false, blockNumber, reason: 'txs_not_available' };
|
|
217
225
|
}
|
|
218
226
|
|
|
227
|
+
// Collect the out hashes of all the checkpoints before this one in the same epoch
|
|
228
|
+
const epoch = getEpochAtSlot(slotNumber, this.epochCache.getL1Constants());
|
|
229
|
+
const previousCheckpointOutHashes = (await this.blockSource.getCheckpointsDataForEpoch(epoch))
|
|
230
|
+
.filter(c => c.checkpointNumber < checkpointNumber)
|
|
231
|
+
.map(c => c.checkpointOutHash);
|
|
232
|
+
|
|
219
233
|
// Try re-executing the transactions in the proposal if needed
|
|
220
234
|
let reexecutionResult;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const previousCheckpointOutHashes = blocksByCheckpoint.map(checkpointBlocks =>
|
|
231
|
-
computeCheckpointOutHash(checkpointBlocks.map(b => b.block.body.txEffects.map(tx => tx.l2ToL1Msgs))),
|
|
235
|
+
try {
|
|
236
|
+
this.log.verbose(`Re-executing transactions in the proposal`, proposalInfo);
|
|
237
|
+
reexecutionResult = await this.reexecuteTransactions(
|
|
238
|
+
proposal,
|
|
239
|
+
blockNumber,
|
|
240
|
+
checkpointNumber,
|
|
241
|
+
txs,
|
|
242
|
+
l1ToL2Messages,
|
|
243
|
+
previousCheckpointOutHashes,
|
|
232
244
|
);
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
proposal,
|
|
238
|
-
blockNumber,
|
|
239
|
-
checkpointNumber,
|
|
240
|
-
txs,
|
|
241
|
-
l1ToL2Messages,
|
|
242
|
-
previousCheckpointOutHashes,
|
|
243
|
-
);
|
|
244
|
-
} catch (error) {
|
|
245
|
-
this.log.error(`Error reexecuting txs while processing block proposal`, error, proposalInfo);
|
|
246
|
-
const reason = this.getReexecuteFailureReason(error);
|
|
247
|
-
return { isValid: false, blockNumber, reason, reexecutionResult };
|
|
248
|
-
}
|
|
245
|
+
} catch (error) {
|
|
246
|
+
this.log.error(`Error reexecuting txs while processing block proposal`, error, proposalInfo);
|
|
247
|
+
const reason = this.getReexecuteFailureReason(error);
|
|
248
|
+
return { isValid: false, blockNumber, reason, reexecutionResult };
|
|
249
249
|
}
|
|
250
250
|
|
|
251
251
|
// If we succeeded, push this block into the archiver (unless disabled)
|
|
@@ -254,14 +254,14 @@ export class BlockProposalHandler {
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
this.log.info(
|
|
257
|
-
`Successfully
|
|
258
|
-
proposalInfo,
|
|
257
|
+
`Successfully re-executed block ${blockNumber} proposal at index ${proposal.indexWithinCheckpoint} on slot ${slotNumber}`,
|
|
258
|
+
{ ...proposalInfo, ...pick(reexecutionResult, 'reexecutionTimeMs', 'totalManaUsed') },
|
|
259
259
|
);
|
|
260
260
|
|
|
261
261
|
return { isValid: true, blockNumber, reexecutionResult };
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
-
private async getParentBlock(proposal: BlockProposal): Promise<'genesis' |
|
|
264
|
+
private async getParentBlock(proposal: BlockProposal): Promise<'genesis' | BlockData | undefined> {
|
|
265
265
|
const parentArchive = proposal.blockHeader.lastArchive.root;
|
|
266
266
|
const slot = proposal.slotNumber;
|
|
267
267
|
const config = this.checkpointsBuilder.getConfig();
|
|
@@ -277,12 +277,11 @@ export class BlockProposalHandler {
|
|
|
277
277
|
|
|
278
278
|
try {
|
|
279
279
|
return (
|
|
280
|
-
(await this.blockSource.
|
|
280
|
+
(await this.blockSource.getBlockDataByArchive(parentArchive)) ??
|
|
281
281
|
(timeoutDurationMs <= 0
|
|
282
282
|
? undefined
|
|
283
283
|
: await retryUntil(
|
|
284
|
-
() =>
|
|
285
|
-
this.blockSource.syncImmediate().then(() => this.blockSource.getBlockHeaderByArchive(parentArchive)),
|
|
284
|
+
() => this.blockSource.syncImmediate().then(() => this.blockSource.getBlockDataByArchive(parentArchive)),
|
|
286
285
|
'force archiver sync',
|
|
287
286
|
timeoutDurationMs / 1000,
|
|
288
287
|
0.5,
|
|
@@ -298,12 +297,12 @@ export class BlockProposalHandler {
|
|
|
298
297
|
}
|
|
299
298
|
}
|
|
300
299
|
|
|
301
|
-
private
|
|
300
|
+
private computeCheckpointNumber(
|
|
302
301
|
proposal: BlockProposal,
|
|
303
|
-
|
|
302
|
+
parentBlock: 'genesis' | BlockData,
|
|
304
303
|
proposalInfo: object,
|
|
305
|
-
):
|
|
306
|
-
if (
|
|
304
|
+
): CheckpointComputationResult {
|
|
305
|
+
if (parentBlock === 'genesis') {
|
|
307
306
|
// First block is in checkpoint 1
|
|
308
307
|
if (proposal.indexWithinCheckpoint !== 0) {
|
|
309
308
|
this.log.warn(`First block proposal has non-zero indexWithinCheckpoint`, proposalInfo);
|
|
@@ -312,19 +311,9 @@ export class BlockProposalHandler {
|
|
|
312
311
|
return { checkpointNumber: CheckpointNumber.INITIAL };
|
|
313
312
|
}
|
|
314
313
|
|
|
315
|
-
// Get the parent block to find its checkpoint number
|
|
316
|
-
// TODO(palla/mbps): The block header should include the checkpoint number to avoid this lookup,
|
|
317
|
-
// or at least the L2BlockSource should return a different struct that includes it.
|
|
318
|
-
const parentBlockNumber = parentBlockHeader.getBlockNumber();
|
|
319
|
-
const parentBlock = await this.blockSource.getL2Block(parentBlockNumber);
|
|
320
|
-
if (!parentBlock) {
|
|
321
|
-
this.log.warn(`Parent block ${parentBlockNumber} not found in archiver`, proposalInfo);
|
|
322
|
-
return { reason: 'invalid_proposal' };
|
|
323
|
-
}
|
|
324
|
-
|
|
325
314
|
if (proposal.indexWithinCheckpoint === 0) {
|
|
326
315
|
// If this is the first block in a new checkpoint, increment the checkpoint number
|
|
327
|
-
if (!(proposal.blockHeader.getSlot() >
|
|
316
|
+
if (!(proposal.blockHeader.getSlot() > parentBlock.header.getSlot())) {
|
|
328
317
|
this.log.warn(`Slot should be greater than parent block slot for first block in checkpoint`, proposalInfo);
|
|
329
318
|
return { reason: 'invalid_proposal' };
|
|
330
319
|
}
|
|
@@ -336,7 +325,7 @@ export class BlockProposalHandler {
|
|
|
336
325
|
this.log.warn(`Non-sequential indexWithinCheckpoint`, proposalInfo);
|
|
337
326
|
return { reason: 'invalid_proposal' };
|
|
338
327
|
}
|
|
339
|
-
if (proposal.blockHeader.getSlot() !==
|
|
328
|
+
if (proposal.blockHeader.getSlot() !== parentBlock.header.getSlot()) {
|
|
340
329
|
this.log.warn(`Slot should be equal to parent block slot for non-first block in checkpoint`, proposalInfo);
|
|
341
330
|
return { reason: 'invalid_proposal' };
|
|
342
331
|
}
|
|
@@ -357,7 +346,7 @@ export class BlockProposalHandler {
|
|
|
357
346
|
*/
|
|
358
347
|
private validateNonFirstBlockInCheckpoint(
|
|
359
348
|
proposal: BlockProposal,
|
|
360
|
-
parentBlock:
|
|
349
|
+
parentBlock: BlockData,
|
|
361
350
|
proposalInfo: object,
|
|
362
351
|
): CheckpointComputationResult | undefined {
|
|
363
352
|
const proposalGlobals = proposal.blockHeader.globalVariables;
|
|
@@ -475,13 +464,15 @@ export class BlockProposalHandler {
|
|
|
475
464
|
|
|
476
465
|
// Fork before the block to be built
|
|
477
466
|
const parentBlockNumber = BlockNumber(blockNumber - 1);
|
|
478
|
-
|
|
467
|
+
await this.worldState.syncImmediate(parentBlockNumber);
|
|
468
|
+
await using fork = await this.worldState.fork(parentBlockNumber);
|
|
479
469
|
|
|
480
|
-
// Build checkpoint constants from proposal (excludes blockNumber
|
|
470
|
+
// Build checkpoint constants from proposal (excludes blockNumber which is per-block)
|
|
481
471
|
const constants: CheckpointGlobalVariables = {
|
|
482
472
|
chainId: new Fr(config.l1ChainId),
|
|
483
473
|
version: new Fr(config.rollupVersion),
|
|
484
474
|
slotNumber: slot,
|
|
475
|
+
timestamp: blockHeader.globalVariables.timestamp,
|
|
485
476
|
coinbase: blockHeader.globalVariables.coinbase,
|
|
486
477
|
feeRecipient: blockHeader.globalVariables.feeRecipient,
|
|
487
478
|
gasFees: blockHeader.globalVariables.gasFees,
|
|
@@ -491,26 +482,35 @@ export class BlockProposalHandler {
|
|
|
491
482
|
const checkpointBuilder = await this.checkpointsBuilder.openCheckpoint(
|
|
492
483
|
checkpointNumber,
|
|
493
484
|
constants,
|
|
485
|
+
0n, // only takes effect in the following checkpoint.
|
|
494
486
|
l1ToL2Messages,
|
|
495
487
|
previousCheckpointOutHashes,
|
|
496
488
|
fork,
|
|
497
489
|
priorBlocks,
|
|
490
|
+
this.log.getBindings(),
|
|
498
491
|
);
|
|
499
492
|
|
|
500
493
|
// Build the new block
|
|
501
494
|
const deadline = this.getReexecutionDeadline(slot, config);
|
|
495
|
+
const maxBlockGas =
|
|
496
|
+
this.config.validateMaxL2BlockGas !== undefined || this.config.validateMaxDABlockGas !== undefined
|
|
497
|
+
? new Gas(this.config.validateMaxDABlockGas ?? Infinity, this.config.validateMaxL2BlockGas ?? Infinity)
|
|
498
|
+
: undefined;
|
|
502
499
|
const result = await checkpointBuilder.buildBlock(txs, blockNumber, blockHeader.globalVariables.timestamp, {
|
|
503
500
|
deadline,
|
|
504
501
|
expectedEndState: blockHeader.state,
|
|
502
|
+
maxTransactions: this.config.validateMaxTxsPerBlock,
|
|
503
|
+
maxBlockGas,
|
|
505
504
|
});
|
|
506
505
|
|
|
507
506
|
const { block, failedTxs } = result;
|
|
508
507
|
const numFailedTxs = failedTxs.length;
|
|
509
508
|
|
|
510
|
-
this.log.verbose(`
|
|
509
|
+
this.log.verbose(`Block proposal ${blockNumber} at slot ${slot} transaction re-execution complete`, {
|
|
511
510
|
numFailedTxs,
|
|
512
511
|
numProposalTxs: txHashes.length,
|
|
513
512
|
numProcessedTxs: block.body.txEffects.length,
|
|
513
|
+
blockNumber,
|
|
514
514
|
slot,
|
|
515
515
|
});
|
|
516
516
|
|