@aztec/aztec-node 5.3.0-nightly.20260909 → 5.3.0-nightly.20260911

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dest/aztec-node/next_block/index.d.ts +4 -0
  2. package/dest/aztec-node/next_block/index.d.ts.map +1 -0
  3. package/dest/aztec-node/next_block/index.js +3 -0
  4. package/dest/aztec-node/next_block/next_block_fee_cache.d.ts +110 -0
  5. package/dest/aztec-node/next_block/next_block_fee_cache.d.ts.map +1 -0
  6. package/dest/aztec-node/next_block/next_block_fee_cache.js +201 -0
  7. package/dest/aztec-node/next_block/next_block_planner.d.ts +78 -0
  8. package/dest/aztec-node/next_block/next_block_planner.d.ts.map +1 -0
  9. package/dest/aztec-node/next_block/next_block_planner.js +109 -0
  10. package/dest/aztec-node/next_block/next_block_predictor.d.ts +91 -0
  11. package/dest/aztec-node/next_block/next_block_predictor.d.ts.map +1 -0
  12. package/dest/aztec-node/next_block/next_block_predictor.js +146 -0
  13. package/dest/aztec-node/next_block/test_helpers.d.ts +40 -0
  14. package/dest/aztec-node/next_block/test_helpers.d.ts.map +1 -0
  15. package/dest/aztec-node/next_block/test_helpers.js +100 -0
  16. package/dest/aztec-node/node_public_calls_simulator.d.ts +10 -48
  17. package/dest/aztec-node/node_public_calls_simulator.d.ts.map +1 -1
  18. package/dest/aztec-node/node_public_calls_simulator.js +56 -164
  19. package/dest/aztec-node/server.d.ts +18 -2
  20. package/dest/aztec-node/server.d.ts.map +1 -1
  21. package/dest/aztec-node/server.js +34 -12
  22. package/dest/factory.d.ts +1 -1
  23. package/dest/factory.d.ts.map +1 -1
  24. package/dest/factory.js +17 -1
  25. package/dest/index.d.ts +2 -1
  26. package/dest/index.d.ts.map +1 -1
  27. package/dest/index.js +1 -0
  28. package/package.json +28 -28
  29. package/src/aztec-node/next_block/index.ts +3 -0
  30. package/src/aztec-node/next_block/next_block_fee_cache.ts +279 -0
  31. package/src/aztec-node/next_block/next_block_planner.ts +198 -0
  32. package/src/aztec-node/next_block/next_block_predictor.ts +158 -0
  33. package/src/aztec-node/next_block/test_helpers.ts +115 -0
  34. package/src/aztec-node/node_public_calls_simulator.ts +78 -218
  35. package/src/aztec-node/server.ts +32 -9
  36. package/src/factory.ts +15 -1
  37. package/src/index.ts +1 -0
