@aztec/foundation 0.0.1-commit.ec5f612 → 0.0.1-commit.ec7ac5448

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 (128) hide show
  1. package/dest/branded-types/slot.d.ts +4 -1
  2. package/dest/branded-types/slot.d.ts.map +1 -1
  3. package/dest/branded-types/slot.js +3 -0
  4. package/dest/buffer/buffer16.d.ts +3 -1
  5. package/dest/buffer/buffer16.d.ts.map +1 -1
  6. package/dest/buffer/buffer32.d.ts +3 -1
  7. package/dest/buffer/buffer32.d.ts.map +1 -1
  8. package/dest/buffer/index.d.ts +2 -1
  9. package/dest/buffer/index.d.ts.map +1 -1
  10. package/dest/buffer/index.js +1 -0
  11. package/dest/buffer/utils.d.ts +3 -0
  12. package/dest/buffer/utils.d.ts.map +1 -0
  13. package/dest/buffer/utils.js +7 -0
  14. package/dest/collection/array.d.ts +3 -1
  15. package/dest/collection/array.d.ts.map +1 -1
  16. package/dest/collection/array.js +15 -0
  17. package/dest/collection/index.d.ts +2 -1
  18. package/dest/collection/index.d.ts.map +1 -1
  19. package/dest/collection/index.js +1 -0
  20. package/dest/collection/lru_set.d.ts +35 -0
  21. package/dest/collection/lru_set.d.ts.map +1 -0
  22. package/dest/collection/lru_set.js +95 -0
  23. package/dest/config/env_var.d.ts +2 -2
  24. package/dest/config/env_var.d.ts.map +1 -1
  25. package/dest/config/index.d.ts +1 -1
  26. package/dest/config/index.d.ts.map +1 -1
  27. package/dest/config/index.js +15 -0
  28. package/dest/config/network_config.d.ts +19 -1
  29. package/dest/config/network_config.d.ts.map +1 -1
  30. package/dest/config/network_config.js +4 -1
  31. package/dest/crypto/aes128/index.d.ts +2 -1
  32. package/dest/crypto/aes128/index.d.ts.map +1 -1
  33. package/dest/crypto/aes128/index.js +11 -2
  34. package/dest/crypto/bls/bn254_keystore.d.ts +1 -10
  35. package/dest/crypto/bls/bn254_keystore.d.ts.map +1 -1
  36. package/dest/crypto/bls/bn254_keystore.js +0 -17
  37. package/dest/crypto/poseidon/index.d.ts +1 -1
  38. package/dest/crypto/poseidon/index.d.ts.map +1 -1
  39. package/dest/crypto/poseidon/index.js +40 -33
  40. package/dest/crypto/secp256k1-signer/utils.d.ts +12 -1
  41. package/dest/crypto/secp256k1-signer/utils.d.ts.map +1 -1
  42. package/dest/crypto/secp256k1-signer/utils.js +26 -0
  43. package/dest/curves/grumpkin/point.d.ts +4 -4
  44. package/dest/curves/grumpkin/point.d.ts.map +1 -1
  45. package/dest/curves/grumpkin/point.js +7 -4
  46. package/dest/eth-signature/eth_signature.d.ts +2 -1
  47. package/dest/eth-signature/eth_signature.d.ts.map +1 -1
  48. package/dest/eth-signature/eth_signature.js +7 -2
  49. package/dest/fifo/fifo_frame_reader.d.ts +41 -0
  50. package/dest/fifo/fifo_frame_reader.d.ts.map +1 -0
  51. package/dest/fifo/fifo_frame_reader.js +74 -0
  52. package/dest/fifo/index.d.ts +2 -0
  53. package/dest/fifo/index.d.ts.map +1 -0
  54. package/dest/fifo/index.js +1 -0
  55. package/dest/jest/setup.js +24 -0
  56. package/dest/json-rpc/client/fetch.d.ts +1 -1
  57. package/dest/json-rpc/client/fetch.d.ts.map +1 -1
  58. package/dest/json-rpc/client/fetch.js +4 -3
  59. package/dest/json-rpc/client/undici.d.ts +1 -1
  60. package/dest/json-rpc/client/undici.d.ts.map +1 -1
  61. package/dest/json-rpc/client/undici.js +5 -3
  62. package/dest/log/bigint-utils.d.ts +1 -1
  63. package/dest/log/bigint-utils.d.ts.map +1 -1
  64. package/dest/log/bigint-utils.js +3 -0
  65. package/dest/log/pino-logger.d.ts +1 -1
  66. package/dest/log/pino-logger.d.ts.map +1 -1
  67. package/dest/log/pino-logger.js +17 -2
  68. package/dest/queue/batch_queue.d.ts +1 -1
  69. package/dest/queue/batch_queue.d.ts.map +1 -1
  70. package/dest/queue/batch_queue.js +1 -0
  71. package/dest/retry/index.d.ts +12 -1
  72. package/dest/retry/index.d.ts.map +1 -1
  73. package/dest/retry/index.js +21 -0
  74. package/dest/schemas/api.d.ts +2 -2
  75. package/dest/schemas/api.d.ts.map +1 -1
  76. package/dest/sleep/index.d.ts +2 -1
  77. package/dest/sleep/index.d.ts.map +1 -1
  78. package/dest/sleep/index.js +10 -1
  79. package/dest/string/index.js +1 -1
  80. package/dest/transport/dispatch/create_dispatch_proxy.d.ts +11 -2
  81. package/dest/transport/dispatch/create_dispatch_proxy.d.ts.map +1 -1
  82. package/dest/transport/index.d.ts +1 -2
  83. package/dest/transport/index.d.ts.map +1 -1
  84. package/dest/transport/index.js +0 -1
  85. package/dest/trees/indexed_merkle_tree_calculator.d.ts +1 -1
  86. package/dest/trees/indexed_merkle_tree_calculator.d.ts.map +1 -1
  87. package/dest/trees/indexed_merkle_tree_calculator.js +5 -1
  88. package/package.json +3 -2
  89. package/src/branded-types/slot.ts +5 -0
  90. package/src/buffer/buffer16.ts +3 -0
  91. package/src/buffer/buffer32.ts +3 -0
  92. package/src/buffer/index.ts +1 -0
  93. package/src/buffer/utils.ts +8 -0
  94. package/src/collection/array.ts +14 -0
  95. package/src/collection/index.ts +1 -0
  96. package/src/collection/lru_set.ts +115 -0
  97. package/src/config/env_var.ts +23 -10
  98. package/src/config/index.ts +15 -0
  99. package/src/config/network_config.ts +3 -0
  100. package/src/crypto/aes128/index.ts +11 -2
  101. package/src/crypto/bls/bn254_keystore.ts +0 -23
  102. package/src/crypto/poseidon/index.ts +42 -34
  103. package/src/crypto/secp256k1-signer/utils.ts +32 -0
  104. package/src/curves/grumpkin/point.ts +6 -3
  105. package/src/eth-signature/eth_signature.ts +7 -1
  106. package/src/fifo/fifo_frame_reader.ts +98 -0
  107. package/src/fifo/index.ts +1 -0
  108. package/src/jest/setup.mjs +27 -0
  109. package/src/json-rpc/client/fetch.ts +4 -3
  110. package/src/json-rpc/client/undici.ts +5 -3
  111. package/src/log/bigint-utils.ts +3 -0
  112. package/src/log/pino-logger.ts +19 -2
  113. package/src/queue/batch_queue.ts +1 -0
  114. package/src/retry/index.ts +30 -0
  115. package/src/schemas/api.ts +4 -1
  116. package/src/sleep/index.ts +10 -1
  117. package/src/string/index.ts +1 -1
  118. package/src/transport/dispatch/create_dispatch_proxy.ts +11 -1
  119. package/src/transport/index.ts +0 -1
  120. package/src/trees/indexed_merkle_tree_calculator.ts +5 -1
  121. package/dest/crypto/serialize.d.ts +0 -51
  122. package/dest/crypto/serialize.d.ts.map +0 -1
  123. package/dest/crypto/serialize.js +0 -68
  124. package/dest/transport/dispatch/create_dispatch_fn.d.ts +0 -25
  125. package/dest/transport/dispatch/create_dispatch_fn.d.ts.map +0 -1
  126. package/dest/transport/dispatch/create_dispatch_fn.js +0 -17
  127. package/src/crypto/serialize.ts +0 -85
  128. package/src/transport/dispatch/create_dispatch_fn.ts +0 -35
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/foundation",
3
- "version": "0.0.1-commit.ec5f612",
3
+ "version": "0.0.1-commit.ec7ac5448",
4
4
  "type": "module",
