@aztec/stdlib 0.0.1-commit.3f296a7d2 → 0.0.1-commit.3f5453c7b

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 (219) hide show
  1. package/dest/abi/decoder.d.ts +5 -44
  2. package/dest/abi/decoder.d.ts.map +1 -1
  3. package/dest/abi/decoder.js +12 -67
  4. package/dest/abi/function_selector.js +1 -1
  5. package/dest/abi/function_signature_decoder.d.ts +43 -0
  6. package/dest/abi/function_signature_decoder.d.ts.map +1 -0
  7. package/dest/abi/function_signature_decoder.js +66 -0
  8. package/dest/abi/index.d.ts +2 -1
  9. package/dest/abi/index.d.ts.map +1 -1
  10. package/dest/abi/index.js +1 -0
  11. package/dest/abi/selector.d.ts +2 -2
  12. package/dest/abi/selector.d.ts.map +1 -1
  13. package/dest/abi/selector.js +1 -1
  14. package/dest/avm/avm.d.ts +300 -300
  15. package/dest/avm/revert_code.d.ts +8 -18
  16. package/dest/avm/revert_code.d.ts.map +1 -1
  17. package/dest/avm/revert_code.js +15 -30
  18. package/dest/block/l2_block_source.d.ts +80 -3
  19. package/dest/block/l2_block_source.d.ts.map +1 -1
  20. package/dest/block/l2_block_source.js +1 -0
  21. package/dest/block/l2_block_stream/l2_tips_store_base.d.ts +1 -1
  22. package/dest/block/l2_block_stream/l2_tips_store_base.d.ts.map +1 -1
  23. package/dest/block/l2_block_stream/l2_tips_store_base.js +17 -4
  24. package/dest/block/test/l2_tips_store_test_suite.d.ts +1 -1
  25. package/dest/block/test/l2_tips_store_test_suite.d.ts.map +1 -1
  26. package/dest/block/test/l2_tips_store_test_suite.js +3 -2
  27. package/dest/checkpoint/checkpoint.d.ts +7 -1
  28. package/dest/checkpoint/checkpoint.d.ts.map +1 -1
  29. package/dest/checkpoint/checkpoint.js +9 -1
  30. package/dest/checkpoint/checkpoint_data.d.ts +71 -5
  31. package/dest/checkpoint/checkpoint_data.d.ts.map +1 -1
  32. package/dest/checkpoint/checkpoint_data.js +10 -0
  33. package/dest/config/sequencer-config.d.ts +2 -2
  34. package/dest/config/sequencer-config.d.ts.map +1 -1
  35. package/dest/config/sequencer-config.js +7 -0
  36. package/dest/epoch-helpers/index.d.ts +5 -1
  37. package/dest/epoch-helpers/index.d.ts.map +1 -1
  38. package/dest/epoch-helpers/index.js +6 -0
  39. package/dest/file-store/factory.d.ts +4 -3
  40. package/dest/file-store/factory.d.ts.map +1 -1
  41. package/dest/file-store/factory.js +2 -2
  42. package/dest/file-store/http.d.ts +9 -2
  43. package/dest/file-store/http.d.ts.map +1 -1
  44. package/dest/file-store/http.js +20 -9
  45. package/dest/file-store/index.d.ts +2 -1
  46. package/dest/file-store/index.d.ts.map +1 -1
  47. package/dest/gas/fee_math.d.ts +49 -0
  48. package/dest/gas/fee_math.d.ts.map +1 -0
  49. package/dest/gas/fee_math.js +80 -0
  50. package/dest/gas/gas_fees.d.ts +1 -1
  51. package/dest/gas/gas_fees.d.ts.map +1 -1
  52. package/dest/gas/gas_fees.js +10 -1
  53. package/dest/gas/gas_settings.d.ts +40 -3
  54. package/dest/gas/gas_settings.d.ts.map +1 -1
  55. package/dest/gas/gas_settings.js +50 -6
  56. package/dest/gas/index.d.ts +2 -1
  57. package/dest/gas/index.d.ts.map +1 -1
  58. package/dest/gas/index.js +1 -0
  59. package/dest/hash/hash.d.ts +4 -1
  60. package/dest/hash/hash.d.ts.map +1 -1
  61. package/dest/hash/hash.js +5 -0
  62. package/dest/interfaces/archiver.d.ts +1 -1
  63. package/dest/interfaces/archiver.d.ts.map +1 -1
  64. package/dest/interfaces/archiver.js +3 -1
  65. package/dest/interfaces/aztec-node-admin.d.ts +4 -14
  66. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  67. package/dest/interfaces/aztec-node-admin.js +3 -3
  68. package/dest/interfaces/aztec-node-debug.d.ts +21 -0
  69. package/dest/interfaces/aztec-node-debug.d.ts.map +1 -0
  70. package/dest/interfaces/aztec-node-debug.js +18 -0
  71. package/dest/interfaces/aztec-node.d.ts +10 -1
  72. package/dest/interfaces/aztec-node.d.ts.map +1 -1
  73. package/dest/interfaces/aztec-node.js +2 -0
  74. package/dest/interfaces/client.d.ts +2 -1
  75. package/dest/interfaces/client.d.ts.map +1 -1
  76. package/dest/interfaces/client.js +1 -0
  77. package/dest/interfaces/slasher.d.ts +1 -10
  78. package/dest/interfaces/slasher.d.ts.map +1 -1
  79. package/dest/interfaces/slasher.js +0 -2
  80. package/dest/interfaces/validator.d.ts +4 -15
  81. package/dest/interfaces/validator.d.ts.map +1 -1
  82. package/dest/interfaces/validator.js +0 -1
  83. package/dest/l1-contracts/index.d.ts +2 -2
  84. package/dest/l1-contracts/index.d.ts.map +1 -1
  85. package/dest/l1-contracts/index.js +1 -1
  86. package/dest/logs/extended_directional_app_tagging_secret.d.ts +4 -4
  87. package/dest/logs/extended_directional_app_tagging_secret.d.ts.map +1 -1
  88. package/dest/logs/extended_directional_app_tagging_secret.js +12 -5
  89. package/dest/logs/message_context.d.ts +4 -7
  90. package/dest/logs/message_context.d.ts.map +1 -1
  91. package/dest/logs/message_context.js +23 -9
  92. package/dest/logs/pending_tagged_log.d.ts +2 -3
  93. package/dest/logs/pending_tagged_log.d.ts.map +1 -1
  94. package/dest/logs/pending_tagged_log.js +2 -2
  95. package/dest/logs/shared_secret_derivation.d.ts +11 -10
  96. package/dest/logs/shared_secret_derivation.d.ts.map +1 -1
  97. package/dest/logs/shared_secret_derivation.js +15 -9
  98. package/dest/logs/siloed_tag.d.ts +4 -1
  99. package/dest/logs/siloed_tag.d.ts.map +1 -1
  100. package/dest/logs/siloed_tag.js +7 -3
  101. package/dest/messaging/l1_to_l2_message.d.ts +3 -2
  102. package/dest/messaging/l1_to_l2_message.d.ts.map +1 -1
  103. package/dest/messaging/l1_to_l2_message.js +11 -13
  104. package/dest/note/note_dao.d.ts +1 -1
  105. package/dest/note/note_dao.d.ts.map +1 -1
  106. package/dest/note/note_dao.js +1 -4
  107. package/dest/p2p/checkpoint_proposal.d.ts +2 -2
  108. package/dest/p2p/checkpoint_proposal.d.ts.map +1 -1
  109. package/dest/p2p/checkpoint_proposal.js +3 -15
  110. package/dest/proofs/chonk_proof.d.ts +46 -2
  111. package/dest/proofs/chonk_proof.d.ts.map +1 -1
  112. package/dest/proofs/chonk_proof.js +85 -10
  113. package/dest/slashing/index.d.ts +2 -3
  114. package/dest/slashing/index.d.ts.map +1 -1
  115. package/dest/slashing/index.js +1 -2
  116. package/dest/slashing/serialization.d.ts +2 -6
  117. package/dest/slashing/serialization.d.ts.map +1 -1
  118. package/dest/slashing/serialization.js +0 -60
  119. package/dest/slashing/types.d.ts +4 -90
  120. package/dest/slashing/types.d.ts.map +1 -1
  121. package/dest/slashing/types.js +0 -14
  122. package/dest/slashing/{tally.d.ts → votes.d.ts} +1 -1
  123. package/dest/slashing/{tally.d.ts.map → votes.d.ts.map} +1 -1
  124. package/dest/slashing/{tally.js → votes.js} +1 -1
  125. package/dest/tests/factories.d.ts +1 -1
  126. package/dest/tests/factories.d.ts.map +1 -1
  127. package/dest/tests/factories.js +11 -1
  128. package/dest/tests/mocks.d.ts +1 -1
  129. package/dest/tests/mocks.d.ts.map +1 -1
  130. package/dest/tests/mocks.js +13 -18
  131. package/dest/timetable/index.d.ts +51 -1
  132. package/dest/timetable/index.d.ts.map +1 -1
  133. package/dest/timetable/index.js +204 -14
  134. package/dest/tx/capsule.d.ts +6 -2
  135. package/dest/tx/capsule.d.ts.map +1 -1
  136. package/dest/tx/capsule.js +9 -3
  137. package/dest/tx/fee_provider.d.ts +10 -0
  138. package/dest/tx/fee_provider.d.ts.map +1 -0
  139. package/dest/tx/fee_provider.js +1 -0
  140. package/dest/tx/global_variable_builder.d.ts +3 -4
  141. package/dest/tx/global_variable_builder.d.ts.map +1 -1
  142. package/dest/tx/index.d.ts +2 -1
  143. package/dest/tx/index.d.ts.map +1 -1
  144. package/dest/tx/index.js +1 -0
  145. package/dest/tx/simulated_tx.d.ts +4 -4
  146. package/dest/tx/simulated_tx.d.ts.map +1 -1
  147. package/dest/tx/simulated_tx.js +3 -3
  148. package/dest/tx/tx_receipt.d.ts +8 -4
  149. package/dest/tx/tx_receipt.d.ts.map +1 -1
  150. package/dest/tx/tx_receipt.js +8 -15
  151. package/dest/world-state/genesis_data.d.ts +11 -0
  152. package/dest/world-state/genesis_data.d.ts.map +1 -0
  153. package/dest/world-state/genesis_data.js +4 -0
  154. package/dest/world-state/index.d.ts +2 -1
  155. package/dest/world-state/index.d.ts.map +1 -1
  156. package/dest/world-state/index.js +1 -0
  157. package/package.json +8 -8
  158. package/src/abi/decoder.ts +23 -78
  159. package/src/abi/function_selector.ts +1 -1
  160. package/src/abi/function_signature_decoder.ts +77 -0
  161. package/src/abi/index.ts +1 -0
  162. package/src/abi/selector.ts +1 -1
  163. package/src/avm/revert_code.ts +25 -39
  164. package/src/block/l2_block_source.ts +10 -2
  165. package/src/block/l2_block_stream/l2_tips_store_base.ts +24 -12
  166. package/src/block/test/l2_tips_store_test_suite.ts +8 -1
  167. package/src/checkpoint/checkpoint.ts +11 -1
  168. package/src/checkpoint/checkpoint_data.ts +40 -4
  169. package/src/config/sequencer-config.ts +11 -1
  170. package/src/epoch-helpers/index.ts +13 -0
  171. package/src/file-store/factory.ts +13 -4
  172. package/src/file-store/http.ts +29 -10
  173. package/src/file-store/index.ts +1 -0
  174. package/src/gas/README.md +31 -0
  175. package/src/gas/fee_math.ts +120 -0
  176. package/src/gas/gas_fees.ts +12 -4
  177. package/src/gas/gas_settings.ts +65 -12
  178. package/src/gas/index.ts +1 -0
  179. package/src/hash/hash.ts +5 -0
  180. package/src/interfaces/archiver.ts +3 -1
  181. package/src/interfaces/aztec-node-admin.ts +5 -7
  182. package/src/interfaces/aztec-node-debug.ts +40 -0
  183. package/src/interfaces/aztec-node.ts +15 -0
  184. package/src/interfaces/client.ts +1 -0
  185. package/src/interfaces/slasher.ts +0 -6
  186. package/src/interfaces/validator.ts +2 -9
  187. package/src/l1-contracts/index.ts +1 -1
  188. package/src/logs/extended_directional_app_tagging_secret.ts +19 -8
  189. package/src/logs/message_context.ts +17 -7
  190. package/src/logs/pending_tagged_log.ts +1 -3
  191. package/src/logs/shared_secret_derivation.ts +21 -10
  192. package/src/logs/siloed_tag.ts +7 -2
  193. package/src/messaging/l1_to_l2_message.ts +12 -9
  194. package/src/note/note_dao.ts +1 -4
  195. package/src/p2p/checkpoint_proposal.ts +10 -26
  196. package/src/proofs/chonk_proof.ts +91 -5
  197. package/src/slashing/index.ts +1 -2
  198. package/src/slashing/serialization.ts +1 -81
  199. package/src/slashing/types.ts +3 -35
  200. package/src/slashing/{tally.ts → votes.ts} +1 -1
  201. package/src/tests/factories.ts +5 -1
  202. package/src/tests/mocks.ts +14 -12
  203. package/src/timetable/index.ts +293 -13
  204. package/src/tx/capsule.ts +10 -2
  205. package/src/tx/fee_provider.ts +10 -0
  206. package/src/tx/global_variable_builder.ts +2 -3
  207. package/src/tx/index.ts +1 -0
  208. package/src/tx/simulated_tx.ts +6 -2
  209. package/src/tx/tx_receipt.ts +11 -14
  210. package/src/world-state/genesis_data.ts +15 -0
  211. package/src/world-state/index.ts +1 -0
  212. package/dest/l1-contracts/slash_factory.d.ts +0 -45
  213. package/dest/l1-contracts/slash_factory.d.ts.map +0 -1
  214. package/dest/l1-contracts/slash_factory.js +0 -158
  215. package/dest/slashing/empire.d.ts +0 -31
  216. package/dest/slashing/empire.d.ts.map +0 -1
  217. package/dest/slashing/empire.js +0 -87
  218. package/src/l1-contracts/slash_factory.ts +0 -180
  219. package/src/slashing/empire.ts +0 -104
