@aztec-labs/sequencer-client 6.0.0-nightly.20260921 → 6.0.0-nightly.20260923

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.
@@ -15,8 +15,8 @@ export type DroppedRequest = {
15
15
  * Result of {@link SequencerBundleSimulator.simulate}.
16
16
  *
17
17
  * - `success`: simulation succeeded. `requests` is the filtered survivor list, `gasLimit` is
18
- * the bumped gas limit derived from `gasUsed` (plus blob evaluation gas). `droppedRequests`
19
- * lists the entries that were observed to revert in simulation.
18
+ * the bumped gas limit derived from the simulated transaction gas (plus blob evaluation gas).
19
+ * `droppedRequests` lists the entries that were observed to revert in simulation.
20
20
  * - `fallback`: the node does not support eth_simulateV1 (or the simulate call threw). The
21
21
  * caller should send `requests` as-is with a safe gas limit (e.g. {@link MAX_L1_TX_LIMIT}).
22
22
  * `droppedRequests` carries any entries that the first pass already proved reverted, so the
@@ -82,8 +82,12 @@ export declare class SequencerBundleSimulator {
82
82
  simulate(validRequests: RequestWithExpiry[], targetSlot: SlotNumber): Promise<BundleSimulateResult>;
83
83
  private buildSuccessResult;
84
84
  /**
85
- * `gasLimit = bumpGasLimit(ceil(gasUsed * 64 / 63))`, plus blob evaluation gas if a propose
86
- * survived, capped at the L1 block gas limit.
85
+ * `gasLimit = bumpGasLimit(ceil(basis * 64 / 63))`, plus blob evaluation gas if a propose survived,
86
+ * capped at {@link MAX_L1_TX_LIMIT}.
87
+ *
88
+ * The basis is the simulation's `maxUsedGas` when the node reports it, since that is measured before
89
+ * refunds, and its `gasUsed` otherwise. Either way the headroom on top is the buffer configured for the
90
+ * L1 tx utils; neither figure guarantees a sufficient limit, hence the padding and the buffer.
87
91
  */
88
92
  private computeGasLimit;
89
93
  /**
@@ -93,4 +97,4 @@ export declare class SequencerBundleSimulator {
93
97
  private buildStateOverrides;
94
98
  private simulateAndDecode;
95
99
  }
96
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VxdWVuY2VyLWJ1bmRsZS1zaW11bGF0b3IuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wdWJsaXNoZXIvc2VxdWVuY2VyLWJ1bmRsZS1zaW11bGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDMUQsT0FBTyxFQUFjLEtBQUssY0FBYyxFQUF5QyxNQUFNLGdDQUFnQyxDQUFDO0FBQ3hILE9BQU8sRUFBRSxLQUFLLFNBQVMsRUFBbUIsTUFBTSxrQ0FBa0MsQ0FBQztBQUVuRixPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUN2RSxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sNEJBQTRCLENBQUM7QUFFdkUsT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFpQixNQUFNLE1BQU0sQ0FBQztBQUUvQyxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRWxFLHVGQUF1RjtBQUN2RixNQUFNLE1BQU0sY0FBYyxHQUFHO0lBQzNCLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQztJQUMzQixZQUFZLEVBQUUsTUFBTSxHQUFHLFNBQVMsQ0FBQztJQUNqQyxVQUFVLEVBQUUsR0FBRyxHQUFHLFNBQVMsQ0FBQztDQUM3QixDQUFDO0FBRUY7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQU0sTUFBTSxvQkFBb0IsR0FDNUI7SUFBRSxJQUFJLEVBQUUsU0FBUyxDQUFDO0lBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFFLENBQUM7SUFBQyxRQUFRLEVBQUUsTUFBTSxDQUFDO0lBQUMsZUFBZSxFQUFFLGNBQWMsRUFBRSxDQUFBO0NBQUUsR0FDdkc7SUFBRSxJQUFJLEVBQUUsVUFBVSxDQUFDO0lBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFFLENBQUM7SUFBQyxlQUFlLEVBQUUsY0FBYyxFQUFFLENBQUE7Q0FBRSxHQUN0RjtJQUFFLElBQUksRUFBRSxTQUFTLENBQUM7SUFBQyxNQUFNLEVBQUUsV0FBVyxDQUFDO0lBQUMsZUFBZSxFQUFFLGNBQWMsRUFBRSxDQUFBO0NBQUUsQ0FBQztBQUVoRixNQUFNLE1BQU0sV0FBVyxHQUFHLGNBQWMsR0FBRyxjQUFjLEdBQUcscUJBQXFCLENBQUM7QUFNbEY7Ozs7OztHQU1HO0FBQ0gscUJBQWEsd0JBQXdCO0lBSWpDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSTtJQUh2QixPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBUztJQUU3QixZQUNtQixJQUFJLEVBQUU7UUFDckIsWUFBWSxFQUFFLE1BQU0sU0FBUyxDQUFDO1FBQzlCLGNBQWMsRUFBRSxjQUFjLENBQUM7UUFDL0IsVUFBVSxFQUFFLFVBQVUsQ0FBQztRQUN2QixHQUFHLENBQUMsRUFBRSxNQUFNLENBQUM7S0FDZCxFQUdGO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FzQkc7SUFDVSxRQUFRLENBQUMsYUFBYSxFQUFFLGlCQUFpQixFQUFFLEVBQUUsVUFBVSxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0E2RS9HO0lBRUQsT0FBTyxDQUFDLGtCQUFrQjtJQW1CMUI7OztPQUdHO0lBQ0gsT0FBTyxDQUFDLGVBQWU7SUFNdkI7OztPQUdHO0lBQ0gsT0FBTyxDQUFDLG1CQUFtQjtZQU9iLGlCQUFpQjtDQThDaEMifQ==
100
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VxdWVuY2VyLWJ1bmRsZS1zaW11bGF0b3IuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wdWJsaXNoZXIvc2VxdWVuY2VyLWJ1bmRsZS1zaW11bGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDMUQsT0FBTyxFQUFjLEtBQUssY0FBYyxFQUF5QyxNQUFNLGdDQUFnQyxDQUFDO0FBQ3hILE9BQU8sRUFBRSxLQUFLLFNBQVMsRUFBbUIsTUFBTSxrQ0FBa0MsQ0FBQztBQUVuRixPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUN2RSxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sNEJBQTRCLENBQUM7QUFFdkUsT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFpQixNQUFNLE1BQU0sQ0FBQztBQUUvQyxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRWxFLHVGQUF1RjtBQUN2RixNQUFNLE1BQU0sY0FBYyxHQUFHO0lBQzNCLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQztJQUMzQixZQUFZLEVBQUUsTUFBTSxHQUFHLFNBQVMsQ0FBQztJQUNqQyxVQUFVLEVBQUUsR0FBRyxHQUFHLFNBQVMsQ0FBQztDQUM3QixDQUFDO0FBRUY7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQU0sTUFBTSxvQkFBb0IsR0FDNUI7SUFBRSxJQUFJLEVBQUUsU0FBUyxDQUFDO0lBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFFLENBQUM7SUFBQyxRQUFRLEVBQUUsTUFBTSxDQUFDO0lBQUMsZUFBZSxFQUFFLGNBQWMsRUFBRSxDQUFBO0NBQUUsR0FDdkc7SUFBRSxJQUFJLEVBQUUsVUFBVSxDQUFDO0lBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFFLENBQUM7SUFBQyxlQUFlLEVBQUUsY0FBYyxFQUFFLENBQUE7Q0FBRSxHQUN0RjtJQUFFLElBQUksRUFBRSxTQUFTLENBQUM7SUFBQyxNQUFNLEVBQUUsV0FBVyxDQUFDO0lBQUMsZUFBZSxFQUFFLGNBQWMsRUFBRSxDQUFBO0NBQUUsQ0FBQztBQUVoRixNQUFNLE1BQU0sV0FBVyxHQUFHLGNBQWMsR0FBRyxjQUFjLEdBQUcscUJBQXFCLENBQUM7QUFZbEY7Ozs7OztHQU1HO0FBQ0gscUJBQWEsd0JBQXdCO0lBSWpDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSTtJQUh2QixPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBUztJQUU3QixZQUNtQixJQUFJLEVBQUU7UUFDckIsWUFBWSxFQUFFLE1BQU0sU0FBUyxDQUFDO1FBQzlCLGNBQWMsRUFBRSxjQUFjLENBQUM7UUFDL0IsVUFBVSxFQUFFLFVBQVUsQ0FBQztRQUN2QixHQUFHLENBQUMsRUFBRSxNQUFNLENBQUM7S0FDZCxFQUdGO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FzQkc7SUFDVSxRQUFRLENBQUMsYUFBYSxFQUFFLGlCQUFpQixFQUFFLEVBQUUsVUFBVSxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0E4RS9HO0lBRUQsT0FBTyxDQUFDLGtCQUFrQjtJQXFCMUI7Ozs7Ozs7T0FPRztJQUNILE9BQU8sQ0FBQyxlQUFlO0lBV3ZCOzs7T0FHRztJQUNILE9BQU8sQ0FBQyxtQkFBbUI7WUFPYixpQkFBaUI7Q0FvRGhDIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"sequencer-bundle-simulator.d.ts","sourceRoot":"","sources":["../../src/publisher/sequencer-bundle-simulator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAc,KAAK,cAAc,EAAyC,MAAM,gCAAgC,CAAC;AACxH,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,kCAAkC,CAAC;AAEnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,4BAA4B,CAAC;AAEvE,OAAO,KAAK,EAAE,GAAG,EAAiB,MAAM,MAAM,CAAC;AAE/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,uFAAuF;AACvF,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,UAAU,EAAE,GAAG,GAAG,SAAS,CAAC;CAC7B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,cAAc,EAAE,CAAA;CAAE,GACvG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAAC,eAAe,EAAE,cAAc,EAAE,CAAA;CAAE,GACtF;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,eAAe,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC;AAEhF,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,cAAc,GAAG,qBAAqB,CAAC;AAMlF;;;;;;GAMG;AACH,qBAAa,wBAAwB;IAIjC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,YACmB,IAAI,EAAE;QACrB,YAAY,EAAE,MAAM,SAAS,CAAC;QAC9B,cAAc,EAAE,cAAc,CAAC;QAC/B,UAAU,EAAE,UAAU,CAAC;QACvB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,EAGF;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACU,QAAQ,CAAC,aAAa,EAAE,iBAAiB,EAAE,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA6E/G;IAED,OAAO,CAAC,kBAAkB;IAmB1B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAMvB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;YAOb,iBAAiB;CA8ChC"}
1
+ {"version":3,"file":"sequencer-bundle-simulator.d.ts","sourceRoot":"","sources":["../../src/publisher/sequencer-bundle-simulator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAc,KAAK,cAAc,EAAyC,MAAM,gCAAgC,CAAC;AACxH,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,kCAAkC,CAAC;AAEnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,4BAA4B,CAAC;AAEvE,OAAO,KAAK,EAAE,GAAG,EAAiB,MAAM,MAAM,CAAC;AAE/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,uFAAuF;AACvF,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,UAAU,EAAE,GAAG,GAAG,SAAS,CAAC;CAC7B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,cAAc,EAAE,CAAA;CAAE,GACvG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAAC,eAAe,EAAE,cAAc,EAAE,CAAA;CAAE,GACtF;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,eAAe,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC;AAEhF,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,cAAc,GAAG,qBAAqB,CAAC;AAYlF;;;;;;GAMG;AACH,qBAAa,wBAAwB;IAIjC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,YACmB,IAAI,EAAE;QACrB,YAAY,EAAE,MAAM,SAAS,CAAC;QAC9B,cAAc,EAAE,cAAc,CAAC;QAC/B,UAAU,EAAE,UAAU,CAAC;QACvB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,EAGF;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACU,QAAQ,CAAC,aAAa,EAAE,iBAAiB,EAAE,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA8E/G;IAED,OAAO,CAAC,kBAAkB;IAqB1B;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAWvB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;YAOb,iBAAiB;CAoDhC"}
@@ -74,7 +74,7 @@ import { getLastL1SlotTimestampForL2Slot } from '@aztec-labs/stdlib/epoch-helper
74
74
  };
75
75
  }
76
76
  if (firstPass.droppedRequests.length === 0) {
77
- return this.buildSuccessResult(l1TxUtils, firstPass.survivors, [], firstPass.gasUsed, proposeRequest);
77
+ return this.buildSuccessResult(l1TxUtils, firstPass.survivors, [], firstPass, proposeRequest);
78
78
  }
79
79
  this.log.warn('Some bundle entries reverted; re-simulating reduced bundle', {
80
80
  droppedActions: firstPass.droppedRequests.map((d)=>d.request.action),
@@ -109,15 +109,18 @@ import { getLastL1SlotTimestampForL2Slot } from '@aztec-labs/stdlib/epoch-helper
109
109
  ]
110
110
  };
111
111
  }
112
- return this.buildSuccessResult(l1TxUtils, secondPass.survivors, firstPass.droppedRequests, secondPass.gasUsed, proposeRequest);
112
+ // The reduced bundle is what we are about to send, so its own gas metrics are the ones that size the tx.
113
+ return this.buildSuccessResult(l1TxUtils, secondPass.survivors, firstPass.droppedRequests, secondPass, proposeRequest);
113
114
  }
114
- buildSuccessResult(l1TxUtils, survivors, droppedRequests, bundleGasUsed, proposeRequest) {
115
+ buildSuccessResult(l1TxUtils, survivors, droppedRequests, bundleGas, proposeRequest) {
115
116
  const proposeSurvived = proposeRequest !== undefined && survivors.includes(proposeRequest);
116
117
  const blobEvaluationGas = proposeSurvived ? proposeRequest?.blobEvaluationGas ?? 0n : 0n;
117
- const gasLimit = this.computeGasLimit(l1TxUtils, bundleGasUsed, blobEvaluationGas);
118
+ const gasLimit = this.computeGasLimit(l1TxUtils, bundleGas, blobEvaluationGas);
118
119
  this.log.debug('Bundle simulate complete', {
119
120
  survivingRequests: survivors.length,
120
- bundleGasUsed,
121
+ bundleGasUsed: bundleGas.gasUsed,
122
+ bundleMaxUsedGas: bundleGas.maxUsedGas,
123
+ blobEvaluationGas,
121
124
  gasLimit,
122
125
  actions: survivors.map((r)=>r.action)
123
126
  });
@@ -129,10 +132,15 @@ import { getLastL1SlotTimestampForL2Slot } from '@aztec-labs/stdlib/epoch-helper
129
132
  };
130
133
  }
131
134
  /**
132
- * `gasLimit = bumpGasLimit(ceil(gasUsed * 64 / 63))`, plus blob evaluation gas if a propose
133
- * survived, capped at the L1 block gas limit.
134
- */ computeGasLimit(l1TxUtils, bundleGasUsed, blobEvaluationGas) {
135
- const gasUsedWithEip150 = (bundleGasUsed * 64n + 62n) / 63n;
135
+ * `gasLimit = bumpGasLimit(ceil(basis * 64 / 63))`, plus blob evaluation gas if a propose survived,
136
+ * capped at {@link MAX_L1_TX_LIMIT}.
137
+ *
138
+ * The basis is the simulation's `maxUsedGas` when the node reports it, since that is measured before
139
+ * refunds, and its `gasUsed` otherwise. Either way the headroom on top is the buffer configured for the
140
+ * L1 tx utils; neither figure guarantees a sufficient limit, hence the padding and the buffer.
141
+ */ computeGasLimit(l1TxUtils, bundleGas, blobEvaluationGas) {
142
+ const basis = bundleGas.maxUsedGas ?? bundleGas.gasUsed;
143
+ const gasUsedWithEip150 = (basis * 64n + 62n) / 63n;
136
144
  const gasLimit = l1TxUtils.bumpGasLimit(gasUsedWithEip150) + blobEvaluationGas;
137
145
  return gasLimit > MAX_L1_TX_LIMIT ? MAX_L1_TX_LIMIT : gasLimit;
138
146
  }
@@ -192,7 +200,8 @@ import { getLastL1SlotTimestampForL2Slot } from '@aztec-labs/stdlib/epoch-helper
192
200
  kind: 'decoded',
193
201
  survivors,
194
202
  droppedRequests,
195
- gasUsed: simResult.gasUsed
203
+ gasUsed: simResult.gasUsed,
204
+ maxUsedGas: simResult.maxUsedGas
196
205
  };
197
206
  }
198
207
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec-labs/sequencer-client",
3
- "version": "6.0.0-nightly.20260921",
3
+ "version": "6.0.0-nightly.20260923",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -27,32 +27,32 @@
27
27
  "test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --config jest.integration.config.json"
28
28
  },
