@aztec/stdlib 6.0.0-nightly.20260810 → 6.0.0-nightly.20260821

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 (228) hide show
  1. package/dest/abi/abi.d.ts +4 -3
  2. package/dest/abi/abi.d.ts.map +1 -1
  3. package/dest/abi/abi.js +5 -1
  4. package/dest/abi/contract_artifact.d.ts +7 -2
  5. package/dest/abi/contract_artifact.d.ts.map +1 -1
  6. package/dest/abi/contract_artifact.js +18 -19
  7. package/dest/avm/avm.d.ts +3 -2
  8. package/dest/avm/avm.d.ts.map +1 -1
  9. package/dest/avm/avm.js +9 -3
  10. package/dest/avm/avm_proving_request.d.ts +70 -70
  11. package/dest/block/l2_block.d.ts +1 -2
  12. package/dest/block/l2_block.d.ts.map +1 -1
  13. package/dest/block/l2_block.js +2 -3
  14. package/dest/block/l2_block_source.d.ts +3 -6
  15. package/dest/block/l2_block_source.d.ts.map +1 -1
  16. package/dest/block/l2_block_stream/event_driven_l2_block_stream.d.ts +11 -20
  17. package/dest/block/l2_block_stream/event_driven_l2_block_stream.d.ts.map +1 -1
  18. package/dest/block/l2_block_stream/event_driven_l2_block_stream.js +12 -116
  19. package/dest/checkpoint/checkpoint_data.d.ts +14 -2
  20. package/dest/checkpoint/checkpoint_data.d.ts.map +1 -1
  21. package/dest/checkpoint/checkpoint_data.js +2 -1
  22. package/dest/checkpoint/index.d.ts +2 -1
  23. package/dest/checkpoint/index.d.ts.map +1 -1
  24. package/dest/checkpoint/index.js +1 -0
  25. package/dest/checkpoint/previous_checkpoint_inbox_rolling_hash.d.ts +21 -0
  26. package/dest/checkpoint/previous_checkpoint_inbox_rolling_hash.d.ts.map +1 -0
  27. package/dest/checkpoint/previous_checkpoint_inbox_rolling_hash.js +34 -0
  28. package/dest/checkpoint/simulation_overrides.d.ts +2 -2
  29. package/dest/checkpoint/simulation_overrides.d.ts.map +1 -1
  30. package/dest/checkpoint/simulation_overrides.js +11 -8
  31. package/dest/config/network-consensus-config.d.ts +4 -3
  32. package/dest/config/network-consensus-config.d.ts.map +1 -1
  33. package/dest/config/network-consensus-config.js +9 -4
  34. package/dest/config/node-rpc-config.d.ts +13 -1
  35. package/dest/config/node-rpc-config.d.ts.map +1 -1
  36. package/dest/config/node-rpc-config.js +34 -1
  37. package/dest/deserialization/index.d.ts +17 -17
  38. package/dest/deserialization/index.d.ts.map +1 -1
  39. package/dest/deserialization/index.js +18 -18
  40. package/dest/gas/gas_settings.d.ts +17 -5
  41. package/dest/gas/gas_settings.d.ts.map +1 -1
  42. package/dest/gas/gas_settings.js +4 -4
  43. package/dest/gas/tx_gas_limits.d.ts +3 -4
  44. package/dest/gas/tx_gas_limits.d.ts.map +1 -1
  45. package/dest/gas/tx_gas_limits.js +4 -5
  46. package/dest/interfaces/archiver.d.ts +2 -2
  47. package/dest/interfaces/archiver.d.ts.map +1 -1
  48. package/dest/interfaces/archiver.js +32 -5
  49. package/dest/interfaces/aztec-node-admin.d.ts +2 -1
  50. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  51. package/dest/interfaces/aztec-node.d.ts +22 -4
  52. package/dest/interfaces/aztec-node.d.ts.map +1 -1
  53. package/dest/interfaces/aztec-node.js +11 -9
  54. package/dest/interfaces/block-builder.d.ts +11 -2
  55. package/dest/interfaces/block-builder.d.ts.map +1 -1
  56. package/dest/interfaces/configs.d.ts +7 -1
  57. package/dest/interfaces/configs.d.ts.map +1 -1
  58. package/dest/interfaces/configs.js +2 -1
  59. package/dest/interfaces/p2p.d.ts +18 -1
  60. package/dest/interfaces/p2p.d.ts.map +1 -1
  61. package/dest/interfaces/p2p.js +8 -0
  62. package/dest/interfaces/proving-job.d.ts +17 -42
  63. package/dest/interfaces/proving-job.d.ts.map +1 -1
  64. package/dest/interfaces/proving-job.js +16 -47
  65. package/dest/interfaces/server_circuit_prover.d.ts +8 -15
  66. package/dest/interfaces/server_circuit_prover.d.ts.map +1 -1
  67. package/dest/interfaces/validator.d.ts +7 -7
  68. package/dest/interfaces/validator.d.ts.map +1 -1
  69. package/dest/messaging/append_l1_to_l2_messages.d.ts +5 -5
  70. package/dest/messaging/append_l1_to_l2_messages.d.ts.map +1 -1
  71. package/dest/messaging/append_l1_to_l2_messages.js +4 -8
  72. package/dest/messaging/inbox_bucket.d.ts +77 -0
  73. package/dest/messaging/inbox_bucket.d.ts.map +1 -0
  74. package/dest/messaging/inbox_bucket.js +73 -0
  75. package/dest/messaging/inbox_consumption.d.ts +55 -0
  76. package/dest/messaging/inbox_consumption.d.ts.map +1 -0
  77. package/dest/messaging/inbox_consumption.js +53 -0
  78. package/dest/messaging/inbox_rolling_hash.d.ts +16 -0
  79. package/dest/messaging/inbox_rolling_hash.d.ts.map +1 -0
  80. package/dest/messaging/inbox_rolling_hash.js +23 -0
  81. package/dest/messaging/index.d.ts +6 -3
  82. package/dest/messaging/index.d.ts.map +1 -1
  83. package/dest/messaging/index.js +5 -2
  84. package/dest/messaging/l1_to_l2_message_bundle.d.ts +31 -0
  85. package/dest/messaging/l1_to_l2_message_bundle.d.ts.map +1 -0
  86. package/dest/messaging/l1_to_l2_message_bundle.js +51 -0
  87. package/dest/messaging/l1_to_l2_message_source.d.ts +44 -10
  88. package/dest/messaging/l1_to_l2_message_source.d.ts.map +1 -1
  89. package/dest/messaging/l1_to_l2_message_sponge.d.ts +40 -0
  90. package/dest/messaging/l1_to_l2_message_sponge.d.ts.map +1 -0
  91. package/dest/messaging/l1_to_l2_message_sponge.js +56 -0
  92. package/dest/noir/index.d.ts +3 -3
  93. package/dest/noir/index.d.ts.map +1 -1
  94. package/dest/p2p/block_proposal.d.ts +24 -9
  95. package/dest/p2p/block_proposal.d.ts.map +1 -1
  96. package/dest/p2p/block_proposal.js +42 -20
  97. package/dest/p2p/checkpoint_attestation.d.ts +1 -1
  98. package/dest/p2p/checkpoint_proposal.d.ts +13 -3
  99. package/dest/p2p/checkpoint_proposal.d.ts.map +1 -1
  100. package/dest/p2p/checkpoint_proposal.js +26 -8
  101. package/dest/p2p/consensus_payload.d.ts +1 -1
  102. package/dest/p2p/index.d.ts +2 -1
  103. package/dest/p2p/index.d.ts.map +1 -1
  104. package/dest/p2p/index.js +1 -0
  105. package/dest/p2p/validated_proposal.d.ts +35 -0
  106. package/dest/p2p/validated_proposal.d.ts.map +1 -0
  107. package/dest/p2p/validated_proposal.js +17 -0
  108. package/dest/p2p/wire_compat_fixtures.d.ts +7 -0
  109. package/dest/p2p/wire_compat_fixtures.d.ts.map +1 -0
  110. package/dest/p2p/wire_compat_fixtures.js +14 -0
  111. package/dest/parity/inbox_parity_private_inputs.d.ts +61 -0
  112. package/dest/parity/inbox_parity_private_inputs.d.ts.map +1 -0
  113. package/dest/parity/inbox_parity_private_inputs.js +79 -0
  114. package/dest/parity/index.d.ts +2 -3
  115. package/dest/parity/index.d.ts.map +1 -1
  116. package/dest/parity/index.js +1 -2
  117. package/dest/parity/parity_public_inputs.d.ts +15 -14
  118. package/dest/parity/parity_public_inputs.d.ts.map +1 -1
  119. package/dest/parity/parity_public_inputs.js +13 -15
  120. package/dest/proofs/proving_request_type.d.ts +11 -14
  121. package/dest/proofs/proving_request_type.d.ts.map +1 -1
  122. package/dest/proofs/proving_request_type.js +10 -13
  123. package/dest/rollup/block_constant_data.d.ts +8 -8
  124. package/dest/rollup/block_constant_data.js +4 -4
  125. package/dest/rollup/block_rollup_public_inputs.d.ts +18 -6
  126. package/dest/rollup/block_rollup_public_inputs.d.ts.map +1 -1
  127. package/dest/rollup/block_rollup_public_inputs.js +14 -7
  128. package/dest/rollup/block_root_rollup_private_inputs.d.ts +109 -113
  129. package/dest/rollup/block_root_rollup_private_inputs.d.ts.map +1 -1
  130. package/dest/rollup/block_root_rollup_private_inputs.js +79 -130
  131. package/dest/rollup/checkpoint_header.d.ts +14 -6
  132. package/dest/rollup/checkpoint_header.d.ts.map +1 -1
  133. package/dest/rollup/checkpoint_header.js +18 -14
  134. package/dest/rollup/checkpoint_rollup_public_inputs.d.ts +22 -2
  135. package/dest/rollup/checkpoint_rollup_public_inputs.d.ts.map +1 -1
  136. package/dest/rollup/checkpoint_rollup_public_inputs.js +14 -3
  137. package/dest/rollup/checkpoint_root_rollup_private_inputs.d.ts +27 -6
  138. package/dest/rollup/checkpoint_root_rollup_private_inputs.d.ts.map +1 -1
  139. package/dest/rollup/checkpoint_root_rollup_private_inputs.js +17 -4
  140. package/dest/rollup/root_rollup_public_inputs.d.ts +10 -2
  141. package/dest/rollup/root_rollup_public_inputs.d.ts.map +1 -1
  142. package/dest/rollup/root_rollup_public_inputs.js +9 -3
  143. package/dest/stats/stats.d.ts +2 -2
  144. package/dest/stats/stats.d.ts.map +1 -1
  145. package/dest/tests/factories.d.ts +7 -7
  146. package/dest/tests/factories.d.ts.map +1 -1
  147. package/dest/tests/factories.js +26 -22
  148. package/dest/tests/fixtures.d.ts +1 -1
  149. package/dest/tests/fixtures.d.ts.map +1 -1
  150. package/dest/tests/fixtures.js +2 -0
  151. package/dest/tests/mocks.d.ts +4 -2
  152. package/dest/tests/mocks.d.ts.map +1 -1
  153. package/dest/tests/mocks.js +4 -7
  154. package/dest/tx/state_reference.d.ts +5 -2
  155. package/dest/tx/state_reference.d.ts.map +1 -1
  156. package/dest/tx/state_reference.js +5 -5
  157. package/package.json +8 -8
  158. package/src/abi/abi.ts +7 -2
  159. package/src/abi/contract_artifact.ts +20 -23
  160. package/src/avm/avm.ts +11 -1
  161. package/src/block/l2_block.ts +2 -3
  162. package/src/block/l2_block_source.ts +2 -5
  163. package/src/block/l2_block_stream/event_driven_l2_block_stream.ts +17 -143
  164. package/src/checkpoint/checkpoint_data.ts +14 -1
  165. package/src/checkpoint/index.ts +1 -0
  166. package/src/checkpoint/previous_checkpoint_inbox_rolling_hash.ts +46 -0
  167. package/src/checkpoint/simulation_overrides.ts +11 -8
  168. package/src/config/network-consensus-config.ts +17 -4
  169. package/src/config/node-rpc-config.ts +51 -1
  170. package/src/deserialization/index.ts +18 -18
  171. package/src/gas/README.md +4 -3
  172. package/src/gas/gas_settings.ts +7 -3
  173. package/src/gas/tx_gas_limits.ts +4 -12
  174. package/src/interfaces/archiver.ts +19 -2
  175. package/src/interfaces/aztec-node.ts +33 -12
  176. package/src/interfaces/block-builder.ts +10 -1
  177. package/src/interfaces/configs.ts +6 -0
  178. package/src/interfaces/p2p.ts +21 -0
  179. package/src/interfaces/proving-job.ts +19 -70
  180. package/src/interfaces/server_circuit_prover.ts +13 -37
  181. package/src/interfaces/validator.ts +6 -5
  182. package/src/kernel/private_kernel_reset_dimensions.ts +1 -1
  183. package/src/messaging/append_l1_to_l2_messages.ts +5 -13
  184. package/src/messaging/inbox_bucket.ts +125 -0
  185. package/src/messaging/inbox_consumption.ts +74 -0
  186. package/src/messaging/inbox_rolling_hash.ts +24 -0
  187. package/src/messaging/index.ts +5 -2
  188. package/src/messaging/l1_to_l2_message_bundle.ts +65 -0
  189. package/src/messaging/l1_to_l2_message_source.ts +48 -10
  190. package/src/messaging/l1_to_l2_message_sponge.ts +69 -0
  191. package/src/noir/index.ts +1 -2
  192. package/src/p2p/block_proposal.ts +41 -28
  193. package/src/p2p/checkpoint_proposal.ts +31 -6
  194. package/src/p2p/index.ts +1 -0
  195. package/src/p2p/validated_proposal.ts +43 -0
  196. package/src/p2p/wire_compat_fixtures.ts +23 -0
  197. package/src/parity/inbox_parity_private_inputs.ts +116 -0
  198. package/src/parity/index.ts +1 -2
  199. package/src/parity/parity_public_inputs.ts +12 -14
  200. package/src/proofs/proving_request_type.ts +2 -5
  201. package/src/rollup/block_constant_data.ts +4 -4
  202. package/src/rollup/block_rollup_public_inputs.ts +14 -5
  203. package/src/rollup/block_root_rollup_private_inputs.ts +117 -153
  204. package/src/rollup/checkpoint_header.ts +17 -13
  205. package/src/rollup/checkpoint_rollup_public_inputs.ts +15 -0
  206. package/src/rollup/checkpoint_root_rollup_private_inputs.ts +16 -3
  207. package/src/rollup/root_rollup_public_inputs.ts +10 -0
  208. package/src/stats/stats.ts +4 -5
  209. package/src/tests/factories.ts +38 -32
  210. package/src/tests/fixtures.ts +3 -0
  211. package/src/tests/mocks.ts +6 -7
  212. package/src/tx/state_reference.ts +5 -12
  213. package/dest/messaging/in_hash.d.ts +0 -6
  214. package/dest/messaging/in_hash.d.ts.map +0 -1
  215. package/dest/messaging/in_hash.js +0 -10
  216. package/dest/messaging/inbox_leaf.d.ts +0 -25
  217. package/dest/messaging/inbox_leaf.d.ts.map +0 -1
  218. package/dest/messaging/inbox_leaf.js +0 -42
  219. package/dest/parity/parity_base_private_inputs.d.ts +0 -39
  220. package/dest/parity/parity_base_private_inputs.d.ts.map +0 -1
  221. package/dest/parity/parity_base_private_inputs.js +0 -51
  222. package/dest/parity/parity_root_private_inputs.d.ts +0 -39
  223. package/dest/parity/parity_root_private_inputs.d.ts.map +0 -1
  224. package/dest/parity/parity_root_private_inputs.js +0 -46
  225. package/src/messaging/in_hash.ts +0 -12
  226. package/src/messaging/inbox_leaf.ts +0 -44
  227. package/src/parity/parity_base_private_inputs.ts +0 -71
  228. package/src/parity/parity_root_private_inputs.ts +0 -64
