@aztec/stdlib 2.0.3 → 2.1.0-rc.2

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 (77) hide show
  1. package/dest/block/in_block.d.ts +5 -5
  2. package/dest/block/in_block.d.ts.map +1 -1
  3. package/dest/block/proposal/attestations_and_signers.d.ts +48 -0
  4. package/dest/block/proposal/attestations_and_signers.d.ts.map +1 -0
  5. package/dest/block/proposal/attestations_and_signers.js +99 -0
  6. package/dest/block/proposal/committee_attestation.d.ts +1 -0
  7. package/dest/block/proposal/committee_attestation.d.ts.map +1 -1
  8. package/dest/block/proposal/committee_attestation.js +3 -0
  9. package/dest/block/proposal/index.d.ts +1 -0
  10. package/dest/block/proposal/index.d.ts.map +1 -1
  11. package/dest/block/proposal/index.js +1 -0
  12. package/dest/contract/interfaces/contract_class.d.ts +3 -3
  13. package/dest/epoch-helpers/index.d.ts +2 -0
  14. package/dest/epoch-helpers/index.d.ts.map +1 -1
  15. package/dest/epoch-helpers/index.js +3 -0
  16. package/dest/file-store/factory.d.ts.map +1 -1
  17. package/dest/file-store/factory.js +18 -0
  18. package/dest/file-store/interface.d.ts +8 -2
  19. package/dest/file-store/interface.d.ts.map +1 -1
  20. package/dest/file-store/s3.d.ts +26 -0
  21. package/dest/file-store/s3.d.ts.map +1 -0
  22. package/dest/file-store/s3.js +252 -0
  23. package/dest/interfaces/aztec-node-admin.d.ts +13 -7
  24. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  25. package/dest/interfaces/block-builder.d.ts +1 -0
  26. package/dest/interfaces/block-builder.d.ts.map +1 -1
  27. package/dest/interfaces/proving-job.d.ts +6 -6
  28. package/dest/interfaces/slasher.d.ts +4 -0
  29. package/dest/interfaces/slasher.d.ts.map +1 -1
  30. package/dest/interfaces/slasher.js +1 -0
  31. package/dest/interfaces/validator.d.ts +9 -2
  32. package/dest/interfaces/validator.d.ts.map +1 -1
  33. package/dest/interfaces/validator.js +2 -1
  34. package/dest/p2p/consensus_payload.d.ts +27 -0
  35. package/dest/p2p/consensus_payload.d.ts.map +1 -1
  36. package/dest/p2p/consensus_payload.js +10 -0
  37. package/dest/p2p/signature_utils.d.ts +2 -1
  38. package/dest/p2p/signature_utils.d.ts.map +1 -1
  39. package/dest/p2p/signature_utils.js +1 -0
  40. package/dest/slashing/types.d.ts +1 -0
  41. package/dest/slashing/types.d.ts.map +1 -1
  42. package/dest/slashing/types.js +22 -0
  43. package/dest/snapshots/download.d.ts.map +1 -1
  44. package/dest/snapshots/download.js +58 -2
  45. package/dest/snapshots/upload.d.ts.map +1 -1
  46. package/dest/snapshots/upload.js +1 -0
  47. package/dest/tests/mocks.d.ts +2 -0
  48. package/dest/tests/mocks.d.ts.map +1 -1
  49. package/dest/tests/mocks.js +4 -0
  50. package/dest/tx/indexed_tx_effect.d.ts +3 -3
  51. package/dest/tx/proposed_block_header.d.ts +1 -0
  52. package/dest/tx/proposed_block_header.d.ts.map +1 -1
  53. package/dest/tx/proposed_block_header.js +3 -0
  54. package/dest/tx/state_reference.js +1 -1
  55. package/dest/tx/tx.d.ts +0 -7
  56. package/dest/tx/tx.d.ts.map +1 -1
  57. package/dest/tx/tx.js +0 -8
  58. package/package.json +10 -9
  59. package/src/block/proposal/attestations_and_signers.ts +121 -0
  60. package/src/block/proposal/committee_attestation.ts +4 -0
  61. package/src/block/proposal/index.ts +1 -0
  62. package/src/epoch-helpers/index.ts +8 -0
  63. package/src/file-store/factory.ts +15 -0
  64. package/src/file-store/interface.ts +8 -2
  65. package/src/file-store/s3.ts +254 -0
  66. package/src/interfaces/block-builder.ts +1 -0
  67. package/src/interfaces/slasher.ts +2 -0
  68. package/src/interfaces/validator.ts +12 -2
  69. package/src/p2p/consensus_payload.ts +16 -0
  70. package/src/p2p/signature_utils.ts +1 -0
  71. package/src/slashing/types.ts +23 -0
  72. package/src/snapshots/download.ts +66 -2
  73. package/src/snapshots/upload.ts +1 -0
  74. package/src/tests/mocks.ts +12 -0
  75. package/src/tx/proposed_block_header.ts +13 -0
  76. package/src/tx/state_reference.ts +1 -1
  77. package/src/tx/tx.ts +0 -10
