@aztec/stdlib 2.1.0-rc.9 → 2.1.1-rc.1

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 (67) hide show
  1. package/dest/block/attestation_info.d.ts +30 -0
  2. package/dest/block/attestation_info.d.ts.map +1 -0
  3. package/dest/block/attestation_info.js +39 -0
  4. package/dest/block/index.d.ts +1 -0
  5. package/dest/block/index.d.ts.map +1 -1
  6. package/dest/block/index.js +1 -0
  7. package/dest/block/l2_block_source.d.ts +34 -5
  8. package/dest/block/l2_block_source.d.ts.map +1 -1
  9. package/dest/block/published_l2_block.d.ts +0 -6
  10. package/dest/block/published_l2_block.d.ts.map +1 -1
  11. package/dest/block/published_l2_block.js +0 -9
  12. package/dest/interfaces/archiver.d.ts +1 -1
  13. package/dest/interfaces/archiver.d.ts.map +1 -1
  14. package/dest/interfaces/archiver.js +10 -3
  15. package/dest/interfaces/aztec-node-admin.d.ts +35 -34
  16. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  17. package/dest/interfaces/aztec-node-admin.js +2 -2
  18. package/dest/interfaces/aztec-node.d.ts +24 -0
  19. package/dest/interfaces/aztec-node.d.ts.map +1 -1
  20. package/dest/interfaces/aztec-node.js +4 -0
  21. package/dest/interfaces/p2p.d.ts +2 -0
  22. package/dest/interfaces/p2p.d.ts.map +1 -1
  23. package/dest/interfaces/p2p.js +2 -1
  24. package/dest/interfaces/tx_provider.d.ts +1 -1
  25. package/dest/interfaces/tx_provider.d.ts.map +1 -1
  26. package/dest/interfaces/validator.d.ts +93 -1
  27. package/dest/interfaces/validator.d.ts.map +1 -1
  28. package/dest/interfaces/validator.js +6 -0
  29. package/dest/p2p/block_attestation.d.ts +13 -13
  30. package/dest/p2p/block_attestation.d.ts.map +1 -1
  31. package/dest/p2p/block_attestation.js +27 -25
  32. package/dest/p2p/block_proposal.d.ts +4 -8
  33. package/dest/p2p/block_proposal.d.ts.map +1 -1
  34. package/dest/p2p/block_proposal.js +10 -13
  35. package/dest/p2p/gossipable.d.ts +4 -12
  36. package/dest/p2p/gossipable.d.ts.map +1 -1
  37. package/dest/p2p/gossipable.js +4 -7
  38. package/dest/p2p/topic_type.d.ts +4 -8
  39. package/dest/p2p/topic_type.d.ts.map +1 -1
  40. package/dest/p2p/topic_type.js +14 -8
  41. package/dest/tests/factories.d.ts +1 -1
  42. package/dest/tests/factories.d.ts.map +1 -1
  43. package/dest/tests/factories.js +6 -5
  44. package/dest/tests/mocks.d.ts +3 -1
  45. package/dest/tests/mocks.d.ts.map +1 -1
  46. package/dest/tests/mocks.js +33 -11
  47. package/dest/zkpassport/index.d.ts +15 -11
  48. package/dest/zkpassport/index.d.ts.map +1 -1
  49. package/dest/zkpassport/index.js +18 -17
  50. package/package.json +9 -9
  51. package/src/block/attestation_info.ts +62 -0
  52. package/src/block/index.ts +1 -0
  53. package/src/block/l2_block_source.ts +37 -5
  54. package/src/block/published_l2_block.ts +0 -17
  55. package/src/interfaces/archiver.ts +12 -4
  56. package/src/interfaces/aztec-node-admin.ts +2 -2
  57. package/src/interfaces/aztec-node.ts +36 -0
  58. package/src/interfaces/p2p.ts +4 -0
  59. package/src/interfaces/tx_provider.ts +1 -0
  60. package/src/interfaces/validator.ts +14 -1
  61. package/src/p2p/block_attestation.ts +31 -24
  62. package/src/p2p/block_proposal.ts +9 -16
  63. package/src/p2p/gossipable.ts +4 -12
  64. package/src/p2p/topic_type.ts +15 -8
  65. package/src/tests/factories.ts +7 -10
  66. package/src/tests/mocks.ts +53 -17
  67. package/src/zkpassport/index.ts +37 -33
