@aztec/stdlib 2.1.0-rc.1 → 2.1.0-rc.11

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 (63) 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/proposal/attestations_and_signers.js +1 -1
  8. package/dest/block/published_l2_block.d.ts +0 -2
  9. package/dest/block/published_l2_block.d.ts.map +1 -1
  10. package/dest/block/published_l2_block.js +0 -6
  11. package/dest/epoch-helpers/index.d.ts +2 -0
  12. package/dest/epoch-helpers/index.d.ts.map +1 -1
  13. package/dest/epoch-helpers/index.js +3 -0
  14. package/dest/file-store/factory.d.ts.map +1 -1
  15. package/dest/file-store/factory.js +18 -0
  16. package/dest/file-store/interface.d.ts +8 -2
  17. package/dest/file-store/interface.d.ts.map +1 -1
  18. package/dest/file-store/s3.d.ts +26 -0
  19. package/dest/file-store/s3.d.ts.map +1 -0
  20. package/dest/file-store/s3.js +252 -0
  21. package/dest/interfaces/aztec-node-admin.d.ts +3 -0
  22. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  23. package/dest/interfaces/configs.d.ts +5 -0
  24. package/dest/interfaces/configs.d.ts.map +1 -1
  25. package/dest/interfaces/configs.js +2 -1
  26. package/dest/interfaces/p2p.d.ts +2 -0
  27. package/dest/interfaces/p2p.d.ts.map +1 -1
  28. package/dest/interfaces/p2p.js +2 -1
  29. package/dest/l1-contracts/slash_factory.d.ts +1 -1
  30. package/dest/l1-contracts/slash_factory.d.ts.map +1 -1
  31. package/dest/l1-contracts/slash_factory.js +1 -1
  32. package/dest/p2p/block_attestation.d.ts +47 -1
  33. package/dest/p2p/block_attestation.d.ts.map +1 -1
  34. package/dest/p2p/block_attestation.js +43 -9
  35. package/dest/p2p/consensus_payload.js +1 -1
  36. package/dest/p2p/gossipable.d.ts +2 -4
  37. package/dest/p2p/gossipable.d.ts.map +1 -1
  38. package/dest/p2p/gossipable.js +5 -14
  39. package/dest/snapshots/download.d.ts.map +1 -1
  40. package/dest/snapshots/download.js +58 -2
  41. package/dest/snapshots/upload.d.ts.map +1 -1
  42. package/dest/snapshots/upload.js +1 -0
  43. package/dest/tests/mocks.d.ts +3 -1
  44. package/dest/tests/mocks.d.ts.map +1 -1
  45. package/dest/tests/mocks.js +31 -9
  46. package/package.json +10 -9
  47. package/src/block/attestation_info.ts +62 -0
  48. package/src/block/index.ts +1 -0
  49. package/src/block/proposal/attestations_and_signers.ts +1 -1
  50. package/src/block/published_l2_block.ts +0 -11
  51. package/src/epoch-helpers/index.ts +8 -0
  52. package/src/file-store/factory.ts +15 -0
  53. package/src/file-store/interface.ts +8 -2
  54. package/src/file-store/s3.ts +254 -0
  55. package/src/interfaces/configs.ts +3 -0
  56. package/src/interfaces/p2p.ts +4 -0
  57. package/src/l1-contracts/slash_factory.ts +1 -1
  58. package/src/p2p/block_attestation.ts +57 -6
  59. package/src/p2p/consensus_payload.ts +1 -1
  60. package/src/p2p/gossipable.ts +6 -16
  61. package/src/snapshots/download.ts +66 -2
  62. package/src/snapshots/upload.ts +1 -0
  63. package/src/tests/mocks.ts +51 -12
@@ -29,5 +29,6 @@ export const P2PApiSchema = {
29
29
  getPendingTxs: z.function().args(optional(z.number().gte(1).lte(MAX_RPC_TXS_LEN).default(MAX_RPC_TXS_LEN)), optional(TxHash.schema)).returns(z.array(Tx.schema)),
30
30
  getPendingTxCount: z.function().returns(schemas.Integer),
31
31
  getEncodedEnr: z.function().returns(z.string().optional()),
32
- getPeers: z.function().args(optional(z.boolean())).returns(z.array(PeerInfoSchema))
32
+ getPeers: z.function().args(optional(z.boolean())).returns(z.array(PeerInfoSchema)),
33
+ deleteAttestation: z.function().args(BlockAttestation.schema).returns(z.void())
33
34
  };
@@ -1,6 +1,6 @@
1
1
  import { type L1TxRequest, type ViemClient } from '@aztec/ethereum';
2
2
  import { EthAddress } from '@aztec/foundation/eth-address';
3
- import { type Hex, type Log } from 'viem';
3
+ import { type Hex, type Log } from '@spalladino/viem';
4
4
  import type { L1RollupConstants } from '../epoch-helpers/index.js';
5
5
  import { type SlashPayload, type ValidatorSlash, type ValidatorSlashOffense } from '../slashing/index.js';