@@ -1,156 +1,51 @@
1
- import { type Logger, createLogger } from '@aztec/foundation/log';
1
+ import { createLogger } from '@aztec/foundation/log';
2
2
  import { RunningPromise } from '@aztec/foundation/running-promise';
3
3
 
4
- import type { BlockData } from '../block_data.js';
5
- import type { L2Block } from '../l2_block.js';
6
4
  import {
7
5
  type ArchiverEmitter,
8
- type BlockQuery,
9
- type BlocksQuery,
10
6
  type L2BlockSource,
11
7
  type L2BlockSourceEventEmitter,
12
8
  L2BlockSourceEvents,
13
- type L2BlockSourceUpdatedEvent,
14
- type L2Tips,
15
9
  } from '../l2_block_source.js';
16
- import { type L2BlockStreamEventHandler, type L2BlockStreamLocalDataProvider, localTipsMatch } from './interfaces.js';
17
- import { L2BlockStream, type L2BlockStreamOptions, type L2BlockStreamSource } from './l2_block_stream.js';
18
-
19
- /** Derives the metadata-only {@link BlockData} view of a hydrated {@link L2Block}. */
20
- async function l2BlockToBlockData(block: L2Block): Promise<BlockData> {
21
- return {
22
- header: block.header,
23
- archive: block.archive,
24
- blockHash: await block.hash(),
25
- checkpointNumber: block.checkpointNumber,
26
- indexWithinCheckpoint: block.indexWithinCheckpoint,
27
- };
28
- }
10
+ import type { L2BlockStreamEventHandler, L2BlockStreamLocalDataProvider } from './interfaces.js';
11
+ import { L2BlockStream, type L2BlockStreamOptions } from './l2_block_stream.js';
29
12
 