@@ -57,6 +57,9 @@ export interface P2PApiWithAttestations extends P2PApiWithoutAttestations {
57
57
  * @returns BlockAttestations
58
58
  */
59
59
  getAttestationsForSlot(slot: bigint, proposalId?: string): Promise<BlockAttestation[]>;
60
+
61
+ /** Deletes a given attestation manually from the p2p client attestation pool. */
62
+ deleteAttestation(attestation: BlockAttestation): Promise<void>;
60
63
  }
61
64
 
62
65
  export interface P2PClient extends P2PApiWithAttestations {
@@ -85,4 +88,5 @@ export const P2PApiSchema: ApiSchemaFor<P2PApi> = {
85
88
  getPendingTxCount: z.function().returns(schemas.Integer),
86
89
  getEncodedEnr: z.function().returns(z.string().optional()),
87
90
  getPeers: z.function().args(optional(z.boolean())).returns(z.array(PeerInfoSchema)),
91
+ deleteAttestation: z.function().args(BlockAttestation.schema).returns(z.void()),
88
92
  };
@@ -9,6 +9,7 @@ export interface ITxProvider {
9
9
 
10
10
  getTxsForBlockProposal(
11
11
  blockProposal: BlockProposal,
12
+ blockNumber: number,
12
13
  opts: { pinnedPeer: PeerId | undefined; deadline: Date },
13
14
  ): Promise<{ txs: Tx[]; missingTxs: TxHash[] }>;
14
15
 
@@ -11,6 +11,7 @@ import type { PeerId } from '@libp2p/interface';
11
11
  import { z } from 'zod';
12
12
 
13
13
  import type { CommitteeAttestationsAndSigners } from '../block/index.js';
14
+ import { AllowedElementSchema } from './allowed_element.js';
14
15
 
15
16
  /**
16
17
  * Validator client configuration
@@ -43,7 +44,13 @@ export interface ValidatorClientConfig {
43
44
 
44
45
  export type ValidatorClientFullConfig = ValidatorClientConfig &
45
46
  Pick<SequencerConfig, 'txPublicSetupAllowList'> &
46
- Pick<SlasherConfig, 'slashBroadcastedInvalidBlockPenalty'>;
47
+ Pick<SlasherConfig, 'slashBroadcastedInvalidBlockPenalty'> & {
48
+ /**
49
+ * Whether transactions are disabled for this node
50
+ * @remarks This should match the property in P2PConfig. It's not picked from there to avoid circular dependencies.
51
+ */
52
+ disableTransactions?: boolean;
53
+ };
47
54
 
48
55
  export const ValidatorClientConfigSchema = z.object({
49
56
  validatorAddresses: z.array(schemas.EthAddress).optional(),
@@ -55,6 +62,12 @@ export const ValidatorClientConfigSchema = z.object({
55
62
  alwaysReexecuteBlockProposals: z.boolean().optional(),
56
63
  }) satisfies ZodFor<Omit<ValidatorClientConfig, 'validatorPrivateKeys'>>;
57
64
 
65
+ export const ValidatorClientFullConfigSchema = ValidatorClientConfigSchema.extend({
66
+ txPublicSetupAllowList: z.array(AllowedElementSchema).optional(),
67
+ slashBroadcastedInvalidBlockPenalty: schemas.BigInt,
68
+ disableTransactions: z.boolean().optional(),
69
+ }) satisfies ZodFor<Omit<ValidatorClientFullConfig, 'validatorPrivateKeys'>>;
70
+
58
71
  export interface Validator {
59
72
  start(): Promise<void>;
60
73
  updateConfig(config: Partial<ValidatorClientFullConfig>): void;
@@ -1,5 +1,5 @@
1
1
  import { Buffer32 } from '@aztec/foundation/buffer';
2
- import { keccak256, recoverAddress } from '@aztec/foundation/crypto';
2
+ import { keccak256, tryRecoverAddress } from '@aztec/foundation/crypto';
3
3
  import type { EthAddress } from '@aztec/foundation/eth-address';
4
4
  import { Signature } from '@aztec/foundation/eth-signature';
5
5
  import { Fr } from '@aztec/foundation/fields';
@@ -7,8 +7,7 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
7
7
 
8
8
  import { z } from 'zod';
9
9
 
10
- import { type ZodFor, schemas } from '../schemas/index.js';
11
- import type { UInt32 } from '../types/index.js';
10
+ import type { ZodFor } from '../schemas/index.js';
12
11
  import { ConsensusPayload } from './consensus_payload.js';
13
12
  import { Gossipable } from './gossipable.js';
14
13
  import { SignatureDomainSeparator, getHashedSignaturePayloadEthSignedMessage } from './signature_utils.js';
@@ -30,16 +29,17 @@ export class BlockAttestation extends Gossipable {
30
29
  static override p2pTopic = TopicType.block_attestation;
31
30
 
32
31
  private sender: EthAddress | undefined;
32
+ private proposer: EthAddress | undefined;
33
33
 
34
34
  constructor(
35
- /** The block number of the attestation. */
36
- public readonly blockNumber: UInt32,
37
-
38
35
  /** The payload of the message, and what the signature is over */
39
36
  public readonly payload: ConsensusPayload,
40
37
 
41
38
  /** The signature of the block attester */
42
39
  public readonly signature: Signature,
40
+
41
+ /** The signature from the block proposer */
42
+ public readonly proposerSignature: Signature,
43
43
  ) {
44
44
  super();
45
45
  }
@@ -47,11 +47,11 @@ export class BlockAttestation extends Gossipable {
47
47
  static get schema(): ZodFor<BlockAttestation> {
48
48
  return z
49
49
  .object({
50
- blockNumber: schemas.UInt32,
51
50
  payload: ConsensusPayload.schema,
52
51
  signature: Signature.schema,
52
+ proposerSignature: Signature.schema,
53
53
  })
54
- .transform(obj => new BlockAttestation(obj.blockNumber, obj.payload, obj.signature));
54
+ .transform(obj => new BlockAttestation(obj.payload, obj.signature, obj.proposerSignature));
55
55
  }
56
56
 
57
57
  override generateP2PMessageIdentifier(): Promise<Buffer32> {
@@ -68,29 +68,32 @@ export class BlockAttestation extends Gossipable {
68
68
 
69
69
  /**
70
70
  * Lazily evaluate and cache the signer of the attestation
71
- * @returns The signer of the attestation
71
+ * @returns The signer of the attestation, or undefined if signature recovery fails
72
72
  */
73
- getSender(): EthAddress {
73
+ getSender(): EthAddress | undefined {
74
74
  if (!this.sender) {
75
75
  // Recover the sender from the attestation
76
76
  const hashed = getHashedSignaturePayloadEthSignedMessage(this.payload, SignatureDomainSeparator.blockAttestation);
77
77
  // Cache the sender for later use
78
- this.sender = recoverAddress(hashed, this.signature);
78
+ this.sender = tryRecoverAddress(hashed, this.signature);
79
79
  }
80
80
 
81
81
  return this.sender;
82
82
  }
83
83
 
84
84
  /**
85
- * Tries to get the sender of the attestation
86
- * @returns The sender of the attestation or undefined if it fails during recovery
85
+ * Lazily evaluate and cache the proposer of the block
86
+ * @returns The proposer of the block
87
87
  */
88
- tryGetSender(): EthAddress | undefined {
89
- try {
90
- return this.getSender();
91
- } catch {
92
- return undefined;
88
+ getProposer(): EthAddress | undefined {
89
+ if (!this.proposer) {
90
+ // Recover the proposer from the proposal signature
91
+ const hashed = getHashedSignaturePayloadEthSignedMessage(this.payload, SignatureDomainSeparator.blockProposal);
92
+ // Cache the proposer for later use
93
+ this.proposer = tryRecoverAddress(hashed, this.proposerSignature);
93
94
  }
95
+
96
+ return this.proposer;
94
97
  }
95
98
 
96
99
  getPayload(): Buffer {
@@ -98,31 +101,35 @@ export class BlockAttestation extends Gossipable {
98
101
  }
99
102
 
100
103
  toBuffer(): Buffer {
101
- return serializeToBuffer([this.blockNumber, this.payload, this.signature]);
104
+ return serializeToBuffer([this.payload, this.signature, this.proposerSignature]);
102
105
  }
103
106
 
104
107
  static fromBuffer(buf: Buffer | BufferReader): BlockAttestation {
105
108
  const reader = BufferReader.asReader(buf);
106
- return new BlockAttestation(reader.readNumber(), reader.readObject(ConsensusPayload), reader.readObject(Signature));
109
+ return new BlockAttestation(
110
+ reader.readObject(ConsensusPayload),
111
+ reader.readObject(Signature),
112
+ reader.readObject(Signature),
113
+ );
107
114
  }
108
115
 
109
116
  static empty(): BlockAttestation {
110
- return new BlockAttestation(0, ConsensusPayload.empty(), Signature.empty());
117
+ return new BlockAttestation(ConsensusPayload.empty(), Signature.empty(), Signature.empty());
111
118
  }
112
119
 
113
120
  static random(): BlockAttestation {
114
- return new BlockAttestation(Math.floor(Math.random() * 1000) + 1, ConsensusPayload.random(), Signature.random());
121
+ return new BlockAttestation(ConsensusPayload.random(), Signature.random(), Signature.random());
115
122
  }
116
123
 
117
124
  getSize(): number {
118
- return 4 /* blockNumber */ + this.payload.getSize() + this.signature.getSize();
125
+ return this.payload.getSize() + this.signature.getSize() + this.proposerSignature.getSize();
119
126
  }
120
127
 
121
128
  toInspect() {
122
129
  return {
123
- blockNumber: this.blockNumber,
124
130
  payload: this.payload.toInspect(),
125
131
  signature: this.signature.toString(),
132
+ proposerSignature: this.proposerSignature.toString(),
126
133
  };
127
134
  }
128
135
  }
@@ -1,5 +1,5 @@
1
1
  import { Buffer32 } from '@aztec/foundation/buffer';
2
- import { keccak256, recoverAddress } from '@aztec/foundation/crypto';
2
+ import { keccak256, tryRecoverAddress } from '@aztec/foundation/crypto';
3
3
  import type { EthAddress } from '@aztec/foundation/eth-address';
4
4
  import { Signature } from '@aztec/foundation/eth-signature';
5
5
  import { Fr } from '@aztec/foundation/fields';
@@ -8,7 +8,6 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
8
8
  import type { L2BlockInfo } from '../block/l2_block_info.js';
9
9
  import { TxHash } from '../tx/index.js';
10
10
  import { Tx } from '../tx/tx.js';
11
- import type { UInt32 } from '../types/index.js';
12
11
  import { ConsensusPayload } from './consensus_payload.js';
13
12
  import { Gossipable } from './gossipable.js';
14
13
  import {
@@ -40,9 +39,6 @@ export class BlockProposal extends Gossipable {
40
39
  private sender: EthAddress | undefined;
41
40
 
42
41
  constructor(
43
- /** The number of the block */
44
- public readonly blockNumber: UInt32,
45
-
46
42
  /** The payload of the message, and what the signature is over */
47
43
  public readonly payload: ConsensusPayload,
48
44
 
@@ -71,9 +67,8 @@ export class BlockProposal extends Gossipable {
71
67
  return this.payload.header.slotNumber;
72
68
  }
73
69
 
74
- toBlockInfo(): L2BlockInfo {
70
+ toBlockInfo(): Omit<L2BlockInfo, 'blockNumber'> {
75
71
  return {
76
- blockNumber: this.blockNumber,
77
72
  slotNumber: this.slotNumber.toNumber(),
78
73
  lastArchive: this.payload.header.lastArchiveRoot,
79
74
  timestamp: this.payload.header.timestamp,
@@ -83,7 +78,6 @@ export class BlockProposal extends Gossipable {
83
78
  }
84
79
 
85
80
  static async createProposalFromSigner(
86
- blockNumber: UInt32,
87
81
  payload: ConsensusPayload,
88
82
  txHashes: TxHash[],
89
83
  // Note(md): Provided separately to tx hashes such that this function can be optional
@@ -93,17 +87,18 @@ export class BlockProposal extends Gossipable {
93
87
  const hashed = getHashedSignaturePayload(payload, SignatureDomainSeparator.blockProposal);
94
88
  const sig = await payloadSigner(hashed);
95
89
 
96
- return new BlockProposal(blockNumber, payload, sig, txHashes, txs);
90
+ return new BlockProposal(payload, sig, txHashes, txs);
97
91
  }
98
92
 
99
93
  /**Get Sender
100
94
  * Lazily evaluate the sender of the proposal; result is cached
95
+ * @returns The sender address, or undefined if signature recovery fails
101
96
  */
102
- getSender() {
97
+ getSender(): EthAddress | undefined {
103
98
  if (!this.sender) {
104
99
  const hashed = getHashedSignaturePayloadEthSignedMessage(this.payload, SignatureDomainSeparator.blockProposal);
105
100
  // Cache the sender for later use
106
- this.sender = recoverAddress(hashed, this.signature);
101
+ this.sender = tryRecoverAddress(hashed, this.signature);
107
102
  }
108
103
 
109
104
  return this.sender;
@@ -114,7 +109,7 @@ export class BlockProposal extends Gossipable {
114
109
  }
115
110
 
116
111
  toBuffer(): Buffer {
117
- const buffer: any[] = [this.blockNumber, this.payload, this.signature, this.txHashes.length, this.txHashes];
112
+ const buffer: any[] = [this.payload, this.signature, this.txHashes.length, this.txHashes];
118
113
  if (this.txs) {
119
114
  buffer.push(this.txs.length);
120
115
  buffer.push(this.txs);
@@ -125,22 +120,20 @@ export class BlockProposal extends Gossipable {
125
120
  static fromBuffer(buf: Buffer | BufferReader): BlockProposal {
126
121
  const reader = BufferReader.asReader(buf);
127
122
 
128
- const blockNumber = reader.readNumber();
129
123
  const payload = reader.readObject(ConsensusPayload);
130
124
  const sig = reader.readObject(Signature);
131
125
  const txHashes = reader.readArray(reader.readNumber(), TxHash);
132
126
 
133
127
  if (!reader.isEmpty()) {
134
128
  const txs = reader.readArray(reader.readNumber(), Tx);
135
- return new BlockProposal(blockNumber, payload, sig, txHashes, txs);
129
+ return new BlockProposal(payload, sig, txHashes, txs);
136
130
  }
137
131
 
138
- return new BlockProposal(blockNumber, payload, sig, txHashes);
132
+ return new BlockProposal(payload, sig, txHashes);
139
133
  }
140
134
 
141
135
  getSize(): number {
142
136
  return (
143
- 4 /* blockNumber */ +
144
137
  this.payload.getSize() +
145
138
  this.signature.getSize() +
146
139
  4 /* txHashes.length */ +
@@ -28,15 +28,12 @@ export class P2PMessage {
28
28
  */
29
29
  export abstract class Gossipable {
30
30
  private cachedId: Buffer32 | undefined;
31
- /** p2p Topic
32
- *
33
- * - The p2p topic identifier, this determines how the message is handled
34
- */
31
+ /** The p2p topic identifier, this determines how the message is handled */
35
32
  static p2pTopic: TopicType;
36
33
 
37
- /** p2p Message Identifier
38
- *
39
- * - A digest of the message information, this key is used for deduplication
34
+ /**
35
+ * A digest of the message information **used for logging only**.
36
+ * The identifier used for deduplication is `getMsgIdFn` as defined in `encoding.ts` which is a hash over topic and data.
40
37
  */
41
38
  async p2pMessageIdentifier(): Promise<Buffer32> {
42
39
  if (this.cachedId) {
@@ -48,10 +45,6 @@ export abstract class Gossipable {
48
45
 
49
46
  abstract generateP2PMessageIdentifier(): Promise<Buffer32>;
50
47
 
51
- /** To Buffer
52
- *
53
- * - Serialization method
54
- */
55
48
  abstract toBuffer(): Buffer;
56
49
 
57
50
  toMessage(): Buffer {
@@ -60,7 +53,6 @@ export abstract class Gossipable {
60
53
 
61
54
  /**
62
55
  * Get the size of the gossipable object.
63
- *
64
56
  * This is used for metrics recording.
65
57
  */
66
58
  abstract getSize(): number;
@@ -1,18 +1,25 @@
1
1
  import { P2PClientType } from './client_type.js';
2
2
 
3
- /** Create Topic String
4
- *
5
- * The topic channel identifier
6
- * @param topicType
7
- * @returns
3
+ /**
4
+ * Creates the topic channel identifier string from a given topic type
8
5
  */
9
6
  export function createTopicString(topicType: TopicType, protocolVersion: string) {
10
7
  return `/aztec/${TopicType[topicType]}/${protocolVersion}`;
11
8
  }
12
9
 
13
- /**
14
- *
15
- */
10
+ /** Extracts the topic type from a topic string */
11
+ export function getTopicFromString(topicStr: string): TopicType | undefined {
12
+ const parts = topicStr.split('/');
13
+ if (parts.length < 4 || parts[1] !== 'aztec') {
14
+ return undefined;
15
+ }
16
+ const topic = parts[2];
17
+ if (Object.values(TopicType).includes(topic as TopicType)) {
18
+ return topic as TopicType;
19
+ }
20
+ return undefined;
21
+ }
22
+
16
23
  export enum TopicType {
17
24
  tx = 'tx',
18
25
  block_proposal = 'block_proposal',
@@ -46,9 +46,9 @@ import {
46
46
  } from '@aztec/constants';
47
47
  import { type FieldsOf, makeHalfFullTuple, makeTuple } from '@aztec/foundation/array';
48
48
  import { compact, padArrayEnd } from '@aztec/foundation/collection';
49
- import { SchnorrSignature, poseidon2HashWithSeparator, sha256 } from '@aztec/foundation/crypto';
49
+ import { Grumpkin, SchnorrSignature, poseidon2HashWithSeparator, sha256 } from '@aztec/foundation/crypto';
50
50
  import { EthAddress } from '@aztec/foundation/eth-address';
51
- import { BLS12Point, Fr, GrumpkinScalar, Point } from '@aztec/foundation/fields';
51
+ import { BLS12Point, Fq, Fr, GrumpkinScalar, Point } from '@aztec/foundation/fields';
52
52
  import type { Bufferable, Serializable, Tuple } from '@aztec/foundation/serialize';
53
53
  import { MembershipWitness } from '@aztec/foundation/trees';
54
54
 
@@ -1250,13 +1250,10 @@ export async function makeMapAsync<T>(size: number, fn: (i: number) => Promise<[
1250
1250
  return new Map(await makeArrayAsync(size, i => fn(i + offset)));
1251
1251
  }
1252
1252
 
1253
- export function makePublicKeys(seed = 0): PublicKeys {
1254
- return new PublicKeys(
1255
- new Point(new Fr(seed + 0), new Fr(seed + 1), false),
1256
- new Point(new Fr(seed + 2), new Fr(seed + 3), false),
1257
- new Point(new Fr(seed + 4), new Fr(seed + 5), false),
1258
- new Point(new Fr(seed + 6), new Fr(seed + 7), false),
1259
- );
1253
+ export async function makePublicKeys(seed = 0): Promise<PublicKeys> {
1254
+ const f = (offset: number) => new Grumpkin().mul(Grumpkin.generator, new Fq(seed + offset));
1255
+
1256
+ return new PublicKeys(await f(0), await f(1), await f(2), await f(3));
1260
1257
  }
1261
1258
 
1262
1259
  export async function makeContractInstanceFromClassId(
@@ -1272,7 +1269,7 @@ export async function makeContractInstanceFromClassId(
1272
1269
  const salt = new Fr(seed);
1273
1270
  const initializationHash = overrides?.initializationHash ?? new Fr(seed + 1);
1274
1271
  const deployer = overrides?.deployer ?? new AztecAddress(new Fr(seed + 2));
1275
- const publicKeys = overrides?.publicKeys ?? makePublicKeys(seed + 3);
1272
+ const publicKeys = overrides?.publicKeys ?? (await makePublicKeys(seed + 3));
1276
1273
 
1277
1274
  const saltedInitializationHash = await poseidon2HashWithSeparator(
1278
1275
  [salt, initializationHash, deployer],
@@ -248,6 +248,8 @@ export const randomDeployedContract = async () => {
248
248
 
249
249
  export interface MakeConsensusPayloadOptions {
250
250
  signer?: Secp256k1Signer;
251
+ attesterSigner?: Secp256k1Signer;
252
+ proposerSigner?: Secp256k1Signer;
251
253
  header?: BlockHeader;
252
254
  archive?: Fr;
253
255
  stateReference?: StateReference;
@@ -286,31 +288,65 @@ export const makeAndSignCommitteeAttestationsAndSigners = (
286
288
  };
287
289
 
288
290
  export const makeBlockProposal = (options?: MakeConsensusPayloadOptions): BlockProposal => {
289
- const { blockNumber, payload, signature } = makeAndSignConsensusPayload(
290
- SignatureDomainSeparator.blockProposal,
291
- options,
292
- );
291
+ const { payload, signature } = makeAndSignConsensusPayload(SignatureDomainSeparator.blockProposal, options);
293
292
  const txHashes = options?.txHashes ?? [0, 1, 2, 3, 4, 5].map(() => TxHash.random());
294
- return new BlockProposal(blockNumber, payload, signature, txHashes, options?.txs ?? []);
293
+ return new BlockProposal(payload, signature, txHashes, options?.txs ?? []);
295
294
  };
296
295
 
297
296
  // TODO(https://github.com/AztecProtocol/aztec-packages/issues/8028)
298
297
  export const makeBlockAttestation = (options?: MakeConsensusPayloadOptions): BlockAttestation => {
299
- const { blockNumber, payload, signature } = makeAndSignConsensusPayload(
300
- SignatureDomainSeparator.blockAttestation,
301
- options,
302
- );
303
- return new BlockAttestation(blockNumber, payload, signature);
298
+ const header = options?.header ?? makeHeader(1);
299
+ const {
300
+ signer,
301
+ attesterSigner = signer ?? Secp256k1Signer.random(),
302
+ proposerSigner = signer ?? Secp256k1Signer.random(),
303
+ archive = Fr.random(),
304
+ stateReference = header.state,
305
+ } = options ?? {};
306
+
307
+ const payload = ConsensusPayload.fromFields({
308
+ header: header.toPropose(),
309
+ archive,
310
+ stateReference,
311
+ });
312
+
313
+ // Sign as attester
314
+ const attestationHash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockAttestation);
315
+ const attestationSignature = attesterSigner.sign(attestationHash);
316
+
317
+ // Sign as proposer
318
+ const proposalHash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockProposal);
319
+ const proposerSignature = proposerSigner.sign(proposalHash);
320
+
321
+ return new BlockAttestation(payload, attestationSignature, proposerSignature);
304
322
  };
305
323
 
306
- export const makeBlockAttestationFromBlock = (block: L2Block, signer?: Secp256k1Signer): BlockAttestation => {
307
- return makeBlockAttestation({
308
- signer,
309
- header: block.header,
310
- archive: block.archive.root,
311
- stateReference: block.header.state,
312
- txHashes: block.body.txEffects.map(tx => tx.txHash),
324
+ export const makeBlockAttestationFromBlock = (
325
+ block: L2Block,
326
+ attesterSigner?: Secp256k1Signer,
327
+ proposerSigner?: Secp256k1Signer,
328
+ ): BlockAttestation => {
329
+ const header = block.header;
330
+ const archive = block.archive.root;
331
+ const stateReference = block.header.state;
332
+
333
+ const payload = ConsensusPayload.fromFields({
334
+ header: header.toPropose(),
335
+ archive,
336
+ stateReference,
313
337
  });
338
+
339
+ // Sign as attester
340
+ const attestationHash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockAttestation);
341
+ const attestationSigner = attesterSigner ?? Secp256k1Signer.random();
342
+ const attestationSignature = attestationSigner.sign(attestationHash);
343
+
344
+ // Sign as proposer
345
+ const proposalHash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockProposal);
346
+ const proposalSignerToUse = proposerSigner ?? Secp256k1Signer.random();
347
+ const proposerSignature = proposalSignerToUse.sign(proposalHash);
348
+
349
+ return new BlockAttestation(payload, attestationSignature, proposerSignature);
314
350
  };
315
351
 
316
352
  export async function randomPublishedL2Block(
@@ -5,15 +5,20 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
5
5
  import { withoutHexPrefix } from '@aztec/foundation/string';
6
6
 
7
7
  export type ViemZkPassportProofParams = {
8
- vkeyHash: `0x${string}`;
9
- proof: `0x${string}`;
10
- publicInputs: `0x${string}`[];
11
- committedInputs: `0x${string}`;
12
- committedInputCounts: bigint[];
13
- validityPeriodInSeconds: bigint;
14
- domain: string;
15
- scope: string;
16
- devMode: boolean;
8
+ proofVerificationData: {
9
+ vkeyHash: `0x${string}`;
10
+ proof: `0x${string}`;
11
+ publicInputs: `0x${string}`[];
12
+ };
13
+ commitments: {
14
+ committedInputs: `0x${string}`;
15
+ };
16
+ serviceConfig: {
17
+ validityPeriodInSeconds: bigint;
18
+ domain: string;
19
+ scope: string;
20
+ devMode: boolean;
21
+ };
17
22
  };
18
23
 
19
24
  // NOTE: Must match the ZkPassportProofParams struct in the zkpassport verifier contract
@@ -25,7 +30,6 @@ export class ZkPassportProofParams {
25
30
  public proof: Buffer,
26
31
  public publicInputs: Fr[],
27
32
  public committedInputs: Buffer,
28
- public committedInputCounts: bigint[],
29
33
  public validityPeriodInSeconds: bigint,
30
34
  public domain: string,
31
35
  public scope: string,
@@ -41,8 +45,6 @@ export class ZkPassportProofParams {
41
45
  this.publicInputs,
42
46
  this.committedInputs.length,
43
47
  this.committedInputs,
44
- this.committedInputCounts.length,
45
- this.committedInputCounts,
46
48
  this.validityPeriodInSeconds,
47
49
  this.domain,
48
50
  this.scope,
@@ -63,8 +65,7 @@ export class ZkPassportProofParams {
63
65
  randomBytes(1024),
64
66
  publicInputs,
65
67
  committedInputs,
66
- committedInputCounts,
67
- BigInt(100 * 60 * 60 * 24),
68
+ BigInt(7 * 24 * 60 * 60), // 7 days
68
69
  'sequencer.alpha-testnet.aztec.network',
69
70
  'personhood',
70
71
  );
@@ -78,7 +79,6 @@ export class ZkPassportProofParams {
78
79
  reader.readBuffer(),
79
80
  reader.readVector(Fr),
80
81
  reader.readBuffer(),
81
- reader.readUint256Vector(),
82
82
  reader.readUInt256(),
83
83
  reader.readString(),
84
84
  reader.readString(),
@@ -87,29 +87,33 @@ export class ZkPassportProofParams {
87
87
 
88
88
  static fromViem(params: ViemZkPassportProofParams) {
89
89
  return new ZkPassportProofParams(
90
- params.devMode,
91
- Buffer32.fromString(params.vkeyHash),
92
- Buffer.from(withoutHexPrefix(params.proof), 'hex'),
93
- params.publicInputs.map(input => Fr.fromString(input)),
94
- Buffer.from(withoutHexPrefix(params.committedInputs), 'hex'),
95
- params.committedInputCounts,
96
- params.validityPeriodInSeconds,
97
- params.domain,
98
- params.scope,
90
+ params.serviceConfig.devMode,
91
+ Buffer32.fromString(params.proofVerificationData.vkeyHash),
92
+ Buffer.from(withoutHexPrefix(params.proofVerificationData.proof), 'hex'),
93
+ params.proofVerificationData.publicInputs.map(input => Fr.fromString(input)),
94
+ Buffer.from(withoutHexPrefix(params.commitments.committedInputs), 'hex'),
95
+ params.serviceConfig.validityPeriodInSeconds,
96
+ params.serviceConfig.domain,
97
+ params.serviceConfig.scope,
99
98
  );
100
99
  }
101
100
 
102
101
  toViem(): ViemZkPassportProofParams {
103
102
  return {
104
- devMode: this.devMode,
105
- vkeyHash: this.vkeyHash.toString(),
106
- proof: `0x${this.proof.toString('hex')}`,
107
- publicInputs: this.publicInputs.map(input => input.toString()),
108
- committedInputs: `0x${this.committedInputs.toString('hex')}`,
109
- committedInputCounts: this.committedInputCounts,
110
- validityPeriodInSeconds: this.validityPeriodInSeconds,
111
- domain: this.domain,
112
- scope: this.scope,
103
+ serviceConfig: {
104
+ devMode: this.devMode,
105
+ validityPeriodInSeconds: this.validityPeriodInSeconds,
106
+ domain: this.domain,
107
+ scope: this.scope,
108
+ },
109
+ proofVerificationData: {
110
+ vkeyHash: this.vkeyHash.toString(),
111
+ proof: `0x${this.proof.toString('hex')}`,
112
+ publicInputs: this.publicInputs.map(input => input.toString()),
113
+ },
114
+ commitments: {
115
+ committedInputs: `0x${this.committedInputs.toString('hex')}`,
116
+ },
113
117
  };
114
118
  }
115
119
  }