5
5
  "main": "./dest/index.js",
6
6
  "types": "./dest/index.d.ts",
@@ -61,6 +61,7 @@
61
61
  "./eth-address": "./dest/eth-address/index.js",
62
62
  "./eth-signature": "./dest/eth-signature/index.js",
63
63
  "./queue": "./dest/queue/index.js",
64
+ "./fifo": "./dest/fifo/index.js",
64
65
  "./fs": "./dest/fs/index.js",
65
66
  "./buffer": "./dest/buffer/index.js",
66
67
  "./json-rpc": "./dest/json-rpc/index.js",
@@ -144,7 +145,7 @@
144
145
  "testEnvironment": "../../foundation/src/jest/env.mjs"
145
146
  },
146
147
  "dependencies": {
147
- "@aztec/bb.js": "0.0.1-commit.ec5f612",
148
+ "@aztec/bb.js": "0.0.1-commit.ec7ac5448",
148
149
  "@koa/cors": "^5.0.0",
149
150
  "@noble/curves": "=1.7.0",
150
151
  "@noble/hashes": "^1.6.1",
@@ -73,6 +73,11 @@ SlotNumber.isValid = function (value: unknown): value is SlotNumber {
73
73
  return typeof value === 'number' && Number.isInteger(value) && value >= 0;
74
74
  };
75
75
 
76
+ /** Increments a SlotNumber by a given value. */
77
+ SlotNumber.add = function (sn: SlotNumber, increment: number): SlotNumber {
78
+ return SlotNumber(sn + increment);
79
+ };
80
+
76
81
  /**
77
82
  * The zero slot value.
78
83
  */
@@ -10,6 +10,9 @@ import { bufferToHex } from '../string/index.js';
10
10
  * A class representing a 16 byte Buffer.
11
11
  */
12
12
  export class Buffer16 {
13
+ /** Branding to prevent structural compatibility with Buffer32. */
14
+ declare readonly __brand: 'Buffer16';
15
+
13
16
  /**
14
17
  * The size of the hash in bytes.
15
18
  */
@@ -10,6 +10,9 @@ import { bufferToHex } from '../string/index.js';
10
10
  * A class representing a 32 byte Buffer.
11
11
  */
12
12
  export class Buffer32 {
13
+ /** Branding to prevent structural compatibility with Buffer16. */
14
+ declare readonly __brand: 'Buffer32';
15
+
13
16
  /**
14
17
  * The size of the hash in bytes.
15
18
  */
@@ -1,2 +1,3 @@
1
1
  export * from './buffer32.js';
2
2
  export * from './buffer16.js';
3
+ export * from './utils.js';
@@ -0,0 +1,8 @@
1
+ /** Returns the number of bytes in the buffer, excluding any trailing zero bytes. */
2
+ export function trimmedBytesLength(buf: Uint8Array): number {
3
+ let end = buf.length;
4
+ while (end > 0 && buf[end - 1] === 0) {
5
+ end--;
6
+ }
7
+ return end;
8
+ }
@@ -315,3 +315,17 @@ export function partition<T>(items: T[], predicate: (item: T) => boolean): [T[],
315
315
  }
316
316
  return [pass, fail];
317
317
  }
318
+
319
+ /** Partitions the given iterable into two arrays based on the predicate. */
320
+ export async function partitionAsync<T>(items: T[], predicate: (item: T) => Promise<boolean>): Promise<[T[], T[]]> {
321
+ const pass: T[] = [];
322
+ const fail: T[] = [];
323
+ for (const item of items) {
324
+ if (await predicate(item)) {
325
+ pass.push(item);
326
+ } else {
327
+ fail.push(item);
328
+ }
329
+ }
330
+ return [pass, fail];
331
+ }
@@ -1,2 +1,3 @@
1
1
  export * from './array.js';
2
+ export * from './lru_set.js';
2
3
  export * from './object.js';
@@ -0,0 +1,115 @@
1
+ /** Node in a doubly-linked list used by {@link LruSet}. */
2
+ type LruNode<T> = {
3
+ value: T;
4
+ prev: LruNode<T> | undefined;
5
+ next: LruNode<T> | undefined;
6
+ };
7
+
8
+ /**
9
+ * A bounded set with Least Recently Used (LRU) eviction.
10
+ * Both {@link has} and {@link add} count as an access and refresh the entry's
11
+ * recency, so items that are actively checked stay in the set longest.
12
+ *
13
+ * Uses a doubly-linked list for O(1) ordering and a Map for O(1) lookup.
14
+ * Head = least recent, tail = most recent.
15
+ */
16
+ export class LruSet<T> {
17
+ /** Map from value to its linked-list node for O(1) lookup. */
18
+ private readonly map = new Map<T, LruNode<T>>();
19
+ private head: LruNode<T> | undefined;
20
+ private tail: LruNode<T> | undefined;
21
+
22
+ constructor(private readonly maxSize: number) {
23
+ if (maxSize < 1) {
24
+ throw new Error('LruSet maxSize must be at least 1');
25
+ }
26
+ }
27
+
28
+ /** Number of entries in the set. */
29
+ get size(): number {
30
+ return this.map.size;
31
+ }
32
+
33
+ /**
34
+ * Returns true if the item is in the set.
35
+ * Refreshes the item's recency so it becomes the most recently used.
36
+ */
37
+ has(item: T): boolean {
38
+ const node = this.map.get(item);
39
+ if (!node) {
40
+ return false;
41
+ }
42
+ this.moveToTail(node);
43
+ return true;
44
+ }
45
+
46
+ /**
47
+ * Adds an item to the set. If the item already exists, refreshes its recency.
48
+ * If the set is at capacity, evicts the least recently used item.
49
+ */
50
+ add(item: T): void {
51
+ const existing = this.map.get(item);
52
+ if (existing) {
53
+ this.moveToTail(existing);
54
+ return;
55
+ }
56
+
57
+ if (this.map.size >= this.maxSize) {
58
+ this.evictHead();
59
+ }
60
+
61
+ const node: LruNode<T> = { value: item, prev: this.tail, next: undefined };
62
+ if (this.tail) {
63
+ this.tail.next = node;
64
+ } else {
65
+ this.head = node;
66
+ }
67
+ this.tail = node;
68
+ this.map.set(item, node);
69
+ }
70
+
71
+ /** Removes all entries from the set. */
72
+ clear(): void {
73
+ this.map.clear();
74
+ this.head = undefined;
75
+ this.tail = undefined;
76
+ }
77
+
78
+ /** Unlinks a node from its current position and relinks it at the tail. */
79
+ private moveToTail(node: LruNode<T>): void {
80
+ if (node === this.tail) {
81
+ return;
82
+ }
83
+
84
+ // Unlink
85
+ if (node.prev) {
86
+ node.prev.next = node.next;
87
+ } else {
88
+ this.head = node.next;
89
+ }
90
+ if (node.next) {
91
+ node.next.prev = node.prev;
92
+ }
93
+
94
+ // Relink at tail
95
+ node.prev = this.tail;
96
+ node.next = undefined;
97
+ if (this.tail) {
98
+ this.tail.next = node;
99
+ }
100
+ this.tail = node;
101
+ }
102
+
103
+ /** Evicts the head (least recently used) node. */
104
+ private evictHead(): void {
105
+ const oldHead = this.head!;
106
+ this.map.delete(oldHead.value);
107
+
108
+ this.head = oldHead.next;
109
+ if (this.head) {
110
+ this.head.prev = undefined;
111
+ } else {
112
+ this.tail = undefined;
113
+ }
114
+ }
115
+ }
@@ -1,7 +1,6 @@
1
1
  export type EnvVar =
2
2
  | 'REGISTRY_CONTRACT_ADDRESS'
3
3
  | 'FEE_ASSET_HANDLER_CONTRACT_ADDRESS'
4
- | 'SLASH_FACTORY_CONTRACT_ADDRESS'
5
4
  | 'ACVM_BINARY_PATH'
6
5
  | 'ACVM_WORKING_DIRECTORY'
7
6
  | 'API_KEY'
@@ -12,6 +11,7 @@ export type EnvVar =
12
11
  | 'ARCHIVER_VIEM_POLLING_INTERVAL_MS'
13
12
  | 'ARCHIVER_BATCH_SIZE'
14
13
  | 'AZTEC_ADMIN_PORT'
14
+ | 'AZTEC_NODE_DEBUG'
15
15
  | 'AZTEC_ADMIN_API_KEY_HASH'
16
16
  | 'AZTEC_DISABLE_ADMIN_API_KEY'
17
17
  | 'AZTEC_RESET_ADMIN_API_KEY'
@@ -23,6 +23,8 @@ export type EnvVar =
23
23
  | 'BB_WORKING_DIRECTORY'
24
24
  | 'BB_NUM_IVC_VERIFIERS'
25
25
  | 'BB_IVC_CONCURRENCY'
26
+ | 'BB_CHONK_VERIFY_MAX_BATCH'
27
+ | 'BB_CHONK_VERIFY_BATCH_CONCURRENCY'
26
28
  | 'BOOTSTRAP_NODES'
27
29
  | 'BLOB_ARCHIVE_API_URL'
28
30
  | 'BLOB_FILE_STORE_URLS'
@@ -62,6 +64,7 @@ export type EnvVar =
62
64
  | 'BLOB_SINK_MAP_SIZE_KB'
63
65
  | 'P2P_STORE_MAP_SIZE_KB'
64
66
  | 'PROVER_BROKER_STORE_MAP_SIZE_KB'
67
+ | 'SIGNING_PROTECTION_MAP_SIZE_KB'
65
68
  | 'WS_DB_MAP_SIZE_KB'
66
69
  | 'ARCHIVE_TREE_MAP_SIZE_KB'
67
70
  | 'NULLIFIER_TREE_MAP_SIZE_KB'
@@ -80,6 +83,7 @@ export type EnvVar =
80
83
  | 'KEY_STORE_DIRECTORY'
81
84
  | 'L1_CHAIN_ID'
82
85
  | 'L1_CONSENSUS_HOST_URLS'
86
+ | 'ETHEREUM_HTTP_TIMEOUT_MS'
83
87
  | 'L1_CONSENSUS_HOST_API_KEYS'
84
88
  | 'L1_CONSENSUS_HOST_API_KEY_HEADERS'
85
89
  | 'L1_TX_FAILED_STORE'
@@ -90,7 +94,6 @@ export type EnvVar =
90
94
  | 'MNEMONIC'
91
95
  | 'NETWORK'
92
96
  | 'NETWORK_CONFIG_LOCATION'
93
- | 'NO_PXE'
94
97
  | 'USE_GCLOUD_LOGGING'
95
98
  | 'OTEL_EXPORTER_OTLP_METRICS_ENDPOINT'
96
99
  | 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'
@@ -129,6 +132,7 @@ export type EnvVar =
129
132
  | 'P2P_L2_QUEUE_SIZE'
130
133
  | 'P2P_MAX_PEERS'
131
134
  | 'P2P_PEER_CHECK_INTERVAL_MS'
135
+ | 'P2P_PEER_FAILED_BAN_TIME_MS'
132
136
  | 'P2P_PEER_PENALTY_VALUES'
133
137
  | 'P2P_QUERY_FOR_IP'
134
138
  | 'P2P_REQRESP_INDIVIDUAL_REQUEST_TIMEOUT_MS'
@@ -152,6 +156,7 @@ export type EnvVar =
152
156
  | 'P2P_DROP_TX_CHANCE'
153
157
  | 'P2P_TX_POOL_DELETE_TXS_AFTER_REORG'
154
158
  | 'P2P_MIN_TX_POOL_AGE_MS'
159
+ | 'P2P_RPC_PRICE_BUMP_PERCENTAGE'
155
160
  | 'DEBUG_P2P_INSTRUMENT_MESSAGES'
156
161
  | 'PEER_ID_PRIVATE_KEY'
157
162
  | 'PEER_ID_PRIVATE_KEY_PATH'
@@ -167,6 +172,7 @@ export type EnvVar =
167
172
  | 'PROVER_BROKER_MAX_EPOCHS_TO_KEEP_RESULTS_FOR'
168
173
  | 'PROVER_BROKER_DEBUG_REPLAY_ENABLED'
169
174
  | 'PROVER_CANCEL_JOBS_ON_STOP'
175
+ | 'PROVER_ENQUEUE_CONCURRENCY'
170
176
  | 'PROVER_COORDINATION_NODE_URLS'
171
177
  | 'PROVER_PROOF_STORE'
172
178
  | 'PROVER_FAILED_PROOF_STORE'
@@ -200,17 +206,22 @@ export type EnvVar =
200
206
  | 'SENTINEL_ENABLED'
201
207
  | 'SENTINEL_HISTORY_LENGTH_IN_EPOCHS'
202
208
  | 'SENTINEL_HISTORIC_PROVEN_PERFORMANCE_LENGTH_IN_EPOCHS'
203
- | 'SEQ_MAX_BLOCK_SIZE_IN_BYTES'
209
+ | 'SEQ_ENABLE_PROPOSER_PIPELINING'
204
210
  | 'SEQ_MAX_TX_PER_BLOCK'
211
+ | 'SEQ_MAX_TX_PER_CHECKPOINT'
205
212
  | 'SEQ_MIN_TX_PER_BLOCK'
206
213
  | 'SEQ_PUBLISH_TXS_WITH_PROPOSALS'
207
214
  | 'SEQ_MAX_DA_BLOCK_GAS'
208
215
  | 'SEQ_MAX_L2_BLOCK_GAS'
216
+ | 'SEQ_PER_BLOCK_ALLOCATION_MULTIPLIER'
217
+ | 'SEQ_REDISTRIBUTE_CHECKPOINT_BUDGET'
209
218
  | 'SEQ_PUBLISHER_PRIVATE_KEY'
210
219
  | 'SEQ_PUBLISHER_PRIVATE_KEYS'
211
220
  | 'SEQ_PUBLISHER_ADDRESSES'
212
221
  | 'SEQ_PUBLISHER_ALLOW_INVALID_STATES'
213
222
  | 'SEQ_PUBLISHER_FORWARDER_ADDRESS'
223
+ | 'PUBLISHER_FUNDING_THRESHOLD'
224
+ | 'PUBLISHER_FUNDING_AMOUNT'
214
225
  | 'SEQ_POLLING_INTERVAL_MS'
215
226
  | 'SEQ_ENFORCE_TIME_TABLE'
216
227
  | 'SEQ_L1_PUBLISHING_TIME_ALLOWANCE_IN_SLOT'
@@ -221,8 +232,6 @@ export type EnvVar =
221
232
  | 'SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_COMMITTEE_MEMBER'
222
233
  | 'SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_NON_COMMITTEE_MEMBER'
223
234
  | 'SEQ_SKIP_CHECKPOINT_PUBLISH_PERCENT'
224
- | 'SLASH_MIN_PENALTY_PERCENTAGE'
225
- | 'SLASH_MAX_PENALTY_PERCENTAGE'
226
235
  | 'SLASH_VALIDATORS_ALWAYS'
227
236
  | 'SLASH_VALIDATORS_NEVER'
228
237
  | 'SLASH_PRUNE_PENALTY'
@@ -247,6 +256,7 @@ export type EnvVar =
247
256
  | 'TELEMETRY'
248
257
  | 'TEST_ACCOUNTS'
249
258
  | 'SPONSORED_FPC'
259
+ | 'PREFUND_ADDRESSES'
250
260
  | 'TX_COLLECTION_FAST_NODES_TIMEOUT_BEFORE_REQ_RESP_MS'
251
261
  | 'TX_COLLECTION_SLOW_NODES_INTERVAL_MS'
252
262
  | 'TX_COLLECTION_SLOW_REQ_RESP_INTERVAL_MS'
@@ -276,9 +286,12 @@ export type EnvVar =
276
286
  | 'TRANSACTIONS_DISABLED'
277
287
  | 'VALIDATOR_ATTESTATIONS_POLLING_INTERVAL_MS'
278
288
  | 'VALIDATOR_DISABLED'
289
+ | 'VALIDATOR_MAX_DA_BLOCK_GAS'
290
+ | 'VALIDATOR_MAX_L2_BLOCK_GAS'
291
+ | 'VALIDATOR_MAX_TX_PER_BLOCK'
292
+ | 'VALIDATOR_MAX_TX_PER_CHECKPOINT'
279
293
  | 'VALIDATOR_PRIVATE_KEYS'
280
294
  | 'VALIDATOR_PRIVATE_KEY'
281
- | 'VALIDATOR_REEXECUTE'
282
295
  | 'VALIDATOR_ADDRESSES'
283
296
  | 'ROLLUP_VERSION'
284
297
  | 'WS_BLOCK_CHECK_INTERVAL_MS'
@@ -311,7 +324,7 @@ export type EnvVar =
311
324
  | 'AZTEC_SLASH_AMOUNT_SMALL'
312
325
  | 'AZTEC_SLASH_AMOUNT_MEDIUM'
313
326
  | 'AZTEC_SLASH_AMOUNT_LARGE'
314
- | 'AZTEC_SLASHER_FLAVOR'
327
+ | 'AZTEC_SLASHER_ENABLED'
315
328
  | 'AZTEC_GOVERNANCE_PROPOSER_QUORUM'
316
329
  | 'AZTEC_GOVERNANCE_PROPOSER_ROUND_SIZE'
317
330
  | 'AZTEC_GOVERNANCE_VOTING_DURATION'
@@ -340,12 +353,12 @@ export type EnvVar =
340
353
  | 'K8S_POD_NAME'
341
354
  | 'K8S_POD_UID'
342
355
  | 'K8S_NAMESPACE_NAME'
343
- | 'VALIDATOR_REEXECUTE_DEADLINE_MS'
344
- | 'AUTO_UPDATE'
345
- | 'AUTO_UPDATE_URL'
356
+ | 'ENABLE_VERSION_CHECK'
346
357
  | 'WEB3_SIGNER_URL'
347
358
  | 'SKIP_ARCHIVER_INITIAL_SYNC'
348
359
  | 'BLOB_ALLOW_EMPTY_SOURCES'
360
+ | 'BLOB_PREFER_FILESTORES'
361
+ | 'BLOB_FILE_STORE_TIMEOUT_MS'
349
362
  | 'FISHERMAN_MODE'
350
363
  | 'MAX_ALLOWED_ETH_CLIENT_DRIFT_SECONDS'
351
364
  | 'LEGACY_BLS_CLI'
@@ -177,6 +177,21 @@ export function bigintConfigHelper(defaultVal?: bigint): Pick<ConfigMapping, 'pa
177
177
  if (val === '') {
178
178
  return defaultVal;
179
179
  }
180
+ // Handle scientific notation (e.g. "1e+23", "2E23") which BigInt() doesn't accept directly.
181
+ // We parse it losslessly using bigint arithmetic instead of going through float64.
182
+ if (/[eE]/.test(val)) {
183
+ const match = val.match(/^(-?\d+(?:\.(\d+))?)[eE]([+-]?\d+)$/);
184
+ if (!match) {
185
+ throw new Error(`Cannot convert '${val}' to a BigInt`);
186
+ }
187
+ const digits = match[1].replace('.', '');
188
+ const decimalPlaces = match[2]?.length ?? 0;
189
+ const exponent = parseInt(match[3], 10) - decimalPlaces;
190
+ if (exponent < 0) {
191
+ throw new Error(`Cannot convert '${val}' to a BigInt: result is not an integer`);
192
+ }
193
+ return BigInt(digits) * 10n ** BigInt(exponent);
194
+ }
180
195
  return BigInt(val);
181
196
  },
182
197
  defaultValue: defaultVal,
@@ -5,10 +5,13 @@ export const NetworkConfigSchema = z
5
5
  bootnodes: z.array(z.string()),
6
6
  snapshots: z.array(z.string()),
7
7
  blobFileStoreUrls: z.array(z.string()).optional(),
8
+ txCollectionFileStoreUrls: z.array(z.string()).optional(),
8
9
  registryAddress: z.string(),
9
10
  feeAssetHandlerAddress: z.string().optional(),
10
11
  l1ChainId: z.number(),
11
12
  blockDurationMs: z.number().positive().optional(),
13
+ txPublicSetupAllowListExtend: z.string().optional(),
14
+ nodeVersion: z.string().optional(),
12
15
  })