30
13
  /** Returns the event emitter of a source that exposes one, or undefined for plain (e.g. RPC-backed) sources. */
31
14
  function getEmitter(source: L2BlockSource | L2BlockSourceEventEmitter): ArchiverEmitter | undefined {
32
15
  return 'events' in source ? source.events : undefined;
33
16
  }
34
17
 
35
- /** Fast-path context for a single sync pass: blocks to serve by number, plus the tips to report as the source's. */
36
- type ActiveUpdate = { byNumber: Map<number, L2Block>; toTips: L2Tips };
37
-
38
- /**
39
- * Wraps a block source so a single sync pass can be served from blocks delivered by an aggregate update event,
40
- * avoiding round-trips to archiver storage. The fast path is only armed (via {@link activate}) for a pass that is
41
- * confirmed caught up to the event's pre-pass tips: in that case the event's `blocksAdded` contiguously cover the
42
- * pass's download range and `toTips` is the exact post-pass tip, so `getL2Tips` can report it without querying the
43
- * source. When the fast path is not armed, every read delegates to the source, so a stale or partial cache never
44
- * changes the sync outcome.
45
- */
46
- class HotBlockSourceAdapter implements L2BlockStreamSource {
47
- /** Set for the duration of one fast-path pass; undefined when reads must delegate to the source. */
48
- private active: ActiveUpdate | undefined;
49
-
50
- constructor(
51
- private readonly source: L2BlockStreamSource,
52
- private readonly log: Logger,
53
- ) {}
54
-
55
- /** Arms the fast path for the current pass: serve these blocks and report `toTips` as the source tips. */
56
- public activate(blocks: readonly L2Block[], toTips: L2Tips): void {
57
- const byNumber = new Map<number, L2Block>();
58
- for (const block of blocks) {
59
- byNumber.set(block.number, block);
60
- }
61
- this.active = { byNumber, toTips };
62
- this.log.trace(`Armed hot-block fast path`, { blocks: byNumber.size, toTips });
63
- }
64
-
65
- /** Disarms the fast path so subsequent reads delegate to the source again. */
66
- public deactivate(): void {
67
- this.active = undefined;
68
- }
69
-
70
- public getL2Tips(): Promise<L2Tips> {
71
- return this.active ? Promise.resolve(this.active.toTips) : this.source.getL2Tips();
72
- }
73
-
74
- public getBlocks(query: BlocksQuery): Promise<L2Block[]> {
75
- const served = this.active ? this.tryServeBlocksFromCache(query) : undefined;
76
- return served ? Promise.resolve(served) : this.source.getBlocks(query);
77
- }
78
-
79
- public getBlockData(query: BlockQuery): Promise<BlockData | undefined> {
80
- if (this.active && 'number' in query) {
81
- const block = this.active.byNumber.get(query.number);
82
- if (block) {
83
- return l2BlockToBlockData(block);
84
- }
85
- }
86
- return this.source.getBlockData(query);
87
- }
88
-
89
- /** Serves a block range from the cache only when it is fully covered by contiguous cached blocks. */
90
- private tryServeBlocksFromCache(query: BlocksQuery): L2Block[] | undefined {
91
- // Only the by-range form is cacheable, and only for the full (not checkpointed-only) chain: the cache may hold
92
- // uncheckpointed blocks that an onlyCheckpointed query must not receive.
93
- if (!this.active || !('from' in query) || query.onlyCheckpointed) {
94
- return undefined;
95
- }
96
- const from = query.from;
97
- const to = from + query.limit - 1;
98
- const blocks: L2Block[] = [];
99
- for (let n = from; n <= to; n++) {
100
- const block = this.active.byNumber.get(n);
101
- if (!block) {
102
- // A gap inside the requested range: bail out and let the source serve the whole range.
103
- return undefined;
104
- }
105
- blocks.push(block);
106
- }
107
- return blocks;
108
- }
109
- }
110
-
111
18
  /**
112
19
  * Event-driven wrapper around {@link L2BlockStream}. Subscribes to the source's aggregate `l2BlockSourceUpdated`
113
- * event (when the source exposes one) to trigger an immediate reconciliation, while keeping the periodic poll as
114
- * the correctness fallback. Subsystems keep consuming the same {@link L2BlockStreamEvent}s; the archiver aggregate
115
- * event is handled entirely here.
116
- *
117
- * The event is passed through to the sync pass via {@link RunningPromise.trigger}. If, at the time the pass runs,
118
- * the stream's local tips match the event's `fromTips` (it is caught up to where the event began), the event's
119
- * hydrated blocks are served back through a hot-block cache and the event's `toTips` is reported as the source tips
120
- * — so the triggered sync re-reads neither block bodies nor tips from the archiver. Otherwise the pass delegates
121
- * entirely to the source, and the periodic poll guarantees eventual catch-up.
20
+ * event (when the source exposes one) and uses it purely as a doorbell: each event triggers an immediate
21
+ * reconciliation pass instead of waiting for the next tick, while the periodic poll remains the correctness
22
+ * fallback. Every pass reads tips and blocks authoritatively from the source, so a missed, stale, or duplicated
23
+ * event only affects latency. Subsystems keep consuming the same {@link L2BlockStreamEvent}s; the archiver
24
+ * aggregate event is handled entirely here.
122
25
  */