29
29
  "dependencies": {
30
- "@aztec-foundation/l1-artifacts": "6.0.0-nightly.20260918.a",
31
- "@aztec-labs/archiver": "6.0.0-nightly.20260921",
32
- "@aztec-labs/blob-client": "6.0.0-nightly.20260921",
33
- "@aztec-labs/blob-lib": "6.0.0-nightly.20260921",
34
- "@aztec-labs/constants": "6.0.0-nightly.20260921",
35
- "@aztec-labs/epoch-cache": "6.0.0-nightly.20260921",
36
- "@aztec-labs/ethereum": "6.0.0-nightly.20260921",
37
- "@aztec-labs/foundation": "6.0.0-nightly.20260921",
38
- "@aztec-labs/node-keystore": "6.0.0-nightly.20260921",
39
- "@aztec-labs/p2p": "6.0.0-nightly.20260921",
40
- "@aztec-labs/prover-client": "6.0.0-nightly.20260921",
41
- "@aztec-labs/simulator": "6.0.0-nightly.20260921",
42
- "@aztec-labs/slasher": "6.0.0-nightly.20260921",
43
- "@aztec-labs/stdlib": "6.0.0-nightly.20260921",
44
- "@aztec-labs/telemetry-client": "6.0.0-nightly.20260921",
45
- "@aztec-labs/validator-client": "6.0.0-nightly.20260921",
46
- "@aztec-labs/validator-ha-signer": "6.0.0-nightly.20260921",
30
+ "@aztec-foundation/l1-artifacts": "6.0.0-nightly.20260921",
31
+ "@aztec-labs/archiver": "6.0.0-nightly.20260923",
32
+ "@aztec-labs/blob-client": "6.0.0-nightly.20260923",
33
+ "@aztec-labs/blob-lib": "6.0.0-nightly.20260923",
34
+ "@aztec-labs/constants": "6.0.0-nightly.20260923",
35
+ "@aztec-labs/epoch-cache": "6.0.0-nightly.20260923",
36
+ "@aztec-labs/ethereum": "6.0.0-nightly.20260923",
37
+ "@aztec-labs/foundation": "6.0.0-nightly.20260923",
38
+ "@aztec-labs/node-keystore": "6.0.0-nightly.20260923",
39
+ "@aztec-labs/p2p": "6.0.0-nightly.20260923",
40
+ "@aztec-labs/prover-client": "6.0.0-nightly.20260923",
41
+ "@aztec-labs/simulator": "6.0.0-nightly.20260923",
42
+ "@aztec-labs/slasher": "6.0.0-nightly.20260923",
43
+ "@aztec-labs/stdlib": "6.0.0-nightly.20260923",
44
+ "@aztec-labs/telemetry-client": "6.0.0-nightly.20260923",
45
+ "@aztec-labs/validator-client": "6.0.0-nightly.20260923",
46
+ "@aztec-labs/validator-ha-signer": "6.0.0-nightly.20260923",
47
47
  "lodash.chunk": "^4.2.0",
48
48
  "tslib": "^2.4.0",
49
- "viem": "npm:@aztec/viem@2.38.2",
49
+ "viem": "npm:@aztec/viem@2.38.3",
50
50
  "zod": "~4.4.3"
51
51
  },