13
16
  .passthrough(); // Allow additional unknown fields to pass through
14
17
 
@@ -59,10 +59,19 @@ export class Aes128 {
59
59
  * @param iv - AES initialization vector.
60
60
  * @param key - Key to decrypt with.
61
61
  * @returns Decrypted data.
62
+ * @throws If the decrypted buffer has invalid PKCS#7 padding.
62
63
  */
63
64
  public async decryptBufferCBC(data: Uint8Array, iv: Uint8Array, key: Uint8Array) {
64
65
  const paddedBuffer = await this.decryptBufferCBCKeepPadding(data, iv, key);
65
- const paddingToRemove = paddedBuffer[paddedBuffer.length - 1];
66
- return paddedBuffer.subarray(0, paddedBuffer.length - paddingToRemove);
66
+ const paddingLen = paddedBuffer[paddedBuffer.length - 1];
67
+ if (paddingLen === 0 || paddingLen > 16) {
68
+ throw new Error(`Invalid PKCS#7 padding length: ${paddingLen}`);
69
+ }
70
+ for (let i = paddedBuffer.length - paddingLen; i < paddedBuffer.length; i++) {
71
+ if (paddedBuffer[i] !== paddingLen) {
72
+ throw new Error('Invalid PKCS#7 padding');
73
+ }
74
+ }
75
+ return paddedBuffer.subarray(0, paddedBuffer.length - paddingLen);
67
76
  }
68
77
  }