@@ -5,35 +5,17 @@ import { BufferReader, FieldReader } from '@aztec/foundation/serialize';
5
5
  import { inspect } from 'util';
6
6
  import { z } from 'zod';
7
7
 
8
- /**
9
- * Tracks which revertible phases of a transaction's public execution reverted.
10
- *
11
- * A transaction executes in three sequential phases:
12
- * 1. SETUP – non-revertible; if this fails the entire transaction is rejected.
13
- * 2. APP_LOGIC – revertible; its state changes are rolled back on failure.
14
- * 3. TEARDOWN – revertible; always runs (even after app-logic revert) so the fee-payment contract can clean up.
15
- *
16
- * Only APP_LOGIC and TEARDOWN can produce a revert code. SETUP failures throw instead and discard the transaction
17
- * entirely.
18
- */
8
+ /** Whether a transaction's public execution reverted. */
19
9
  export enum RevertCodeEnum {
20
10
  /** All phases completed successfully; no state was rolled back. */
21
11
  OK = 0,
22
- /** APP_LOGIC reverted; its state changes were discarded. If present, TEARDOWN still ran and succeeded. */
23
- APP_LOGIC_REVERTED = 1,
24
- /** TEARDOWN reverted; its state changes were discarded. APP_LOGIC succeeded. */
25
- TEARDOWN_REVERTED = 2,
26
- /** Both APP_LOGIC and TEARDOWN reverted; only SETUP effects are kept. */
27
- BOTH_REVERTED = 3,
12
+ /** One or more revertible phases reverted; their state changes were discarded. */
13
+ REVERTED = 1,
28
14
  }