123
26
  export class EventDrivenL2BlockStream {
124
- private readonly adapter: HotBlockSourceAdapter;
125
27
  private readonly blockStream: L2BlockStream;
126
- private readonly runningPromise: RunningPromise<L2BlockSourceUpdatedEvent>;
28
+ private readonly runningPromise: RunningPromise;
127
29
  private readonly emitter: ArchiverEmitter | undefined;
128
30
  private started = false;
129
31
 
130
- private readonly onSourceUpdated = (event: L2BlockSourceUpdatedEvent) => {
32
+ private readonly onSourceUpdated = () => {
131
33
  // Fire-and-forget: trigger coalesces with any in-flight or periodic pass (see RunningPromise.trigger), so a
132
34
  // burst of events does not run passes concurrently. Errors are swallowed by the inner stream's own handler.
133
- void this.runningPromise
134
- .trigger(event)
135
- .catch(err => this.log.error(`Error in event-triggered block stream sync`, err));
35
+ void this.runningPromise.trigger().catch(err => this.log.error(`Error in event-triggered block stream sync`, err));
136
36
  };
137
37
 
138
38
  constructor(
139
39
  source: L2BlockSource | L2BlockSourceEventEmitter,
140
- private readonly localData: L2BlockStreamLocalDataProvider,
40
+ localData: L2BlockStreamLocalDataProvider,
141
41
  handler: L2BlockStreamEventHandler,
142
42
  private readonly log = createLogger('types:event_driven_block_stream'),
143
43
  opts: L2BlockStreamOptions = {},
144
44
  ) {
145
- this.adapter = new HotBlockSourceAdapter(source, log);
146
45
  // The inner stream's own RunningPromise is never started; this wrapper owns the polling loop and drives the
147
46
  // stream through `sync()` (which runs `work()` directly when the inner loop is stopped).
148
- this.blockStream = new L2BlockStream(this.adapter, localData, handler, log, opts);
149
- this.runningPromise = new RunningPromise<L2BlockSourceUpdatedEvent>(
150
- this.runPass.bind(this),
151
- log,
152
- opts.pollIntervalMS ?? 1000,
153
- );
47
+ this.blockStream = new L2BlockStream(source, localData, handler, log, opts);
48
+ this.runningPromise = new RunningPromise(() => this.blockStream.sync(), log, opts.pollIntervalMS ?? 1000);
154
49
  this.emitter = getEmitter(source);
155
50
  }
156
51
 
@@ -176,32 +71,11 @@ export class EventDrivenL2BlockStream {
176
71
  }
177
72
 
178
73
  /**
179
- * Runs a synchronization pass now, bypassing the poll interval, and resolves once that pass completes. Concurrent
180
- * callers and periodic ticks coalesce onto a single pass; a caller that coalesces onto an already in-flight pass
181
- * can resolve against a pass that began just before it, so this guarantees freshness only up to that coalescing
182
- * window. The periodic poll and per-pass reorg handling make the gap a latency effect, never a correctness one.
74
+ * Runs a synchronization pass now, bypassing the poll interval. Resolves once a pass that started after this call
75
+ * completes, so the caller observes state at least as fresh as the moment it asked. Concurrent callers coalesce
76
+ * onto a single such pass. Rejects if the stream is stopped before that pass runs.
183
77
  */
184
78
  public sync(): Promise<void> {
185
79
  return this.runningPromise.trigger();
186
80
  }
187
-
188
- /**
189
- * Runs a single pass over the underlying block stream. When triggered by an aggregate event and the stream is
190
- * caught up to the event's pre-pass tips, the event's blocks and tips serve the pass directly; the fast path is
191
- * always disarmed afterwards so a subsequent poll-driven pass reads from the source.
192
- */
193
- private async runPass(event?: L2BlockSourceUpdatedEvent): Promise<void> {
194
- if (event) {
195
- const localTips = await this.localData.getL2Tips();
196
- if (localTipsMatch(localTips, event.fromTips)) {
197
- this.adapter.activate(event.blocksAdded, event.toTips);
198
- }
199
- }
200
-
201
- try {
202
- await this.blockStream.sync();
203
- } finally {
204
- this.adapter.deactivate();
205
- }
206
- }
207
81
  }
@@ -42,6 +42,18 @@ export type ProposedOnlyCheckpointData = {
42
42
  feeAssetPriceModifier: bigint;
43
43
  };
44
44
 
45
+ /** Inbox consumption record of a proposed checkpoint, mirroring what `propose` writes for it on L1. */
46
+ export type ProposedInboxConsumption = {
47
+ /**
48
+ * Cumulative Inbox message count consumed as of this checkpoint: its last block's L1-to-L2 message tree leaf count
49
+ * under compact indexing. L1 records this per checkpoint and reads it back as the parent total
50
+ * when validating the next checkpoint's consumption, so a simulation against a not-yet-mined parent must override
51
+ * the parent's cell with it — otherwise the parent reads as having consumed nothing and the child's consumption
52
+ * looks larger than it is.
53
+ */
54
+ inboxMsgTotal: bigint;
55
+ };
56
+
45
57
  /** Lightweight checkpoint metadata without full block data. */
46
58
  export type CheckpointData = CommonCheckpointData & StorageEnrichedCheckpointData & L1EnrichedCheckpointData;
47
59
 
@@ -51,7 +63,7 @@ export type ProposedCheckpointInput = CommonCheckpointData & ProposedOnlyCheckpo
51
63
 
52
64
  /** Full data for a proposed checkpoint (proposed but not yet L1-confirmed).
53
65
  * Includes fee-relevant fields used during pipelining to compute the fee header override. */
54
- export type ProposedCheckpointData = ProposedCheckpointInput & StorageEnrichedCheckpointData;
66
+ export type ProposedCheckpointData = ProposedCheckpointInput & StorageEnrichedCheckpointData & ProposedInboxConsumption;
55
67
 
56
68
  export const ProposedCheckpointDataSchema = z.object({
57
69
  checkpointNumber: CheckpointNumberSchema,
@@ -62,6 +74,7 @@ export const ProposedCheckpointDataSchema = z.object({
62
74
  blockCount: z.number(),
63
75
  totalManaUsed: schemas.BigInt,
64
76
  feeAssetPriceModifier: schemas.BigInt,
77
+ inboxMsgTotal: schemas.BigInt,
65
78
  });
66
79
 
67
80
  export const CheckpointDataSchema = z
@@ -3,6 +3,7 @@ export * from './checkpoint_data.js';
3
3
  export * from './checkpoint_info.js';
4
4
  export * from './checkpoint_reexecution_tracker.js';
5
5
  export * from './digest.js';
6
+ export * from './previous_checkpoint_inbox_rolling_hash.js';
6
7
  export * from './previous_checkpoint_out_hashes.js';
7
8
  export * from './published_checkpoint.js';
8
9
  export * from './simulation_overrides.js';
@@ -0,0 +1,46 @@
1
+ import { CheckpointNumber } from '@aztec/foundation/branded-types';
2
+ import { Fr } from '@aztec/foundation/curves/bn254';
3
+ import type { Logger } from '@aztec/foundation/log';
4
+
5
+ import type { L2BlockSource } from '../block/l2_block_source.js';
6
+ import type { ProposedCheckpointData } from './checkpoint_data.js';
7
+
8
+ /**
9
+ * Returns the inbox rolling hash chain-start for `checkpointNumber`: the `inboxRollingHash` of the immediately
10
+ * preceding checkpoint. Unlike the epoch out-hash tree, the rolling-hash chain is continuous across epoch boundaries,
11
+ * so the parent is always `checkpointNumber - 1` regardless of epoch. The genesis checkpoint (and the first checkpoint
12
+ * built on it) starts the chain at zero.
13
+ *
14
+ * Under proposer pipelining the parent may not be confirmed on L1 yet, so the locally-known proposed checkpoint is
15
+ * preferred when it is the parent, mirroring `getPreviousCheckpointOutHashes`.
16
+ */
17
+ export async function getPreviousCheckpointInboxRollingHash(input: {
18
+ blockSource: Pick<L2BlockSource, 'getCheckpointData' | 'getProposedCheckpointData'>;
19
+ checkpointNumber: CheckpointNumber;
20
+ proposedCheckpointData?: ProposedCheckpointData;
21
+ log?: Logger;
22
+ }): Promise<Fr> {
23
+ const { blockSource, checkpointNumber, proposedCheckpointData, log } = input;
24
+ if (checkpointNumber <= 1) {
25
+ return Fr.ZERO;
26
+ }
27
+
28
+ const parent = CheckpointNumber(checkpointNumber - 1);
29
+
30
+ if (proposedCheckpointData?.checkpointNumber === parent) {
31
+ log?.debug(`Using pipelined parent cp ${parent} inbox rolling hash for cp ${checkpointNumber}`);
32
+ return proposedCheckpointData.header.inboxRollingHash;
33
+ }
34
+
35
+ const confirmed = await blockSource.getCheckpointData({ number: parent });
36
+ if (confirmed) {
37
+ return confirmed.header.inboxRollingHash;
38
+ }
39
+
40
+ const proposed = await blockSource.getProposedCheckpointData({ number: parent });
41
+ if (proposed) {
42
+ return proposed.header.inboxRollingHash;
43
+ }
44
+
45
+ throw new Error(`Cannot source inbox rolling hash for parent checkpoint ${parent} of checkpoint ${checkpointNumber}`);
46
+ }
@@ -45,7 +45,7 @@ type CheckpointSimulationOverridesPlanInput = {
45
45
  /**
46
46
  * Builds the SimulationOverridesPlan describing the simulated L1 rollup state for a checkpoint's
47
47
  * enqueue-time simulations: `canProposeAt` (in Sequencer.doWork) and the propose-related sims
48
- * (validateBlockHeader, simulateProposeTx). The plan reflects "as if our pipelined parent
48
+ * (validateCheckpointHeader, simulateProposeTx). The plan reflects "as if our pipelined parent
49
49
  * checkpoint has landed and any required invalidation has executed" — the gap that needs to be
50
50
  * bridged at enqueue time.
51
51
  *
@@ -73,21 +73,24 @@ export async function buildCheckpointSimulationOverridesPlan(
73
73
  builder.withChainTips({ pending: overridenChainTip, proven: overridenChainTip });
74
74
 
75
75
  if (input.proposedCheckpointData) {
76
- const { header, archive, checkpointOutHash, feeAssetPriceModifier } = input.proposedCheckpointData;
76
+ const { header, archive, checkpointOutHash, feeAssetPriceModifier, inboxMsgTotal } = input.proposedCheckpointData;
77
77
  builder.withPendingArchive(archive.root);
78
78
  // Override every locally-derivable `tempCheckpointLogs[parent]` field that L1 will eventually
79
- // write. `slotNumber` is load-bearing for `STFLib.canPruneAtTime`: without it the cell reads
79
+ // write. `slotNumber` is required by `STFLib.canPruneAtTime`: without it the cell reads
80
80
  // slotNumber 0, the contract treats the pending tip as belonging to an expired epoch, and
81
81
  // `getEffectivePendingCheckpointNumber` silently collapses pending back to proven — producing
82
- // a spurious `Rollup__InvalidArchive` against the on-chain genesis archive. The other fields
83
- // (headerHash, outHash, payloadDigest) are not strictly load-bearing for `canProposeAt` /
84
- // `validateBlockHeader`, but mirroring the full cell keeps the simulation byte-faithful with
85
- // what the actual `propose()` send will observe, which is a defense against future reads
86
- // taking dependencies on them.
82
+ // a spurious `Rollup__InvalidArchive` against the on-chain genesis archive. `inboxMsgTotal` is
83
+ // read by `ProposeLib.validateInboxConsumption` as the parent's consumed total: left at zero it
84
+ // makes our consumption look like the Inbox's entire history and trips
85
+ // `Rollup__TooManyInboxMessagesConsumed`. The remaining fields (headerHash, outHash,
86
+ // payloadDigest) are not read by `canProposeAt` / `validateCheckpointHeader`, but mirroring the full
87
+ // cell keeps the simulation byte-faithful with what the actual `propose()` send will observe,
88
+ // which is a defense against future reads taking dependencies on them.
87
89
  builder.withPendingTempCheckpointLogFields({
88
90
  headerHash: header.hash(),
89
91
  outHash: checkpointOutHash,
90
92
  slotNumber: header.slotNumber,
93
+ inboxMsgTotal,
91
94
  payloadDigest: computeCheckpointPayloadDigest({
92
95
  header,
93
96
  archiveRoot: archive.root,
@@ -1,7 +1,9 @@
1
1
  import { type L1ContractsConfig, l1ContractsConfigMappings, validateSlotDurations } from '@aztec/ethereum/config';
2
2
  import { type EnvVar, pickConfigMappings } from '@aztec/foundation/config';
3
3
 
4
+ import { MAX_ATTESTABLE_BLOCKS_PER_CHECKPOINT } from '../deserialization/index.js';
4
5
  import type { SequencerConfig } from '../interfaces/configs.js';
6
+ import { MIN_BLOCKS_FOR_INBOX_CATCHUP } from '../messaging/inbox_consumption.js';
5
7
  import {
6
8
  DEFAULT_CHECKPOINT_PROPOSAL_INIT_TIME,
7
9
  DEFAULT_CHECKPOINT_PROPOSAL_PREPARE_TIME,
@@ -47,7 +49,6 @@ export const NETWORK_CONSENSUS_ENV_VARS = [
47
49
  'AZTEC_EJECTION_THRESHOLD',
48
50
  'AZTEC_LOCAL_EJECTION_THRESHOLD',
49
51
  'AZTEC_EXIT_DELAY_SECONDS',
50
- 'AZTEC_INBOX_LAG',
51
52
  'AZTEC_PROOF_SUBMISSION_EPOCHS',
52
53
  'AZTEC_MANA_TARGET',
53
54
  'AZTEC_PROVING_COST_PER_MANA',
@@ -142,7 +143,8 @@ export function getConsensusConfigFromNetworkEnv(
142
143
  * The check requires `maxBlocksPerCheckpoint` to be *exactly* what a {@link ProposerTimetable} built from the
143
144
  * same slot timings and the production default budgets derives. This exact-equality requirement ensures the
144
145
  * published network value is precisely what the production default budgets produce, so every node running those
145
- * defaults agrees on the per-checkpoint block count without clamping.
146
+ * defaults agrees on the per-checkpoint block count without clamping. It must also be at least
147
+ * {@link MIN_BLOCKS_FOR_INBOX_CATCHUP}, without which the network is permanently haltable.
146
148
  */
147
149
  export function validateNetworkConsensusConfig(config: NetworkConsensusConfig): string[] {
148
150
  const errors: string[] = [];
@@ -165,8 +167,19 @@ export function validateNetworkConsensusConfig(config: NetworkConsensusConfig):
165
167
  `blockDurationMs (${config.blockDurationMs}ms) exceeds aztecSlotDuration (${config.aztecSlotDuration}s)`,
166
168
  );
167
169
  }
168
- if (config.maxBlocksPerCheckpoint < 1) {
169
- errors.push(`maxBlocksPerCheckpoint must be at least 1 (got ${config.maxBlocksPerCheckpoint})`);
170
+ if (config.maxBlocksPerCheckpoint < MIN_BLOCKS_FOR_INBOX_CATCHUP) {
171
+ errors.push(
172
+ `maxBlocksPerCheckpoint must be at least ${MIN_BLOCKS_FOR_INBOX_CATCHUP} so a checkpoint can always clear a ` +
173
+ `mandatory streaming-Inbox backlog (got ${config.maxBlocksPerCheckpoint}); lower the block duration or raise ` +
174
+ `the slot duration so the proposer budgets derive at least that many blocks`,
175
+ );
176
+ }
177
+ if (config.maxBlocksPerCheckpoint > MAX_ATTESTABLE_BLOCKS_PER_CHECKPOINT) {
178
+ errors.push(
179
+ `maxBlocksPerCheckpoint (${config.maxBlocksPerCheckpoint}) exceeds the ` +
180
+ `${MAX_ATTESTABLE_BLOCKS_PER_CHECKPOINT} blocks nodes will build or attest to, so the network would ` +
181
+ `reject block indices its own configuration admits`,
182
+ );
170
183
  }
171
184
  if (config.checkpointProposalSyncGraceSeconds < 0) {
172
185
  errors.push(
@@ -1,7 +1,13 @@
1
- import { type ConfigMappingsType, numberConfigHelper } from '@aztec/foundation/config';
1
+ import { type ConfigMappingsType, booleanConfigHelper, numberConfigHelper } from '@aztec/foundation/config';
2
2
 
3
3
  import { DEFAULT_MAX_DEBUG_LOG_MEMORY_READS } from '../avm/avm.js';
4
4
 
5
+ const parseCommaSeparatedList = (value: string) =>
6
+ value
7
+ .split(',')
8
+ .map(item => item.trim())
9
+ .filter(Boolean);
10
+
5
11
  export const nodeRpcConfigMappings: ConfigMappingsType<NodeRPCConfig> = {
6
12
  rpcSimulatePublicMaxGasLimit: {
7
13
  env: 'RPC_SIMULATE_PUBLIC_MAX_GAS_LIMIT',
@@ -24,6 +30,33 @@ export const nodeRpcConfigMappings: ConfigMappingsType<NodeRPCConfig> = {
24
30
  description: 'Maximum allowed batch size for JSON RPC batch requests.',
25
31
  defaultValue: '1mb',
26
32
  },
33
+ rpcHttpKeepAliveTimeoutMs: {
34
+ env: 'RPC_HTTP_KEEP_ALIVE_TIMEOUT_MS',
35
+ description: 'HTTP keep-alive timeout for JSON RPC connections in milliseconds.',
36
+ ...numberConfigHelper(5_000),
37
+ },
38
+ rpcHttpHeadersTimeoutMs: {
39
+ env: 'RPC_HTTP_HEADERS_TIMEOUT_MS',
40
+ description: 'Timeout for receiving complete HTTP headers on JSON RPC connections in milliseconds.',
41
+ ...numberConfigHelper(60_000),
42
+ },
43
+ rpcCorsAllowedOrigins: {
44
+ env: 'RPC_CORS_ALLOWED_ORIGINS',
45
+ description: 'Origins allowed to make credentialed cross-origin JSON RPC requests, separated by commas.',
46
+ parseEnv: parseCommaSeparatedList,
47
+ defaultValue: [],
48
+ },
49
+ rpcCorsAllowedHeaders: {
50
+ env: 'RPC_CORS_ALLOWED_HEADERS',
51
+ description: 'Headers allowed in cross-origin JSON RPC requests, separated by commas.',
52
+ parseEnv: parseCommaSeparatedList,
53
+ defaultValue: [],
54
+ },
55
+ rpcCorsAllowAnyOrigin: {
56
+ env: 'RPC_CORS_ALLOW_ANY_ORIGIN',
57
+ description: 'Allow credentialed cross-origin JSON RPC requests from any origin.',
58
+ ...booleanConfigHelper(false),
59
+ },
27
60
  };
28
61
 
29
62
  export type NodeRPCConfig = {
@@ -35,4 +68,21 @@ export type NodeRPCConfig = {
35
68
  rpcMaxBatchSize: number;
36
69
  /** The maximum body size the RPC server will accept */
37
70
  rpcMaxBodySize: string;
71
+ /** HTTP keep-alive timeout for JSON RPC connections in milliseconds. */
72
+ rpcHttpKeepAliveTimeoutMs: number;
73
+ /** Timeout for receiving complete HTTP headers on JSON RPC connections in milliseconds. */
74
+ rpcHttpHeadersTimeoutMs: number;
75
+ /** Origins allowed to make credentialed cross-origin requests to the RPC server. */
76
+ rpcCorsAllowedOrigins: string[];
77
+ /** Headers allowed in cross-origin requests to the RPC server. */
78
+ rpcCorsAllowedHeaders: string[];
79
+ /** Whether to allow credentialed cross-origin requests from any origin. */
80
+ rpcCorsAllowAnyOrigin: boolean;
38
81
  };
82
+
83
+ /** Resolves the CORS origin policy for an RPC server. */
84
+ export function getRpcCorsAllowedOrigins(
85
+ config: Pick<NodeRPCConfig, 'rpcCorsAllowedOrigins' | 'rpcCorsAllowAnyOrigin'>,
86
+ ): string[] {
87
+ return config.rpcCorsAllowAnyOrigin ? ['*'] : config.rpcCorsAllowedOrigins;
88
+ }
@@ -3,7 +3,7 @@
3
3
  * These constants define maximum allowed sizes during deserialization
4
4
  * to prevent DoS attacks via maliciously crafted messages.
5
5
  */
6
- import { BLOBS_PER_CHECKPOINT, FIELDS_PER_BLOB } from '@aztec/constants';
6
+ import { BLOBS_PER_CHECKPOINT, FIELDS_PER_BLOB, MAX_BLOCKS_PER_CHECKPOINT } from '@aztec/constants';
7
7
 
8
8
  /** Max transactions per block for deserialization validation */
9
9
  export const MAX_TXS_PER_BLOCK = 2 ** 16;
@@ -17,35 +17,35 @@ export const MAX_COMMITTEE_SIZE = 2048;
17
17
  *
18
18
  * This MUST be >= the number of blocks the proving system can carry, or a structurally-valid, provable
19
19
  * checkpoint that L1 accepts would be rejected on ingest (`validateCheckpoint`) and wedge the archiver.
20
- * The circuits and L1 impose no explicit per-checkpoint block count; the ceiling comes from the
21
- * blob-field budget:
20
+ * The checkpoint root circuit caps a checkpoint at {@link MAX_BLOCKS_PER_CHECKPOINT} blocks, well under
21
+ * the looser ceiling the blob-field budget imposes:
22
22
  *
23
23
  * budget = BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB = 6 * 4096 = 24,576 fields
24
24
  *
25
- * per-block minimal blob footprint:
26
- * first block (may be empty) = 7 fields (NUM_FIRST_BLOCK_END_BLOB_FIELDS)
27
- * every other (needs >= 1 tx) = 6 + 4 = 10 fields
25
+ * per-block minimal blob footprint (every block carries a per-block l1-to-l2 root):
26
+ * a block with no txs = 7 fields (NUM_BLOCK_END_BLOB_FIELDS)
27
+ * a block with one minimal tx = 7 + 4 = 11 fields
28
28
  * (NUM_BLOCK_END_BLOB_FIELDS + a 4-field minimal tx:
29
29
  * tx start marker + tx hash + fee + 1 mandatory nullifier)
30
30
  * + 1 checkpoint-end marker (NUM_CHECKPOINT_END_MARKER_FIELDS)
31
31
  *
32
- * max N: 7 + 10*(N - 1) + 1 <= 24,576 => 10*(N - 1) <= 24,568 => N <= 2,457
32
+ * max N: 7 + 11*(N - 1) + 1 <= 24,576 => 11*(N - 1) <= 24,568 => N <= 2,234
33
33
  *
34
- * Only the first block may be empty; every other block needs >= 1 tx (the circuits have no empty-tx
35
- * variant for non-first blocks), so 2457 is the largest provable checkpoint. The blob format can encode
36
- * more blocks than this (up to ~4095 with all-empty blocks), but such a checkpoint is unprovable and
37
- * can only reach L1 with a malicious committee supermajority — a terminal network compromise where a
38
- * wedged archiver is an acceptable outcome. We therefore bound ingest to the provable maximum.
39
- * Invariant checked by the unit test in deserialization.test.ts.
34
+ * 2234 is kept as the deserialization bound: it is far above the circuit cap, so it never rejects a
35
+ * provable checkpoint, while still bounding how much a malformed blob payload can allocate. L1 carries
36
+ * no block count of its own, so an over-cap (and therefore unprovable) checkpoint can only reach it with
37
+ * a malicious committee supermajority — a terminal network compromise. Invariant checked by the unit
38
+ * test in deserialization.test.ts.
40
39
  */
41
- export const MAX_CAPACITY_BLOCKS_PER_CHECKPOINT = 2457;
40
+ export const MAX_CAPACITY_BLOCKS_PER_CHECKPOINT = 2234;
42
41
 
43
42
  /**
44
- * Max blocks per checkpoint we are willing to build or attest to (conservative client policy, and the
45
- * default block-count limit for `validateCheckpoint`). Distinct from {@link MAX_CAPACITY_BLOCKS_PER_CHECKPOINT},
46
- * which is the higher ceiling we tolerate when deserializing checkpoints already accepted by L1.
43
+ * Max blocks per checkpoint we are willing to build or attest to, and the default block-count limit for
44
+ * `validateCheckpoint`. This is the protocol cap the checkpoint root circuit enforces: anything above it
45
+ * is unprovable, so a node must never build or attest to it. Distinct from
46
+ * {@link MAX_CAPACITY_BLOCKS_PER_CHECKPOINT}, the looser bound used when deserializing untrusted payloads.
47
47
  */
48
- export const MAX_ATTESTABLE_BLOCKS_PER_CHECKPOINT = 72;
48
+ export const MAX_ATTESTABLE_BLOCKS_PER_CHECKPOINT = MAX_BLOCKS_PER_CHECKPOINT;
49
49
 
50
50
  /** Max tx effects per body (based on blob capacity per checkpoint) */
51
51
  export const MAX_TX_EFFECTS_PER_BODY = BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB;
package/src/gas/README.md CHANGED
@@ -226,7 +226,8 @@ must also be buildable into a block and fit a valid checkpoint.
226
226
  ### Per-tx protocol maxima
227
227
 
228
228
  Hard ceilings on what any single tx may declare, independent of network configuration. Declaring more is
229
- rejected everywhere a tx is validated.
229
+ rejected by `GasLimitsValidator` at every tx validation entry point except simulation, which is exempt
230
+ because gas estimation deliberately declares limits above the per-tx maximum.
230
231
 
231
232
  - **`MAX_TX_DA_GAS`** (271,200) — `MAX_TX_BLOB_DATA_SIZE_IN_FIELDS` (8,475) × `DA_GAS_PER_FIELD` (32). This
232
233
  is the most DA a single tx's effects can encode into a blob, so it is the most DA gas a tx could ever use.
@@ -300,8 +301,8 @@ The outermost limits, enforced as proposal validity in `validateCheckpointLimits
300
301
 
301
302
  | Limit | Value (mainnet defaults) | Scope | Where enforced |
302
303
  | --------------------------------------- | ------------------------------- | ------------- | ----------------------------------------------------------- |
303
- | `MAX_TX_DA_GAS` | 271,200 | per-tx | every gas validator (hard ceiling) |
304
- | `MAX_PROCESSABLE_L2_GAS` | 6,540,000 | per-tx | every gas validator (hard ceiling) |
304
+ | `MAX_TX_DA_GAS` | 271,200 | per-tx | `GasLimitsValidator` (hard ceiling; simulation exempt) |
305
+ | `MAX_PROCESSABLE_L2_GAS` | 6,540,000 | per-tx | `GasLimitsValidator` (hard ceiling; simulation exempt) |
305
306
  | Network DA admission limit | min(271,200, ceil(784,448/10×1.5)) = 117,668 | per-tx (relay) | RPC, gossip, pending pool (`GasLimitsValidator`) |
306
307
  | Network L2 admission limit | min(6,540,000, ceil(manaLimit/10×1.2)) | per-tx (relay) | RPC, gossip, pending pool (`GasLimitsValidator`) |
307
308
  | Per-block fair share + caps | remaining budget / blocks × multiplier, min absolute caps & blob-field cap | per-block | `CheckpointBuilder.capLimitsByCheckpointBudgets` |
@@ -20,9 +20,13 @@ export const GAS_ESTIMATION_DA_GAS_LIMIT = GAS_ESTIMATION_TEARDOWN_DA_GAS_LIMIT
20
20
  /** Gas usage and fees limits set by the transaction sender for different dimensions and phases. */
21
21
  export class GasSettings {
22
22
  constructor(
23
+ /** Total gas the tx may consume across all phases, teardown included. */
23
24
  public readonly gasLimits: Gas,
25
+ /** Portion of gasLimits reserved for the teardown phase, billed in full when the tx has a teardown call. */
24
26
  public readonly teardownGasLimits: Gas,
27
+ /** Maximum fees per gas unit the sender is willing to pay. */
25
28
  public readonly maxFeesPerGas: GasFees,
29
+ /** Maximum priority fees per gas unit the sender is willing to pay on top of the base fee. */
26
30
  public readonly maxPriorityFeesPerGas: GasFees,
27
31
  ) {}
28
32
  // docs:end:gas_settings_vars
@@ -132,9 +136,9 @@ export class GasSettings {
132
136
  * the effective gas available for app logic is gasLimits - teardownGasLimits - privateOverhead.
133
137
  * To ensure estimation never hits gas caps, we set both limits above what the protocol allows:
134
138
  * teardown gets MAX_PROCESSABLE and gasLimits gets teardown + MAX_PROCESSABLE, so the full
135
- * processable amount remains available for each phase independently. To be used in conjunction
136
- * with skipTxValidation: true during public simulation, or the node would reject the transaction
137
- * outright due to gas limits being above protocol max.
139
+ * processable amount remains available for each phase independently. Tx validation exempts
140
+ * simulated txs from gas-limit admission (`isValidTx` with `isSimulation: true`), so these
141
+ * inflated limits pass validation; the wallet clamps the real tx to the admission limit afterward.
138
142
  */
139
143
  static forEstimation(overrides: {
140
144
  gasLimits?: Gas;
@@ -1,8 +1,4 @@
1
- import {
2
- NUM_BLOCK_END_BLOB_FIELDS,
3
- NUM_CHECKPOINT_END_MARKER_FIELDS,
4
- NUM_FIRST_BLOCK_END_BLOB_FIELDS,
5
- } from '@aztec/blob-lib/encoding';
1
+ import { NUM_BLOCK_END_BLOB_FIELDS, NUM_CHECKPOINT_END_MARKER_FIELDS } from '@aztec/blob-lib/encoding';
6
2
  import {
7
3
  BLOBS_PER_CHECKPOINT,
8
4
  DA_GAS_PER_FIELD,
@@ -38,9 +34,8 @@ export const MIN_PER_BLOCK_DA_ALLOCATION_MULTIPLIER = 1.5;
38
34
  * raw blob capacity (`BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB * DA_GAS_PER_FIELD`) minus the fields the blob
39
35
  * encoding reserves for overhead that no tx pays DA gas for:
40
36
  *
41
- * - one checkpoint-end marker field (`NUM_CHECKPOINT_END_MARKER_FIELDS`),
42
- * - the first block's block-end fields (`NUM_FIRST_BLOCK_END_BLOB_FIELDS`, 7), and
43
- * - `NUM_BLOCK_END_BLOB_FIELDS` (6) for each of the `blocks - 1` subsequent blocks.
37
+ * - one checkpoint-end marker field (`NUM_CHECKPOINT_END_MARKER_FIELDS`), and
38
+ * - `NUM_BLOCK_END_BLOB_FIELDS` (7, including the per-block l1-to-l2 root) for each of the `blocks` blocks.
44
39
  *
45
40
  * Subtracting the overhead for every block (not just the first) keeps the network DA admission limit at or
46
41
  * below the builder's first-block blob-field cap at every geometry. The builder is the MOST generous for the
@@ -57,10 +52,7 @@ export function getDaCheckpointBudgetForTxs(maxBlocksPerCheckpoint: number): num
57
52
  // raw blob capacity, which would otherwise yield a negative advertised DA budget.
58
53
  const fields = Math.max(
59
54
  0,
60
- BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB -
61
- NUM_CHECKPOINT_END_MARKER_FIELDS -
62
- NUM_FIRST_BLOCK_END_BLOB_FIELDS -
63
- (blocks - 1) * NUM_BLOCK_END_BLOB_FIELDS,
55
+ BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB - NUM_CHECKPOINT_END_MARKER_FIELDS - blocks * NUM_BLOCK_END_BLOB_FIELDS,
64
56
  );
65
57
  return fields * DA_GAS_PER_FIELD;
66
58
  }