@aztec/stdlib 5.0.0-nightly.20260429 → 5.0.0-nightly.20260430

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 (120) hide show
  1. package/dest/avm/avm.d.ts +300 -300
  2. package/dest/block/attestation_info.d.ts +3 -2
  3. package/dest/block/attestation_info.d.ts.map +1 -1
  4. package/dest/block/attestation_info.js +7 -5
  5. package/dest/block/block_data.d.ts +290 -1
  6. package/dest/block/block_data.d.ts.map +1 -1
  7. package/dest/block/block_data.js +14 -0
  8. package/dest/block/block_parameter.d.ts +30 -3
  9. package/dest/block/block_parameter.d.ts.map +1 -1
  10. package/dest/block/block_parameter.js +36 -2
  11. package/dest/block/l2_block_source.d.ts +39 -4
  12. package/dest/block/l2_block_source.d.ts.map +1 -1
  13. package/dest/block/proposal/attestations_and_signers.d.ts +13 -6
  14. package/dest/block/proposal/attestations_and_signers.d.ts.map +1 -1
  15. package/dest/block/proposal/attestations_and_signers.js +26 -18
  16. package/dest/checkpoint/checkpoint_data.d.ts +7 -1
  17. package/dest/checkpoint/checkpoint_data.d.ts.map +1 -1
  18. package/dest/checkpoint/checkpoint_data.js +2 -0
  19. package/dest/config/chain-config.d.ts +2 -2
  20. package/dest/config/chain-config.d.ts.map +1 -1
  21. package/dest/config/chain-config.js +2 -2
  22. package/dest/config/sequencer-config.d.ts +2 -2
  23. package/dest/config/sequencer-config.d.ts.map +1 -1
  24. package/dest/config/sequencer-config.js +6 -6
  25. package/dest/ha-signing/local_config.d.ts +1 -1
  26. package/dest/ha-signing/local_config.d.ts.map +1 -1
  27. package/dest/ha-signing/local_config.js +2 -2
  28. package/dest/interfaces/archiver.d.ts +1 -1
  29. package/dest/interfaces/archiver.d.ts.map +1 -1
  30. package/dest/interfaces/archiver.js +7 -3
  31. package/dest/interfaces/aztec-node-admin.d.ts +11 -1
  32. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  33. package/dest/interfaces/aztec-node-admin.js +2 -1
  34. package/dest/interfaces/aztec-node.d.ts +45 -55
  35. package/dest/interfaces/aztec-node.d.ts.map +1 -1
  36. package/dest/interfaces/aztec-node.js +18 -16
  37. package/dest/interfaces/block_response.d.ts +156 -0
  38. package/dest/interfaces/block_response.d.ts.map +1 -0
  39. package/dest/interfaces/block_response.js +24 -0
  40. package/dest/interfaces/chain_tips.d.ts +304 -0
  41. package/dest/interfaces/chain_tips.d.ts.map +1 -0
  42. package/dest/interfaces/chain_tips.js +11 -0
  43. package/dest/interfaces/checkpoint_parameter.d.ts +27 -0
  44. package/dest/interfaces/checkpoint_parameter.d.ts.map +1 -0
  45. package/dest/interfaces/checkpoint_parameter.js +20 -0
  46. package/dest/interfaces/checkpoint_response.d.ts +312 -0
  47. package/dest/interfaces/checkpoint_response.d.ts.map +1 -0
  48. package/dest/interfaces/checkpoint_response.js +26 -0
  49. package/dest/interfaces/client.d.ts +6 -1
  50. package/dest/interfaces/client.d.ts.map +1 -1
  51. package/dest/interfaces/client.js +5 -0
  52. package/dest/interfaces/configs.d.ts +7 -2
  53. package/dest/interfaces/configs.d.ts.map +1 -1
  54. package/dest/interfaces/configs.js +2 -1
  55. package/dest/interfaces/l1_publish_info.d.ts +43 -0
  56. package/dest/interfaces/l1_publish_info.d.ts.map +1 -0
  57. package/dest/interfaces/l1_publish_info.js +26 -0
  58. package/dest/interfaces/proving-job.d.ts +166 -166
  59. package/dest/interfaces/server.d.ts +6 -1
  60. package/dest/interfaces/server.d.ts.map +1 -1
  61. package/dest/interfaces/server.js +5 -0
  62. package/dest/interfaces/validator.d.ts +10 -1
  63. package/dest/interfaces/validator.d.ts.map +1 -1
  64. package/dest/interfaces/validator.js +1 -0
  65. package/dest/p2p/block_proposal.d.ts +19 -9
  66. package/dest/p2p/block_proposal.d.ts.map +1 -1
  67. package/dest/p2p/block_proposal.js +42 -32
  68. package/dest/p2p/checkpoint_attestation.d.ts +7 -3
  69. package/dest/p2p/checkpoint_attestation.d.ts.map +1 -1
  70. package/dest/p2p/checkpoint_attestation.js +15 -17
  71. package/dest/p2p/checkpoint_proposal.d.ts +15 -7
  72. package/dest/p2p/checkpoint_proposal.d.ts.map +1 -1
  73. package/dest/p2p/checkpoint_proposal.js +31 -29
  74. package/dest/p2p/consensus_payload.d.ts +18 -7
  75. package/dest/p2p/consensus_payload.d.ts.map +1 -1
  76. package/dest/p2p/consensus_payload.js +31 -19
  77. package/dest/p2p/signature_utils.d.ts +28 -19
  78. package/dest/p2p/signature_utils.d.ts.map +1 -1
  79. package/dest/p2p/signature_utils.js +118 -21
  80. package/dest/p2p/signed_txs.d.ts +15 -13
  81. package/dest/p2p/signed_txs.d.ts.map +1 -1
  82. package/dest/p2p/signed_txs.js +26 -24
  83. package/dest/tests/mocks.d.ts +7 -1
  84. package/dest/tests/mocks.d.ts.map +1 -1
  85. package/dest/tests/mocks.js +28 -14
  86. package/dest/timetable/index.d.ts +1 -1
  87. package/dest/timetable/index.d.ts.map +1 -1
  88. package/dest/timetable/index.js +25 -11
  89. package/dest/tx/profiling.js +4 -4
  90. package/package.json +8 -8
  91. package/src/block/attestation_info.ts +11 -11
  92. package/src/block/block_data.ts +17 -0
  93. package/src/block/block_parameter.ts +35 -2
  94. package/src/block/l2_block_source.ts +43 -3
  95. package/src/block/proposal/attestations_and_signers.ts +32 -17
  96. package/src/checkpoint/checkpoint_data.ts +4 -0
  97. package/src/config/chain-config.ts +2 -3
  98. package/src/config/sequencer-config.ts +10 -6
  99. package/src/ha-signing/local_config.ts +2 -2
  100. package/src/interfaces/archiver.ts +13 -3
  101. package/src/interfaces/aztec-node-admin.ts +3 -1
  102. package/src/interfaces/aztec-node.ts +105 -95
  103. package/src/interfaces/block_response.ts +79 -0
  104. package/src/interfaces/chain_tips.ts +24 -0
  105. package/src/interfaces/checkpoint_parameter.ts +22 -0
  106. package/src/interfaces/checkpoint_response.ts +84 -0
  107. package/src/interfaces/client.ts +5 -0
  108. package/src/interfaces/configs.ts +5 -1
  109. package/src/interfaces/l1_publish_info.ts +40 -0
  110. package/src/interfaces/server.ts +5 -0
  111. package/src/interfaces/validator.ts +5 -0
  112. package/src/p2p/block_proposal.ts +84 -28
  113. package/src/p2p/checkpoint_attestation.ts +15 -20
  114. package/src/p2p/checkpoint_proposal.ts +69 -37
  115. package/src/p2p/consensus_payload.ts +50 -28
  116. package/src/p2p/signature_utils.ts +110 -25
  117. package/src/p2p/signed_txs.ts +46 -28
  118. package/src/tests/mocks.ts +46 -26
  119. package/src/timetable/index.ts +26 -11
  120. package/src/tx/profiling.ts +4 -4