@@ -0,0 +1,146 @@
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
2
+ import { createLogger } from '@aztec/foundation/log';
3
+ import { GlobalVariables } from '@aztec/stdlib/tx';
4
+ import { NextBlockFeeCache } from './next_block_fee_cache.js';
5
+ import { computeBoundaryFeeKey, getClockSlot, planNextBlock } from './next_block_planner.js';
6
+ /**
7
+ * How long a fee quote waits for a boundary refresh before answering with what it already has. Long enough for
8
+ * a slow but alive L1 RPC; short enough that an L1 outage does not turn every quote into a multi-second RPC.
9
+ */ export const QUOTE_MAX_WAIT_MS = 5000;
10
+ /**
11
+ * Answers "what would the next block look like" for everything on the RPC side: the public simulation forks and
12
+ * executes against this prediction, and the fee quote reports the fee it carries.
13
+ *
14
+ * The plan is re-derived from a fresh archiver snapshot on every call — it is a handful of in-memory reads, and
15
+ * a stale plan would fork the wrong block, target the wrong checkpoint's L1-to-L2 messages, or miss that an
16
+ * in-progress checkpoint froze a different fee. Only the L1-derived part, the checkpoint globals of a block that
17
+ * opens a fresh checkpoint, is cached (see {@link NextBlockFeeCache}).
18
+ *
19
+ * Deliberately not used by the sequencer: its slot policy is stricter (it declines to build rather than
20
+ * predicting inclusion) and a stale fee would make L1 reject its checkpoint.
21
+ */ export class NextBlockPredictor {
22
+ blockSource;
23
+ feeCache;
24
+ epochCache;
25
+ log;
26
+ constructor(deps){
27
+ this.blockSource = deps.blockSource;
28
+ this.feeCache = deps.feeCache;
29
+ this.epochCache = deps.epochCache;
30
+ this.log = deps.log ?? createLogger('node:next-block-predictor');
31
+ }
32
+ /**
33
+ * Builds a predictor together with the fee cache it reads from. It takes the cache's dependencies rather than
34
+ * {@link NextBlockPredictorDeps} because the cache is constructed here; everything the predictor itself needs is
35
+ * a subset of them.
36
+ */ static create(deps) {
37
+ const feeCache = new NextBlockFeeCache({
38
+ ...deps,
39
+ log: deps.log?.createChild('fee-cache')
40
+ });
41
+ return new NextBlockPredictor({
42
+ blockSource: deps.blockSource,
43
+ feeCache,
44
+ epochCache: deps.epochCache,
45
+ log: deps.log
46
+ });
47
+ }
48
+ start(pollingIntervalMs) {
49
+ this.feeCache.start(pollingIntervalMs);
50
+ }
51
+ stop() {
52
+ return this.feeCache.stop();
53
+ }
54
+ /**
55
+ * Plans the next block and builds the globals it would carry, in one of two ways, mirroring how the sequencer
56
+ * builds the next block:
57
+ *
58
+ * - **Continuing an in-progress checkpoint**: every block in a checkpoint shares the same
59
+ * `CheckpointGlobalVariables`, so the latest proposed block's globals are copied verbatim — including the
60
+ * proposer's real coinbase and fee recipient — with only the block number bumped. No L1 involved.
61
+ * - **Opening a new checkpoint**: the globals are priced for the slot the next block will land in, under the
62
+ * same overrides plan the sequencer applies, so the simulated mana min fee matches what the sequencer will
63
+ * write into the block header. Coinbase and fee recipient stay zero: the future proposer's payout addresses
64
+ * are unknowable.
65
+ *
66
+ * Waits without a bound for a boundary fee it does not have cached, and surfaces the L1 failure if that read
67
+ * fails, as a simulation did before this cache existed.
68
+ */ async predict() {
69
+ const { frontier, plan, key } = await this.planFromFrontier();
70
+ const blockNumber = BlockNumber.add(plan.latestBlockNumber, 1);
71
+ if (!key) {
72
+ return {
73
+ plan,
74
+ frontier,
75
+ globals: this.copyGlobalsFromLatestBlock(frontier, blockNumber)
76
+ };
77
+ }
78
+ const checkpointGlobals = await this.feeCache.getBoundaryGlobals(key, frontier);
79
+ if (!checkpointGlobals) {
80
+ throw new Error(`Could not price the next block at slot ${key.targetSlot}: no boundary fee available`);
81
+ }
82
+ return {
83
+ plan,
84
+ frontier,
85
+ globals: GlobalVariables.from({
86
+ blockNumber,
87
+ ...checkpointGlobals
88
+ })
89
+ };
90
+ }
91
+ /**
92
+ * The mana min fee the next block will charge, for wallets to pad and pay. Mid-checkpoint this is the fee the
93
+ * in-progress checkpoint froze into its first block, which no forward-looking L1 projection can see. At a
94
+ * boundary it is the cached L1 price, waited on for at most {@link QUOTE_MAX_WAIT_MS}; undefined when the node
95
+ * has nothing usable, in which case the caller falls back to the fee provider's projections alone.
96
+ *
97
+ * Returns the L1 block the answer describes so the caller can tag its own fee reads with the same anchor.
98
+ */ async quoteMinFees() {
99
+ const { frontier, plan, key } = await this.planFromFrontier();
100
+ if (!key) {
101
+ const fees = frontier.latestBlockHeader?.globalVariables.gasFees;
102
+ if (!fees) {
103
+ this.log.warn(`Cannot quote the next block fee: frontier reports no header for its proposed tip`, {
104
+ blockNumber: plan.latestBlockNumber
105
+ });
106
+ return undefined;
107
+ }
108
+ return {
109
+ fees,
110
+ l1SyncPoint: frontier.l1SyncPoint
111
+ };
112
+ }
113
+ const checkpointGlobals = await this.feeCache.getBoundaryGlobals(key, frontier, {
114
+ maxWaitMs: QUOTE_MAX_WAIT_MS
115
+ });
116
+ return checkpointGlobals ? {
117
+ fees: checkpointGlobals.gasFees,
118
+ l1SyncPoint: frontier.l1SyncPoint
119
+ } : undefined;
120
+ }
121
+ /** Plans the next block from a fresh archiver snapshot; `key` is set only when that block opens a checkpoint. */ async planFromFrontier() {
122
+ const frontier = await this.blockSource.getL2Frontier();
123
+ const plan = planNextBlock(frontier, getClockSlot(this.epochCache));
124
+ const key = computeBoundaryFeeKey(plan, frontier.pendingChainValidationStatus);
125
+ return {
126
+ frontier,
127
+ plan,
128
+ key
129
+ };
130
+ }
131
+ /**
132
+ * The header comes from the same snapshot as the tips, so it cannot describe a different block than the
133
+ * proposed tip. A missing header at a non-genesis proposed tip is an invariant violation and throws rather
134
+ * than falling through to the new-checkpoint path: a fork at the proposed tip already contains the ongoing
135
+ * checkpoint's L1-to-L2 messages, so a caller inserting the next checkpoint's messages would append them a
136
+ * second time.
137
+ */ copyGlobalsFromLatestBlock(frontier, blockNumber) {
138
+ if (!frontier.latestBlockHeader) {
139
+ throw new Error(`Cannot predict the next block: frontier reports proposed tip ${frontier.tips.proposed.number} but carries no header`);
140
+ }
141
+ return GlobalVariables.from({
142
+ ...frontier.latestBlockHeader.globalVariables,
143
+ blockNumber
144
+ });
145
+ }
146
+ }
@@ -0,0 +1,40 @@
1
+ import type { FeeHeader } from '@aztec/ethereum/contracts';
2
+ import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
4
+ import { BlockHash, type L1SyncPoint, type L2Frontier, type ValidateCheckpointResult } from '@aztec/stdlib/block';
5
+ import { type ProposedCheckpointData } from '@aztec/stdlib/checkpoint';
6
+ import { GasFees } from '@aztec/stdlib/gas';
7
+ /** Shape of the frontier snapshot a next-block test wants; every field has a sensible default. */
8
+ export type L2FrontierArgs = {
9
+ proposed: BlockNumber;
10
+ checkpointedBlock: BlockNumber;
11
+ checkpointed: CheckpointNumber;
12
+ /** Slot of the checkpointed checkpoint, the floor for the next block's slot. Omit for the genesis shape. */
13
+ checkpointedTipSlot?: SlotNumber;
14
+ proposedCheckpoint?: ProposedCheckpointData;
15
+ /** Globals of the proposed tip's header, copied verbatim when the next block continues a checkpoint. */
16
+ latestBlockGlobals?: {
17
+ slotNumber: SlotNumber;
18
+ gasFees?: GasFees;
19
+ };
20
+ /** Omit the proposed tip's header from the snapshot, an invariant violation the predictor must reject. */
21
+ omitLatestBlockHeader?: boolean;
22
+ pendingChainValidationStatus?: ValidateCheckpointResult;
23
+ /** L1 block the archiver's snapshot reflects; fee reads must be pinned to it. */
24
+ l1SyncPoint?: L1SyncPoint;
25
+ };
26
+ /** Stable per-block hash, so tips and the frontier agree on block identity. */
27
+ export declare const blockHashOf: (blockNumber: BlockNumber) => BlockHash;
28
+ export declare const makeFrontier: (args: L2FrontierArgs) => L2Frontier;
29
+ export declare function makeFeeHeader(): FeeHeader;
30
+ export declare function makeProposedCheckpointData(args: {
31
+ checkpointNumber: CheckpointNumber;
32
+ lastBlock: BlockNumber;
33
+ slotNumber?: SlotNumber;
34
+ archiveRoot?: Fr;
35
+ totalManaUsed?: bigint;
36
+ feeAssetPriceModifier?: bigint;
37
+ checkpointOutHash?: Fr;
38
+ }): ProposedCheckpointData;
39
+ export declare function makeInvalidStatus(firstInvalid: CheckpointNumber): ValidateCheckpointResult;
40
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdF9oZWxwZXJzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXp0ZWMtbm9kZS9uZXh0X2Jsb2NrL3Rlc3RfaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixFQUFlLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3pHLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssV0FBVyxFQUNoQixLQUFLLFVBQVUsRUFFZixLQUFLLHdCQUF3QixFQUM5QixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBbUIsS0FBSyxzQkFBc0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3hGLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUs1QyxrR0FBa0c7QUFDbEcsTUFBTSxNQUFNLGNBQWMsR0FBRztJQUMzQixRQUFRLEVBQUUsV0FBVyxDQUFDO0lBQ3RCLGlCQUFpQixFQUFFLFdBQVcsQ0FBQztJQUMvQixZQUFZLEVBQUUsZ0JBQWdCLENBQUM7SUFDL0IsNEdBQTRHO0lBQzVHLG1CQUFtQixDQUFDLEVBQUUsVUFBVSxDQUFDO0lBQ2pDLGtCQUFrQixDQUFDLEVBQUUsc0JBQXNCLENBQUM7SUFDNUMsd0dBQXdHO0lBQ3hHLGtCQUFrQixDQUFDLEVBQUU7UUFBRSxVQUFVLEVBQUUsVUFBVSxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsT0FBTyxDQUFBO0tBQUUsQ0FBQztJQUNuRSwwR0FBMEc7SUFDMUcscUJBQXFCLENBQUMsRUFBRSxPQUFPLENBQUM7SUFDaEMsNEJBQTRCLENBQUMsRUFBRSx3QkFBd0IsQ0FBQztJQUN4RCxpRkFBaUY7SUFDakYsV0FBVyxDQUFDLEVBQUUsV0FBVyxDQUFDO0NBQzNCLENBQUM7QUFFRiwrRUFBK0U7QUFDL0UsZUFBTyxNQUFNLFdBQVcseUNBQXFGLENBQUM7QUFhOUcsZUFBTyxNQUFNLFlBQVksc0NBc0J2QixDQUFDO0FBRUgsd0JBQWdCLGFBQWEsSUFBSSxTQUFTLENBRXpDO0FBRUQsd0JBQWdCLDBCQUEwQixDQUFDLElBQUksRUFBRTtJQUMvQyxnQkFBZ0IsRUFBRSxnQkFBZ0IsQ0FBQztJQUNuQyxTQUFTLEVBQUUsV0FBVyxDQUFDO0lBQ3ZCLFVBQVUsQ0FBQyxFQUFFLFVBQVUsQ0FBQztJQUN4QixXQUFXLENBQUMsRUFBRSxFQUFFLENBQUM7SUFDakIsYUFBYSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ3ZCLHFCQUFxQixDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQy9CLGlCQUFpQixDQUFDLEVBQUUsRUFBRSxDQUFDO0NBQ3hCLEdBQUcsc0JBQXNCLENBV3pCO0FBRUQsd0JBQWdCLGlCQUFpQixDQUFDLFlBQVksRUFBRSxnQkFBZ0IsR0FBRyx3QkFBd0IsQ0FrQjFGIn0=
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_helpers.d.ts","sourceRoot":"","sources":["../../../src/aztec-node/next_block/test_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAe,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACzG,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EACL,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,UAAU,EAEf,KAAK,wBAAwB,EAC9B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAmB,KAAK,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAK5C,kGAAkG;AAClG,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,WAAW,CAAC;IACtB,iBAAiB,EAAE,WAAW,CAAC;IAC/B,YAAY,EAAE,gBAAgB,CAAC;IAC/B,4GAA4G;IAC5G,mBAAmB,CAAC,EAAE,UAAU,CAAC;IACjC,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,wGAAwG;IACxG,kBAAkB,CAAC,EAAE;QAAE,UAAU,EAAE,UAAU,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACnE,0GAA0G;IAC1G,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,4BAA4B,CAAC,EAAE,wBAAwB,CAAC;IACxD,iFAAiF;IACjF,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,WAAW,yCAAqF,CAAC;AAa9G,eAAO,MAAM,YAAY,sCAsBvB,CAAC;AAEH,wBAAgB,aAAa,IAAI,SAAS,CAEzC;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,SAAS,EAAE,WAAW,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,EAAE,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,iBAAiB,CAAC,EAAE,EAAE,CAAC;CACxB,GAAG,sBAAsB,CAWzB;AAED,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,gBAAgB,GAAG,wBAAwB,CAkB1F"}
@@ -0,0 +1,100 @@
1
+ import { BlockNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
+ import { Fr } from '@aztec/foundation/curves/bn254';
3
+ import { BlockHash } from '@aztec/stdlib/block';
4
+ import { L1PublishedData } from '@aztec/stdlib/checkpoint';
5
+ import { GasFees } from '@aztec/stdlib/gas';
6
+ import { CheckpointHeader } from '@aztec/stdlib/rollup';
7
+ import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
8
+ import { BlockHeader, GlobalVariables } from '@aztec/stdlib/tx';
9
+ /** Stable per-block hash, so tips and the frontier agree on block identity. */ export const blockHashOf = (blockNumber)=>new BlockHash(new Fr(1000 + blockNumber));
10
+ const makeTips = (args)=>{
11
+ const blockId = (number)=>({
12
+ number,
13
+ hash: blockHashOf(number).toString()
14
+ });
15
+ const checkpointId = (number)=>({
16
+ number,
17
+ hash: `0xc${number}`
18
+ });
19
+ return {
20
+ proposed: blockId(args.proposed),
21
+ checkpointed: {
22
+ block: blockId(args.checkpointedBlock),
23
+ checkpoint: checkpointId(args.checkpointed)
24
+ },
25
+ proven: {
26
+ block: blockId(BlockNumber.ZERO),
27
+ checkpoint: checkpointId(args.checkpointed)
28
+ },
29
+ finalized: {
30
+ block: blockId(BlockNumber.ZERO),
31
+ checkpoint: checkpointId(args.checkpointed)
32
+ }
33
+ };
34
+ };
35
+ export const makeFrontier = (args)=>({
36
+ tips: makeTips(args),
37
+ proposedCheckpoint: args.proposedCheckpoint,
38
+ l1SyncPoint: args.l1SyncPoint,
39
+ latestBlockHeader: args.omitLatestBlockHeader || !args.latestBlockGlobals ? undefined : BlockHeader.empty({
40
+ globalVariables: GlobalVariables.empty({
41
+ blockNumber: args.proposed,
42
+ slotNumber: args.latestBlockGlobals.slotNumber,
43
+ gasFees: args.latestBlockGlobals.gasFees ?? GasFees.empty()
44
+ })
45
+ }),
46
+ checkpointedCheckpoint: args.checkpointedTipSlot === undefined ? undefined : {
47
+ header: CheckpointHeader.empty({
48
+ slotNumber: args.checkpointedTipSlot
49
+ }),
50
+ l1: new L1PublishedData(1n, 0n, `0x`)
51
+ },
52
+ pendingChainValidationStatus: args.pendingChainValidationStatus ?? {
53
+ valid: true
54
+ }
55
+ });
56
+ export function makeFeeHeader() {
57
+ return {
58
+ excessMana: 0n,
59
+ manaUsed: 0n,
60
+ ethPerFeeAsset: 0n,
61
+ congestionCost: 0n,
62
+ proverCost: 0n
63
+ };
64
+ }
65
+ export function makeProposedCheckpointData(args) {
66
+ return {
67
+ checkpointNumber: args.checkpointNumber,
68
+ header: CheckpointHeader.empty({
69
+ slotNumber: args.slotNumber ?? SlotNumber(0)
70
+ }),
71
+ startBlock: args.lastBlock,
72
+ blockCount: 1,
73
+ totalManaUsed: args.totalManaUsed ?? 555n,
74
+ feeAssetPriceModifier: args.feeAssetPriceModifier ?? 7n,
75
+ archive: new AppendOnlyTreeSnapshot(args.archiveRoot ?? Fr.ZERO, 0),
76
+ checkpointOutHash: args.checkpointOutHash ?? Fr.fromString('0xfeed')
77
+ };
78
+ }
79
+ export function makeInvalidStatus(firstInvalid) {
80
+ return {
81
+ valid: false,
82
+ checkpoint: {
83
+ archive: Fr.random(),
84
+ lastArchive: Fr.random(),
85
+ slotNumber: SlotNumber(10),
86
+ checkpointNumber: firstInvalid,
87
+ timestamp: 0n
88
+ },
89
+ committee: [],
90
+ epoch: EpochNumber.ZERO,
91
+ seed: 0n,
92
+ attestors: [],
93
+ attestations: [],
94
+ verbatimAttestations: {
95
+ signatureIndices: '0x',
96
+ signaturesOrAddresses: '0x'
97
+ },
98
+ reason: 'insufficient-attestations'
99
+ };
100
+ }
@@ -1,13 +1,10 @@
1
- import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
- import { type RollupContract } from '@aztec/ethereum/contracts';
3
1
  import { type Logger } from '@aztec/foundation/log';
4
- import type { L2BlockSource } from '@aztec/stdlib/block';
5
2
  import type { ContractDataSource } from '@aztec/stdlib/contract';
6
3
  import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
7
4
  import { type L1ToL2MessageSource } from '@aztec/stdlib/messaging';
8
- import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p';
9
- import { type GlobalVariableBuilder, PublicSimulationOutput, type SimulationOverrides, type Tx } from '@aztec/stdlib/tx';
5
+ import { PublicSimulationOutput, type SimulationOverrides, type Tx } from '@aztec/stdlib/tx';
10
6
  import { type TelemetryClient } from '@aztec/telemetry-client';
7
+ import type { NextBlockPredictor } from './next_block/index.js';
11
8
  /** Config fields the simulator needs — a narrow subset of `AztecNodeConfig`. */
12
9
  export interface NodePublicCallsSimulatorConfig {
13
10
  /** Maximum total gas limit accepted for an incoming simulation. */
@@ -17,20 +14,10 @@ export interface NodePublicCallsSimulatorConfig {
17
14
  }
18
15
  /** Dependencies required to build a {@link NodePublicCallsSimulator}. */
19
16
  export interface NodePublicCallsSimulatorDeps {
20
- blockSource: L2BlockSource;
21
17
  worldStateSynchronizer: WorldStateSynchronizer;
22
18
  l1ToL2MessageSource: L1ToL2MessageSource;
23
19
  contractDataSource: ContractDataSource;
24
- globalVariableBuilder: GlobalVariableBuilder;
25
- /**
26
- * Rollup contract used to build the fee-relevant L1 state overrides when opening a new checkpoint.
27
- * Only needed when a proposed parent checkpoint exists (pipelining) or the pending chain is invalid;
28
- * may be omitted in environments that never reach those states (e.g. TXE). When omitted, those paths
29
- * degrade to a pinned-tips plan (non-pipelined fees) instead.
30
- */
31
- rollupContract?: RollupContract;
32
- epochCache: EpochCacheInterface;
33
- signatureContext: CoordinationSignatureContext;
20
+ predictor: NextBlockPredictor;
34
21
  config: NodePublicCallsSimulatorConfig;
35
22
  telemetry?: TelemetryClient;
36
23
  log?: Logger;
@@ -38,28 +25,16 @@ export interface NodePublicCallsSimulatorDeps {
38
25
  /**
39
26
  * Simulates the public part of a transaction against a fresh world-state fork.
40
27
  *
41
- * Extracted from `AztecNodeService` so the slot/globals selection can be unit-tested without
42
- * standing up the whole node, and to keep `server.ts` smaller.
43
- *
44
- * The simulator picks globals in one of two ways, mirroring how the sequencer builds the next block:
45
- * - **When the next block continues an in-progress checkpoint** (the latest proposed block is ahead of
46
- * the proposed-checkpoint frontier): every block in a checkpoint shares the same
47
- * `CheckpointGlobalVariables`, so we copy the latest proposed block's globals verbatim and only
48
- * bump the block number. No L1 calls, no L1-to-L2 message insertion.
49
- * - **When the next block opens a new checkpoint** (the latest proposed block coincides with the
50
- * proposed-checkpoint frontier): we compute fresh globals for the slot the next block will land in,
51
- * applying the same `SimulationOverridesPlan` the sequencer applies so the simulated mana min fee
52
- * matches what the sequencer will write into the block header.
28
+ * Extracted from `AztecNodeService` so forking and execution can be unit-tested without standing up the whole
29
+ * node, and to keep `server.ts` smaller. Which block is simulated, and the globals it carries, are decided by
30
+ * the {@link NextBlockPredictor}: the simulator's job is to fork the chain that plan describes, insert the
31
+ * L1-to-L2 messages a checkpoint-opening block would see, and run the processor.
53
32
  */
54
33
  export declare class NodePublicCallsSimulator {
55
- private readonly blockSource;
56
34
  private readonly worldStateSynchronizer;
57
35
  private readonly l1ToL2MessageSource;
58
36
  private readonly contractDataSource;
59
- private readonly globalVariableBuilder;
60
- private readonly rollupContract;
61
- private readonly epochCache;
62
- private readonly signatureContext;
37
+ private readonly predictor;
63
38
  private readonly config;
64
39
  private readonly telemetry;
65
40
  private readonly log;
@@ -71,20 +46,7 @@ export declare class NodePublicCallsSimulator {
71
46
  * @param overrides - Optional pre-simulation overrides applied to the ephemeral fork and contract DB.
72
47
  */
73
48
  simulate(tx: Tx, skipFeeEnforcement?: boolean, overrides?: SimulationOverrides): Promise<PublicSimulationOutput>;
49
+ private prepareNextBlock;
74
50
  private getNextCheckpointMessages;
75
- private copyGlobalVariablesFromLatestProposedBlock;
76
- private buildGlobalVariablesForNewCheckpoint;
77
- /**
78
- * Slot the next block will land in. The first term is the sequencer's exact formula
79
- * (`getEpochAndSlotInNextL1Slot().slot + PROPOSER_PIPELINING_SLOT_OFFSET`). The `max` with
80
- * `proposedCheckpointSlot + 1` is an RPC-side approximation of the next build: when a proposed
81
- * checkpoint is gossiped before its L1 slot starts, the next build (once its wall clock arrives)
82
- * will target `parentSlot + 1`. The sequencer never advances its own target past wall clock — it
83
- * just declines to build — so this is a prediction of inclusion globals, not literal sequencer
84
- * behavior. The parent slot comes from the proposed checkpoint header so the slot and the
85
- * overrides plan cannot derive from different snapshots.
86
- */
87
- private computeTargetSlot;
88
- private buildSimulationOverridesPlan;
89
51
  }
90
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9wdWJsaWNfY2FsbHNfc2ltdWxhdG9yLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXp0ZWMtbm9kZS9ub2RlX3B1YmxpY19jYWxsc19zaW11bGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM5RCxPQUFPLEVBQ0wsS0FBSyxjQUFjLEVBR3BCLE1BQU0sMkJBQTJCLENBQUM7QUFNbkMsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBTWxFLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBVSxNQUFNLHFCQUFxQixDQUFDO0FBRWpFLE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakUsT0FBTyxLQUFLLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsS0FBSyxtQkFBbUIsRUFBOEIsTUFBTSx5QkFBeUIsQ0FBQztBQUMvRixPQUFPLEtBQUssRUFBRSw0QkFBNEIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3RFLE9BQU8sRUFDTCxLQUFLLHFCQUFxQixFQUUxQixzQkFBc0IsRUFDdEIsS0FBSyxtQkFBbUIsRUFDeEIsS0FBSyxFQUFFLEVBQ1IsTUFBTSxrQkFBa0IsQ0FBQztBQUMxQixPQUFPLEVBQUUsS0FBSyxlQUFlLEVBQXNCLE1BQU0seUJBQXlCLENBQUM7QUFJbkYsa0ZBQWdGO0FBQ2hGLE1BQU0sV0FBVyw4QkFBOEI7SUFDN0MsbUVBQW1FO0lBQ25FLDRCQUE0QixFQUFFLE1BQU0sQ0FBQztJQUNyQyw0RUFBNEU7SUFDNUUsdUNBQXVDLEVBQUUsTUFBTSxDQUFDO0NBQ2pEO0FBRUQseUVBQXlFO0FBQ3pFLE1BQU0sV0FBVyw0QkFBNEI7SUFDM0MsV0FBVyxFQUFFLGFBQWEsQ0FBQztJQUMzQixzQkFBc0IsRUFBRSxzQkFBc0IsQ0FBQztJQUMvQyxtQkFBbUIsRUFBRSxtQkFBbUIsQ0FBQztJQUN6QyxrQkFBa0IsRUFBRSxrQkFBa0IsQ0FBQztJQUN2QyxxQkFBcUIsRUFBRSxxQkFBcUIsQ0FBQztJQUM3Qzs7Ozs7T0FLRztJQUNILGNBQWMsQ0FBQyxFQUFFLGNBQWMsQ0FBQztJQUNoQyxVQUFVLEVBQUUsbUJBQW1CLENBQUM7SUFDaEMsZ0JBQWdCLEVBQUUsNEJBQTRCLENBQUM7SUFDL0MsTUFBTSxFQUFFLDhCQUE4QixDQUFDO0lBQ3ZDLFNBQVMsQ0FBQyxFQUFFLGVBQWUsQ0FBQztJQUM1QixHQUFHLENBQUMsRUFBRSxNQUFNLENBQUM7Q0FDZDtBQUVEOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILHFCQUFhLHdCQUF3QjtJQUNuQyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBZ0I7SUFDNUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxzQkFBc0IsQ0FBeUI7SUFDaEUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBc0I7SUFDMUQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBcUI7SUFDeEQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBd0I7SUFDOUQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQTZCO0lBQzVELE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFzQjtJQUNqRCxPQUFPLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUErQjtJQUNoRSxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBaUM7SUFDeEQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQWtCO0lBQzVDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFTO0lBRTdCLFlBQVksSUFBSSxFQUFFLDRCQUE0QixFQVk3QztJQUVEOzs7OztPQUtHO0lBQ1UsUUFBUSxDQUNuQixFQUFFLEVBQUUsRUFBRSxFQUNOLGtCQUFrQixVQUFRLEVBQzFCLFNBQVMsQ0FBQyxFQUFFLG1CQUFtQixHQUM5QixPQUFPLENBQUMsc0JBQXNCLENBQUMsQ0EwR2pDO1lBVWEseUJBQXlCO1lBbUN6QiwwQ0FBMEM7WUF1QjFDLG9DQUFvQztJQTJCbEQ7Ozs7Ozs7OztPQVNHO0lBQ0gsT0FBTyxDQUFDLGlCQUFpQjtZQW1CWCw0QkFBNEI7Q0FrQzNDIn0=
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9wdWJsaWNfY2FsbHNfc2ltdWxhdG9yLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXp0ZWMtbm9kZS9ub2RlX3B1YmxpY19jYWxsc19zaW11bGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBTWxFLE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakUsT0FBTyxLQUFLLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsS0FBSyxtQkFBbUIsRUFBOEIsTUFBTSx5QkFBeUIsQ0FBQztBQUMvRixPQUFPLEVBQXdCLHNCQUFzQixFQUFFLEtBQUssbUJBQW1CLEVBQUUsS0FBSyxFQUFFLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNuSCxPQUFPLEVBQUUsS0FBSyxlQUFlLEVBQXNCLE1BQU0seUJBQXlCLENBQUM7QUFHbkYsT0FBTyxLQUFLLEVBQWlCLGtCQUFrQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFNL0Usa0ZBQWdGO0FBQ2hGLE1BQU0sV0FBVyw4QkFBOEI7SUFDN0MsbUVBQW1FO0lBQ25FLDRCQUE0QixFQUFFLE1BQU0sQ0FBQztJQUNyQyw0RUFBNEU7SUFDNUUsdUNBQXVDLEVBQUUsTUFBTSxDQUFDO0NBQ2pEO0FBRUQseUVBQXlFO0FBQ3pFLE1BQU0sV0FBVyw0QkFBNEI7SUFDM0Msc0JBQXNCLEVBQUUsc0JBQXNCLENBQUM7SUFDL0MsbUJBQW1CLEVBQUUsbUJBQW1CLENBQUM7SUFDekMsa0JBQWtCLEVBQUUsa0JBQWtCLENBQUM7SUFDdkMsU0FBUyxFQUFFLGtCQUFrQixDQUFDO0lBQzlCLE1BQU0sRUFBRSw4QkFBOEIsQ0FBQztJQUN2QyxTQUFTLENBQUMsRUFBRSxlQUFlLENBQUM7SUFDNUIsR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDO0NBQ2Q7QUFVRDs7Ozs7OztHQU9HO0FBQ0gscUJBQWEsd0JBQXdCO0lBQ25DLE9BQU8sQ0FBQyxRQUFRLENBQUMsc0JBQXNCLENBQXlCO0lBQ2hFLE9BQU8sQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQXNCO0lBQzFELE9BQU8sQ0FBQyxRQUFRLENBQUMsa0JBQWtCLENBQXFCO0lBQ3hELE9BQU8sQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFxQjtJQUMvQyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBaUM7SUFDeEQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQWtCO0lBQzVDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFTO0lBRTdCLFlBQVksSUFBSSxFQUFFLDRCQUE0QixFQVE3QztJQUVEOzs7OztPQUtHO0lBQ1UsUUFBUSxDQUNuQixFQUFFLEVBQUUsRUFBRSxFQUNOLGtCQUFrQixVQUFRLEVBQzFCLFNBQVMsQ0FBQyxFQUFFLG1CQUFtQixHQUM5QixPQUFPLENBQUMsc0JBQXNCLENBQUMsQ0E4RWpDO1lBUWEsZ0JBQWdCO1lBb0NoQix5QkFBeUI7Q0FzQnhDIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"node_public_calls_simulator.d.ts","sourceRoot":"","sources":["../../src/aztec-node/node_public_calls_simulator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EACL,KAAK,cAAc,EAGpB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAMlE,OAAO,KAAK,EAAE,aAAa,EAAU,MAAM,qBAAqB,CAAC;AAEjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,KAAK,mBAAmB,EAA8B,MAAM,yBAAyB,CAAC;AAC/F,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EACL,KAAK,qBAAqB,EAE1B,sBAAsB,EACtB,KAAK,mBAAmB,EACxB,KAAK,EAAE,EACR,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAInF,kFAAgF;AAChF,MAAM,WAAW,8BAA8B;IAC7C,mEAAmE;IACnE,4BAA4B,EAAE,MAAM,CAAC;IACrC,4EAA4E;IAC5E,uCAAuC,EAAE,MAAM,CAAC;CACjD;AAED,yEAAyE;AACzE,MAAM,WAAW,4BAA4B;IAC3C,WAAW,EAAE,aAAa,CAAC;IAC3B,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C;;;;;OAKG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,UAAU,EAAE,mBAAmB,CAAC;IAChC,gBAAgB,EAAE,4BAA4B,CAAC;IAC/C,MAAM,EAAE,8BAA8B,CAAC;IACvC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgB;IAC5C,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAyB;IAChE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsB;IAC1D,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;IACxD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAwB;IAC9D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAC5D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;IACjD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA+B;IAChE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;IAC5C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,YAAY,IAAI,EAAE,4BAA4B,EAY7C;IAED;;;;;OAKG;IACU,QAAQ,CACnB,EAAE,EAAE,EAAE,EACN,kBAAkB,UAAQ,EAC1B,SAAS,CAAC,EAAE,mBAAmB,GAC9B,OAAO,CAAC,sBAAsB,CAAC,CA0GjC;YAUa,yBAAyB;YAmCzB,0CAA0C;YAuB1C,oCAAoC;IA2BlD;;;;;;;;;OASG;IACH,OAAO,CAAC,iBAAiB;YAmBX,4BAA4B;CAkC3C"}
1
+ {"version":3,"file":"node_public_calls_simulator.d.ts","sourceRoot":"","sources":["../../src/aztec-node/node_public_calls_simulator.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAMlE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,KAAK,mBAAmB,EAA8B,MAAM,yBAAyB,CAAC;AAC/F,OAAO,EAAwB,sBAAsB,EAAE,KAAK,mBAAmB,EAAE,KAAK,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACnH,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAGnF,OAAO,KAAK,EAAiB,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAM/E,kFAAgF;AAChF,MAAM,WAAW,8BAA8B;IAC7C,mEAAmE;IACnE,4BAA4B,EAAE,MAAM,CAAC;IACrC,4EAA4E;IAC5E,uCAAuC,EAAE,MAAM,CAAC;CACjD;AAED,yEAAyE;AACzE,MAAM,WAAW,4BAA4B;IAC3C,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,MAAM,EAAE,8BAA8B,CAAC;IACvC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAUD;;;;;;;GAOG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAyB;IAChE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsB;IAC1D,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;IAC5C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,YAAY,IAAI,EAAE,4BAA4B,EAQ7C;IAED;;;;;OAKG;IACU,QAAQ,CACnB,EAAE,EAAE,EAAE,EACN,kBAAkB,UAAQ,EAC1B,SAAS,CAAC,EAAE,mBAAmB,GAC9B,OAAO,CAAC,sBAAsB,CAAC,CA8EjC;YAQa,gBAAgB;YAoChB,yBAAyB;CAsBxC"}