@@ -262,26 +262,3 @@ export function decryptBn254KeystoreFromObject(keystore: Bn254Keystore, password
262
262
  throw new Bn254KeystoreError(`Failed to decrypt keystore: ${String(error)}`, error as Error);
263
263
  }
264
264
  }
265
-
266
- /**
267
- * Validates that a decrypted private key matches the public key in the keystore.
268
- *
269
- * @param privateKeyHex - Decrypted private key (0x-prefixed)
270
- * @param expectedPubkey - Expected public key from keystore
271
- * @param computePublicKey - Function to compute public key from private key
272
- * @returns true if keys match, false otherwise
273
- */
274
- export function verifyBn254Keypair(
275
- privateKeyHex: string,
276
- expectedPubkey: string,
277
- computePublicKey: (privateKey: string) => string,
278
- ): boolean {
279
- try {
280
- const computedPubkey = computePublicKey(privateKeyHex);
281
- const normalizedExpected = expectedPubkey.toLowerCase().replace(/^0x/i, '');
282
- const normalizedComputed = computedPubkey.toLowerCase().replace(/^0x/i, '');
283
- return normalizedExpected === normalizedComputed;
284
- } catch {
285
- return false;
286
- }
287
- }
@@ -1,21 +1,35 @@
1
- import { Barretenberg } from '@aztec/bb.js';
1
+ import { Barretenberg, BarretenbergSync } from '@aztec/bb.js';
2
2
 