@@ -88,28 +88,42 @@
88
88
  /**
89
89
  * Checkpoint timing model for proposer pipelining.
90
90
  *
91
- * In this mode, the build work still starts in the current slot, but checkpoint
92
- * assembly and attestation collection can extend into the target slot. The extra
93
- * target-slot window getters are intended for consumers such as P2P validators
94
- * that need to validate pipelined messages against wallclock time.
91
+ * In this mode, the build work starts at the wall-clock slot boundary and the
92
+ * checkpoint proposal is broadcast early enough that attestations complete by
93
+ * the end of the build slot. L1 submission can then be sent at the boundary of
94
+ * the target slot. The extra target-slot window getters are intended for
95
+ * consumers such as P2P validators that need to validate pipelined messages
96
+ * against wallclock time.
95
97
  */ class PipelinedCheckpointTimingModel extends BaseCheckpointTiming {
96
98
  get proposalWindowIntoTargetSlot() {
97
- // Allow the p2p propagation time to receive a checkpoint proposal from leader
98
- return this.p2pPropagationTime;
99
+ // Proposals no longer spill into the target slot: they are broadcast early
100
+ // enough in the build slot that attestations complete before the boundary.
101
+ // Any residual tolerance into the target slot is covered by clock disparity.
102
+ return 0;
99
103
  }
100
104
  get attestationWindowIntoTargetSlot() {
101
- return this.aztecSlotDuration - this.l1PublishingTime;
105
+ // Straggler grace: attestations aim to complete by build-slot end. Allow a
106
+ // small window into the target slot for late arrivals (round-trip p2p).
107
+ return 2 * this.p2pPropagationTime;
108
+ }
109
+ get pipeliningAttestationGracePeriod() {
110
+ // Under the early-pipelining regime attestations complete inside the build
111
+ // slot itself, so there is no extra grace into the target slot.
112
+ return 0;
102
113
  }
103
114
  get timeReservedAtEnd() {
104
- return this.checkpointAssembleTime + this.p2pPropagationTime;
115
+ // Reserve enough time at the end of the build slot for:
116
+ // - assembling and broadcasting the checkpoint proposal
117
+ // - round-trip p2p propagation (proposal out, attestations back)
118
+ // - validators re-executing the last block
119
+ return this.checkpointAssembleTime + 2 * this.p2pPropagationTime + (this.blockDuration ?? 0);
105
120
  }
106
121
  get minimumBuildSlotWork() {
107
122
  return this.checkpointInitializationTime + this.minExecutionTime * 2;
108
123
  }
109
124
  get checkpointAssemblyDeadline() {
110
- // Allow enough time to
111
- // - build all blocks
112
- // - receive attestations
125
+ // Allow enough time to build all blocks and receive attestations. With
126
+ // `pipeliningAttestationGracePeriod = 0` this equals `aztecSlotDuration`.
113
127
  return this.aztecSlotDuration + this.pipeliningAttestationGracePeriod;
114
128
  }
115
129
  get checkpointAttestationDeadline() {
@@ -78,7 +78,7 @@ export class TxProfileResult {
78
78
  ], {
79
79
  nodeRPCCalls: {
80
80
  perMethod: {
81
- getBlockHeader: {
81
+ getBlock: {
82
82
  times: [
83
83
  1
84
84
  ]
@@ -92,7 +92,7 @@ export class TxProfileResult {
92
92
  ],
93
93
  roundTripMethods: [
94
94
  [
95
- 'getBlockHeader'
95
+ 'getBlock'
96
96
  ]
97
97
  ]
98
98
  }
@@ -140,7 +140,7 @@ export class UtilityExecutionResult {
140
140
  ], [], 0n, {
141
141
  nodeRPCCalls: {
142
142
  perMethod: {
143
- getBlockHeader: {
143
+ getBlock: {
144
144
  times: [
145
145
  1
146
146
  ]
@@ -154,7 +154,7 @@ export class UtilityExecutionResult {
154
154
  ],
155
155
  roundTripMethods: [
156
156
  [
157
- 'getBlockHeader'
157
+ 'getBlock'
158
158
  ]
159
159
  ]
160
160
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/stdlib",
3
- "version": "5.0.0-nightly.20260429",
3
+ "version": "5.0.0-nightly.20260430",
4
4
  "type": "module",
5
5
  "inherits": [
6
6
  "../package.common.json",
@@ -92,13 +92,13 @@
92
92
  },
93
93
  "dependencies": {
94
94
  "@aws-sdk/client-s3": "^3.892.0",
95
- "@aztec/bb.js": "5.0.0-nightly.20260429",
96
- "@aztec/blob-lib": "5.0.0-nightly.20260429",
97
- "@aztec/constants": "5.0.0-nightly.20260429",
98
- "@aztec/ethereum": "5.0.0-nightly.20260429",
99
- "@aztec/foundation": "5.0.0-nightly.20260429",
100
- "@aztec/l1-artifacts": "5.0.0-nightly.20260429",
101
- "@aztec/noir-noirc_abi": "5.0.0-nightly.20260429",
95
+ "@aztec/bb.js": "5.0.0-nightly.20260430",
96
+ "@aztec/blob-lib": "5.0.0-nightly.20260430",
97
+ "@aztec/constants": "5.0.0-nightly.20260430",
98
+ "@aztec/ethereum": "5.0.0-nightly.20260430",
99
+ "@aztec/foundation": "5.0.0-nightly.20260430",
100
+ "@aztec/l1-artifacts": "5.0.0-nightly.20260430",
101
+ "@aztec/noir-noirc_abi": "5.0.0-nightly.20260430",
102
102
  "@google-cloud/storage": "^7.15.0",
103
103
  "axios": "^1.13.5",
104
104
  "json-stringify-deterministic": "1.0.12",
@@ -3,7 +3,7 @@ import type { EthAddress } from '@aztec/foundation/eth-address';
3
3
 
4
4
  import { Checkpoint } from '../checkpoint/checkpoint.js';
5
5
  import { ConsensusPayload } from '../p2p/consensus_payload.js';
6
- import { SignatureDomainSeparator, getHashedSignaturePayloadEthSignedMessage } from '../p2p/signature_utils.js';
6
+ import { type CoordinationSignatureContext, getHashedSignaturePayloadTypedData } from '../p2p/signature_utils.js';
7
7
  import type { CommitteeAttestation } from './proposal/committee_attestation.js';
8
8
 
9
9
  /**
@@ -32,11 +32,14 @@ export type AttestationInfo =
32
32
  * Extracts attestation information from a published checkpoint.
33
33
  * Returns info for each attestation, preserving array indices.
34
34
  */
35
- export function getAttestationInfoFromPublishedCheckpoint(block: {
36
- attestations: CommitteeAttestation[];
37
- checkpoint: Checkpoint;
38
- }): AttestationInfo[] {
39
- const payload = ConsensusPayload.fromCheckpoint(block.checkpoint);
35
+ export function getAttestationInfoFromPublishedCheckpoint(
36
+ block: {
37
+ attestations: CommitteeAttestation[];
38
+ checkpoint: Checkpoint;
39
+ },
40
+ signatureContext: CoordinationSignatureContext,
41
+ ): AttestationInfo[] {
42
+ const payload = ConsensusPayload.fromCheckpoint(block.checkpoint, signatureContext);
40
43
  return getAttestationInfoFromPayload(payload, block.attestations);
41
44
  }
42
45
 
@@ -44,10 +47,7 @@ export function getAttestationInfoFromPayload(
44
47
  payload: ConsensusPayload,
45
48
  attestations: CommitteeAttestation[],
46
49
  ): AttestationInfo[] {
47
- const hashedPayload = getHashedSignaturePayloadEthSignedMessage(
48
- payload,
49
- SignatureDomainSeparator.checkpointAttestation,
50
- );
50
+ const hashedPayload = getHashedSignaturePayloadTypedData(payload);
51
51
 
52
52
  return attestations.map(attestation => {
53
53
  // If signature is empty, check if we have an address directly
@@ -62,7 +62,7 @@ export function getAttestationInfoFromPayload(
62
62
 
63
63
  // Try to recover address from signature
64
64
  try {
65
- const recoveredAddress = recoverAddress(hashedPayload, attestation.signature);
65
+ const recoveredAddress = recoverAddress(hashedPayload, attestation.signature, { allowYParityAsV: true });
66
66
  return { address: recoveredAddress, status: 'recovered-from-signature' as const };
67
67
  } catch {
68
68
  // Signature present but recovery failed
@@ -3,9 +3,12 @@ import type { CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/
3
3
 
4
4
  import { z } from 'zod';
5
5
 
6
+ import { CheckpointDataSchema } from '../checkpoint/checkpoint_data.js';
7
+ import { L1PublishedData } from '../checkpoint/published_checkpoint.js';
6
8
  import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js';
7
9
  import { BlockHeader } from '../tx/block_header.js';
8
10
  import { BlockHash } from './block_hash.js';
11
+ import { CommitteeAttestation } from './proposal/committee_attestation.js';
9
12
 
10
13
  /** L2Block metadata. Equivalent to L2Block but without block body containing tx data. */
11
14
  export type BlockData = {
@@ -23,3 +26,17 @@ export const BlockDataSchema = z.object({
23
26
  checkpointNumber: CheckpointNumberSchema,
24
27
  indexWithinCheckpoint: IndexWithinCheckpointSchema,
25
28
  });
29
+
30
+ export const BlockDataWithCheckpointContextSchema = z
31
+ .object({
32
+ data: BlockDataSchema,
33
+ checkpoint: CheckpointDataSchema.optional(),
34
+ l1: L1PublishedData.schema.optional(),
35
+ attestations: z.array(CommitteeAttestation.schema),
36
+ })
37
+ .transform(obj => ({
38
+ data: obj.data,
39
+ checkpoint: obj.checkpoint,
40
+ l1: obj.l1,
41
+ attestations: obj.attestations,
42
+ }));
@@ -1,10 +1,43 @@
1
1
  import { BlockNumberSchema } from '@aztec/foundation/branded-types';
2
+ import { jsonStringify } from '@aztec/foundation/json-rpc';
3
+ import { schemas } from '@aztec/foundation/schemas';
2
4
 
3
5
  import { z } from 'zod';
4
6
 
7
+ import { ChainTipSchema } from '../interfaces/chain_tips.js';
5
8
  import { BlockHash } from './block_hash.js';
6
9
 
7
- export const BlockParameterSchema = z.union([BlockHash.schema, BlockNumberSchema, z.literal('latest')]);
10
+ /**
11
+ * Selector for a block in RPC calls.
12
+ *
13
+ * Accepts a block number, a {@link BlockHash}, a chain-tip name (e.g. `'proven'`, `'checkpointed'`),
14
+ * `'latest'` (alias for `'proposed'`), or the explicit object variants `{ number }`, `{ hash }`,
15
+ * and `{ archive }`.
16
+ */
17
+ export const BlockParameterSchema = z.union([
18
+ BlockHash.schema,
19
+ BlockNumberSchema,
20
+ ChainTipSchema,
21
+ z.literal('latest'),
22
+ z.object({ number: BlockNumberSchema }),
23
+ z.object({ hash: BlockHash.schema }),
24
+ z.object({ archive: schemas.Fr }),
25
+ ]);
8
26
 
9
- /** Block parameter - either a specific BlockNumber, block hash (BlockHash), or 'latest' */
10
27
  export type BlockParameter = z.infer<typeof BlockParameterSchema>;
28
+
29
+ export function inspectBlockParameter(param: BlockParameter) {
30
+ if (typeof param === 'number') {
31
+ return param.toString();
32
+ } else if (typeof param === 'string') {
33
+ return param;
34
+ } else if ('number' in param) {
35
+ return `number=${param.number.toString()}`;
36
+ } else if ('hash' in param) {
37
+ return `hash=${param.hash.toString()}`;
38
+ } else if ('archive' in param) {
39
+ return `archive=${param.archive.toString()}`;
40
+ } else {
41
+ return jsonStringify(param);
42
+ }
43
+ }
@@ -14,7 +14,7 @@ import { z } from 'zod';
14
14
 
15
15
  import type { Checkpoint } from '../checkpoint/checkpoint.js';
16
16
  import type { CheckpointData, CommonCheckpointData, ProposedCheckpointData } from '../checkpoint/checkpoint_data.js';
17
- import type { PublishedCheckpoint } from '../checkpoint/published_checkpoint.js';
17
+ import type { L1PublishedData, 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';
20
20
  import type { BlockHeader } from '../tx/block_header.js';
@@ -25,8 +25,17 @@ import type { BlockData } from './block_data.js';
25
25
  import type { BlockHash } from './block_hash.js';
26
26
  import type { CheckpointedL2Block } from './checkpointed_l2_block.js';
27
27
  import type { L2Block } from './l2_block.js';
28
+ import type { CommitteeAttestation } from './proposal/committee_attestation.js';
28
29
  import type { ValidateCheckpointNegativeResult, ValidateCheckpointResult } from './validate_block_result.js';
29
30
 
31
+ /** Block metadata plus checkpoint-derived context (L1 publish info, attestations). */
32
+ export type BlockDataWithCheckpointContext = {
33
+ data: BlockData;
34
+ checkpoint?: CheckpointData;
35
+ l1?: L1PublishedData;
36
+ attestations: CommitteeAttestation[];
37
+ };
38
+
30
39
  /**
31
40
  * Interface of classes allowing for the retrieval of L2 blocks.
32
41
  */
@@ -111,6 +120,37 @@ export interface L2BlockSource {
111
120
  */
112
121
  getCheckpointsDataForEpoch(epochNumber: EpochNumber): Promise<CheckpointData[]>;
113
122
 
123
+ /**
124
+ * Gets lightweight checkpoint metadata for a single checkpoint.
125
+ * Cheap passthrough for metadata-only queries (no block body reads).
126
+ * @param checkpointNumber - The checkpoint number to retrieve.
127
+ * @returns The requested checkpoint data (or undefined if not found).
128
+ */
129
+ getCheckpointData(checkpointNumber: CheckpointNumber): Promise<CheckpointData | undefined>;
130
+
131
+ /**
132
+ * Gets up to `limit` amount of checkpoint metadata entries starting from `from`.
133
+ * Cheap passthrough for metadata-only queries (no block body reads).
134
+ * @param from - The first checkpoint number to return (inclusive).
135
+ * @param limit - The maximum number of checkpoints to return.
136
+ */
137
+ getCheckpointDataRange(from: CheckpointNumber, limit: number): Promise<CheckpointData[]>;
138
+
139
+ /**
140
+ * Looks up the checkpoint number that contains the given slot.
141
+ * @param slot - The slot number to look up.
142
+ * @returns The checkpoint number (or undefined if not found).
143
+ */
144
+ getCheckpointNumberBySlot(slot: SlotNumber): Promise<CheckpointNumber | undefined>;
145
+
146
+ /**
147
+ * Gets block metadata plus checkpoint-derived context (L1 publish info, attestations)
148
+ * without deserializing tx bodies. Uses checkpoint-level values when the block is
149
+ * checkpointed; otherwise returns `l1: undefined` and empty attestations.
150
+ * @param number - The block number to retrieve.
151
+ */
152
+ getBlockDataWithCheckpointContext(number: BlockNumber): Promise<BlockDataWithCheckpointContext | undefined>;
153
+
114
154
  /**
115
155
  * Gets a block header by its hash.
116
156
  * @param blockHash - The block hash to retrieve.
@@ -230,10 +270,10 @@ export interface L2BlockSource {
230
270
  getPendingChainValidationStatus(): Promise<ValidateCheckpointResult>;
231
271
 
232
272
  /** Returns the checkpoint at the proposed chain tip. */
233
- getProposedCheckpoint(): Promise<CommonCheckpointData | undefined>;
273
+ getLastCheckpoint(): Promise<CommonCheckpointData | undefined>;
234
274
 
235
275
  /** Returns proposed checkpoint, if set, undefined if not*/
236
- getProposedCheckpointOnly(): Promise<ProposedCheckpointData | undefined>;
276
+ getLastProposedCheckpoint(): Promise<ProposedCheckpointData | undefined>;
237
277
 
238
278
  /** Force a sync. */
239
279
  syncImmediate(): Promise<void>;
@@ -4,26 +4,37 @@ import { hexToBuffer } from '@aztec/foundation/string';
4
4
  import { encodeAbiParameters, parseAbiParameters } from 'viem';
5
5
  import { z } from 'zod';
6
6
 
7
- import type { Signable, SignatureDomainSeparator } from '../../p2p/signature_utils.js';
7
+ import {
8
+ type CoordinationSignatureContext,
9
+ type CoordinationSignatureType,
10
+ type Signable,
11
+ coordinationSignatureContextSchema,
12
+ } from '../../p2p/signature_utils.js';
8
13
  import { CommitteeAttestation, EthAddress } from './committee_attestation.js';
9
14
 
10
15
  export class CommitteeAttestationsAndSigners implements Signable {
11
- constructor(public attestations: CommitteeAttestation[]) {}
16
+ readonly primaryType: CoordinationSignatureType = 'AttestationsAndSigners';
17
+
18
+ constructor(
19
+ public attestations: CommitteeAttestation[],
20
+ public readonly signatureContext: CoordinationSignatureContext,
21
+ ) {}
12
22
 
13
23
  static get schema() {
14
24
  return z
15
25
  .object({
16
26
  attestations: CommitteeAttestation.schema.array(),
27
+ signatureContext: coordinationSignatureContextSchema,
17
28
  })
18
- .transform(obj => new CommitteeAttestationsAndSigners(obj.attestations));
29
+ .transform(obj => new CommitteeAttestationsAndSigners(obj.attestations, obj.signatureContext));
19
30
  }
20
31
 
21
- getPayloadToSign(domainSeparator: SignatureDomainSeparator): Buffer {
22
- const abi = parseAbiParameters('uint8,(bytes,bytes),address[]');
32
+ getPayloadToSign(): Buffer {
33
+ // Matches the L1 abi.encode(attestations, signers) in AttestationLib.sol#getAttestationsAndSignersDigest.
34
+ const abi = parseAbiParameters('(bytes,bytes),address[]');
23
35
  const packed = this.getPackedAttestations();
24
36
 
25
37
  const encodedData = encodeAbiParameters(abi, [
26
- domainSeparator,
27
38
  [packed.signatureIndices, packed.signaturesOrAddresses],
28
39
  this.getSigners().map(s => s.toString()),
29
40
  ]);
@@ -31,8 +42,8 @@ export class CommitteeAttestationsAndSigners implements Signable {
31
42
  return hexToBuffer(encodedData);
32
43
  }
33
44
 
34
- static empty(): CommitteeAttestationsAndSigners {
35
- return new CommitteeAttestationsAndSigners([]);
45
+ static empty(signatureContext: CoordinationSignatureContext): CommitteeAttestationsAndSigners {
46
+ return new CommitteeAttestationsAndSigners([], signatureContext);
36
47
  }
37
48
 
38
49
  toString() {
@@ -53,9 +64,9 @@ export class CommitteeAttestationsAndSigners implements Signable {
53
64
  * @param attestations - Array of committee attestations with addresses and signatures
54
65
  * @returns Packed attestations with bitmap and tightly packed signature/address data
55
66
  */
56
- getPackedAttestations(): ViemCommitteeAttestations {
57
- const length = this.attestations.length;
58
- const attestations = this.attestations.map(a => a.toViem());
67
+ static packAttestations(attestations: CommitteeAttestation[]): ViemCommitteeAttestations {
68
+ const length = attestations.length;
69
+ const viemAttestations = attestations.map(a => a.toViem());
59
70
 
60
71
  // Calculate bitmap size (1 bit per attestation, rounded up to nearest byte)
61
72
  const bitmapSize = Math.ceil(length / 8);
@@ -63,8 +74,8 @@ export class CommitteeAttestationsAndSigners implements Signable {
63
74
 
64
75
  // Calculate total data size needed
65
76
  let totalDataSize = 0;
66
- for (let i = 0; i < length; i++) {
67
- const signature = attestations[i].signature;
77
+ for (const attestation of viemAttestations) {
78
+ const signature = attestation.signature;
68
79
  // Check if signature is empty (v = 0)
69
80
  const isEmpty = signature.v === 0;
70
81
 
@@ -79,8 +90,7 @@ export class CommitteeAttestationsAndSigners implements Signable {
79
90
  let dataIndex = 0;
80
91
 
81
92
  // Pack the data
82
- for (let i = 0; i < length; i++) {
83
- const attestation = attestations[i];
93
+ for (const [i, attestation] of viemAttestations.entries()) {
84
94
  const signature = attestation.signature;
85
95
 
86
96
  // Check if signature is empty
@@ -90,7 +100,7 @@ export class CommitteeAttestationsAndSigners implements Signable {
90
100
  // Set bit in bitmap (bit 7-0 in each byte, left to right)
91
101
  const byteIndex = Math.floor(i / 8);
92
102
  const bitIndex = 7 - (i % 8);
93
- signatureIndices[byteIndex] |= 1 << bitIndex;
103
+ signatureIndices[byteIndex] = (signatureIndices[byteIndex] ?? 0) | (1 << bitIndex);
94
104
 
95
105
  // Pack signature: v + r + s
96
106
  signaturesOrAddresses[dataIndex] = signature.v;
@@ -118,6 +128,10 @@ export class CommitteeAttestationsAndSigners implements Signable {
118
128
  signaturesOrAddresses: `0x${Buffer.from(signaturesOrAddresses).toString('hex')}`,
119
129
  };
120
130
  }
131
+
132
+ getPackedAttestations(): ViemCommitteeAttestations {
133
+ return CommitteeAttestationsAndSigners.packAttestations(this.attestations);
134
+ }
121
135
  }
122
136
 
123
137
  /**
@@ -130,8 +144,9 @@ export class MaliciousCommitteeAttestationsAndSigners extends CommitteeAttestati
130
144
  constructor(
131
145
  attestations: CommitteeAttestation[],
132
146
  private signers: EthAddress[],
147
+ signatureContext: CoordinationSignatureContext,
133
148
  ) {
134
- super(attestations);
149
+ super(attestations, signatureContext);
135
150
  }
136
151
 
137
152
  override getSigners(): EthAddress[] {
@@ -32,6 +32,8 @@ export type L1EnrichedCheckpointData = {
32
32
  export type StorageEnrichedCheckpointData = {
33
33
  archive: AppendOnlyTreeSnapshot;
34
34
  checkpointOutHash: Fr;
35
+ /** Fee asset price modifier in basis points. Defaults to 0 (no change) when not explicitly set. */
36
+ feeAssetPriceModifier: bigint;
35
37
  };
36
38
 
37
39
  /** Data stored only with proposed checkpoint data */
@@ -70,6 +72,7 @@ export const CheckpointDataSchema = z
70
72
  checkpointOutHash: schemas.Fr,
71
73
  startBlock: BlockNumberSchema,
72
74
  blockCount: schemas.Integer,
75
+ feeAssetPriceModifier: schemas.BigInt,
73
76
  attestations: z.array(CommitteeAttestation.schema),
74
77
  l1: L1PublishedData.schema,
75
78
  })
@@ -81,6 +84,7 @@ export const CheckpointDataSchema = z
81
84
  checkpointOutHash: obj.checkpointOutHash,
82
85
  startBlock: obj.startBlock,
83
86
  blockCount: obj.blockCount,
87
+ feeAssetPriceModifier: obj.feeAssetPriceModifier,
84
88
  attestations: obj.attestations,
85
89
  l1: obj.l1,
86
90
  }),
@@ -1,5 +1,5 @@
1
1
  import { l1ContractAddressesMapping } from '@aztec/ethereum/l1-contract-addresses';
2
- import type { ConfigMappingsType } from '@aztec/foundation/config';
2
+ import { type ConfigMappingsType, numberConfigHelper } from '@aztec/foundation/config';
3
3
  import { EthAddress } from '@aztec/foundation/eth-address';
4
4
 
5
5
  export { type SequencerConfig, SequencerConfigSchema } from '../interfaces/configs.js';
@@ -14,8 +14,7 @@ export const emptyChainConfig: ChainConfig = {
14
14
  export const chainConfigMappings: ConfigMappingsType<ChainConfig> = {
15
15
  l1ChainId: {
16
16
  env: 'L1_CHAIN_ID',
17
- parseEnv: (val: string) => +val,
18
- defaultValue: 31337,
17
+ ...numberConfigHelper(31337),
19
18
  description: 'The chain ID of the ethereum host.',
20
19
  },
21
20
  rollupVersion: {
@@ -1,4 +1,9 @@
1
- import type { ConfigMappingsType } from '@aztec/foundation/config';
1
+ import {
2
+ type ConfigMappingsType,
3
+ floatConfigHelper,
4
+ numberConfigHelper,
5
+ optionalNumberConfigHelper,
6
+ } from '@aztec/foundation/config';
2
7
 
3
8
  import type { SequencerConfig } from '../interfaces/configs.js';
4
9
  import { DEFAULT_P2P_PROPAGATION_TIME } from '../timetable/index.js';
@@ -23,25 +28,24 @@ export const sharedSequencerConfigMappings: ConfigMappingsType<
23
28
  description:
24
29
  'Duration per block in milliseconds when building multiple blocks per slot. ' +
25
30
  'If undefined (default), builds a single block per slot using the full slot duration.',
26
- parseEnv: (val: string) => parseInt(val, 10),
31
+ ...optionalNumberConfigHelper(),
27
32
  },
28
33
  expectedBlockProposalsPerSlot: {
29
34
  env: 'SEQ_EXPECTED_BLOCK_PROPOSALS_PER_SLOT',
30
35
  description:
31
36
  'Expected number of block proposals per slot for P2P peer scoring. ' +
32
37
  '0 (default) disables block proposal scoring. Set to a positive value to enable.',
33
- parseEnv: (val: string) => parseInt(val, 10),
34
- defaultValue: 0,
38
+ ...numberConfigHelper(0),
35
39
  },
36
40
  maxTxsPerBlock: {
37
41
  env: 'SEQ_MAX_TX_PER_BLOCK',
38
42
  description: 'The maximum number of txs to include in a block.',
39
- parseEnv: (val: string) => parseInt(val, 10),
43
+ ...optionalNumberConfigHelper(),
40
44
  },
41
45
  attestationPropagationTime: {
42
46
  env: 'SEQ_ATTESTATION_PROPAGATION_TIME',
43
47
  description: 'How many seconds it takes for proposals and attestations to travel across the p2p layer (one-way).',
44
- parseEnv: (val: string) => parseFloat(val),
45
48
  defaultValue: DEFAULT_P2P_PROPAGATION_TIME,
49
+ ...floatConfigHelper(DEFAULT_P2P_PROPAGATION_TIME),
46
50
  },
47
51
  };
@@ -1,4 +1,4 @@
1
- import { type ConfigMappingsType, getConfigFromMappings } from '@aztec/foundation/config';
1
+ import { type ConfigMappingsType, getConfigFromMappings, optionalNumberConfigHelper } from '@aztec/foundation/config';
2
2
  import { zodFor } from '@aztec/foundation/schemas';
3
3
  import { type DataStoreConfig, dataConfigMappings } from '@aztec/stdlib/kv-store';
4
4
 
@@ -26,7 +26,7 @@ export const localSignerConfigMappings: ConfigMappingsType<LocalSignerConfig> =
26
26
  env: 'SIGNING_PROTECTION_MAP_SIZE_KB',
27
27
  description:
28
28
  'Maximum size of the local signing-protection LMDB store in KB. Overwrites the general dataStoreMapSizeKb.',
29
- parseEnv: (val: string) => +val,
29
+ ...optionalNumberConfigHelper(),
30
30
  },
31
31
  };
32
32
 
@@ -4,7 +4,7 @@ import type { ApiSchemaFor } from '@aztec/foundation/schemas';
4
4
 
5
5
  import { z } from 'zod';
6
6
 
7
- import { BlockDataSchema } from '../block/block_data.js';
7
+ import { BlockDataSchema, BlockDataWithCheckpointContextSchema } from '../block/block_data.js';
8
8
  import { BlockHash } from '../block/block_hash.js';
9
9
  import { CheckpointedL2Block } from '../block/checkpointed_l2_block.js';
10
10
  import { L2Block } from '../block/l2_block.js';
@@ -117,6 +117,16 @@ export const ArchiverApiSchema: ApiSchemaFor<ArchiverApi> = {
117
117
  getBlockHeaderByArchive: z.function().args(schemas.Fr).returns(BlockHeader.schema.optional()),
118
118
  getBlockData: z.function().args(BlockNumberSchema).returns(BlockDataSchema.optional()),
119
119
  getBlockDataByArchive: z.function().args(schemas.Fr).returns(BlockDataSchema.optional()),
120
+ getBlockDataWithCheckpointContext: z
121
+ .function()
122
+ .args(BlockNumberSchema)
123
+ .returns(BlockDataWithCheckpointContextSchema.optional()),
124
+ getCheckpointData: z.function().args(CheckpointNumberSchema).returns(CheckpointDataSchema.optional()),
125
+ getCheckpointDataRange: z
126
+ .function()
127
+ .args(CheckpointNumberSchema, schemas.Integer)
128
+ .returns(z.array(CheckpointDataSchema)),
129
+ getCheckpointNumberBySlot: z.function().args(schemas.SlotNumber).returns(CheckpointNumberSchema.optional()),
120
130
  getL2Block: z.function().args(BlockNumberSchema).returns(L2Block.schema.optional()),
121
131
  getL2BlockByHash: z.function().args(BlockHash.schema).returns(L2Block.schema.optional()),
122
132
  getL2BlockByArchive: z.function().args(schemas.Fr).returns(L2Block.schema.optional()),
@@ -158,8 +168,8 @@ export const ArchiverApiSchema: ApiSchemaFor<ArchiverApi> = {
158
168
  .args()
159
169
  .returns(z.object({ genesisArchiveRoot: schemas.Fr })),
160
170
  getL1Timestamp: z.function().args().returns(schemas.BigInt.optional()),
161
- getProposedCheckpoint: z.function().args().returns(ProposedCheckpointDataSchema.optional()),
162
- getProposedCheckpointOnly: z.function().args().returns(ProposedCheckpointDataSchema.optional()),
171
+ getLastCheckpoint: z.function().args().returns(ProposedCheckpointDataSchema.optional()),
172
+ getLastProposedCheckpoint: z.function().args().returns(ProposedCheckpointDataSchema.optional()),
163
173
  syncImmediate: z.function().args().returns(z.void()),
164
174
  isPendingChainInvalid: z.function().args().returns(z.boolean()),
165
175
  getPendingChainValidationStatus: z.function().args().returns(ValidateCheckpointResultSchema),
@@ -81,6 +81,8 @@ export type AztecNodeAdminConfig = Omit<ValidatorClientFullConfig, 'l1Contracts'
81
81
  'archiverPollingIntervalMS' | 'archiverBatchSize' | 'skipValidateCheckpointAttestations'
82
82
  > & {
83
83
  maxPendingTxCount: number;
84
+ // Keep in sync with P2PConfig.skipIncomingProposals (circular dep prevents Pick<P2PConfig, ...> here)
85
+ skipIncomingProposals?: boolean;
84
86
  };
85
87
 
86
88
  export const AztecNodeAdminConfigSchema = SequencerConfigSchema.merge(ProverConfigSchema)
@@ -93,7 +95,7 @@ export const AztecNodeAdminConfigSchema = SequencerConfigSchema.merge(ProverConf
93
95
  skipValidateCheckpointAttestations: true,
94
96
  }),
95
97
  )
96
- .merge(z.object({ maxPendingTxCount: z.number() }));
98
+ .merge(z.object({ maxPendingTxCount: z.number(), skipIncomingProposals: z.boolean().optional() }));
97
99
 
98
100
  export const AztecNodeAdminApiSchema: ApiSchemaFor<AztecNodeAdmin> = {
99
101
  getConfig: z.function().returns(AztecNodeAdminConfigSchema),