@@ -1 +1 @@
1
- {"version":3,"file":"proposed_block_header.d.ts","sourceRoot":"","sources":["../../src/tx/proposed_block_header.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAuC,MAAM,6BAA6B,CAAC;AAEhG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAG/B,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,0CAA0C;AAC1C,qBAAa,mBAAmB;IAE5B,2DAA2D;IACpD,eAAe,EAAE,EAAE;IAC1B,0CAA0C;IACnC,iBAAiB,EAAE,iBAAiB;IAC3C,kCAAkC;IAC3B,UAAU,EAAE,EAAE;IACrB,iCAAiC;IAC1B,SAAS,EAAE,MAAM;IACxB,iCAAiC;IAC1B,QAAQ,EAAE,UAAU;IAC3B,+BAA+B;IACxB,YAAY,EAAE,YAAY;IACjC,wCAAwC;IACjC,OAAO,EAAE,OAAO;IACvB,wEAAwE;IACjE,aAAa,EAAE,EAAE;;IAfxB,2DAA2D;IACpD,eAAe,EAAE,EAAE;IAC1B,0CAA0C;IACnC,iBAAiB,EAAE,iBAAiB;IAC3C,kCAAkC;IAC3B,UAAU,EAAE,EAAE;IACrB,iCAAiC;IAC1B,SAAS,EAAE,MAAM;IACxB,iCAAiC;IAC1B,QAAQ,EAAE,UAAU;IAC3B,+BAA+B;IACxB,YAAY,EAAE,YAAY;IACjC,wCAAwC;IACjC,OAAO,EAAE,OAAO;IACvB,wEAAwE;IACjE,aAAa,EAAE,EAAE;IAG1B,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,mBAAmB,CAAC,CAa/C;IAED,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,mBAAmB,CAAC;IAatD,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,mBAAmB,CAAC;IAIjD,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,mBAAmB;IAerE,QAAQ;IAcR,IAAI,IAAI,EAAE;IAIV,MAAM,CAAC,KAAK,CAAC,MAAM,GAAE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAM,GAAG,mBAAmB;IActF,MAAM,CAAC,MAAM,IAAI,mBAAmB;IAapC,OAAO,IAAI,OAAO;IAalB;;;OAGG;IACI,QAAQ;IAIf,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB;IAInD,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU;IAalC,MAAM,IAAI,UAAU;IAgBpB,SAAS;;;;;;;;;;;;;;;;;IAaT,CAAC,OAAO,CAAC,MAAM,CAAC;CAajB"}
1
+ {"version":3,"file":"proposed_block_header.d.ts","sourceRoot":"","sources":["../../src/tx/proposed_block_header.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAuC,MAAM,6BAA6B,CAAC;AAEhG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAG/B,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,0CAA0C;AAC1C,qBAAa,mBAAmB;IAE5B,2DAA2D;IACpD,eAAe,EAAE,EAAE;IAC1B,0CAA0C;IACnC,iBAAiB,EAAE,iBAAiB;IAC3C,kCAAkC;IAC3B,UAAU,EAAE,EAAE;IACrB,iCAAiC;IAC1B,SAAS,EAAE,MAAM;IACxB,iCAAiC;IAC1B,QAAQ,EAAE,UAAU;IAC3B,+BAA+B;IACxB,YAAY,EAAE,YAAY;IACjC,wCAAwC;IACjC,OAAO,EAAE,OAAO;IACvB,wEAAwE;IACjE,aAAa,EAAE,EAAE;;IAfxB,2DAA2D;IACpD,eAAe,EAAE,EAAE;IAC1B,0CAA0C;IACnC,iBAAiB,EAAE,iBAAiB;IAC3C,kCAAkC;IAC3B,UAAU,EAAE,EAAE;IACrB,iCAAiC;IAC1B,SAAS,EAAE,MAAM;IACxB,iCAAiC;IAC1B,QAAQ,EAAE,UAAU;IAC3B,+BAA+B;IACxB,YAAY,EAAE,YAAY;IACjC,wCAAwC;IACjC,OAAO,EAAE,OAAO;IACvB,wEAAwE;IACjE,aAAa,EAAE,EAAE;IAG1B,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,mBAAmB,CAAC,CAa/C;IAED,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,mBAAmB,CAAC;IAatD,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,mBAAmB,CAAC;IAIjD,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,mBAAmB;IAerE,MAAM,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO;IAa3C,QAAQ;IAcR,IAAI,IAAI,EAAE;IAIV,MAAM,CAAC,KAAK,CAAC,MAAM,GAAE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAM,GAAG,mBAAmB;IActF,MAAM,CAAC,MAAM,IAAI,mBAAmB;IAapC,OAAO,IAAI,OAAO;IAalB;;;OAGG;IACI,QAAQ;IAIf,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB;IAInD,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU;IAalC,MAAM,IAAI,UAAU;IAgBpB,SAAS;;;;;;;;;;;;;;;;;IAaT,CAAC,OAAO,CAAC,MAAM,CAAC;CAajB"}
@@ -59,6 +59,9 @@ import { ContentCommitment } from './content_commitment.js';
59
59
  const reader = BufferReader.asReader(buffer);
60
60
  return new ProposedBlockHeader(reader.readObject(Fr), reader.readObject(ContentCommitment), Fr.fromBuffer(reader), reader.readUInt64(), reader.readObject(EthAddress), reader.readObject(AztecAddress), reader.readObject(GasFees), reader.readObject(Fr));
61
61
  }
62
+ equals(other) {
63
+ return this.lastArchiveRoot.equals(other.lastArchiveRoot) && this.contentCommitment.equals(other.contentCommitment) && this.slotNumber.equals(other.slotNumber) && this.timestamp === other.timestamp && this.coinbase.equals(other.coinbase) && this.feeRecipient.equals(other.feeRecipient) && this.gasFees.equals(other.gasFees) && this.totalManaUsed.equals(other.totalManaUsed);
64
+ }
62
65
  toBuffer() {
63
66
  // Note: The order here must match the order in the ProposedHeaderLib solidity library.
64
67
  return serializeToBuffer([
@@ -102,6 +102,6 @@ import { PartialStateReference } from './partial_state_reference.js';
102
102
  }`;
103
103
  }
104
104
  equals(other) {
105
- return this.l1ToL2MessageTree.root.equals(other.l1ToL2MessageTree.root) && this.partial.equals(other.partial);
105
+ return this.l1ToL2MessageTree.equals(other.l1ToL2MessageTree) && this.partial.equals(other.partial);
106
106
  }
107
107
  }
package/dest/tx/tx.d.ts CHANGED
@@ -107,13 +107,6 @@ export declare class Tx extends Gossipable {
107
107
  * @returns The hash of the public inputs of the private kernel tail circuit.
108
108
  */
109
109
  getTxHash(): TxHash;
110
- /**
111
- * Allows setting the hash of the Tx.
112
- * Use this when you want to skip computing it from the original data.
113
- * Don't set a Tx hash received from an untrusted source.
114
- * @param hash - The hash to set.
115
- */
116
- setTxHash(_hash: TxHash): this;
117
110
  getCalldataMap(): Map<string, Fr[]>;
118
111
  /** Returns stats about this tx. */
119
112
  getStats(): TxStats;
@@ -1 +1 @@
1
- {"version":3,"file":"tx.d.ts","sourceRoot":"","sources":["../../src/tx/tx.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tx.d.ts","sourceRoot":"","sources":["../../src/tx/tx.ts"],"names":[],"mappings":"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"}
package/dest/tx/tx.js CHANGED
@@ -149,14 +149,6 @@ import { TxHash } from './tx_hash.js';
149
149
  */ getTxHash() {
150
150
  return this.txHash;
151
151
  }
152
- /**
153
- * Allows setting the hash of the Tx.
154
- * Use this when you want to skip computing it from the original data.
155
- * Don't set a Tx hash received from an untrusted source.
156
- * @param hash - The hash to set.
157
- */ setTxHash(_hash) {
158
- return this;
159
- }
160
152
  getCalldataMap() {
161
153
  if (!this.calldataMap) {
162
154
  const calldataMap = new Map();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/stdlib",
3
- "version": "2.0.3",
3
+ "version": "2.1.0-rc.2",
4
4
  "type": "module",
5
5
  "inherits": [
6
6
  "../package.common.json",
@@ -69,15 +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.0.3",
73
- "@aztec/blob-lib": "2.0.3",
74
- "@aztec/constants": "2.0.3",
75
- "@aztec/ethereum": "2.0.3",
76
- "@aztec/foundation": "2.0.3",
77
- "@aztec/l1-artifacts": "2.0.3",
78
- "@aztec/noir-noirc_abi": "2.0.3",
72
+ "@aws-sdk/client-s3": "^3.892.0",
73
+ "@aztec/bb.js": "2.1.0-rc.2",
74
+ "@aztec/blob-lib": "2.1.0-rc.2",
75
+ "@aztec/constants": "2.1.0-rc.2",
76
+ "@aztec/ethereum": "2.1.0-rc.2",
77
+ "@aztec/foundation": "2.1.0-rc.2",
78
+ "@aztec/l1-artifacts": "2.1.0-rc.2",
79
+ "@aztec/noir-noirc_abi": "2.1.0-rc.2",
79
80
  "@google-cloud/storage": "^7.15.0",
80
- "axios": "^1.9.0",
81
+ "axios": "^1.12.0",
81
82
  "json-stringify-deterministic": "1.0.12",
82
83
  "lodash.chunk": "^4.2.0",
83
84
  "lodash.isequal": "^4.5.0",
@@ -0,0 +1,121 @@
1
+ import type { ViemCommitteeAttestations } from '@aztec/ethereum';
2
+ import { hexToBuffer } from '@aztec/foundation/string';
3
+
4
+ import { encodeAbiParameters, parseAbiParameters } from 'viem';
5
+ import { z } from 'zod';
6
+
7
+ import type { Signable, SignatureDomainSeparator } from '../../p2p/signature_utils.js';
8
+ import { CommitteeAttestation } from './committee_attestation.js';
9
+
10
+ export class CommitteeAttestationsAndSigners implements Signable {
11
+ constructor(public attestations: CommitteeAttestation[]) {}
12
+
13
+ static get schema() {
14
+ return z
15
+ .object({
16
+ attestations: CommitteeAttestation.schema.array(),
17
+ })
18
+ .transform(obj => new CommitteeAttestationsAndSigners(obj.attestations));
19
+ }
20
+
21
+ getPayloadToSign(domainSeparator: SignatureDomainSeparator): Buffer {
22
+ const abi = parseAbiParameters('uint8,(bytes,bytes),address[]');
23
+ const packed = this.getPackedAttestations();
24
+
25
+ const encodedData = encodeAbiParameters(abi, [
26
+ domainSeparator,
27
+ [packed.signatureIndices, packed.signaturesOrAddresses],
28
+ this.getSigners().map(s => s.toString()),
29
+ ]);
30
+
31
+ return hexToBuffer(encodedData);
32
+ }
33
+
34
+ static empty(): CommitteeAttestationsAndSigners {
35
+ return new CommitteeAttestationsAndSigners([]);
36
+ }
37
+
38
+ toString() {
39
+ return `CommitteeAttestationsAndSigners(${this.attestations.map(a => a.toString()).join(',')})`;
40
+ }
41
+
42
+ getSigners() {
43
+ return this.attestations.filter(a => !a.signature.isEmpty()).map(a => a.address);
44
+ }
45
+
46
+ getSignedAttestations() {
47
+ return this.attestations.filter(a => !a.signature.isEmpty());
48
+ }
49
+
50
+ /**
51
+ * Packs an array of committee attestations into the format expected by the Solidity contract
52
+ *
53
+ * @param attestations - Array of committee attestations with addresses and signatures
54
+ * @returns Packed attestations with bitmap and tightly packed signature/address data
55
+ */
56
+ getPackedAttestations(): ViemCommitteeAttestations {
57
+ const length = this.attestations.length;
58
+ const attestations = this.attestations.map(a => a.toViem());
59
+
60
+ // Calculate bitmap size (1 bit per attestation, rounded up to nearest byte)
61
+ const bitmapSize = Math.ceil(length / 8);
62
+ const signatureIndices = new Uint8Array(bitmapSize);
63
+
64
+ // Calculate total data size needed
65
+ let totalDataSize = 0;
66
+ for (let i = 0; i < length; i++) {
67
+ const signature = attestations[i].signature;
68
+ // Check if signature is empty (v = 0)
69
+ const isEmpty = signature.v === 0;
70
+
71
+ if (!isEmpty) {
72
+ totalDataSize += 65; // v (1) + r (32) + s (32)
73
+ } else {
74
+ totalDataSize += 20; // address only
75
+ }
76
+ }
77
+
78
+ const signaturesOrAddresses = new Uint8Array(totalDataSize);
79
+ let dataIndex = 0;
80
+
81
+ // Pack the data
82
+ for (let i = 0; i < length; i++) {
83
+ const attestation = attestations[i];
84
+ const signature = attestation.signature;
85
+
86
+ // Check if signature is empty
87
+ const isEmpty = signature.v === 0;
88
+
89
+ if (!isEmpty) {
90
+ // Set bit in bitmap (bit 7-0 in each byte, left to right)
91
+ const byteIndex = Math.floor(i / 8);
92
+ const bitIndex = 7 - (i % 8);
93
+ signatureIndices[byteIndex] |= 1 << bitIndex;
94
+
95
+ // Pack signature: v + r + s
96
+ signaturesOrAddresses[dataIndex] = signature.v;
97
+ dataIndex++;
98
+
99
+ // Pack r (32 bytes)
100
+ const rBytes = Buffer.from(signature.r.slice(2), 'hex');
101
+ signaturesOrAddresses.set(rBytes, dataIndex);
102
+ dataIndex += 32;
103
+
104
+ // Pack s (32 bytes)
105
+ const sBytes = Buffer.from(signature.s.slice(2), 'hex');
106
+ signaturesOrAddresses.set(sBytes, dataIndex);
107
+ dataIndex += 32;
108
+ } else {
109
+ // Pack address only (20 bytes)
110
+ const addrBytes = Buffer.from(attestation.addr.slice(2), 'hex');
111
+ signaturesOrAddresses.set(addrBytes, dataIndex);
112
+ dataIndex += 20;
113
+ }
114
+ }
115
+
116
+ return {
117
+ signatureIndices: `0x${Buffer.from(signatureIndices).toString('hex')}`,
118
+ signaturesOrAddresses: `0x${Buffer.from(signaturesOrAddresses).toString('hex')}`,
119
+ };
120
+ }
121
+ }
@@ -111,6 +111,10 @@ export class CommitteeAttestation {
111
111
  return this.address.equals(other.address) && this.signature.equals(other.signature);
112
112
  }
113
113
 
114
+ toString(): string {
115
+ return `CommitteeAttestation(${this.address.toString()}, ${this.signature.toString()})`;
116
+ }
117
+
114
118
  toViem(): ViemCommitteeAttestation {
115
119
  return {
116
120
  addr: this.address.toString(),
@@ -1 +1,2 @@
1
1
  export * from './committee_attestation.js';
2
+ export * from './attestations_and_signers.js';
@@ -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
+ }
@@ -4,9 +4,11 @@ import { GoogleCloudFileStore } from './gcs.js';
4
4
  import { HttpFileStore } from './http.js';
5
5
  import type { FileStore, ReadOnlyFileStore } from './interface.js';
6
6
  import { LocalFileStore } from './local.js';
7
+ import { S3FileStore } from './s3.js';
7
8
 
8
9
  const supportedExamples = [
9
10
  `gs://bucket-name/path/to/store`,
11
+ `s3://bucket-name/path/to/store`,
10
12
  `file:///absolute/local/path/to/store`,
11
13
  `https://host/path`,
12
14
  ];
@@ -39,6 +41,19 @@ export async function createFileStore(
39
41
  } catch {
40
42
  throw new Error(`Invalid google cloud store definition: '${config}'.`);
41
43
  }
44
+ } else if (config.startsWith('s3://')) {
45
+ try {
46
+ const url = new URL(config);
47
+ const bucket = url.host;
48
+ const path = url.pathname.replace(/^\/+/, '');
49
+ const endpoint = url.searchParams.get('endpoint');
50
+ const publicBaseUrl = url.searchParams.get('publicBaseUrl') ?? undefined;
51
+ logger.info(`Creating S3 file store at ${bucket} ${path}`);
52
+ const store = new S3FileStore(bucket, path, { endpoint: endpoint ?? undefined, publicBaseUrl });
53
+ return store;
54
+ } catch {
55
+ throw new Error(`Invalid S3 store definition: '${config}'.`);
56
+ }
42
57
  } else {
43
58
  throw new Error(`Unknown file store config: '${config}'. Supported values are ${supportedExamples.join(', ')}.`);
44
59
  }
@@ -12,8 +12,14 @@ export type FileStoreSaveOptions = { public?: boolean; metadata?: Record<string,
12
12
 
13
13
  /** Simple file store. */
14
14
  export interface FileStore extends ReadOnlyFileStore {
15
- /** Saves contents to the given path. Returns an URI that can be used later to `read` the file. */
15
+ /**
16
+ * Saves contents to the given path. Returns an URI that can be used later to `read` the file.
17
+ * Default: `compress` is false unless explicitly set.
18
+ */
16
19
  save(path: string, data: Buffer, opts?: FileStoreSaveOptions): Promise<string>;
17
- /** Uploads contents from a local file. Returns an URI that can be used later to `read` the file. */
20
+ /**
21
+ * Uploads contents from a local file. Returns an URI that can be used later to `read` the file.
22
+ * Default: `compress` is true unless explicitly set to false.
23
+ */
18
24
  upload(destPath: string, srcPath: string, opts?: FileStoreSaveOptions): Promise<string>;
19
25
  }
@@ -0,0 +1,254 @@
1
+ import { type Logger, createLogger } from '@aztec/foundation/log';
2
+
3
+ import {
4
+ GetObjectCommand,
5
+ type GetObjectCommandOutput,
6
+ HeadObjectCommand,
7
+ PutObjectCommand,
8
+ S3Client,
9
+ } from '@aws-sdk/client-s3';
10
+ import { createReadStream, createWriteStream } from 'fs';
11
+ import { mkdir, mkdtemp, stat, unlink } from 'fs/promises';
12
+ import { tmpdir } from 'os';
13
+ import { basename, dirname, join } from 'path';
14
+ import { Readable } from 'stream';
15
+ import { finished } from 'stream/promises';
16
+ import { createGzip } from 'zlib';
17
+
18
+ import type { FileStore, FileStoreSaveOptions } from './interface.js';
19
+
20
+ function normalizeBasePath(path: string): string {
21
+ return path?.replace(/^\/+|\/+$/g, '') ?? '';
22
+ }
23
+
24
+ export class S3FileStore implements FileStore {
25
+ private readonly s3: S3Client;
26
+ private readonly region: string;
27
+ private readonly endpoint?: string;
28
+ private readonly publicBaseUrl?: string;
29
+
30
+ constructor(
31
+ private readonly bucketName: string,
32
+ private readonly basePath: string,
33
+ opts: { endpoint?: string; publicBaseUrl?: string },
34
+ private readonly log: Logger = createLogger('stdlib:s3-file-store'),
35
+ ) {
36
+ this.endpoint = opts.endpoint;
37
+ this.region = this.endpoint ? 'auto' : (process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? 'us-east-1');
38
+ this.publicBaseUrl = opts.publicBaseUrl;
39
+
40
+ const clientOptions: any = {};
41
+ if (this.endpoint) {
42
+ clientOptions.region = 'auto';
43
+ clientOptions.endpoint = this.endpoint;
44
+ clientOptions.forcePathStyle = true;
45
+ } else {
46
+ clientOptions.region = this.region;
47
+ }
48
+ this.s3 = new S3Client(clientOptions);
49
+ }
50
+
51
+ public async save(path: string, data: Buffer, opts: FileStoreSaveOptions = {}): Promise<string> {
52
+ const key = this.getFullPath(path);
53
+ const shouldCompress = !!opts.compress;
54
+
55
+ const body = shouldCompress ? (await import('zlib')).gzipSync(data) : data;
56
+ const contentLength = body.length;
57
+ const contentType = this.detectContentType(key, shouldCompress);
58
+ const put = new PutObjectCommand({
59
+ Bucket: this.bucketName,
60
+ Key: key,
61
+ Body: body,
62
+ ContentType: contentType,
63
+ CacheControl: opts.metadata?.['Cache-control'],
64
+ Metadata: this.extractUserMetadata(opts.metadata),
65
+ ContentLength: contentLength,
66
+ });
67
+ await this.s3.send(put);
68
+ return this.buildReturnedUrl(key, !!opts.public);
69
+ }
70
+
71
+ public async upload(destPath: string, srcPath: string, opts: FileStoreSaveOptions = {}): Promise<string> {
72
+ const key = this.getFullPath(destPath);
73
+ const shouldCompress = opts.compress !== false; // default true like GCS impl
74
+
75
+ await mkdir(dirname(srcPath), { recursive: true }).catch(() => undefined);
76
+ let contentLength: number | undefined;
77
+ let bodyPath = srcPath;
78
+
79
+ // We don't set Content-Encoding and we avoid SigV4 streaming (aws-chunked).
80
+ // With AWS SigV4 streaming uploads (Content-Encoding: aws-chunked[,gzip]), servers require
81
+ // x-amz-decoded-content-length (the size of the decoded payload) and an exact Content-Length
82
+ // that includes chunk metadata. For on-the-fly compression, providing
83
+ // those values without buffering or a pre-pass is impractical. Instead, we pre-gzip to a temp file
84
+ // to know ContentLength up-front and upload the gzipped bytes as-is, omitting Content-Encoding.
85
+ // Reference: AWS SigV4 streaming (chunked upload) requirements —
86
+ // https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html
87
+ if (shouldCompress) {
88
+ // Pre-gzip to a temp file so we know the exact length for R2/S3 headers
89
+ const tmpDir = await mkdtemp(join(tmpdir(), 's3-upload-'));
90
+ const gzPath = join(tmpDir, `${basename(srcPath)}.gz`);
91
+ const source = createReadStream(srcPath);
92
+ const gz = createGzip();
93
+ const out = createWriteStream(gzPath);
94
+ try {
95
+ await finished(source.pipe(gz).pipe(out));
96
+ const st = await stat(gzPath);
97
+ contentLength = st.size;
98
+ bodyPath = gzPath;
99
+ } catch (err) {
100
+ // Ensure temp file is removed on failure
101
+ await unlink(gzPath).catch(() => undefined);
102
+ throw err;
103
+ }
104
+ } else {
105
+ const st = await stat(srcPath);
106
+ contentLength = st.size;
107
+ bodyPath = srcPath;
108
+ }
109
+
110
+ const bodyStream = createReadStream(bodyPath);
111
+ const contentType = this.detectContentType(key, shouldCompress);
112
+ try {
113
+ const put = new PutObjectCommand({
114
+ Bucket: this.bucketName,
115
+ Key: key,
116
+ Body: bodyStream as any,
117
+ ContentType: contentType,
118
+ CacheControl: opts.metadata?.['Cache-control'],
119
+ Metadata: this.extractUserMetadata(opts.metadata),
120
+ // Explicitly set ContentLength so R2 can compute x-amz-decoded-content-length correctly
121
+ ContentLength: contentLength,
122
+ } as any);
123
+ await this.s3.send(put);
124
+ } finally {
125
+ if (shouldCompress && bodyPath !== srcPath) {
126
+ await unlink(bodyPath).catch(() => undefined);
127
+ }
128
+ }
129
+ return this.buildReturnedUrl(key, !!opts.public);
130
+ }
131
+
132
+ public async read(pathOrUrlStr: string): Promise<Buffer> {
133
+ const { bucket, key } = this.getBucketAndKey(pathOrUrlStr);
134
+ const out: GetObjectCommandOutput = await this.s3.send(new GetObjectCommand({ Bucket: bucket, Key: key }));
135
+ const stream = out.Body as Readable;
136
+ const chunks: Buffer[] = [];
137
+ for await (const chunk of stream) {
138
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
139
+ }
140
+ return Buffer.concat(chunks);
141
+ }
142
+
143
+ public async download(pathOrUrlStr: string, destPath: string): Promise<void> {
144
+ const { bucket, key } = this.getBucketAndKey(pathOrUrlStr);
145
+ const out: GetObjectCommandOutput = await this.s3.send(new GetObjectCommand({ Bucket: bucket, Key: key }));
146
+ await mkdir(dirname(destPath), { recursive: true });
147
+ const write = createWriteStream(destPath);
148
+ await finished((out.Body as Readable).pipe(write));
149
+ }
150
+
151
+ public async exists(pathOrUrlStr: string): Promise<boolean> {
152
+ try {
153
+ const { bucket, key } = this.getBucketAndKey(pathOrUrlStr);
154
+ await this.s3.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));
155
+ return true;
156
+ } catch (err: any) {
157
+ const code = err?.$metadata?.httpStatusCode ?? err?.name ?? err?.Code;
158
+ if (code === 404 || code === 'NotFound' || code === 'NoSuchKey') {
159
+ return false;
160
+ }
161
+ this.log.warn(`Error checking existence for ${pathOrUrlStr}: ${err?.message ?? String(err)}`);
162
+ return false;
163
+ }
164
+ }
165
+
166
+ private extractUserMetadata(meta?: Record<string, string>): Record<string, string> | undefined {
167
+ if (!meta) {
168
+ return undefined;
169
+ }
170
+ const { ['Cache-control']: _ignored, ...rest } = meta;
171
+ return Object.keys(rest).length ? rest : undefined;
172
+ }
173
+
174
+ private detectContentType(key: string, isCompressed: boolean | undefined): string | undefined {
175
+ // Basic content type inference
176
+ const lower = key.toLowerCase();
177
+ if (lower.endsWith('.json') || lower.endsWith('.json.gz')) {
178
+ return 'application/json';
179
+ }
180
+ if (lower.endsWith('.txt') || lower.endsWith('.log') || lower.endsWith('.csv') || lower.endsWith('.md')) {
181
+ return 'text/plain; charset=utf-8';
182
+ }
183
+ if (lower.endsWith('.db') || lower.endsWith('.sqlite') || lower.endsWith('.bin')) {
184
+ return 'application/octet-stream';
185
+ }
186
+ if (lower.endsWith('.wasm') || lower.endsWith('.wasm.gz')) {
187
+ return 'application/wasm';
188
+ }
189
+ // If compressed, prefer octet-stream unless known
190
+ if (isCompressed) {
191
+ return 'application/octet-stream';
192
+ }
193
+ return undefined;
194
+ }
195
+
196
+ private buildReturnedUrl(key: string, makePublic: boolean): string {
197
+ if (!makePublic) {
198
+ return `s3://${this.bucketName}/${key}`;
199
+ }
200
+
201
+ if (this.publicBaseUrl) {
202
+ const base = this.publicBaseUrl.replace(/\/$/, '');
203
+ // key already includes basePath via getFullPath, so do not prefix basePath again
204
+ const full = key.replace(/^\/+/, '');
205
+ return `${base}/${full}`;
206
+ }
207
+
208
+ // Try to synthesize a URL from endpoint if available (works for public R2 buckets)
209
+ if (this.endpoint) {
210
+ try {
211
+ const url = new URL(this.endpoint);
212
+ return `https://${this.bucketName}.${url.host}/${key}`;
213
+ } catch {
214
+ // fallthrough
215
+ }
216
+ }
217
+
218
+ // Fallback to AWS style URL if region looks valid
219
+ return `https://${this.bucketName}.s3.${this.region}.amazonaws.com/${key}`;
220
+ }
221
+
222
+ private getBucketAndKey(pathOrUrlStr: string): { bucket: string; key: string } {
223
+ if (URL.canParse(pathOrUrlStr)) {
224
+ const url = new URL(pathOrUrlStr);
225
+ if (url.protocol === 's3:') {
226
+ return { bucket: url.host, key: url.pathname.replace(/^\/+/, '') };
227
+ }
228
+ // For https URLs, try to infer virtual-hosted or path-style
229
+ if (url.protocol === 'https:' || url.protocol === 'http:') {
230
+ // If the URL matches the configured publicBaseUrl host, map back to our bucket and key
231
+ if (this.publicBaseUrl && url.host === new URL(this.publicBaseUrl).host) {
232
+ return { bucket: this.bucketName, key: url.pathname.replace(/^\/+/, '') };
233
+ }
234
+ const hostParts = url.host.split('.');
235
+ if (hostParts.length > 3 && (hostParts[1] === 's3' || hostParts[hostParts.length - 2] === 'r2')) {
236
+ // virtual hosted
237
+ return { bucket: hostParts[0], key: url.pathname.replace(/^\/+/, '') };
238
+ } else if (this.endpoint && url.host === new URL(this.endpoint).host) {
239
+ // path-style at custom endpoint
240
+ const [bucket, ...rest] = url.pathname.replace(/^\/+/, '').split('/');
241
+ return { bucket, key: rest.join('/') };
242
+ }
243
+ }
244
+ }
245
+ // Treat as path
246
+ return { bucket: this.bucketName, key: this.getFullPath(pathOrUrlStr) };
247
+ }
248
+
249
+ private getFullPath(path: string): string {
250
+ const base = normalizeBasePath(this.basePath);
251
+ const rel = path.replace(/^\/+/, '');
252
+ return base ? join(base, rel) : rel;
253
+ }
254
+ }
@@ -43,6 +43,7 @@ export interface PublicProcessorLimits {
43
43
  maxTransactions?: number;
44
44
  maxBlockSize?: number;
45
45
  maxBlockGas?: Gas;
46
+ maxBlobFields?: number;
46
47
  deadline?: Date;
47
48
  }