3
3
  import { Fr } from '../../curves/bn254/field.js';
4
4
  import { type Fieldable, serializeToFields } from '../../serialize/serialize.js';
5
5
 
6
+ const IS_BROWSER = typeof self !== 'undefined';
7
+
8
+ async function poseidon2HashFields(inputFields: Fr[]): Promise<Fr> {
9
+ if (IS_BROWSER) {
10
+ await BarretenbergSync.initSingleton();
11
+ const api = BarretenbergSync.getSingleton();
12
+ const response = api.poseidon2Hash({
13
+ inputs: inputFields.map(i => i.toBuffer()),
14
+ });
15
+ return Fr.fromBuffer(Buffer.from(response.hash));
16
+ } else {
17
+ await Barretenberg.initSingleton();
18
+ const api = Barretenberg.getSingleton();
19
+ const response = await api.poseidon2Hash({
20
+ inputs: inputFields.map(i => i.toBuffer()),
21
+ });
22
+ return Fr.fromBuffer(Buffer.from(response.hash));
23
+ }
24
+ }
25
+
6
26
  /**
7
27
  * Create a poseidon hash (field) from an array of input fields.
8
28
  * @param input - The input fields to hash.
9
29
  * @returns The poseidon hash.
10
30
  */
11
- export async function poseidon2Hash(input: Fieldable[]): Promise<Fr> {
12
- const inputFields = serializeToFields(input);
13
- await Barretenberg.initSingleton();
14
- const api = Barretenberg.getSingleton();
15
- const response = await api.poseidon2Hash({
16
- inputs: inputFields.map(i => i.toBuffer()),
17
- });
18
- return Fr.fromBuffer(Buffer.from(response.hash));
31
+ export function poseidon2Hash(input: Fieldable[]): Promise<Fr> {
32
+ return poseidon2HashFields(serializeToFields(input));
19
33
  }
20
34
 
21
35
  /**
@@ -24,15 +38,10 @@ export async function poseidon2Hash(input: Fieldable[]): Promise<Fr> {
24
38
  * @param separator - The domain separator.
25
39
  * @returns The poseidon hash.
26
40
  */
27
- export async function poseidon2HashWithSeparator(input: Fieldable[], separator: number): Promise<Fr> {
41
+ export function poseidon2HashWithSeparator(input: Fieldable[], separator: number): Promise<Fr> {
28
42
  const inputFields = serializeToFields(input);
29
43
  inputFields.unshift(new Fr(separator));
30
- await Barretenberg.initSingleton();
31
- const api = Barretenberg.getSingleton();
32
- const response = await api.poseidon2Hash({
33
- inputs: inputFields.map(i => i.toBuffer()),
34
- });
35
- return Fr.fromBuffer(Buffer.from(response.hash));
44
+ return poseidon2HashFields(inputFields);
36
45
  }
37
46
 
38
47
  /**
@@ -42,19 +51,24 @@ export async function poseidon2HashWithSeparator(input: Fieldable[], separator:
42
51
  */
43
52
  export async function poseidon2Permutation(input: Fieldable[]): Promise<Fr[]> {
44
53
  const inputFields = serializeToFields(input);
45
- // We'd like this assertion but it's not possible to use it in the browser.
46
- // assert(input.length === 4, 'Input state must be of size 4');
47
- await Barretenberg.initSingleton();
48
- const api = Barretenberg.getSingleton();
49
- const response = await api.poseidon2Permutation({
50
- inputs: inputFields.map(i => i.toBuffer()),
51
- });
52
- // We'd like this assertion but it's not possible to use it in the browser.
53
- // assert(response.outputs.length === 4, 'Output state must be of size 4');
54
- return response.outputs.map(o => Fr.fromBuffer(Buffer.from(o)));
54
+ if (IS_BROWSER) {
55
+ await BarretenbergSync.initSingleton();
56
+ const api = BarretenbergSync.getSingleton();
57
+ const response = api.poseidon2Permutation({
58
+ inputs: inputFields.map(i => i.toBuffer()),
59
+ });
60
+ return response.outputs.map(o => Fr.fromBuffer(Buffer.from(o)));
61
+ } else {
62
+ await Barretenberg.initSingleton();
63
+ const api = Barretenberg.getSingleton();
64
+ const response = await api.poseidon2Permutation({
65
+ inputs: inputFields.map(i => i.toBuffer()),
66
+ });
67
+ return response.outputs.map(o => Fr.fromBuffer(Buffer.from(o)));
68
+ }
55
69
  }
56
70
 
57
- export async function poseidon2HashBytes(input: Buffer): Promise<Fr> {
71
+ export function poseidon2HashBytes(input: Buffer): Promise<Fr> {
58
72
  const inputFields = [];
59
73
  for (let i = 0; i < input.length; i += 31) {
60
74
  const fieldBytes = Buffer.alloc(32, 0);
@@ -65,11 +79,5 @@ export async function poseidon2HashBytes(input: Buffer): Promise<Fr> {
65
79
  inputFields.push(Fr.fromBuffer(fieldBytes));
66
80
  }
67
81
 
68
- await Barretenberg.initSingleton();
69
- const api = Barretenberg.getSingleton();
70
- const response = await api.poseidon2Hash({
71
- inputs: inputFields.map(i => i.toBuffer()),
72
- });
73
-
74
- return Fr.fromBuffer(Buffer.from(response.hash));
82
+ return poseidon2HashFields(inputFields);
75
83
  }
@@ -210,3 +210,35 @@ export function recoverPublicKey(hash: Buffer32, signature: Signature, opts: Rec
210
210
  const publicKey = sig.recoverPublicKey(hash.buffer).toHex(false);
211
211
  return Buffer.from(publicKey, 'hex');
212
212
  }
213
+
214
+ /** Arbitrary hash used for testing signature recoverability. */
215
+ const PROBE_HASH = Buffer32.fromBuffer(keccak256(Buffer.from('signature-recoverability-probe')));
216
+
217
+ /**
218
+ * Generates a random valid ECDSA signature that is recoverable to some address.
219
+ * Since Signature.random() produces real signatures via secp256k1 signing, the result is always
220
+ * recoverable, but we verify defensively by checking tryRecoverAddress.
221
+ */
222
+ export function generateRecoverableSignature(): Signature {
223
+ for (let i = 0; i < 100; i++) {
224
+ const sig = Signature.random();
225
+ if (tryRecoverAddress(PROBE_HASH, sig) !== undefined) {
226
+ return sig;
227
+ }
228
+ }
229
+ throw new Secp256k1Error('Failed to generate a recoverable signature after 100 attempts');
230
+ }
231
+
232
+ /**
233
+ * Generates a random signature where ECDSA address recovery fails.
234
+ * Uses random r/s values (not from real signing) so that r is unlikely to be a valid secp256k1 x-coordinate.
235
+ */
236
+ export function generateUnrecoverableSignature(): Signature {
237
+ for (let i = 0; i < 100; i++) {
238
+ const sig = new Signature(Buffer32.random(), Buffer32.random(), 27);
239
+ if (tryRecoverAddress(PROBE_HASH, sig) === undefined) {
240
+ return sig;
241
+ }
242
+ }
243
+ throw new Secp256k1Error('Failed to generate an unrecoverable signature after 100 attempts');
244
+ }
@@ -65,7 +65,7 @@ export class Point {
65
65
  }
66
66
 
67
67
  /**
68
- * Generate a random Point instance.
68
+ * Generate a random Point instance that is on the curve.
69
69
  *
70
70
  * @returns A randomly generated Point instance.
71
71
  */
@@ -125,9 +125,12 @@ export class Point {
125
125
  }
126
126
 
127
127
  /**
128
- * Returns the contents of the point as an array of 2 fields.
129
- * @returns The point as an array of 2 fields
128
+ * Returns the contents of the point as an array of 3 fields.
129
+ * @returns The point as an array of 3 fields
130
130
  */
131
+ // TODO(F-553): Once we take the breaking change and drop the custom Noir `Point` wrapper in
132
+ // `noir-projects/noir-protocol-circuits/crates/types/src/point.nr`, revert this to serialize as `[x, y]` (2 fields)
133
+ // and drop the `is_infinite` flag from `fromFields` / `toNoirStruct` below.
131
134
  toFields() {
132
135
  return [this.x, this.y, new Fr(this.isInfinite)];
133
136
  }
@@ -1,8 +1,10 @@
1
1
  import { Buffer32 } from '@aztec/foundation/buffer';
2
2
  import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
3
3
 
4
+ import { secp256k1 } from '@noble/curves/secp256k1';
4
5
  import { z } from 'zod';
5
6
 
7
+ import { randomBytes } from '../crypto/random/index.js';
6
8
  import { hasHexPrefix, hexToBuffer } from '../string/index.js';
7
9
 
8
10
  /**
@@ -77,8 +79,12 @@ export class Signature {
77
79
  return new Signature(Buffer32.fromBuffer(hexToBuffer(sig.r)), Buffer32.fromBuffer(hexToBuffer(sig.s)), sig.yParity);
78
80
  }
79
81
 
82
+ /** Generates a random valid ECDSA signature with a low s-value by signing a random message with a random key. */
80
83
  static random(): Signature {
81
- return new Signature(Buffer32.random(), Buffer32.random(), 1);
84
+ const privateKey = randomBytes(32);
85
+ const message = randomBytes(32);
86
+ const { r, s, recovery } = secp256k1.sign(message, privateKey);
87
+ return new Signature(Buffer32.fromBigInt(r), Buffer32.fromBigInt(s), recovery ? 28 : 27);
82
88
  }
83
89
 
84
90
  static empty(): Signature {