6
6
  export declare class SlashFactoryContract {
@@ -1 +1 @@
1
- {"version":3,"file":"slash_factory.d.ts","sourceRoot":"","sources":["../../src/l1-contracts/slash_factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAmB,MAAM,iBAAiB,CAAC;AAErF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAI3D,OAAO,EAA8B,KAAK,GAAG,EAAE,KAAK,GAAG,EAAmC,MAAM,MAAM,CAAC;AAEvG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAE3B,MAAM,sBAAsB,CAAC;AAE9B,qBAAa,oBAAoB;aAKb,MAAM,EAAE,UAAU;IAJpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;IAClE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4D;gBAGnE,MAAM,EAAE,UAAU,EAClC,OAAO,EAAE,GAAG,GAAG,UAAU;IAS3B,IAAW,OAAO,eAEjB;IAEM,yBAAyB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,WAAW;IAiBxE,wEAAwE;IACjE,kCAAkC,CAAC,IAAI,EAAE,GAAG,EAAE;;;;;;;;;IAIxC,4BAA4B,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAiBpE;;;;;OAKG;IACU,yBAAyB,CACpC,cAAc,EAAE,UAAU,EAC1B,QAAQ,EAAE;QACR,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,+BAA+B,EAAE,MAAM,CAAC;KACzC,GAAG,IAAI,CAAC,iBAAiB,EAAE,cAAc,GAAG,sBAAsB,CAAC,GACnE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAqDtC,uBAAuB,CAClC,OAAO,EAAE,cAAc,EAAE,GACxB,OAAO,CAAC;QAAE,OAAO,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,GAAG,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;IAUnE,OAAO,CAAC,WAAW;CAQpB;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAMhF;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,qBAAqB,CAKjF"}
1
+ {"version":3,"file":"slash_factory.d.ts","sourceRoot":"","sources":["../../src/l1-contracts/slash_factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAmB,MAAM,iBAAiB,CAAC;AAErF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAI3D,OAAO,EAA8B,KAAK,GAAG,EAAE,KAAK,GAAG,EAAmC,MAAM,kBAAkB,CAAC;AAEnH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAE3B,MAAM,sBAAsB,CAAC;AAE9B,qBAAa,oBAAoB;aAKb,MAAM,EAAE,UAAU;IAJpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;IAClE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4D;gBAGnE,MAAM,EAAE,UAAU,EAClC,OAAO,EAAE,GAAG,GAAG,UAAU;IAS3B,IAAW,OAAO,eAEjB;IAEM,yBAAyB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,WAAW;IAiBxE,wEAAwE;IACjE,kCAAkC,CAAC,IAAI,EAAE,GAAG,EAAE;;;;;;;;;IAIxC,4BAA4B,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAiBpE;;;;;OAKG;IACU,yBAAyB,CACpC,cAAc,EAAE,UAAU,EAC1B,QAAQ,EAAE;QACR,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,+BAA+B,EAAE,MAAM,CAAC;KACzC,GAAG,IAAI,CAAC,iBAAiB,EAAE,cAAc,GAAG,sBAAsB,CAAC,GACnE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAqDtC,uBAAuB,CAClC,OAAO,EAAE,cAAc,EAAE,GACxB,OAAO,CAAC;QAAE,OAAO,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,GAAG,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;IAUnE,OAAO,CAAC,WAAW;CAQpB;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAMhF;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,qBAAqB,CAKjF"}
@@ -3,7 +3,7 @@ import { maxBigint } from '@aztec/foundation/bigint';
3
3
  import { EthAddress } from '@aztec/foundation/eth-address';
4
4
  import { createLogger } from '@aztec/foundation/log';
5
5
  import { SlashFactoryAbi } from '@aztec/l1-artifacts/SlashFactoryAbi';
6
- import { encodeFunctionData, getContract } from 'viem';
6
+ import { encodeFunctionData, getContract } from '@spalladino/viem';
7
7
  import { OffenseToBigInt, bigIntToOffense } from '../slashing/index.js';
8
8
  export class SlashFactoryContract {
9
9
  client;
@@ -24,15 +24,20 @@ export declare class BlockAttestation extends Gossipable {
24
24
  readonly payload: ConsensusPayload;
25
25
  /** The signature of the block attester */
26
26
  readonly signature: Signature;
27
+ /** The signature from the block proposer */
28
+ readonly proposerSignature: Signature;
27
29
  static p2pTopic: TopicType;
28
30
  private sender;
31
+ private proposer;
29
32
  constructor(
30
33
  /** The block number of the attestation. */
31
34
  blockNumber: UInt32,
32
35
  /** The payload of the message, and what the signature is over */
33
36
  payload: ConsensusPayload,
34
37
  /** The signature of the block attester */
35
- signature: Signature);
38
+ signature: Signature,
39
+ /** The signature from the block proposer */
40
+ proposerSignature: Signature);
36
41
  static get schema(): ZodFor<BlockAttestation>;
37
42
  generateP2PMessageIdentifier(): Promise<Buffer32>;
38
43
  get archive(): Fr;
@@ -42,11 +47,52 @@ export declare class BlockAttestation extends Gossipable {
42
47
  * @returns The signer of the attestation
43
48
  */
44
49
  getSender(): EthAddress;
50
+ /**
51
+ * Tries to get the sender of the attestation
52
+ * @returns The sender of the attestation or undefined if it fails during recovery
53
+ */
54
+ tryGetSender(): EthAddress | undefined;
55
+ /**
56
+ * Lazily evaluate and cache the proposer of the block
57
+ * @returns The proposer of the block
58
+ */
59
+ getProposer(): EthAddress;
45
60
  getPayload(): Buffer;
46
61
  toBuffer(): Buffer;
47
62
  static fromBuffer(buf: Buffer | BufferReader): BlockAttestation;
48
63
  static empty(): BlockAttestation;
49
64
  static random(): BlockAttestation;
50
65
  getSize(): number;
66
+ toInspect(): {
67
+ blockNumber: number;
68
+ payload: {
69
+ header: {
70
+ lastArchive: `0x${string}`;
71
+ contentCommitment: {
72
+ blobsHash: `0x${string}`;
73
+ inHash: `0x${string}`;
74
+ outHash: `0x${string}`;
75
+ };
76
+ slotNumber: bigint;
77
+ timestamp: bigint;
78
+ coinbase: `0x${string}`;
79
+ feeRecipient: `0x${string}`;
80
+ gasFees: {
81
+ feePerDaGas: bigint;
82
+ feePerL2Gas: bigint;
83
+ };
84
+ totalManaUsed: bigint;
85
+ };
86
+ archive: `0x${string}`;
87
+ stateReference: {
88
+ l1ToL2MessageTree: `0x${string}`;
89
+ noteHashTree: `0x${string}`;
90
+ nullifierTree: `0x${string}`;
91
+ publicDataTree: `0x${string}`;
92
+ };
93
+ };
94
+ signature: `0x${string}`;
95
+ proposerSignature: `0x${string}`;
96
+ };
51
97
  }
52
98
  //# sourceMappingURL=block_attestation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"block_attestation.d.ts","sourceRoot":"","sources":["../../src/p2p/block_attestation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC;AAI9E,OAAO,EAAE,KAAK,MAAM,EAAW,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,qBAAa,oBAAqB,SAAQ,QAAQ;gBACpC,IAAI,EAAE,MAAM;CAGzB;AAED;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,UAAU;IAM5C,2CAA2C;aAC3B,WAAW,EAAE,MAAM;IAEnC,iEAAiE;aACjD,OAAO,EAAE,gBAAgB;IAEzC,0CAA0C;aAC1B,SAAS,EAAE,SAAS;IAZtC,OAAgB,QAAQ,YAA+B;IAEvD,OAAO,CAAC,MAAM,CAAyB;;IAGrC,2CAA2C;IAC3B,WAAW,EAAE,MAAM;IAEnC,iEAAiE;IACjD,OAAO,EAAE,gBAAgB;IAEzC,0CAA0C;IAC1B,SAAS,EAAE,SAAS;IAKtC,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAQ5C;IAEQ,4BAA4B,IAAI,OAAO,CAAC,QAAQ,CAAC;IAI1D,IAAI,OAAO,IAAI,EAAE,CAEhB;IAED,IAAI,UAAU,IAAI,EAAE,CAEnB;IAED;;;OAGG;IACH,SAAS,IAAI,UAAU;IAWvB,UAAU,IAAI,MAAM;IAIpB,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,gBAAgB;IAK/D,MAAM,CAAC,KAAK,IAAI,gBAAgB;IAIhC,MAAM,CAAC,MAAM,IAAI,gBAAgB;IAIjC,OAAO,IAAI,MAAM;CAGlB"}
1
+ {"version":3,"file":"block_attestation.d.ts","sourceRoot":"","sources":["../../src/p2p/block_attestation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC;AAI9E,OAAO,EAAE,KAAK,MAAM,EAAW,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,qBAAa,oBAAqB,SAAQ,QAAQ;gBACpC,IAAI,EAAE,MAAM;CAGzB;AAED;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,UAAU;IAO5C,2CAA2C;aAC3B,WAAW,EAAE,MAAM;IAEnC,iEAAiE;aACjD,OAAO,EAAE,gBAAgB;IAEzC,0CAA0C;aAC1B,SAAS,EAAE,SAAS;IAEpC,4CAA4C;aAC5B,iBAAiB,EAAE,SAAS;IAhB9C,OAAgB,QAAQ,YAA+B;IAEvD,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,QAAQ,CAAyB;;IAGvC,2CAA2C;IAC3B,WAAW,EAAE,MAAM;IAEnC,iEAAiE;IACjD,OAAO,EAAE,gBAAgB;IAEzC,0CAA0C;IAC1B,SAAS,EAAE,SAAS;IAEpC,4CAA4C;IAC5B,iBAAiB,EAAE,SAAS;IAK9C,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAS5C;IAEQ,4BAA4B,IAAI,OAAO,CAAC,QAAQ,CAAC;IAI1D,IAAI,OAAO,IAAI,EAAE,CAEhB;IAED,IAAI,UAAU,IAAI,EAAE,CAEnB;IAED;;;OAGG;IACH,SAAS,IAAI,UAAU;IAWvB;;;OAGG;IACH,YAAY,IAAI,UAAU,GAAG,SAAS;IAQtC;;;OAGG;IACH,WAAW,IAAI,UAAU;IAWzB,UAAU,IAAI,MAAM;IAIpB,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,gBAAgB;IAU/D,MAAM,CAAC,KAAK,IAAI,gBAAgB;IAIhC,MAAM,CAAC,MAAM,IAAI,gBAAgB;IASjC,OAAO,IAAI,MAAM;IAIjB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQV"}
@@ -22,17 +22,20 @@ export class BlockAttestationHash extends Buffer32 {
22
22
  blockNumber;
23
23
  payload;
24
24
  signature;
25
+ proposerSignature;
25
26
  static p2pTopic = TopicType.block_attestation;
26
27
  sender;
27
- constructor(/** The block number of the attestation. */ blockNumber, /** The payload of the message, and what the signature is over */ payload, /** The signature of the block attester */ signature){
28
- super(), this.blockNumber = blockNumber, this.payload = payload, this.signature = signature;
28
+ proposer;
29
+ constructor(/** The block number of the attestation. */ blockNumber, /** The payload of the message, and what the signature is over */ payload, /** The signature of the block attester */ signature, /** The signature from the block proposer */ proposerSignature){
30
+ super(), this.blockNumber = blockNumber, this.payload = payload, this.signature = signature, this.proposerSignature = proposerSignature;
29
31
  }
30
32
  static get schema() {
31
33
  return z.object({
32
34
  blockNumber: schemas.UInt32,
33
35
  payload: ConsensusPayload.schema,
34
- signature: Signature.schema
35
- }).transform((obj)=>new BlockAttestation(obj.blockNumber, obj.payload, obj.signature));
36
+ signature: Signature.schema,
37
+ proposerSignature: Signature.schema
38
+ }).transform((obj)=>new BlockAttestation(obj.blockNumber, obj.payload, obj.signature, obj.proposerSignature));
36
39
  }
37
40
  generateP2PMessageIdentifier() {
38
41
  return Promise.resolve(new BlockAttestationHash(keccak256(this.signature.toBuffer())));
@@ -55,6 +58,28 @@ export class BlockAttestationHash extends Buffer32 {
55
58
  }
56
59
  return this.sender;
57
60
  }
61
+ /**
62
+ * Tries to get the sender of the attestation
63
+ * @returns The sender of the attestation or undefined if it fails during recovery
64
+ */ tryGetSender() {
65
+ try {
66
+ return this.getSender();
67
+ } catch {
68
+ return undefined;
69
+ }
70
+ }
71
+ /**
72
+ * Lazily evaluate and cache the proposer of the block
73
+ * @returns The proposer of the block
74
+ */ getProposer() {
75
+ if (!this.proposer) {
76
+ // Recover the proposer from the proposal signature
77
+ const hashed = getHashedSignaturePayloadEthSignedMessage(this.payload, SignatureDomainSeparator.blockProposal);
78
+ // Cache the proposer for later use
79
+ this.proposer = recoverAddress(hashed, this.proposerSignature);
80
+ }
81
+ return this.proposer;
82
+ }
58
83
  getPayload() {
59
84
  return this.payload.getPayloadToSign(SignatureDomainSeparator.blockAttestation);
60
85
  }
@@ -62,20 +87,29 @@ export class BlockAttestationHash extends Buffer32 {
62
87
  return serializeToBuffer([
63
88
  this.blockNumber,
64
89
  this.payload,
65
- this.signature
90
+ this.signature,
91
+ this.proposerSignature
66
92
  ]);
67
93
  }
68
94
  static fromBuffer(buf) {
69
95
  const reader = BufferReader.asReader(buf);
70
- return new BlockAttestation(reader.readNumber(), reader.readObject(ConsensusPayload), reader.readObject(Signature));
96
+ return new BlockAttestation(reader.readNumber(), reader.readObject(ConsensusPayload), reader.readObject(Signature), reader.readObject(Signature));
71
97
  }
72
98
  static empty() {
73
- return new BlockAttestation(0, ConsensusPayload.empty(), Signature.empty());
99
+ return new BlockAttestation(0, ConsensusPayload.empty(), Signature.empty(), Signature.empty());
74
100
  }
75
101
  static random() {
76
- return new BlockAttestation(Math.floor(Math.random() * 1000) + 1, ConsensusPayload.random(), Signature.random());
102
+ return new BlockAttestation(Math.floor(Math.random() * 1000) + 1, ConsensusPayload.random(), Signature.random(), Signature.random());
77
103
  }
78
104
  getSize() {
79
- return 4 /* blockNumber */ + this.payload.getSize() + this.signature.getSize();
105
+ return 4 /* blockNumber */ + this.payload.getSize() + this.signature.getSize() + this.proposerSignature.getSize();
106
+ }
107
+ toInspect() {
108
+ return {
109
+ blockNumber: this.blockNumber,
110
+ payload: this.payload.toInspect(),
111
+ signature: this.signature.toString(),
112
+ proposerSignature: this.proposerSignature.toString()
113
+ };
80
114
  }
81
115
  }
@@ -2,7 +2,7 @@ import { Fr } from '@aztec/foundation/fields';
2
2
  import { schemas } from '@aztec/foundation/schemas';
3
3
  import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
4
4
  import { hexToBuffer } from '@aztec/foundation/string';
5
- import { encodeAbiParameters, parseAbiParameters } from 'viem';
5
+ import { encodeAbiParameters, parseAbiParameters } from '@spalladino/viem';
6
6
  import { z } from 'zod';
7
7
  import { ProposedBlockHeader, StateReference } from '../tx/index.js';
8
8
  export class ConsensusPayload {
@@ -1,11 +1,9 @@
1
1
  import { Buffer32 } from '@aztec/foundation/buffer';
2
2
  import type { TopicType } from './topic_type.js';
3
3
  export declare class P2PMessage {
4
- readonly publishTime: Date;
5
- readonly id: Buffer32;
6
4
  readonly payload: Buffer;
7
- constructor(publishTime: Date, id: Buffer32, payload: Buffer);
8
- static fromGossipable(message: Gossipable): Promise<P2PMessage>;
5
+ constructor(payload: Buffer);
6
+ static fromGossipable(message: Gossipable): P2PMessage;
9
7
  static fromMessageData(messageData: Buffer): P2PMessage;
10
8
  toMessageData(): Buffer;
11
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"gossipable.d.ts","sourceRoot":"","sources":["../../src/p2p/gossipable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAGpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,qBAAa,UAAU;aAEH,WAAW,EAAE,IAAI;aACjB,EAAE,EAAE,QAAQ;aACZ,OAAO,EAAE,MAAM;gBAFf,WAAW,EAAE,IAAI,EACjB,EAAE,EAAE,QAAQ,EACZ,OAAO,EAAE,MAAM;WAGpB,cAAc,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAIrE,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU;IAQvD,aAAa,IAAI,MAAM;CAOxB;AAED;;;;GAIG;AACH,8BAAsB,UAAU;IAC9B,OAAO,CAAC,QAAQ,CAAuB;IACvC;;;OAGG;IACH,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC;IAE3B;;;OAGG;IACG,oBAAoB,IAAI,OAAO,CAAC,QAAQ,CAAC;IAQ/C,QAAQ,CAAC,4BAA4B,IAAI,OAAO,CAAC,QAAQ,CAAC;IAE1D;;;OAGG;IACH,QAAQ,CAAC,QAAQ,IAAI,MAAM;IAE3B,SAAS,IAAI,MAAM;IAInB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,IAAI,MAAM;CAC3B"}
1
+ {"version":3,"file":"gossipable.d.ts","sourceRoot":"","sources":["../../src/p2p/gossipable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAGpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,qBAAa,UAAU;aACO,OAAO,EAAE,MAAM;gBAAf,OAAO,EAAE,MAAM;IAE3C,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU;IAItD,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU;IAMvD,aAAa,IAAI,MAAM;CAGxB;AAED;;;;GAIG;AACH,8BAAsB,UAAU;IAC9B,OAAO,CAAC,QAAQ,CAAuB;IACvC;;;OAGG;IACH,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC;IAE3B;;;OAGG;IACG,oBAAoB,IAAI,OAAO,CAAC,QAAQ,CAAC;IAQ/C,QAAQ,CAAC,4BAA4B,IAAI,OAAO,CAAC,QAAQ,CAAC;IAE1D;;;OAGG;IACH,QAAQ,CAAC,QAAQ,IAAI,MAAM;IAE3B,SAAS,IAAI,MAAM;IAInB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,IAAI,MAAM;CAC3B"}
@@ -1,28 +1,19 @@
1
- import { Buffer32 } from '@aztec/foundation/buffer';
2
- import { BufferReader, bigintToUInt64BE, serializeToBuffer } from '@aztec/foundation/serialize';
1
+ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
3
2
  export class P2PMessage {
4
- publishTime;
5
- id;
6
3
  payload;
7
- constructor(publishTime, id, payload){
8
- this.publishTime = publishTime;
9
- this.id = id;
4
+ constructor(payload){
10
5
  this.payload = payload;
11
6
  }
12
- static async fromGossipable(message) {
13
- return new P2PMessage(new Date(), await message.p2pMessageIdentifier(), message.toBuffer());
7
+ static fromGossipable(message) {
8
+ return new P2PMessage(message.toBuffer());
14
9
  }
15
10
  static fromMessageData(messageData) {
16
11
  const reader = new BufferReader(messageData);
17
- const publishTime = reader.readUInt64();
18
- const id = Buffer32.fromBuffer(reader);
19
12
  const payload = reader.readBuffer();
20
- return new P2PMessage(new Date(Number(publishTime)), id, payload);
13
+ return new P2PMessage(payload);
21
14
  }
22
15
  toMessageData() {
23
16
  return serializeToBuffer([
24
- bigintToUInt64BE(BigInt(this.publishTime.getTime())),
25
- this.id,
26
17
  serializeToBuffer(this.payload.length, this.payload)
27
18
  ]);
28
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/snapshots/download.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EACL,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAE5B,MAAM,YAAY,CAAC;AAEpB,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,sBAAsB,EAChC,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAarC;AAED,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,sBAAsB,EAChC,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAGvC;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,sBAAsB,GAAG,MAAM,CAEpE;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,sBAAsB,GAAG,MAAM,CAE7E;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAGnE;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,EAC5C,UAAU,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAC5C,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf"}
1
+ {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/snapshots/download.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAQlE,OAAO,EACL,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAE5B,MAAM,YAAY,CAAC;AAEpB,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,sBAAsB,EAChC,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAcrC;AAED,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,sBAAsB,EAChC,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAGvC;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,sBAAsB,GAAG,MAAM,CAEpE;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,sBAAsB,GAAG,MAAM,CAE7E;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAGnE;AAoCD,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,EAC5C,UAAU,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAC5C,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,IAAI,CAAC,CAyBf"}
@@ -1,5 +1,10 @@
1
1
  import { fromEntries, getEntries, maxBy } from '@aztec/foundation/collection';
2
2
  import { jsonParseWithSchema } from '@aztec/foundation/json-rpc';
3
+ import { createReadStream, createWriteStream } from 'fs';
4
+ import fs from 'fs/promises';
5
+ import pathMod from 'path';
6
+ import { pipeline } from 'stream/promises';
7
+ import { createGunzip, gunzipSync } from 'zlib';
3
8
  import { SnapshotDataKeys, SnapshotsIndexSchema } from './types.js';
4
9
  export async function getSnapshotIndex(metadata, store) {
5
10
  const basePath = getBasePath(metadata);
@@ -7,7 +12,8 @@ export async function getSnapshotIndex(metadata, store) {
7
12
  try {
8
13
  if (await store.exists(snapshotIndexPath)) {
9
14
  const snapshotIndexData = await store.read(snapshotIndexPath);
10
- return jsonParseWithSchema(snapshotIndexData.toString(), SnapshotsIndexSchema);
15
+ const buf = maybeGunzip(snapshotIndexData);
16
+ return jsonParseWithSchema(buf.toString('utf-8'), SnapshotsIndexSchema);
11
17
  } else {
12
18
  return undefined;
13
19
  }
@@ -32,6 +38,56 @@ export function makeSnapshotPaths(baseDir) {
32
38
  `${baseDir}/${key}.db`
33
39
  ]));
34
40
  }
41
+ function isGzipMagic(data) {
42
+ return data.length >= 2 && data[0] === 0x1f && data[1] === 0x8b;
43
+ }
44
+ function maybeGunzip(data) {
45
+ const magicNumberIndicatesGzip = isGzipMagic(data);
46
+ if (magicNumberIndicatesGzip) {
47
+ try {
48
+ const out = gunzipSync(data);
49
+ return out;
50
+ } catch (err) {
51
+ throw new Error(`Decompression of gzipped data failed: ${err.message}`);
52
+ }
53
+ }
54
+ return data;
55
+ }
56
+ async function detectGzip(localFilePathToPeek) {
57
+ // Peek the actual bytes we downloaded.
58
+ try {
59
+ const fd = await fs.open(localFilePathToPeek, 'r');
60
+ try {
61
+ const header = Buffer.alloc(2);
62
+ const { bytesRead } = await fd.read(header, 0, 2, 0);
63
+ return bytesRead >= 2 && isGzipMagic(header);
64
+ } finally{
65
+ await fd.close();
66
+ }
67
+ } catch {
68
+ return false;
69
+ }
70
+ }
35
71
  export async function downloadSnapshot(snapshot, localPaths, store) {
36
- await Promise.all(getEntries(localPaths).map(([key, path])=>store.download(snapshot.dataUrls[key], path)));
72
+ await Promise.all(getEntries(localPaths).map(async ([key, path])=>{
73
+ await fs.mkdir(pathMod.dirname(path), {
74
+ recursive: true
75
+ });
76
+ const tmpPath = `${path}.download`;
77
+ try {
78
+ const url = snapshot.dataUrls[key];
79
+ await store.download(url, tmpPath);
80
+ const isGzip = await detectGzip(tmpPath);
81
+ const read = createReadStream(tmpPath);
82
+ const write = createWriteStream(path);
83
+ if (isGzip) {
84
+ const gunzip = createGunzip();
85
+ await pipeline(read, gunzip, write);
86
+ } else {
87
+ await pipeline(read, write);
88
+ }
89
+ } finally{
90
+ await fs.unlink(tmpPath).catch(()=>undefined);
91
+ }
92
+ }));
37
93
  }
@@ -1 +1 @@
1
- {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/snapshots/upload.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAG1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAkB,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAE7G,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAC5C,cAAc,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,EAClD,QAAQ,EAAE,sBAAsB,EAChC,KAAK,EAAE,SAAS,EAChB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAC5E,OAAO,CAAC,gBAAgB,CAAC,CAsB3B;AAED,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAC5C,cAAc,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,EAClD,QAAQ,EAAE,sBAAsB,EAChC,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,gBAAgB,CAAC,CAU3B"}
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/snapshots/upload.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAG1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAkB,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAE7G,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAC5C,cAAc,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,EAClD,QAAQ,EAAE,sBAAsB,EAChC,KAAK,EAAE,SAAS,EAChB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAC5E,OAAO,CAAC,gBAAgB,CAAC,CAsB3B;AAED,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAC5C,cAAc,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,EAClD,QAAQ,EAAE,sBAAsB,EAChC,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,gBAAgB,CAAC,CAW3B"}
@@ -27,6 +27,7 @@ export async function uploadSnapshotToIndex(localPaths, schemaVersions, metadata
27
27
  snapshotsIndex.snapshots.unshift(newSnapshotMetadata);
28
28
  await store.save(getSnapshotIndexPath(metadata), Buffer.from(jsonStringify(snapshotsIndex, true)), {
29
29
  public: true,
30
+ compress: false,
30
31
  metadata: {
31
32
  ['Cache-control']: 'no-store'
32
33
  }
@@ -43,6 +43,8 @@ export declare const randomDeployedContract: () => Promise<{
43
43
  }>;
44
44
  export interface MakeConsensusPayloadOptions {
45
45
  signer?: Secp256k1Signer;
46
+ attesterSigner?: Secp256k1Signer;
47
+ proposerSigner?: Secp256k1Signer;
46
48
  header?: BlockHeader;
47
49
  archive?: Fr;
48
50
  stateReference?: StateReference;
@@ -52,7 +54,7 @@ export interface MakeConsensusPayloadOptions {
52
54
  export declare const makeAndSignCommitteeAttestationsAndSigners: (attestationsAndSigners: CommitteeAttestationsAndSigners, signer?: Secp256k1Signer) => import("../block/index.js").Signature;
53
55
  export declare const makeBlockProposal: (options?: MakeConsensusPayloadOptions) => BlockProposal;
54
56
  export declare const makeBlockAttestation: (options?: MakeConsensusPayloadOptions) => BlockAttestation;
55
- export declare const makeBlockAttestationFromBlock: (block: L2Block, signer?: Secp256k1Signer) => BlockAttestation;
57
+ export declare const makeBlockAttestationFromBlock: (block: L2Block, attesterSigner?: Secp256k1Signer, proposerSigner?: Secp256k1Signer) => BlockAttestation;
56
58
  export declare function randomPublishedL2Block(l2BlockNumber: number, opts?: {
57
59
  signers?: Secp256k1Signer[];
58
60
  }): Promise<PublishedL2Block>;
@@ -1 +1 @@
1
- {"version":3,"file":"mocks.d.ts","sourceRoot":"","sources":["../../src/tests/mocks.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAe,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,+CAA+C,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAIlE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAS7C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EACL,WAAW,EAIX,cAAc,EACd,EAAE,EACH,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAiC,MAAM,uBAAuB,CAAC;AAE1F,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG1C,eAAO,MAAM,YAAY,QAAO,MAAyB,CAAC;AAE1D,eAAO,MAAM,kBAAkB,GAAU,6DAMtC,OAAO,CAAC,YAAY,CAAM,0BAQ5B,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAU,wEAOpC,OAAO,CAAC,UAAU,CAAM,wBAS1B,CAAC;AAEF,eAAO,MAAM,MAAM,GACjB,aAAQ,EACR,8QAaG;IACD,uCAAuC,CAAC,EAAE,MAAM,CAAC;IACjD,oCAAoC,CAAC,EAAE,MAAM,CAAC;IAC9C,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,OAAO,CAAC,EAAE,EAAE,CAAC;IACb,OAAO,CAAC,EAAE,EAAE,CAAC;IACb,UAAU,CAAC,EAAE,EAAE,CAAC;IAChB,wBAAwB,CAAC,EAAE,EAAE,CAAC;CAC1B,gBAiEP,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,aAAQ,EAAE,OAAM,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAM,gBAC+B,CAAC;AAmBjH,eAAO,MAAM,eAAe,GAAU,aAAQ,gCAgB7C,CAAC;AAEF,eAAO,MAAM,sBAAsB,QAAO,gBAUxC,CAAC;AAEH,eAAO,MAAM,iCAAiC,GAC5C,OAAM;IAAE,eAAe,CAAC,EAAE,EAAE,CAAA;CAAO,EACnC,UAAU,YAAY,KACrB,OAAO,CAAC,2BAA2B,CAUrC,CAAC;AAEF,eAAO,MAAM,sBAAsB;;;EAIlC,CAAC;AAEF,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,EAAE,CAAC;IACb,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC;CACZ;AAqBD,eAAO,MAAM,0CAA0C,GACrD,wBAAwB,+BAA+B,EACvD,SAAQ,eAA0C,0CAOnD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,UAAU,2BAA2B,KAAG,aAOzE,CAAC;AAGF,eAAO,MAAM,oBAAoB,GAAI,UAAU,2BAA2B,KAAG,gBAM5E,CAAC;AAEF,eAAO,MAAM,6BAA6B,GAAI,OAAO,OAAO,EAAE,SAAS,eAAe,KAAG,gBAQxF,CAAC;AAEF,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,MAAM,EACrB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,eAAe,EAAE,CAAA;CAAO,GACzC,OAAO,CAAC,gBAAgB,CAAC,CAc3B"}
1
+ {"version":3,"file":"mocks.d.ts","sourceRoot":"","sources":["../../src/tests/mocks.ts"],"names":[],"mappings":"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"}
@@ -166,17 +166,39 @@ export const makeBlockProposal = (options)=>{
166
166
  };
167
167
  // TODO(https://github.com/AztecProtocol/aztec-packages/issues/8028)
168
168
  export const makeBlockAttestation = (options)=>{
169
- const { blockNumber, payload, signature } = makeAndSignConsensusPayload(SignatureDomainSeparator.blockAttestation, options);
170
- return new BlockAttestation(blockNumber, payload, signature);
169
+ const header = options?.header ?? makeHeader(1);
170
+ const { signer, attesterSigner = signer ?? Secp256k1Signer.random(), proposerSigner = signer ?? Secp256k1Signer.random(), archive = Fr.random(), stateReference = header.state } = options ?? {};
171
+ const payload = ConsensusPayload.fromFields({
172
+ header: header.toPropose(),
173
+ archive,
174
+ stateReference
175
+ });
176
+ // Sign as attester
177
+ const attestationHash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockAttestation);
178
+ const attestationSignature = attesterSigner.sign(attestationHash);
179
+ // Sign as proposer
180
+ const proposalHash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockProposal);
181
+ const proposerSignature = proposerSigner.sign(proposalHash);
182
+ return new BlockAttestation(header.globalVariables.blockNumber, payload, attestationSignature, proposerSignature);
171
183
  };
172
- export const makeBlockAttestationFromBlock = (block, signer)=>{
173
- return makeBlockAttestation({
174
- signer,
175
- header: block.header,
176
- archive: block.archive.root,
177
- stateReference: block.header.state,
178
- txHashes: block.body.txEffects.map((tx)=>tx.txHash)
184
+ export const makeBlockAttestationFromBlock = (block, attesterSigner, proposerSigner)=>{
185
+ const header = block.header;
186
+ const archive = block.archive.root;
187
+ const stateReference = block.header.state;
188
+ const payload = ConsensusPayload.fromFields({
189
+ header: header.toPropose(),
190
+ archive,
191
+ stateReference
179
192
  });
193
+ // Sign as attester
194
+ const attestationHash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockAttestation);
195
+ const attestationSigner = attesterSigner ?? Secp256k1Signer.random();
196
+ const attestationSignature = attestationSigner.sign(attestationHash);
197
+ // Sign as proposer
198
+ const proposalHash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockProposal);
199
+ const proposalSignerToUse = proposerSigner ?? Secp256k1Signer.random();
200
+ const proposerSignature = proposalSignerToUse.sign(proposalHash);
201
+ return new BlockAttestation(header.globalVariables.blockNumber, payload, attestationSignature, proposerSignature);
180
202
  };
181
203
  export async function randomPublishedL2Block(l2BlockNumber, opts = {}) {
182
204
  const block = await L2Block.random(l2BlockNumber);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/stdlib",
3
- "version": "2.1.0-rc.1",
3
+ "version": "2.1.0-rc.11",
4
4
  "type": "module",
5
5
  "inherits": [
6
6
  "../package.common.json",
@@ -69,14 +69,16 @@
69
69
  "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
70
70
  },
71
71
  "dependencies": {
72
- "@aztec/bb.js": "2.1.0-rc.1",
73
- "@aztec/blob-lib": "2.1.0-rc.1",
74
- "@aztec/constants": "2.1.0-rc.1",
75
- "@aztec/ethereum": "2.1.0-rc.1",
76
- "@aztec/foundation": "2.1.0-rc.1",
77
- "@aztec/l1-artifacts": "2.1.0-rc.1",
78
- "@aztec/noir-noirc_abi": "2.1.0-rc.1",
72
+ "@aws-sdk/client-s3": "^3.892.0",
73
+ "@aztec/bb.js": "2.1.0-rc.11",
74
+ "@aztec/blob-lib": "2.1.0-rc.11",
75
+ "@aztec/constants": "2.1.0-rc.11",
76
+ "@aztec/ethereum": "2.1.0-rc.11",
77
+ "@aztec/foundation": "2.1.0-rc.11",
78
+ "@aztec/l1-artifacts": "2.1.0-rc.11",
79
+ "@aztec/noir-noirc_abi": "2.1.0-rc.11",
79
80
  "@google-cloud/storage": "^7.15.0",
81
+ "@spalladino/viem": "2.38.2-eip7594.0",
80
82
  "axios": "^1.12.0",
81
83
  "json-stringify-deterministic": "1.0.12",
82
84
  "lodash.chunk": "^4.2.0",
@@ -86,7 +88,6 @@
86
88
  "msgpackr": "^1.11.2",
87
89
  "pako": "^2.1.0",
88
90
  "tslib": "^2.4.0",
89
- "viem": "2.23.7",
90
91
  "zod": "^3.23.8"
91
92
  },
92
93
  "devDependencies": {
@@ -0,0 +1,62 @@
1
+ import { recoverAddress } from '@aztec/foundation/crypto';
2
+ import type { EthAddress } from '@aztec/foundation/eth-address';
3
+
4
+ import { ConsensusPayload } from '../p2p/consensus_payload.js';
5
+ import { SignatureDomainSeparator, getHashedSignaturePayloadEthSignedMessage } from '../p2p/signature_utils.js';
6
+ import type { L2Block } from './l2_block.js';
7
+ import type { CommitteeAttestation } from './proposal/committee_attestation.js';
8
+
9
+ /**
10
+ * Status indicating how the attestation address was determined
11
+ */
12
+ export type AttestationStatus = 'recovered-from-signature' | 'provided-as-address' | 'invalid-signature' | 'empty';
13
+
14
+ /**
15
+ * Information about an attestation extracted from a published block
16
+ */
17
+ export type AttestationInfo =
18
+ | {
19
+ /** The validator's address, undefined if signature recovery failed or empty */
20
+ address?: undefined;
21
+ /** How the attestation address was determined */
22
+ status: Extract<AttestationStatus, 'invalid-signature' | 'empty'>;
23
+ }
24
+ | {
25
+ /** The validator's address */
26
+ address: EthAddress;
27
+ /** How the attestation address was determined */
28
+ status: Extract<AttestationStatus, 'provided-as-address' | 'recovered-from-signature'>;
29
+ };
30
+
31
+ /**
32
+ * Extracts attestation information from a published L2 block.
33
+ * Returns info for each attestation, preserving array indices.
34
+ */
35
+ export function getAttestationInfoFromPublishedL2Block(block: {
36
+ attestations: CommitteeAttestation[];
37
+ block: L2Block;
38
+ }): AttestationInfo[] {
39
+ const payload = ConsensusPayload.fromBlock(block.block);
40
+ const hashedPayload = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockAttestation);
41
+
42
+ return block.attestations.map(attestation => {
43
+ // If signature is empty, check if we have an address directly
44
+ if (attestation.signature.isEmpty()) {
45
+ if (attestation.address.isZero()) {
46
+ // No signature and no address - empty
47
+ return { status: 'empty' as const };
48
+ }
49
+ // Address provided without signature
50
+ return { address: attestation.address, status: 'provided-as-address' as const };
51
+ }
52
+
53
+ // Try to recover address from signature
54
+ try {
55
+ const recoveredAddress = recoverAddress(hashedPayload, attestation.signature);
56
+ return { address: recoveredAddress, status: 'recovered-from-signature' as const };
57
+ } catch {
58
+ // Signature present but recovery failed
59
+ return { status: 'invalid-signature' as const };
60
+ }
61
+ });
62
+ }
@@ -9,3 +9,4 @@ export * from './published_l2_block.js';
9
9
  export * from './proposal/index.js';
10
10
  export * from './validate_block_result.js';
11
11
  export * from './l2_block_info.js';
12
+ export * from './attestation_info.js';
@@ -1,7 +1,7 @@
1
1
  import type { ViemCommitteeAttestations } from '@aztec/ethereum';
2
2
  import { hexToBuffer } from '@aztec/foundation/string';
3
3
 
4
- import { encodeAbiParameters, parseAbiParameters } from 'viem';
4
+ import { encodeAbiParameters, parseAbiParameters } from '@spalladino/viem';
5
5
  import { z } from 'zod';
6
6
 
7
7
  import type { Signable, SignatureDomainSeparator } from '../../p2p/signature_utils.js';
@@ -7,8 +7,6 @@ import type { FieldsOf } from '@aztec/foundation/types';
7
7
 
8
8
  import { z } from 'zod';
9
9
 
10
- import { BlockAttestation } from '../p2p/block_attestation.js';
11
- import { ConsensusPayload } from '../p2p/consensus_payload.js';
12
10
  import { L2Block } from './l2_block.js';
13
11
  import { CommitteeAttestation } from './proposal/committee_attestation.js';
14
12
 
@@ -82,12 +80,3 @@ export class PublishedL2Block {
82
80
  );
83
81
  }
84
82
  }
85
-
86
- export function getAttestationsFromPublishedL2Block(
87
- block: Pick<PublishedL2Block, 'attestations' | 'block'>,
88
- ): BlockAttestation[] {
89
- const payload = ConsensusPayload.fromBlock(block.block);
90
- return block.attestations
91
- .filter(attestation => !attestation.signature.isEmpty())
92
- .map(attestation => new BlockAttestation(block.block.number, payload, attestation.signature));
93
- }
@@ -118,3 +118,11 @@ export function getProofSubmissionDeadlineTimestamp(
118
118
  const [deadlineSlot] = getSlotRangeForEpoch(deadlineEpoch, constants);
119
119
  return getTimestampForSlot(deadlineSlot, constants);
120
120
  }
121
+
122
+ /** 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. */
123
+ export function getSlotStartBuildTimestamp(
124
+ slotNumber: number | bigint,
125
+ constants: Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration' | 'ethereumSlotDuration'>,
126
+ ): number {
127
+ return Number(constants.l1GenesisTime) + Number(slotNumber) * constants.slotDuration - constants.ethereumSlotDuration;
128
+ }