48
49
 
@@ -24,6 +24,7 @@ export interface SlasherConfig {
24
24
  slashOffenseExpirationRounds: number; // Number of rounds after which pending offenses expire
25
25
  slashMaxPayloadSize: number; // Maximum number of offenses to include in a single slash payload
26
26
  slashGracePeriodL2Slots: number; // Number of L2 slots to wait after genesis before slashing for most offenses
27
+ slashExecuteRoundsLookBack: number; // How many rounds to look back when searching for a round to execute
27
28
  }
28
29
 
29
30
  export const SlasherConfigSchema = z.object({
@@ -44,5 +45,6 @@ export const SlasherConfigSchema = z.object({
44
45
  slashMaxPayloadSize: z.number(),
45
46
  slashGracePeriodL2Slots: z.number(),
46
47
  slashBroadcastedInvalidBlockPenalty: schemas.BigInt,
48
+ slashExecuteRoundsLookBack: z.number(),
47
49
  slashSelfAllowed: z.boolean().optional(),
48
50
  }) satisfies ZodFor<SlasherConfig>;
@@ -1,5 +1,6 @@
1
1
  import type { SecretValue } from '@aztec/foundation/config';
2
2
  import type { EthAddress } from '@aztec/foundation/eth-address';
3
+ import type { Signature } from '@aztec/foundation/eth-signature';
3
4
  import { Fr } from '@aztec/foundation/fields';
4
5
  import { type ZodFor, schemas } from '@aztec/foundation/schemas';
5
6
  import type { SequencerConfig, SlasherConfig } from '@aztec/stdlib/interfaces/server';
@@ -9,6 +10,8 @@ import type { ProposedBlockHeader, StateReference, Tx } from '@aztec/stdlib/tx';
9
10
  import type { PeerId } from '@libp2p/interface';
10
11
  import { z } from 'zod';
11
12
 
13
+ import type { CommitteeAttestationsAndSigners } from '../block/index.js';
14
+
12
15
  /**
13
16
  * Validator client configuration
14
17
  */
@@ -28,11 +31,14 @@ export interface ValidatorClientConfig {
28
31
  /** Interval between polling for new attestations from peers */
29
32
  attestationPollingIntervalMs: number;
30
33
 
31
- /** Re-execute transactions before attesting */
34
+ /** Whether to re-execute transactions in a block proposal before attesting */
32
35
  validatorReexecute: boolean;
33
36
 
34
37
  /** Will re-execute until this many milliseconds are left in the slot */
35
38
  validatorReexecuteDeadlineMs: number;
39
+
40
+ /** Whether to always reexecute block proposals, even for non-validator nodes or when out of the currnet committee */
41
+ alwaysReexecuteBlockProposals?: boolean;
36
42
  }
37
43
 
38
44
  export type ValidatorClientFullConfig = ValidatorClientConfig &
@@ -46,11 +52,11 @@ export const ValidatorClientConfigSchema = z.object({
46
52
  attestationPollingIntervalMs: z.number().min(0),
47
53
  validatorReexecute: z.boolean(),
48
54
  validatorReexecuteDeadlineMs: z.number().min(0),
55
+ alwaysReexecuteBlockProposals: z.boolean().optional(),
49
56
  }) satisfies ZodFor<Omit<ValidatorClientConfig, 'validatorPrivateKeys'>>;
50
57
 
51
58
  export interface Validator {
52
59
  start(): Promise<void>;
53
- registerBlockProposalHandler(): void;
54
60
  updateConfig(config: Partial<ValidatorClientFullConfig>): void;
55
61
 
56
62
  // Block validation responsibilities
@@ -67,4 +73,8 @@ export interface Validator {
67
73
 
68
74
  broadcastBlockProposal(proposal: BlockProposal): Promise<void>;
69
75
  collectAttestations(proposal: BlockProposal, required: number, deadline: Date): Promise<BlockAttestation[]>;
76
+ signAttestationsAndSigners(
77
+ attestationsAndSigners: CommitteeAttestationsAndSigners,
78
+ proposer: EthAddress,
79
+ ): Promise<Signature>;
70
80
  }