52
52
  "devDependencies": {
53
- "@aztec-labs/noir-protocol-circuits-types": "6.0.0-nightly.20260921",
54
- "@aztec-labs/protocol-contracts": "6.0.0-nightly.20260921",
55
- "@aztec-labs/world-state": "6.0.0-nightly.20260921",
53
+ "@aztec-labs/noir-protocol-circuits-types": "6.0.0-nightly.20260923",
54
+ "@aztec-labs/protocol-contracts": "6.0.0-nightly.20260923",
55
+ "@aztec-labs/world-state": "6.0.0-nightly.20260923",
56
56
  "@electric-sql/pglite": "^0.3.14",
57
57
  "@jest/globals": "^30.0.0",
58
58
  "@types/jest": "^30.0.0",
@@ -20,8 +20,8 @@ export type DroppedRequest = {
20
20
  * Result of {@link SequencerBundleSimulator.simulate}.
21
21
  *
22
22
  * - `success`: simulation succeeded. `requests` is the filtered survivor list, `gasLimit` is
23
- * the bumped gas limit derived from `gasUsed` (plus blob evaluation gas). `droppedRequests`
24
- * lists the entries that were observed to revert in simulation.
23
+ * the bumped gas limit derived from the simulated transaction gas (plus blob evaluation gas).
24
+ * `droppedRequests` lists the entries that were observed to revert in simulation.
25
25
  * - `fallback`: the node does not support eth_simulateV1 (or the simulate call threw). The
26
26
  * caller should send `requests` as-is with a safe gas limit (e.g. {@link MAX_L1_TX_LIMIT}).
27
27
  * `droppedRequests` carries any entries that the first pass already proved reverted, so the
@@ -38,7 +38,13 @@ export type BundleSimulateResult =
38
38
  export type AbortReason = 'empty-bundle' | 'all-reverted' | 'second-pass-reverts';
39
39
 
40
40
  type SimulatePassResult =
41
- | { kind: 'decoded'; survivors: RequestWithExpiry[]; droppedRequests: DroppedRequest[]; gasUsed: bigint }
41
+ | {
42
+ kind: 'decoded';
43
+ survivors: RequestWithExpiry[];
44
+ droppedRequests: DroppedRequest[];
45
+ gasUsed: bigint;
46
+ maxUsedGas?: bigint;
47
+ }
42
48
  | { kind: 'fallback' };
43
49
 
44
50
  /**
@@ -114,7 +120,7 @@ export class SequencerBundleSimulator {
114
120
  }
115
121
 
116
122
  if (firstPass.droppedRequests.length === 0) {
117
- return this.buildSuccessResult(l1TxUtils, firstPass.survivors, [], firstPass.gasUsed, proposeRequest);
123
+ return this.buildSuccessResult(l1TxUtils, firstPass.survivors, [], firstPass, proposeRequest);
118
124
  }
119
125
 
120
126
  this.log.warn('Some bundle entries reverted; re-simulating reduced bundle', {
@@ -155,11 +161,12 @@ export class SequencerBundleSimulator {
155
161
  };
156
162
  }
157
163
 
164
+ // The reduced bundle is what we are about to send, so its own gas metrics are the ones that size the tx.
158
165
  return this.buildSuccessResult(
159
166
  l1TxUtils,
160
167
  secondPass.survivors,
161
168
  firstPass.droppedRequests,
162
- secondPass.gasUsed,
169
+ secondPass,
163
170
  proposeRequest,
164
171
  );
165
172
  }
@@ -168,15 +175,17 @@ export class SequencerBundleSimulator {
168
175
  l1TxUtils: L1TxUtils,
169
176
  survivors: RequestWithExpiry[],
170
177
  droppedRequests: DroppedRequest[],
171
- bundleGasUsed: bigint,
178
+ bundleGas: { gasUsed: bigint; maxUsedGas?: bigint },
172
179
  proposeRequest: RequestWithExpiry | undefined,
173
180
  ): BundleSimulateResult {
174
181
  const proposeSurvived = proposeRequest !== undefined && survivors.includes(proposeRequest);
175
182
  const blobEvaluationGas = proposeSurvived ? (proposeRequest?.blobEvaluationGas ?? 0n) : 0n;
176
- const gasLimit = this.computeGasLimit(l1TxUtils, bundleGasUsed, blobEvaluationGas);
183
+ const gasLimit = this.computeGasLimit(l1TxUtils, bundleGas, blobEvaluationGas);
177
184
  this.log.debug('Bundle simulate complete', {
178
185
  survivingRequests: survivors.length,
179
- bundleGasUsed,
186
+ bundleGasUsed: bundleGas.gasUsed,
187
+ bundleMaxUsedGas: bundleGas.maxUsedGas,
188
+ blobEvaluationGas,
180
189
  gasLimit,
181
190
  actions: survivors.map(r => r.action),
182
191
  });
@@ -184,11 +193,20 @@ export class SequencerBundleSimulator {
184
193
  }
185
194
 
186
195
  /**
187
- * `gasLimit = bumpGasLimit(ceil(gasUsed * 64 / 63))`, plus blob evaluation gas if a propose
188
- * survived, capped at the L1 block gas limit.
196
+ * `gasLimit = bumpGasLimit(ceil(basis * 64 / 63))`, plus blob evaluation gas if a propose survived,
197
+ * capped at {@link MAX_L1_TX_LIMIT}.
198
+ *
199
+ * The basis is the simulation's `maxUsedGas` when the node reports it, since that is measured before
200
+ * refunds, and its `gasUsed` otherwise. Either way the headroom on top is the buffer configured for the
201
+ * L1 tx utils; neither figure guarantees a sufficient limit, hence the padding and the buffer.
189
202
  */
190
- private computeGasLimit(l1TxUtils: L1TxUtils, bundleGasUsed: bigint, blobEvaluationGas: bigint): bigint {
191
- const gasUsedWithEip150 = (bundleGasUsed * 64n + 62n) / 63n;
203
+ private computeGasLimit(
204
+ l1TxUtils: L1TxUtils,
205
+ bundleGas: { gasUsed: bigint; maxUsedGas?: bigint },
206
+ blobEvaluationGas: bigint,
207
+ ): bigint {
208
+ const basis = bundleGas.maxUsedGas ?? bundleGas.gasUsed;
209
+ const gasUsedWithEip150 = (basis * 64n + 62n) / 63n;
192
210
  const gasLimit = l1TxUtils.bumpGasLimit(gasUsedWithEip150) + blobEvaluationGas;
193
211
  return gasLimit > MAX_L1_TX_LIMIT ? MAX_L1_TX_LIMIT : gasLimit;
194
212
  }
@@ -248,6 +266,12 @@ export class SequencerBundleSimulator {
248
266
  returnData: entry.returnData,
249
267
  });
250
268
  }
251
- return { kind: 'decoded', survivors, droppedRequests, gasUsed: simResult.gasUsed };
269
+ return {
270
+ kind: 'decoded',
271
+ survivors,
272
+ droppedRequests,
273
+ gasUsed: simResult.gasUsed,
274
+ maxUsedGas: simResult.maxUsedGas,
275
+ };
252
276
  }
253
277
  }