29
15
 
30
- function isRevertCodeEnum(value: number): value is RevertCodeEnum {
31
- return (
32
- (value as RevertCodeEnum) === RevertCodeEnum.OK ||
33
- (value as RevertCodeEnum) === RevertCodeEnum.APP_LOGIC_REVERTED ||
34
- (value as RevertCodeEnum) === RevertCodeEnum.TEARDOWN_REVERTED ||
35
- (value as RevertCodeEnum) === RevertCodeEnum.BOTH_REVERTED
36
- );
16
+ /** Returns a valid RevertCodeEnum, coercing any value >= 1 to REVERTED. */
17
+ function toRevertCodeEnum(value: number): RevertCodeEnum {
18
+ return value >= 1 ? RevertCodeEnum.REVERTED : RevertCodeEnum.OK;
37
19
  }
38
20
 
39
21
  /**
@@ -45,9 +27,13 @@ export class RevertCode {
45
27
  this.code = e.valueOf();
46
28
  }
47
29
  static readonly OK: RevertCode = new RevertCode(RevertCodeEnum.OK);
48
- static readonly APP_LOGIC_REVERTED: RevertCode = new RevertCode(RevertCodeEnum.APP_LOGIC_REVERTED);
49
- static readonly TEARDOWN_REVERTED: RevertCode = new RevertCode(RevertCodeEnum.TEARDOWN_REVERTED);
50
- static readonly BOTH_REVERTED: RevertCode = new RevertCode(RevertCodeEnum.BOTH_REVERTED);
30
+ static readonly REVERTED: RevertCode = new RevertCode(RevertCodeEnum.REVERTED);
31
+ /** @deprecated Use REVERTED instead. */
32
+ static readonly APP_LOGIC_REVERTED: RevertCode = RevertCode.REVERTED;
33
+ /** @deprecated Use REVERTED instead. */
34
+ static readonly TEARDOWN_REVERTED: RevertCode = RevertCode.REVERTED;
35
+ /** @deprecated Use REVERTED instead. */
36
+ static readonly BOTH_REVERTED: RevertCode = RevertCode.REVERTED;
51
37
 
52
38
  public getCode(): RevertCodeEnum {
53
39
  return this.code;
@@ -65,12 +51,8 @@ export class RevertCode {
65
51
  switch (this.code as RevertCodeEnum) {
66
52
  case RevertCodeEnum.OK:
67
53
  return 'OK';
68
- case RevertCodeEnum.APP_LOGIC_REVERTED:
69
- return 'Application logic reverted';
70
- case RevertCodeEnum.TEARDOWN_REVERTED:
71
- return 'Teardown reverted';
72
- case RevertCodeEnum.BOTH_REVERTED:
73
- return 'Both reverted';
54
+ case RevertCodeEnum.REVERTED:
55
+ return 'Reverted';
74
56
  default:
75
57
  return `Unknown RevertCode: ${this.code}`;
76
58
  }
@@ -81,7 +63,11 @@ export class RevertCode {
81
63
  }
82
64
 
83
65
  static get schema(): ZodFor<RevertCode> {
84
- return z.nativeEnum(RevertCodeEnum).transform(value => new RevertCode(value));
66
+ return z
67
+ .number()
68
+ .int()
69
+ .min(0)
70
+ .transform(value => new RevertCode(toRevertCodeEnum(value)));
85
71
  }
86
72
 
87
73
  /**
@@ -96,10 +82,10 @@ export class RevertCode {
96
82
  return obj;
97
83
  }
98
84
  const code = typeof obj === 'number' ? obj : (obj.code ?? obj);
99
- if (!isRevertCodeEnum(code)) {
85
+ if (typeof code !== 'number' || code < 0) {
100
86
  throw new Error(`Invalid RevertCode: ${code}`);
101
87
  }
102
- return new RevertCode(code);
88
+ return new RevertCode(toRevertCodeEnum(code));
103
89
  }
104
90
 
105
91
  /**
@@ -131,10 +117,10 @@ export class RevertCode {
131
117
  }
132
118
 
133
119
  public static fromNumber(code: number): RevertCode {
134
- if (!isRevertCodeEnum(code)) {
120
+ if (code < 0) {
135
121
  throw new Error(`Invalid RevertCode: ${code}`);
136
122
  }
137
- return new RevertCode(code);
123
+ return new RevertCode(toRevertCodeEnum(code));
138
124
  }
139
125
 
140
126
  public static fromField(field: Fr): RevertCode {
@@ -152,7 +138,7 @@ export class RevertCode {
152
138
  return RevertCode.fromNumber(code);
153
139
  }
154
140
 
155
- private static readonly NUM_OPTIONS = 4;
141
+ private static readonly NUM_OPTIONS = 2;
156
142
  static random(): RevertCode {
157
143
  return new RevertCode(Math.floor(Math.random() * RevertCode.NUM_OPTIONS));
158
144
  }
@@ -13,7 +13,7 @@ import type { TypedEventEmitter } from '@aztec/foundation/types';
13
13
  import { z } from 'zod';
14
14
 
15
15
  import type { Checkpoint } from '../checkpoint/checkpoint.js';
16
- import type { CheckpointData } from '../checkpoint/checkpoint_data.js';
16
+ import type { CheckpointData, CommonCheckpointData, ProposedCheckpointData } from '../checkpoint/checkpoint_data.js';
17
17
  import type { PublishedCheckpoint } from '../checkpoint/published_checkpoint.js';
18
18
  import type { L1RollupConstants } from '../epoch-helpers/index.js';
19
19
  import { CheckpointHeader } from '../rollup/checkpoint_header.js';
@@ -229,6 +229,12 @@ export interface L2BlockSource {
229
229
  */
230
230
  getPendingChainValidationStatus(): Promise<ValidateCheckpointResult>;
231
231
 
232
+ /** Returns the checkpoint at the proposed chain tip. */
233
+ getProposedCheckpoint(): Promise<CommonCheckpointData | undefined>;
234
+
235
+ /** Returns proposed checkpoint, if set, undefined if not*/
236
+ getProposedCheckpointOnly(): Promise<ProposedCheckpointData | undefined>;
237
+
232
238
  /** Force a sync. */
233
239
  syncImmediate(): Promise<void>;
234
240
 
@@ -312,12 +318,13 @@ export interface L2BlockSourceEventEmitter extends L2BlockSource {
312
318
  * - proven: Proven block on L1.
313
319
  * - finalized: Proven block on a finalized L1 block (not implemented, set to proven for now).
314
320
  */
315
- export type L2BlockTag = 'proposed' | 'checkpointed' | 'proven' | 'finalized';
321
+ export type L2BlockTag = 'proposed' | 'proposedCheckpoint' | 'checkpointed' | 'proven' | 'finalized';
316
322
 
317
323
  /** Tips of the L2 chain. */
318
324
  export type L2Tips = {
319
325
  proposed: L2BlockId;
320
326
  checkpointed: L2TipId;
327
+ proposedCheckpoint: L2TipId;
321
328
  proven: L2TipId;
322
329
  finalized: L2TipId;
323
330
  };
@@ -362,6 +369,7 @@ const L2TipIdSchema = z.object({
362
369
  export const L2TipsSchema = z.object({
363
370
  proposed: L2BlockIdSchema,
364
371
  checkpointed: L2TipIdSchema,
372
+ proposedCheckpoint: L2TipIdSchema,
365
373
  proven: L2TipIdSchema,
366
374
  finalized: L2TipIdSchema,
367
375
  });
@@ -66,24 +66,29 @@ export abstract class L2TipsStoreBase implements L2BlockStreamEventHandler, L2Bl
66
66
 
67
67
  public getL2Tips(): Promise<L2Tips> {
68
68
  return this.runInTransaction(async () => {
69
- const [proposedBlockId, finalizedBlockId, provenBlockId, checkpointedBlockId] = await Promise.all([
70
- this.getBlockId('proposed'),
71
- this.getBlockId('finalized'),
72
- this.getBlockId('proven'),
73
- this.getBlockId('checkpointed'),
74
- ]);
75
-
76
- const [finalizedCheckpointId, provenCheckpointId, checkpointedCheckpointId] = await Promise.all([
77
- this.getCheckpointId('finalized'),
78
- this.getCheckpointId('proven'),
79
- this.getCheckpointId('checkpointed'),
80
- ]);
69
+ const [proposedBlockId, finalizedBlockId, provenBlockId, checkpointedBlockId, proposedCheckpointBlockId] =
70
+ await Promise.all([
71
+ this.getBlockId('proposed'),
72
+ this.getBlockId('finalized'),
73
+ this.getBlockId('proven'),
74
+ this.getBlockId('checkpointed'),
75
+ this.getBlockId('proposedCheckpoint'),
76
+ ]);
77
+
78
+ const [finalizedCheckpointId, provenCheckpointId, checkpointedCheckpointId, proposedCheckpointId] =
79
+ await Promise.all([
80
+ this.getCheckpointId('finalized'),
81
+ this.getCheckpointId('proven'),
82
+ this.getCheckpointId('checkpointed'),
83
+ this.getCheckpointId('proposedCheckpoint'),
84
+ ]);
81
85
 
82
86
  return {
83
87
  proposed: proposedBlockId,
84
88
  finalized: { block: finalizedBlockId, checkpoint: finalizedCheckpointId },
85
89
  proven: { block: provenBlockId, checkpoint: provenCheckpointId },
86
90
  checkpointed: { block: checkpointedBlockId, checkpoint: checkpointedCheckpointId },
91
+ proposedCheckpoint: { block: proposedCheckpointBlockId, checkpoint: proposedCheckpointId },
87
92
  };
88
93
  });
89
94
  }
@@ -164,6 +169,12 @@ export abstract class L2TipsStoreBase implements L2BlockStreamEventHandler, L2Bl
164
169
  await this.runInTransaction(async () => {
165
170
  await this.saveTag('checkpointed', event.block);
166
171
  await this.saveCheckpoint(event.checkpoint);
172
+ // proposedCheckpoint is always >= checkpointed. If checkpointed has caught up
173
+ // or surpassed it, advance proposedCheckpoint to match.
174
+ const proposedCheckpointBlock = await this.getBlockId('proposedCheckpoint');
175
+ if (event.block.number > proposedCheckpointBlock.number) {
176
+ await this.saveTag('proposedCheckpoint', event.block);
177
+ }
167
178
  });
168
179
  }
169
180
 
@@ -174,6 +185,7 @@ export abstract class L2TipsStoreBase implements L2BlockStreamEventHandler, L2Bl
174
185
  await this.runInTransaction(async () => {
175
186
  await this.saveTag('proposed', event.block);
176
187
  await this.saveTag('checkpointed', event.block);
188
+ await this.saveTag('proposedCheckpoint', event.block);
177
189
  const storeProven = await this.getBlockId('proven');
178
190
  if (storeProven.number > event.block.number) {
179
191
  await this.saveTag('proven', event.block);
@@ -67,11 +67,18 @@ export function testL2TipsStore(makeTipsStore: () => Promise<L2TipsStore>) {
67
67
  checkpoint: makeCheckpointIdForBlock(blockNumber),
68
68
  });
69
69
 
70
- const makeTips = (proposed: number, proven: number, finalized: number, checkpointed: number = 0) => ({
70
+ const makeTips = (
71
+ proposed: number,
72
+ proven: number,
73
+ finalized: number,
74
+ checkpointed: number = 0,
75
+ proposedCheckpoint: number = 0,
76
+ ) => ({
71
77
  proposed: makeTip(proposed),
72
78
  proven: makeTipId(proven),
73
79
  finalized: makeTipId(finalized),
74
80
  checkpointed: makeTipId(checkpointed),
81
+ proposedCheckpoint: makeTipId(proposedCheckpoint),
75
82
  });
76
83
 
77
84
  const makeCheckpoint = async (checkpointNumber: number, blocks: L2Block[]): Promise<PublishedCheckpoint> => {
@@ -100,7 +100,16 @@ export class Checkpoint {
100
100
  * checkpoints up to and including this one in the epoch.
101
101
  */
102
102
  public getCheckpointOutHash(): Fr {
103
- const msgs = this.blocks.map(block => block.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs));
103
+ return Checkpoint.getCheckpointOutHash(this.blocks);
104
+ }
105
+
106
+ /**
107
+ * Returns the out hash computed from all l2-to-l1 messages in this checkpoint.
108
+ * Note: This value is different from the out hash in the header, which is the **accumulated** out hash over all
109
+ * checkpoints up to and including this one in the epoch.
110
+ */
111
+ static getCheckpointOutHash(blocks: L2Block[]): Fr {
112
+ const msgs = blocks.map(block => block.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs));
104
113
  return computeCheckpointOutHash(msgs);
105
114
  }
106
115
 
@@ -165,6 +174,7 @@ export class Checkpoint {
165
174
  let lastArchive = previousArchive;
166
175
  for (let i = 0; i < numBlocks; i++) {
167
176
  const block = await L2Block.random(BlockNumber(startBlockNumber + i), {
177
+ checkpointNumber,
168
178
  indexWithinCheckpoint: IndexWithinCheckpoint(i),
169
179
  ...options,
170
180
  ...(lastArchive ? { lastArchive } : {}),
@@ -14,18 +14,54 @@ import { CheckpointHeader } from '../rollup/checkpoint_header.js';
14
14
  import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js';
15
15
  import { L1PublishedData } from './published_checkpoint.js';
16
16
 
17
- /** Lightweight checkpoint metadata without full block data. */
18
- export type CheckpointData = {
17
+ /** Base type for checkpoint data */
18
+ export type CommonCheckpointData = {
19
19
  checkpointNumber: CheckpointNumber;
20
20
  header: CheckpointHeader;
21
- archive: AppendOnlyTreeSnapshot;
22
- checkpointOutHash: Fr;
23
21
  startBlock: BlockNumber;
24
22
  blockCount: number;
23
+ };
24
+
25
+ /** Data stored with checkpoint data after publishing on l1 */
26
+ export type L1EnrichedCheckpointData = {
25
27
  attestations: CommitteeAttestation[];
26
28
  l1: L1PublishedData;
27
29
  };
28
30
 
31
+ /** Data stored alongside checkpoint data in storage */
32
+ export type StorageEnrichedCheckpointData = {
33
+ archive: AppendOnlyTreeSnapshot;
34
+ checkpointOutHash: Fr;
35
+ };
36
+
37
+ /** Data stored only with proposed checkpoint data */
38
+ export type ProposedOnlyCheckpointData = {
39
+ totalManaUsed: bigint;
40
+ feeAssetPriceModifier: bigint;
41
+ };
42
+
43
+ /** Lightweight checkpoint metadata without full block data. */
44
+ export type CheckpointData = CommonCheckpointData & StorageEnrichedCheckpointData & L1EnrichedCheckpointData;
45
+
46
+ /** Input for setting a proposed checkpoint. The archive and checkpointOutHash are computed
47
+ * internally by the block store from the stored blocks. */
48
+ export type ProposedCheckpointInput = CommonCheckpointData & ProposedOnlyCheckpointData;
49
+
50
+ /** Full data for a proposed checkpoint (proposed but not yet L1-confirmed).
51
+ * Includes fee-relevant fields used during pipelining to compute the fee header override. */
52
+ export type ProposedCheckpointData = ProposedCheckpointInput & StorageEnrichedCheckpointData;
53
+
54
+ export const ProposedCheckpointDataSchema = z.object({
55
+ checkpointNumber: CheckpointNumberSchema,
56
+ header: CheckpointHeader.schema,
57
+ archive: AppendOnlyTreeSnapshot.schema,
58
+ checkpointOutHash: schemas.Fr,
59
+ startBlock: BlockNumberSchema,
60
+ blockCount: z.number(),
61
+ totalManaUsed: schemas.BigInt,
62
+ feeAssetPriceModifier: schemas.BigInt,
63
+ });
64
+
29
65
  export const CheckpointDataSchema = z
30
66
  .object({
31
67
  checkpointNumber: CheckpointNumberSchema,
@@ -1,6 +1,7 @@
1
1
  import type { ConfigMappingsType } from '@aztec/foundation/config';
2
2
 
3
3
  import type { SequencerConfig } from '../interfaces/configs.js';
4
+ import { DEFAULT_P2P_PROPAGATION_TIME } from '../timetable/index.js';
4
5
 
5
6
  /** Default maximum number of transactions per block. */
6
7
  export const DEFAULT_MAX_TXS_PER_BLOCK = 32;
@@ -12,7 +13,10 @@ export const DEFAULT_MAX_TXS_PER_BLOCK = 32;
12
13
  * to avoid duplication.
13
14
  */
14
15
  export const sharedSequencerConfigMappings: ConfigMappingsType<
15
- Pick<SequencerConfig, 'blockDurationMs' | 'expectedBlockProposalsPerSlot' | 'maxTxsPerBlock'>
16
+ Pick<
17
+ SequencerConfig,
18
+ 'blockDurationMs' | 'expectedBlockProposalsPerSlot' | 'maxTxsPerBlock' | 'attestationPropagationTime'
19
+ >
16
20
  > = {
17
21
  blockDurationMs: {
18
22
  env: 'SEQ_BLOCK_DURATION_MS',
@@ -34,4 +38,10 @@ export const sharedSequencerConfigMappings: ConfigMappingsType<
34
38
  description: 'The maximum number of txs to include in a block.',
35
39
  parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
36
40
  },
41
+ attestationPropagationTime: {
42
+ env: 'SEQ_ATTESTATION_PROPAGATION_TIME',
43
+ description: 'How many seconds it takes for proposals and attestations to travel across the p2p layer (one-way).',
44
+ parseEnv: (val: string) => (val ? parseFloat(val) : undefined),
45
+ defaultValue: DEFAULT_P2P_PROPAGATION_TIME,
46
+ },
37
47
  };
@@ -68,6 +68,14 @@ export function getNextL1SlotTimestamp(
68
68
  return constants.l1GenesisTime + (currentL1Slot + 1n) * BigInt(constants.ethereumSlotDuration);
69
69
  }
70
70
 
71
+ /** Returns the timestamp of the last L1 slot within a given L2 slot. */
72
+ export function getLastL1SlotTimestampForL2Slot(
73
+ slot: SlotNumber,
74
+ constants: Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration' | 'ethereumSlotDuration'>,
75
+ ): bigint {
76
+ return getTimestampForSlot(slot, constants) + BigInt(constants.slotDuration - constants.ethereumSlotDuration);
77
+ }
78
+
71
79
  /** Returns the L2 slot number at the next L1 block based on the current timestamp. */
72
80
  export function getSlotAtNextL1Block(
73
81
  currentL1Timestamp: bigint,
@@ -154,6 +162,11 @@ export function getProofSubmissionDeadlineTimestamp(
154
162
  return getTimestampForSlot(deadlineSlot, constants);
155
163
  }
156
164
 
165
+ /** Computes the quorum size required for a committee (⌊2n/3⌋ + 1). */
166
+ export function computeQuorum(committeeSize: number): number {
167
+ return Math.floor((committeeSize * 2) / 3) + 1;
168
+ }
169
+
157
170
  /** Returns the timestamp to start building a block for a given L2 slot. Computed as the start timestamp of the slot minus one L1 slot duration. */
158
171
  export function getSlotStartBuildTimestamp(
159
172
  slotNumber: SlotNumber,
@@ -1,7 +1,7 @@
1
1
  import { type Logger, createLogger } from '@aztec/foundation/log';
2
2
 
3
3
  import { GoogleCloudFileStore } from './gcs.js';
4
- import { HttpFileStore } from './http.js';
4
+ import { HttpFileStore, type HttpFileStoreOptions } from './http.js';
5
5
  import type { FileStore, ReadOnlyFileStore } from './interface.js';
6
6
  import { LocalFileStore } from './local.js';
7
7
  import { S3FileStore } from './s3.js';
@@ -59,17 +59,26 @@ export async function createFileStore(
59
59
  }
60
60
  }
61
61
 
62
- export async function createReadOnlyFileStore(config: string, logger?: Logger): Promise<ReadOnlyFileStore>;
63
- export async function createReadOnlyFileStore(config: undefined, logger?: Logger): Promise<undefined>;
62
+ export async function createReadOnlyFileStore(
63
+ config: string,
64
+ logger?: Logger,
65
+ options?: HttpFileStoreOptions,
66
+ ): Promise<ReadOnlyFileStore>;
67
+ export async function createReadOnlyFileStore(
68
+ config: undefined,
69
+ logger?: Logger,
70
+ options?: HttpFileStoreOptions,
71
+ ): Promise<undefined>;
64
72
  export async function createReadOnlyFileStore(
65
73
  config: string | undefined,
66
74
  logger = createLogger('stdlib:file-store'),
75
+ options?: HttpFileStoreOptions,
67
76
  ): Promise<ReadOnlyFileStore | undefined> {
68
77
  if (config === undefined) {
69
78
  return undefined;
70
79
  } else if (config.startsWith('http://') || config.startsWith('https://')) {
71
80
  logger.info(`Creating read-only HTTP file store at ${config}`);
72
- return new HttpFileStore(config, logger);
81
+ return new HttpFileStore(config, logger, options);
73
82
  } else {
74
83
  return await createFileStore(config, logger);
75
84
  }
@@ -10,6 +10,14 @@ import { pipeline } from 'stream/promises';
10
10
 
11
11
  import type { ReadOnlyFileStore } from './interface.js';
12
12
 
13
+ /** Options for configuring HttpFileStore behavior. */
14
+ export interface HttpFileStoreOptions {
15
+ /** Retry backoff intervals in seconds. Empty array disables retries. Default: [1, 1, 3]. */
16
+ retryBackoff?: number[];
17
+ /** Request timeout in milliseconds. Default: no timeout (axios default). */
18
+ timeoutMs?: number;
19
+ }
20
+
13
21
  export class HttpFileStore implements ReadOnlyFileStore {
14
22
  private readonly axiosInstance: AxiosInstance;
15
23
  private readonly fetch: <T>(config: AxiosRequestConfig) => Promise<AxiosResponse<T>>;
@@ -17,17 +25,28 @@ export class HttpFileStore implements ReadOnlyFileStore {
17
25
  constructor(
18
26
  private readonly baseUrl: string,
19
27
  private readonly log: Logger = createLogger('stdlib:http-file-store'),
28
+ options?: HttpFileStoreOptions,
20
29
  ) {
21
- this.axiosInstance = axios.create();
22
- this.fetch = async <T>(config: AxiosRequestConfig) => {
23
- return await retry(
24
- () => this.axiosInstance.request<T>(config),
25
- `Fetching ${config.url}`,
26
- makeBackoff([1, 1, 3]),
27
- this.log,
28
- /*failSilently=*/ true,
29
- );
30
- };
30
+ this.axiosInstance = axios.create({
31
+ ...(options?.timeoutMs !== undefined && { timeout: options.timeoutMs }),
32
+ });
33
+
34
+ const retryBackoff = options?.retryBackoff ?? [1, 1, 3];
35
+ if (retryBackoff.length > 0) {
36
+ this.fetch = async <T>(config: AxiosRequestConfig) => {
37
+ return await retry(
38
+ () => this.axiosInstance.request<T>(config),
39
+ `Fetching ${config.url}`,
40
+ makeBackoff(retryBackoff),
41
+ this.log,
42
+ /*failSilently=*/ true,
43
+ );
44
+ };
45
+ } else {
46
+ this.fetch = async <T>(config: AxiosRequestConfig) => {
47
+ return await this.axiosInstance.request<T>(config);
48
+ };
49
+ }
31
50
  }
32
51
 
33
52
  public async read(pathOrUrl: string): Promise<Buffer> {
@@ -1,2 +1,3 @@
1
1
  export * from './interface.js';
2
2
  export * from './factory.js';
3
+ export { type HttpFileStoreOptions } from './http.js';
package/src/gas/README.md CHANGED
@@ -84,6 +84,37 @@ else → use post (new fees)
84
84
  **Net effect**: L1 fee changes reach L2 with a 2-slot delay and can update at most once
85
85
  every 5 slots.
86
86
 
87
+ ### Worked Example
88
+
89
+ Suppose the oracle is updated at slot 10 with new L1 fees. Here is the timeline:
90
+
91
+ ```
92
+ Slot Oracle state Active fees Notes
93
+ ──── ──────────────────── ──────────── ──────────────────────────────────
94
+ 10 pre=A, post=B, soc=12 A Update queued. slotOfChange = 10 + LAG = 12.
95
+ 11 (same) A Still before slotOfChange → pre (A).
96
+ 12 (same) B slot >= slotOfChange → post (B) activates.
97
+ 13 (same) B B remains active.
98
+ 14 (same) B B remains active.
99
+ 15 Update allowed again B Earliest next update: soc + (LIFETIME - LAG)
100
+ = 12 + 3 = 15.
101
+ ```
102
+
103
+ Key observations:
104
+
105
+ 1. **Slots 10-11**: The old fees (A) are still in effect. Transactions submitted during
106
+ these slots see the old L1 cost. This is the **LAG** window — it gives pending
107
+ transactions 2 slots to land before fees change.
108
+
109
+ 2. **Slot 12**: The new fees (B) activate. Any checkpoint proposed at slot >= 12 uses B
110
+ for its sequencer/prover cost calculation.
111
+
112
+ 3. **Slots 12-14**: No new oracle update is accepted. The system is in a **cooldown**
113
+ period of `LIFETIME - LAG = 3` slots after the transition.
114
+
115
+ 4. **Slot 15**: A new oracle update can be queued (earliest `acceptableSlot`). If
116
+ triggered, the new values would activate at slot 15 + LAG = 17.
117
+
87
118
  ## Fee Asset Price
88
119
 
89
120
  Fees are computed in ETH internally but converted to the fee asset (Fee Juice) via
@@ -0,0 +1,120 @@
1
+ /**
2
+ * TypeScript port of fee computation logic from FeeLib.sol.
3
+ * Used to predict worst-case min fees over a future window of L2 slots.
4
+ */
5
+
6
+ // Constants matching FeeLib.sol
7
+ export const MINIMUM_CONGESTION_MULTIPLIER = 1_000_000_000n;
8
+ export const L1_GAS_PER_CHECKPOINT_PROPOSED = 300_000n;
9
+ export const L1_GAS_PER_EPOCH_VERIFIED = 3_600_000n;
10
+ export const BLOBS_PER_CHECKPOINT = 3n;
11
+ export const BLOB_GAS_PER_BLOB = 2n ** 17n;
12
+ export const MAGIC_CONGESTION_VALUE_MULTIPLIER = 854_700_854n;
13
+ export const MAGIC_CONGESTION_VALUE_DIVISOR = 100_000_000n;
14
+ export const ETH_PER_FEE_ASSET_PRECISION = 1_000_000_000_000n;
15
+ export const MIN_ETH_PER_FEE_ASSET = 100n;
16
+
17
+ /** Number of L2 slots of lag before new oracle values activate. Defines the prediction window. */
18
+ export const FEE_ORACLE_LAG = 2;
19
+
20
+ /** Expected mana usage per checkpoint for fee prediction. */
21
+ export enum ManaUsageEstimate {
22
+ /** No usage — fees decrease as congestion drains. */
23
+ None = 'none',
24
+ /** Target usage — congestion stays roughly flat (steady state). */
25
+ Target = 'target',
26
+ /** Limit usage (2x target) — worst case, congestion grows maximally. */
27
+ Limit = 'limit',
28
+ }
29
+
30
+ /** Parameters for computing the mana min fee at a given point in time. */
31
+ export type ManaMinFeeParams = {
32
+ l1BaseFee: bigint;
33
+ l1BlobFee: bigint;
34
+ manaTarget: bigint;
35
+ epochDuration: bigint;
36
+ provingCostPerManaEth: bigint;
37
+ excessMana: bigint;
38
+ ethPerFeeAsset: bigint;
39
+ };
40
+
41
+ /**
42
+ * Taylor series approximation of `factor * e^(numerator/denominator)`.
43
+ * Direct port of FeeLib.sol fakeExponential (EIP-4844 style).
44
+ */
45
+ export function fakeExponential(factor: bigint, numerator: bigint, denominator: bigint): bigint {
46
+ let i = 1n;
47
+ let output = 0n;
48
+ let numeratorAccumulator = factor * denominator;
49
+ while (numeratorAccumulator > 0n) {
50
+ output += numeratorAccumulator;
51
+ numeratorAccumulator = (numeratorAccumulator * numerator) / (denominator * i);
52
+ i += 1n;
53
+ }
54
+ return output / denominator;
55
+ }
56
+
57
+ /** Computes excess mana for the next checkpoint, clamped to zero. */
58
+ export function computeExcessMana(prevExcessMana: bigint, prevManaUsed: bigint, manaTarget: bigint): bigint {
59
+ const sum = prevExcessMana + prevManaUsed;
60
+ return sum > manaTarget ? sum - manaTarget : 0n;
61
+ }
62
+
63
+ /** Computes the congestion multiplier from excess mana (1e9 = no congestion). */
64
+ export function computeCongestionMultiplier(excessMana: bigint, manaTarget: bigint): bigint {
65
+ const denominator = (manaTarget * MAGIC_CONGESTION_VALUE_MULTIPLIER) / MAGIC_CONGESTION_VALUE_DIVISOR;
66
+ const cappedNumerator = excessMana < denominator * 100n ? excessMana : denominator * 100n;
67
+ return fakeExponential(MINIMUM_CONGESTION_MULTIPLIER, cappedNumerator, denominator);
68
+ }
69
+
70
+ /** Ceiling division for positive bigints. */
71
+ function ceilDiv(a: bigint, b: bigint): bigint {
72
+ return (a + b - 1n) / b;
73
+ }
74
+
75
+ /** Converts an ETH value to fee asset value using ethPerFeeAsset (1e12 precision). */
76
+ function toFeeAsset(ethValue: bigint, ethPerFeeAsset: bigint): bigint {
77
+ if (ethPerFeeAsset === 0n) {
78
+ return 0n;
79
+ }
80
+ return ceilDiv(ethValue * ETH_PER_FEE_ASSET_PRECISION, ethPerFeeAsset);
81
+ }
82
+
83
+ /**
84
+ * Computes the full mana min fee (sequencer + prover + congestion) in fee asset terms.
85
+ * Mirrors FeeLib.getManaMinFeeComponentsAt + summedMinFee.
86
+ */
87
+ export function computeManaMinFee(params: ManaMinFeeParams): bigint {
88
+ const { l1BaseFee, l1BlobFee, manaTarget, epochDuration, provingCostPerManaEth, excessMana, ethPerFeeAsset } = params;
89
+
90
+ if (manaTarget === 0n) {
91
+ return 0n;
92
+ }
93
+
94
+ // Sequencer cost per mana (in ETH)
95
+ const ethUsed = L1_GAS_PER_CHECKPOINT_PROPOSED * l1BaseFee + BLOBS_PER_CHECKPOINT * BLOB_GAS_PER_BLOB * l1BlobFee;
96
+ const sequencerCostEth = ceilDiv(ethUsed, manaTarget);
97
+
98
+ // Prover cost per mana (in ETH): L1 verification gas + governance-set proving cost
99
+ const proverCostEth =
100
+ ceilDiv(ceilDiv(L1_GAS_PER_EPOCH_VERIFIED * l1BaseFee, epochDuration), manaTarget) + provingCostPerManaEth;
101
+
102
+ // Total base cost in ETH (congestion is computed on this)
103
+ const totalEth = sequencerCostEth + proverCostEth;
104
+
105
+ // Congestion multiplier and cost (in ETH)
106
+ const congestionMul = computeCongestionMultiplier(excessMana, manaTarget);
107
+ const congestionCostEth = (totalEth * congestionMul) / MINIMUM_CONGESTION_MULTIPLIER - totalEth;
108
+
109
+ // Convert all components to fee asset
110
+ const clampedEthPerFeeAsset = ethPerFeeAsset < MIN_ETH_PER_FEE_ASSET ? MIN_ETH_PER_FEE_ASSET : ethPerFeeAsset;
111
+ const sequencerCost = toFeeAsset(sequencerCostEth, clampedEthPerFeeAsset);
112
+ const proverCost = toFeeAsset(proverCostEth, clampedEthPerFeeAsset);
113
+ const congestionCost = toFeeAsset(congestionCostEth, clampedEthPerFeeAsset);
114
+
115
+ const total = sequencerCost + proverCost + congestionCost;
116
+
117
+ // Cap at uint128 max (matching FeeLib.summedMinFee)
118
+ const UINT128_MAX = (1n << 128n) - 1n;
119
+ return total < UINT128_MAX ? total : UINT128_MAX;
120
+ }