@aztec/stdlib 0.0.1-commit.88e6f9396 → 0.0.1-commit.8c0b8ff

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 (216) hide show
  1. package/dest/abi/abi.d.ts +26 -191
  2. package/dest/abi/abi.d.ts.map +1 -1
  3. package/dest/abi/abi.js +45 -4
  4. package/dest/abi/buffer.d.ts +14 -4
  5. package/dest/abi/buffer.d.ts.map +1 -1
  6. package/dest/abi/buffer.js +25 -4
  7. package/dest/abi/decoder.d.ts +5 -44
  8. package/dest/abi/decoder.d.ts.map +1 -1
  9. package/dest/abi/decoder.js +12 -67
  10. package/dest/abi/function_selector.js +1 -1
  11. package/dest/abi/function_signature_decoder.d.ts +43 -0
  12. package/dest/abi/function_signature_decoder.d.ts.map +1 -0
  13. package/dest/abi/function_signature_decoder.js +66 -0
  14. package/dest/abi/index.d.ts +2 -1
  15. package/dest/abi/index.d.ts.map +1 -1
  16. package/dest/abi/index.js +1 -0
  17. package/dest/abi/selector.d.ts +2 -2
  18. package/dest/abi/selector.d.ts.map +1 -1
  19. package/dest/abi/selector.js +1 -1
  20. package/dest/avm/avm_accumulated_data.js +2 -2
  21. package/dest/avm/avm_circuit_public_inputs.js +2 -2
  22. package/dest/avm/revert_code.d.ts +8 -18
  23. package/dest/avm/revert_code.d.ts.map +1 -1
  24. package/dest/avm/revert_code.js +15 -30
  25. package/dest/block/l2_block_source.d.ts +5 -3
  26. package/dest/block/l2_block_source.d.ts.map +1 -1
  27. package/dest/block/l2_block_stream/interfaces.d.ts +6 -3
  28. package/dest/block/l2_block_stream/interfaces.d.ts.map +1 -1
  29. package/dest/config/index.d.ts +1 -2
  30. package/dest/config/index.d.ts.map +1 -1
  31. package/dest/config/index.js +0 -1
  32. package/dest/config/sequencer-config.d.ts +1 -3
  33. package/dest/config/sequencer-config.d.ts.map +1 -1
  34. package/dest/config/sequencer-config.js +0 -1
  35. package/dest/contract/contract_address.d.ts +3 -3
  36. package/dest/contract/contract_address.js +3 -3
  37. package/dest/contract/contract_class_id.d.ts +2 -2
  38. package/dest/contract/contract_class_id.js +2 -2
  39. package/dest/epoch-helpers/index.d.ts +5 -1
  40. package/dest/epoch-helpers/index.d.ts.map +1 -1
  41. package/dest/epoch-helpers/index.js +9 -0
  42. package/dest/gas/gas_settings.d.ts +40 -3
  43. package/dest/gas/gas_settings.d.ts.map +1 -1
  44. package/dest/gas/gas_settings.js +50 -6
  45. package/dest/hash/hash.d.ts +4 -1
  46. package/dest/hash/hash.d.ts.map +1 -1
  47. package/dest/hash/hash.js +5 -0
  48. package/dest/interfaces/aztec-node-admin.d.ts +4 -13
  49. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  50. package/dest/interfaces/aztec-node-debug.d.ts +21 -0
  51. package/dest/interfaces/aztec-node-debug.d.ts.map +1 -0
  52. package/dest/interfaces/aztec-node-debug.js +18 -0
  53. package/dest/interfaces/client.d.ts +2 -1
  54. package/dest/interfaces/client.d.ts.map +1 -1
  55. package/dest/interfaces/client.js +1 -0
  56. package/dest/interfaces/l2_logs_source.d.ts +3 -5
  57. package/dest/interfaces/l2_logs_source.d.ts.map +1 -1
  58. package/dest/interfaces/proving-job.d.ts +166 -166
  59. package/dest/interfaces/validator.d.ts +17 -37
  60. package/dest/interfaces/validator.d.ts.map +1 -1
  61. package/dest/interfaces/validator.js +2 -2
  62. package/dest/kernel/claimed_length_array.js +1 -1
  63. package/dest/kernel/hints/private_kernel_reset_hints.d.ts +1 -1
  64. package/dest/kernel/hints/private_kernel_reset_hints.d.ts.map +1 -1
  65. package/dest/kernel/padded_side_effects.js +1 -1
  66. package/dest/kernel/private_to_avm_accumulated_data.js +2 -2
  67. package/dest/kernel/private_to_public_accumulated_data.js +2 -2
  68. package/dest/kernel/private_to_rollup_accumulated_data.js +1 -1
  69. package/dest/logs/extended_directional_app_tagging_secret.d.ts +4 -4
  70. package/dest/logs/extended_directional_app_tagging_secret.d.ts.map +1 -1
  71. package/dest/logs/extended_directional_app_tagging_secret.js +12 -5
  72. package/dest/logs/message_context.d.ts +4 -7
  73. package/dest/logs/message_context.d.ts.map +1 -1
  74. package/dest/logs/message_context.js +23 -9
  75. package/dest/logs/pending_tagged_log.d.ts +2 -3
  76. package/dest/logs/pending_tagged_log.d.ts.map +1 -1
  77. package/dest/logs/pending_tagged_log.js +2 -2
  78. package/dest/logs/private_log.js +1 -1
  79. package/dest/logs/public_log.d.ts +1 -1
  80. package/dest/logs/public_log.d.ts.map +1 -1
  81. package/dest/logs/public_log.js +7 -1
  82. package/dest/logs/shared_secret_derivation.d.ts +11 -10
  83. package/dest/logs/shared_secret_derivation.d.ts.map +1 -1
  84. package/dest/logs/shared_secret_derivation.js +15 -9
  85. package/dest/logs/siloed_tag.d.ts +4 -1
  86. package/dest/logs/siloed_tag.d.ts.map +1 -1
  87. package/dest/logs/siloed_tag.js +7 -3
  88. package/dest/messaging/l1_to_l2_message.d.ts +3 -2
  89. package/dest/messaging/l1_to_l2_message.d.ts.map +1 -1
  90. package/dest/messaging/l1_to_l2_message.js +11 -13
  91. package/dest/messaging/l1_to_l2_message_source.d.ts +2 -4
  92. package/dest/messaging/l1_to_l2_message_source.d.ts.map +1 -1
  93. package/dest/note/note_dao.d.ts +1 -1
  94. package/dest/note/note_dao.d.ts.map +1 -1
  95. package/dest/note/note_dao.js +1 -4
  96. package/dest/p2p/block_proposal.d.ts +2 -2
  97. package/dest/p2p/block_proposal.d.ts.map +1 -1
  98. package/dest/p2p/block_proposal.js +1 -1
  99. package/dest/p2p/checkpoint_proposal.d.ts +2 -2
  100. package/dest/p2p/checkpoint_proposal.d.ts.map +1 -1
  101. package/dest/p2p/checkpoint_proposal.js +1 -1
  102. package/dest/parity/parity_base_private_inputs.js +1 -1
  103. package/dest/proofs/chonk_proof.d.ts +1 -1
  104. package/dest/proofs/chonk_proof.d.ts.map +1 -1
  105. package/dest/proofs/chonk_proof.js +7 -1
  106. package/dest/rollup/base_rollup_hints.js +2 -2
  107. package/dest/rollup/block_root_rollup_private_inputs.js +5 -5
  108. package/dest/rollup/checkpoint_rollup_public_inputs.js +1 -1
  109. package/dest/rollup/checkpoint_root_rollup_private_inputs.js +3 -3
  110. package/dest/rollup/root_rollup_public_inputs.js +1 -1
  111. package/dest/rollup/tree_snapshot_diff_hints.js +2 -2
  112. package/dest/tests/factories.js +1 -1
  113. package/dest/tests/mocks.d.ts +1 -1
  114. package/dest/tests/mocks.d.ts.map +1 -1
  115. package/dest/tests/mocks.js +2 -2
  116. package/dest/tx/capsule.d.ts +6 -2
  117. package/dest/tx/capsule.d.ts.map +1 -1
  118. package/dest/tx/capsule.js +9 -3
  119. package/dest/tx/protocol_contracts.js +2 -2
  120. package/dest/tx/simulated_tx.d.ts +29 -154
  121. package/dest/tx/simulated_tx.d.ts.map +1 -1
  122. package/dest/tx/simulated_tx.js +3 -3
  123. package/dest/tx/tx_receipt.d.ts +8 -4
  124. package/dest/tx/tx_receipt.d.ts.map +1 -1
  125. package/dest/tx/tx_receipt.js +8 -15
  126. package/dest/tx/validator/error_texts.d.ts +5 -1
  127. package/dest/tx/validator/error_texts.d.ts.map +1 -1
  128. package/dest/tx/validator/error_texts.js +6 -0
  129. package/dest/vks/vk_data.js +1 -1
  130. package/package.json +10 -11
  131. package/src/abi/abi.ts +67 -14
  132. package/src/abi/buffer.ts +25 -4
  133. package/src/abi/decoder.ts +23 -78
  134. package/src/abi/function_selector.ts +1 -1
  135. package/src/abi/function_signature_decoder.ts +77 -0
  136. package/src/abi/index.ts +1 -0
  137. package/src/abi/selector.ts +1 -1
  138. package/src/avm/avm_accumulated_data.ts +6 -6
  139. package/src/avm/avm_circuit_public_inputs.ts +4 -4
  140. package/src/avm/revert_code.ts +25 -39
  141. package/src/block/l2_block_source.ts +4 -2
  142. package/src/block/l2_block_stream/interfaces.ts +6 -2
  143. package/src/config/index.ts +0 -1
  144. package/src/config/sequencer-config.ts +0 -3
  145. package/src/contract/contract_address.ts +3 -3
  146. package/src/contract/contract_class_id.ts +2 -2
  147. package/src/epoch-helpers/index.ts +19 -0
  148. package/src/gas/gas_settings.ts +65 -12
  149. package/src/hash/hash.ts +5 -0
  150. package/src/interfaces/aztec-node-debug.ts +40 -0
  151. package/src/interfaces/client.ts +1 -0
  152. package/src/interfaces/l2_logs_source.ts +1 -4
  153. package/src/interfaces/validator.ts +34 -40
  154. package/src/kernel/claimed_length_array.ts +2 -2
  155. package/src/kernel/hints/private_kernel_reset_hints.ts +5 -2
  156. package/src/kernel/hints/read_request_hints.ts +3 -3
  157. package/src/kernel/padded_side_effects.ts +3 -3
  158. package/src/kernel/private_to_avm_accumulated_data.ts +4 -4
  159. package/src/kernel/private_to_public_accumulated_data.ts +10 -10
  160. package/src/kernel/private_to_rollup_accumulated_data.ts +5 -5
  161. package/src/logs/extended_directional_app_tagging_secret.ts +19 -8
  162. package/src/logs/message_context.ts +17 -7
  163. package/src/logs/pending_tagged_log.ts +1 -3
  164. package/src/logs/private_log.ts +1 -1
  165. package/src/logs/public_log.ts +11 -1
  166. package/src/logs/shared_secret_derivation.ts +21 -10
  167. package/src/logs/siloed_tag.ts +7 -2
  168. package/src/messaging/l1_to_l2_message.ts +12 -9
  169. package/src/messaging/l1_to_l2_message_source.ts +1 -3
  170. package/src/note/note_dao.ts +1 -4
  171. package/src/p2p/block_proposal.ts +1 -1
  172. package/src/p2p/checkpoint_proposal.ts +1 -1
  173. package/src/parity/parity_base_private_inputs.ts +1 -1
  174. package/src/proofs/chonk_proof.ts +9 -1
  175. package/src/rollup/base_rollup_hints.ts +2 -2
  176. package/src/rollup/block_root_rollup_private_inputs.ts +8 -8
  177. package/src/rollup/checkpoint_rollup_public_inputs.ts +2 -2
  178. package/src/rollup/checkpoint_root_rollup_private_inputs.ts +4 -4
  179. package/src/rollup/root_rollup_public_inputs.ts +2 -2
  180. package/src/rollup/tree_snapshot_diff_hints.ts +5 -5
  181. package/src/tests/factories.ts +1 -1
  182. package/src/tests/mocks.ts +2 -2
  183. package/src/tx/capsule.ts +10 -2
  184. package/src/tx/protocol_contracts.ts +2 -2
  185. package/src/tx/simulated_tx.ts +6 -2
  186. package/src/tx/tx_receipt.ts +11 -14
  187. package/src/tx/validator/error_texts.ts +8 -0
  188. package/src/vks/vk_data.ts +1 -1
  189. package/dest/config/pipelining-config.d.ts +0 -19
  190. package/dest/config/pipelining-config.d.ts.map +0 -1
  191. package/dest/config/pipelining-config.js +0 -18
  192. package/dest/ha-signing/config.d.ts +0 -136
  193. package/dest/ha-signing/config.d.ts.map +0 -1
  194. package/dest/ha-signing/config.js +0 -97
  195. package/dest/ha-signing/index.d.ts +0 -4
  196. package/dest/ha-signing/index.d.ts.map +0 -1
  197. package/dest/ha-signing/index.js +0 -3
  198. package/dest/ha-signing/local_config.d.ts +0 -63
  199. package/dest/ha-signing/local_config.d.ts.map +0 -1
  200. package/dest/ha-signing/local_config.js +0 -24
  201. package/dest/ha-signing/types.d.ts +0 -85
  202. package/dest/ha-signing/types.d.ts.map +0 -1
  203. package/dest/ha-signing/types.js +0 -32
  204. package/dest/kv-store/config.d.ts +0 -17
  205. package/dest/kv-store/config.d.ts.map +0 -1
  206. package/dest/kv-store/config.js +0 -26
  207. package/dest/kv-store/index.d.ts +0 -2
  208. package/dest/kv-store/index.d.ts.map +0 -1
  209. package/dest/kv-store/index.js +0 -1
  210. package/src/config/pipelining-config.ts +0 -31
  211. package/src/ha-signing/config.ts +0 -156
  212. package/src/ha-signing/index.ts +0 -27
  213. package/src/ha-signing/local_config.ts +0 -46
  214. package/src/ha-signing/types.ts +0 -112
  215. package/src/kv-store/config.ts +0 -36
  216. package/src/kv-store/index.ts +0 -1
@@ -2,10 +2,14 @@ import type { PublishedCheckpoint } from '../../checkpoint/published_checkpoint.
2
2
  import type { L2Block } from '../l2_block.js';
3
3
  import type { CheckpointId, L2BlockId, L2Tips } from '../l2_block_source.js';
4
4
 
5
+ /** Provides the current chain tips. Implemented by world-state, l2-tips-store, and AztecNode. */
6
+ export interface L2TipsProvider {
7
+ getL2Tips(): Promise<L2Tips>;
8
+ }
9
+
5
10
  /** Interface to the local view of the chain. Implemented by world-state and l2-tips-store. */
6
- export interface L2BlockStreamLocalDataProvider {
11
+ export interface L2BlockStreamLocalDataProvider extends L2TipsProvider {
7
12
  getL2BlockHash(number: number): Promise<string | undefined>;
8
- getL2Tips(): Promise<L2Tips>;
9
13
  }
10
14
 
11
15
  /** Interface to a handler of events emitted. */
@@ -1,4 +1,3 @@
1
1
  export * from './chain-config.js';
2
2
  export * from './node-rpc-config.js';
3
- export * from './pipelining-config.js';
4
3
  export * from './sequencer-config.js';
@@ -2,9 +2,6 @@ import type { ConfigMappingsType } from '@aztec/foundation/config';
2
2
 
3
3
  import type { SequencerConfig } from '../interfaces/configs.js';
4
4
 
5
- /** Default maximum number of transactions per block. */
6
- export const DEFAULT_MAX_TXS_PER_BLOCK = 32;
7
-
8
5
  /**
9
6
  * Partial sequencer config mappings for fields that need to be shared across packages.
10
7
  * The full sequencer config mappings remain in sequencer-client, but shared fields
@@ -13,9 +13,9 @@ import type { ContractInstance } from './interfaces/contract_instance.js';
13
13
  /**
14
14
  * Returns the deployment address for a given contract instance.
15
15
  * ```
16
- * salted_initialization_hash = poseidon2(DOM_SEP__PARTIAL_ADDRESS, [salt, initialization_hash, deployer])
17
- * partial_address = poseidon2(DOM_SEP__PARTIAL_ADDRESS, [contract_class_id, salted_initialization_hash])
18
- * address = ((poseidon2(DOM_SEP__CONTRACT_ADDRESS_V1, [public_keys_hash, partial_address]) * G) + ivpk_m).x <- the x-coordinate of the address point
16
+ * salted_initialization_hash = pedersen([salt, initialization_hash, deployer], GENERATOR__SALTED_INITIALIZATION_HASH)
17
+ * partial_address = pedersen([contract_class_id, salted_initialization_hash], GENERATOR__CONTRACT_PARTIAL_ADDRESS_V1)
18
+ * address = ((poseidon2Hash([public_keys_hash, partial_address, GENERATOR__CONTRACT_ADDRESS_V1]) * G) + ivpk_m).x <- the x-coordinate of the address point
19
19
  * ```
20
20
  * @param instance - A contract instance for which to calculate the deployment address.
21
21
  */
@@ -13,10 +13,10 @@ import { computePrivateFunctionsRoot } from './private_function.js';
13
13
  *
14
14
  * ```
15
15
  * version = 1
16
- * private_function_leaves = private_functions.map(fn => poseidon2(DOM_SEP__PRIVATE_FUNCTION_LEAF, [fn.function_selector as Field, fn.vk_hash]))
16
+ * private_function_leaves = private_functions.map(fn => pedersen([fn.function_selector as Field, fn.vk_hash], GENERATOR__PRIVATE_FUNCTION_LEAF))
17
17
  * private_functions_root = merkleize(private_function_leaves)
18
18
  * bytecode_commitment = calculate_commitment(packed_bytecode)
19
- * contract_class_id = poseidon2(DOM_SEP__CONTRACT_CLASS_ID, [version, artifact_hash, private_functions_root, bytecode_commitment])
19
+ * contract_class_id = pedersen([version, artifact_hash, private_functions_root, bytecode_commitment], GENERATOR__CLASS_IDENTIFIER)
20
20
  * ```
21
21
  * @param contractClass - Contract class.
22
22
  * @returns The identifier.
@@ -57,6 +57,25 @@ export function getSlotAtTimestamp(
57
57
  : SlotNumber.fromBigInt((ts - constants.l1GenesisTime) / BigInt(constants.slotDuration));
58
58
  }
59
59
 
60
+ /** Returns the timestamp of the next L1 slot boundary after the given wall-clock time. */
61
+ export function getNextL1SlotTimestamp(
62
+ nowInSeconds: number,
63
+ constants: Pick<L1RollupConstants, 'l1GenesisTime' | 'ethereumSlotDuration'>,
64
+ ): bigint {
65
+ const now = BigInt(nowInSeconds);
66
+ const elapsed = now - constants.l1GenesisTime;
67
+ const currentL1Slot = elapsed / BigInt(constants.ethereumSlotDuration);
68
+ return constants.l1GenesisTime + (currentL1Slot + 1n) * BigInt(constants.ethereumSlotDuration);
69
+ }
70
+
71
+ /** Returns the timestamp of the last L1 slot within a given L2 slot. */
72
+ export function getLastL1SlotTimestampForL2Slot(
73
+ slot: SlotNumber,
74
+ constants: Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration' | 'ethereumSlotDuration'>,
75
+ ): bigint {
76
+ return getTimestampForSlot(slot, constants) + BigInt(constants.slotDuration - constants.ethereumSlotDuration);
77
+ }
78
+
60
79
  /** Returns the L2 slot number at the next L1 block based on the current timestamp. */
61
80
  export function getSlotAtNextL1Block(
62
81
  currentL1Timestamp: bigint,
@@ -1,10 +1,4 @@
1
- import {
2
- DEFAULT_DA_GAS_LIMIT,
3
- DEFAULT_L2_GAS_LIMIT,
4
- DEFAULT_TEARDOWN_DA_GAS_LIMIT,
5
- DEFAULT_TEARDOWN_L2_GAS_LIMIT,
6
- GAS_SETTINGS_LENGTH,
7
- } from '@aztec/constants';
1
+ import { GAS_SETTINGS_LENGTH, MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT, MAX_PROCESSABLE_L2_GAS } from '@aztec/constants';
8
2
  import { Fr } from '@aztec/foundation/curves/bn254';
9
3
  import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize';
10
4
  import type { FieldsOf } from '@aztec/foundation/types';
@@ -14,6 +8,21 @@ import { z } from 'zod';
14
8
  import { Gas, GasDimensions } from './gas.js';
15
9
  import { GasFees } from './gas_fees.js';
16
10
 
11
+ /** Approximate max DA gas limit. Arbitrary, assuming 4 blocks per checkpoint — users should use gas estimation. */
12
+ export const APPROXIMATE_MAX_DA_GAS_PER_BLOCK = Math.floor(MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT / 4);
13
+ /** Fallback teardown L2 gas limit. Arbitrary — users should use gas estimation. */
14
+ export const FALLBACK_TEARDOWN_L2_GAS_LIMIT = Math.floor(MAX_PROCESSABLE_L2_GAS / 8);
15
+ /** Fallback teardown DA gas limit. Arbitrary — users should use gas estimation. */
16
+ export const FALLBACK_TEARDOWN_DA_GAS_LIMIT = Math.floor(APPROXIMATE_MAX_DA_GAS_PER_BLOCK / 2);
17
+
18
+ // For gas estimation, we use intentionally high limits above what the network can process,
19
+ // so the simulation runs without hitting gas caps. Since teardown gas is counted towards total,
20
+ // the total estimation limit is teardown + max processable.
21
+ export const GAS_ESTIMATION_TEARDOWN_L2_GAS_LIMIT = MAX_PROCESSABLE_L2_GAS;
22
+ export const GAS_ESTIMATION_L2_GAS_LIMIT = GAS_ESTIMATION_TEARDOWN_L2_GAS_LIMIT + MAX_PROCESSABLE_L2_GAS;
23
+ export const GAS_ESTIMATION_TEARDOWN_DA_GAS_LIMIT = MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT;
24
+ export const GAS_ESTIMATION_DA_GAS_LIMIT = GAS_ESTIMATION_TEARDOWN_DA_GAS_LIMIT + MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT;
25
+
17
26
  // docs:start:gas_settings_vars
18
27
  /** Gas usage and fees limits set by the transaction sender for different dimensions and phases. */
19
28
  export class GasSettings {
@@ -95,18 +104,62 @@ export class GasSettings {
95
104
  return new GasSettings(Gas.empty(), Gas.empty(), GasFees.empty(), GasFees.empty());
96
105
  }
97
106
 
98
- /** Default gas settings to use when user has not provided them. Requires explicit max fees per gas. */
99
- static default(overrides: {
107
+ /**
108
+ * Fills in gas limits high enough for transactions to be included in most cases.
109
+ * gasLimits is set to the maximum the protocol allows; since teardown gas is reserved
110
+ * from gasLimits during private execution (see gas_meter.nr), the effective gas available
111
+ * for app logic will be gasLimits - teardownGasLimits - privateOverhead.
112
+ * The DA gas limit is set to an approximate max per block assuming 4 blocks per checkpoint,
113
+ * since using the maximum per checkpoint would cause nodes to reject transactions.
114
+ * These values won't work if:
115
+ * - Teardown consumes more than the arbitrarily assigned fallback limits
116
+ * - The rest of the transaction consumes more than the remaining gas after teardown
117
+ * - The DA gas limit is too low for the transaction, while still within the checkpoint limit
118
+ */
119
+ static fallback(overrides: {
120
+ gasLimits?: Gas;
121
+ teardownGasLimits?: Gas;
122
+ maxFeesPerGas: GasFees;
123
+ maxPriorityFeesPerGas?: GasFees;
124
+ }) {
125
+ return GasSettings.from({
126
+ gasLimits: overrides.gasLimits ?? {
127
+ l2Gas: MAX_PROCESSABLE_L2_GAS,
128
+ daGas: APPROXIMATE_MAX_DA_GAS_PER_BLOCK,
129
+ },
130
+ teardownGasLimits: overrides.teardownGasLimits ?? {
131
+ l2Gas: FALLBACK_TEARDOWN_L2_GAS_LIMIT,
132
+ daGas: FALLBACK_TEARDOWN_DA_GAS_LIMIT,
133
+ },
134
+ maxFeesPerGas: overrides.maxFeesPerGas,
135
+ maxPriorityFeesPerGas: overrides.maxPriorityFeesPerGas ?? GasFees.empty(),
136
+ });
137
+ }
138
+
139
+ /**
140
+ * Gas settings for simulation/estimation only.
141
+ * Since teardown gas is reserved upfront from gasLimits during private execution (see gas_meter.nr),
142
+ * the effective gas available for app logic is gasLimits - teardownGasLimits - privateOverhead.
143
+ * To ensure estimation never hits gas caps, we set both limits above what the protocol allows:
144
+ * teardown gets MAX_PROCESSABLE and gasLimits gets teardown + MAX_PROCESSABLE, so the full
145
+ * processable amount remains available for each phase independently. To be used in conjunction
146
+ * with skipTxValidation: true during public simulation, or the node would reject the transaction
147
+ * outright due to gas limits being above protocol max.
148
+ */
149
+ static forEstimation(overrides: {
100
150
  gasLimits?: Gas;
101
151
  teardownGasLimits?: Gas;
102
152
  maxFeesPerGas: GasFees;
103
153
  maxPriorityFeesPerGas?: GasFees;
104
154
  }) {
105
155
  return GasSettings.from({
106
- gasLimits: overrides.gasLimits ?? { l2Gas: DEFAULT_L2_GAS_LIMIT, daGas: DEFAULT_DA_GAS_LIMIT },
156
+ gasLimits: overrides.gasLimits ?? {
157
+ l2Gas: GAS_ESTIMATION_L2_GAS_LIMIT,
158
+ daGas: GAS_ESTIMATION_DA_GAS_LIMIT,
159
+ },
107
160
  teardownGasLimits: overrides.teardownGasLimits ?? {
108
- l2Gas: DEFAULT_TEARDOWN_L2_GAS_LIMIT,
109
- daGas: DEFAULT_TEARDOWN_DA_GAS_LIMIT,
161
+ l2Gas: GAS_ESTIMATION_TEARDOWN_L2_GAS_LIMIT,
162
+ daGas: GAS_ESTIMATION_TEARDOWN_DA_GAS_LIMIT,
110
163
  },
111
164
  maxFeesPerGas: overrides.maxFeesPerGas,
112
165
  maxPriorityFeesPerGas: overrides.maxPriorityFeesPerGas ?? GasFees.empty(),
package/src/hash/hash.ts CHANGED
@@ -98,6 +98,11 @@ export function computeProtocolNullifier(txRequestHash: Fr): Promise<Fr> {
98
98
  return siloNullifier(AztecAddress.fromBigInt(NULL_MSG_SENDER_CONTRACT_ADDRESS), txRequestHash);
99
99
  }
100
100
 
101
+ /** Domain-separates a raw log tag with the given domain separator. */
102
+ export function computeLogTag(rawTag: number | bigint | boolean | Fr | Buffer, domSep: DomainSeparator): Promise<Fr> {
103
+ return poseidon2HashWithSeparator([new Fr(rawTag)], domSep);
104
+ }
105
+
101
106
  export function computeSiloedPrivateLogFirstField(contract: AztecAddress, field: Fr): Promise<Fr> {
102
107
  return poseidon2HashWithSeparator([contract, field], DomainSeparator.PRIVATE_LOG_FIRST_FIELD);
103
108
  }
@@ -0,0 +1,40 @@
1
+ import { createSafeJsonRpcClient, defaultFetch } from '@aztec/foundation/json-rpc/client';
2
+
3
+ import { z } from 'zod';
4
+
5
+ import type { ApiSchemaFor } from '../schemas/schemas.js';
6
+ import { type ComponentsVersions, getVersioningResponseHandler } from '../versioning/index.js';
7
+
8
+ /**
9
+ * Debug interface for Aztec node available in sandbox/local-network mode.
10
+ */
11
+ export interface AztecNodeDebug {
12
+ /**
13
+ * Triggers the sequencer to produce an L2 block and waits for it to appear.
14
+ *
15
+ * **Precondition**: The current L2 slot must not already contain a block. Callers must ensure L1 time has been
16
+ * advanced to a slot with no existing block before calling this method (e.g. via `EthCheatCodes.warp()`).
17
+ * If the slot is already taken, the sequencer will fail to propose and this call will time out.
18
+ *
19
+ * @throws If no sequencer is running.
20
+ */
21
+ mineBlock(): Promise<void>;
22
+ }
23
+
24
+ export const AztecNodeDebugApiSchema: ApiSchemaFor<AztecNodeDebug> = {
25
+ mineBlock: z.function().returns(z.void()),
26
+ };
27
+
28
+ export function createAztecNodeDebugClient(
29
+ url: string,
30
+ versions: Partial<ComponentsVersions> = {},
31
+ fetch = defaultFetch,
32
+ apiKey?: string,
33
+ ): AztecNodeDebug {
34
+ return createSafeJsonRpcClient<AztecNodeDebug>(url, AztecNodeDebugApiSchema, {
35
+ namespaceMethods: 'nodeDebug',
36
+ fetch,
37
+ onResponse: getVersioningResponseHandler(versions),
38
+ ...(apiKey ? { extraHeaders: { 'x-api-key': apiKey } } : {}),
39
+ });
40
+ }
@@ -1,5 +1,6 @@
1
1
  export * from './aztec-node.js';
2
2
  export * from './aztec-node-admin.js';
3
+ export * from './aztec-node-debug.js';
3
4
  export * from './private_kernel_prover.js';
4
5
  export * from './get_logs_response.js';
5
6
  export * from './api_limit.js';
@@ -16,11 +16,10 @@ export interface L2LogsSource {
16
16
  * array implies no logs match that tag.
17
17
  * @param tags - The tags to search for.
18
18
  * @param page - The page number (0-indexed) for pagination.
19
- * @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
20
19
  * @returns An array of log arrays, one per tag. Returns at most 10 logs per tag per page. If 10 logs are returned
21
20
  * for a tag, the caller should fetch the next page to check for more logs.
22
21
  */
23
- getPrivateLogsByTags(tags: SiloedTag[], page?: number, upToBlockNumber?: BlockNumber): Promise<TxScopedL2Log[][]>;
22
+ getPrivateLogsByTags(tags: SiloedTag[], page?: number): Promise<TxScopedL2Log[][]>;
24
23
 
25
24
  /**
26
25
  * Gets public logs that match any of the `tags` from the specified contract. For each tag, an array of matching
@@ -28,7 +27,6 @@ export interface L2LogsSource {
28
27
  * @param contractAddress - The contract address to search logs for.
29
28
  * @param tags - The tags to search for.
30
29
  * @param page - The page number (0-indexed) for pagination.
31
- * @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
32
30
  * @returns An array of log arrays, one per tag. Returns at most 10 logs per tag per page. If 10 logs are returned
33
31
  * for a tag, the caller should fetch the next page to check for more logs.
34
32
  */
@@ -36,7 +34,6 @@ export interface L2LogsSource {
36
34
  contractAddress: AztecAddress,
37
35
  tags: Tag[],
38
36
  page?: number,
39
- upToBlockNumber?: BlockNumber,
40
37
  ): Promise<TxScopedL2Log[][]>;
41
38
 
42
39
  /**
@@ -15,69 +15,63 @@ import type {
15
15
  } from '@aztec/stdlib/p2p';
16
16
  import type { CheckpointHeader } from '@aztec/stdlib/rollup';
17
17
  import type { BlockHeader, Tx } from '@aztec/stdlib/tx';
18
+ import { type ValidatorHASignerConfig, ValidatorHASignerConfigSchema } from '@aztec/validator-ha-signer/config';
18
19
 
19
20
  import type { PeerId } from '@libp2p/interface';
20
21
  import { z } from 'zod';
21
22
 
22
23
  import type { CommitteeAttestationsAndSigners } from '../block/index.js';
23
- import {
24
- type LocalSignerConfig,
25
- LocalSignerConfigSchema,
26
- type ValidatorHASignerConfig,
27
- ValidatorHASignerConfigSchema,
28
- } from '../ha-signing/index.js';
29
24
  import { AllowedElementSchema } from './allowed_element.js';
30
25
 
31
26
  /**
32
27
  * Validator client configuration
33
28
  */
34
- export type ValidatorClientConfig = ValidatorHASignerConfig &
35
- LocalSignerConfig & {
36
- /** The private keys of the validators participating in attestation duties */
37
- validatorPrivateKeys?: SecretValue<`0x${string}`[]>;
29
+ export type ValidatorClientConfig = ValidatorHASignerConfig & {
30
+ /** The private keys of the validators participating in attestation duties */
31
+ validatorPrivateKeys?: SecretValue<`0x${string}`[]>;
38
32
 
39
- /** The addresses of the validators to use with remote signers */
40
- validatorAddresses?: EthAddress[];
33
+ /** The addresses of the validators to use with remote signers */
34
+ validatorAddresses?: EthAddress[];
41
35
 
42
- /** Do not run the validator */
43
- disableValidator: boolean;
36
+ /** Do not run the validator */
37
+ disableValidator: boolean;
44
38
 
45
- /** Temporarily disable these specific validator addresses */
46
- disabledValidators: EthAddress[];
39
+ /** Temporarily disable these specific validator addresses */
40
+ disabledValidators: EthAddress[];
47
41
 
48
- /** Interval between polling for new attestations from peers */
49
- attestationPollingIntervalMs: number;
42
+ /** Interval between polling for new attestations from peers */
43
+ attestationPollingIntervalMs: number;
50
44
 
51
- /** Whether to re-execute transactions in a block proposal before attesting */
52
- validatorReexecute: boolean;
45
+ /** Whether to re-execute transactions in a block proposal before attesting */
46
+ validatorReexecute: boolean;
53
47
 
54
- /** Whether to always reexecute block proposals, even for non-validator nodes or when out of the currnet committee */
55
- alwaysReexecuteBlockProposals?: boolean;
48
+ /** Whether to always reexecute block proposals, even for non-validator nodes or when out of the currnet committee */
49
+ alwaysReexecuteBlockProposals?: boolean;
56
50
 
57
- /** Whether to run in fisherman mode: validates all proposals and attestations but does not broadcast attestations or participate in consensus */
58
- fishermanMode?: boolean;
51
+ /** Whether to run in fisherman mode: validates all proposals and attestations but does not broadcast attestations or participate in consensus */
52
+ fishermanMode?: boolean;
59
53
 
60
- /** Skip checkpoint proposal validation and always attest (default: false) */
61
- skipCheckpointProposalValidation?: boolean;
54
+ /** Skip checkpoint proposal validation and always attest (default: false) */
55
+ skipCheckpointProposalValidation?: boolean;
62
56
 
63
- /** Skip pushing re-executed blocks to archiver (default: false) */
64
- skipPushProposedBlocksToArchiver?: boolean;
57
+ /** Skip pushing re-executed blocks to archiver (default: false) */
58
+ skipPushProposedBlocksToArchiver?: boolean;
65
59
 
66
- /** Agree to attest to equivocated checkpoint proposals (for testing purposes only) */
67
- attestToEquivocatedProposals?: boolean;
60
+ /** Agree to attest to equivocated checkpoint proposals (for testing purposes only) */
61
+ attestToEquivocatedProposals?: boolean;
68
62
 
69
- /** Maximum L2 gas per block for validation. Proposals exceeding this limit are rejected. */
70
- validateMaxL2BlockGas?: number;
63
+ /** Maximum L2 gas per block for validation. Proposals exceeding this limit are rejected. */
64
+ validateMaxL2BlockGas?: number;
71
65
 
72
- /** Maximum DA gas per block for validation. Proposals exceeding this limit are rejected. */
73
- validateMaxDABlockGas?: number;
66
+ /** Maximum DA gas per block for validation. Proposals exceeding this limit are rejected. */
67
+ validateMaxDABlockGas?: number;
74
68
 
75
- /** Maximum transactions per block for validation. Proposals exceeding this limit are rejected. */
76
- validateMaxTxsPerBlock?: number;
69
+ /** Maximum transactions per block for validation. Proposals exceeding this limit are rejected. */
70
+ validateMaxTxsPerBlock?: number;
77
71
 
78
- /** Maximum transactions per checkpoint for validation. Proposals exceeding this limit are rejected. */
79
- validateMaxTxsPerCheckpoint?: number;
80
- };
72
+ /** Maximum transactions per checkpoint for validation. Proposals exceeding this limit are rejected. */
73
+ validateMaxTxsPerCheckpoint?: number;
74
+ };
81
75
 
82
76
  export type ValidatorClientFullConfig = ValidatorClientConfig &
83
77
  Pick<SequencerConfig, 'txPublicSetupAllowListExtend' | 'broadcastInvalidBlockProposal'> &
@@ -93,7 +87,7 @@ export type ValidatorClientFullConfig = ValidatorClientConfig &
93
87
  };
94
88
 
95
89
  export const ValidatorClientConfigSchema = zodFor<Omit<ValidatorClientConfig, 'validatorPrivateKeys'>>()(
96
- ValidatorHASignerConfigSchema.merge(LocalSignerConfigSchema).extend({
90
+ ValidatorHASignerConfigSchema.extend({
97
91
  validatorAddresses: z.array(schemas.EthAddress).optional(),
98
92
  disableValidator: z.boolean(),
99
93
  disabledValidators: z.array(schemas.EthAddress),
@@ -25,7 +25,7 @@ export class ClaimedLengthArray<T extends Serializable, N extends number> {
25
25
  arrayLength: N,
26
26
  ): ClaimedLengthArray<T, N> {
27
27
  const reader = BufferReader.asReader(buffer);
28
- const array = reader.readArray(arrayLength, deserializer);
28
+ const array = reader.readArray(arrayLength, deserializer) as Tuple<T, N>;
29
29
  const claimedLength = reader.readNumber();
30
30
  return new ClaimedLengthArray(array, claimedLength);
31
31
  }
@@ -42,7 +42,7 @@ export class ClaimedLengthArray<T extends Serializable, N extends number> {
42
42
  arrayLength: N,
43
43
  ): ClaimedLengthArray<T, N> {
44
44
  const reader = FieldReader.asReader(fields);
45
- const array = reader.readArray(arrayLength, deserializer);
45
+ const array = reader.readTuple(arrayLength, deserializer);
46
46
  const claimedLength = reader.readU32();
47
47
  return new ClaimedLengthArray(array, claimedLength);
48
48
  }
@@ -105,8 +105,11 @@ export class PrivateKernelResetHints<
105
105
  fromBuffer: buf =>
106
106
  nullifierReadRequestHintsFromBuffer(buf, numNullifierReadRequestPending, numNullifierReadRequestSettled),
107
107
  }),
108
- reader.readArray(numKeyValidationHints, KeyValidationHint),
109
- reader.readArray(numTransientDataSquashingHints, TransientDataSquashingHint),
108
+ reader.readArray(numKeyValidationHints, KeyValidationHint) as Tuple<KeyValidationHint, KEY_VALIDATION_HINTS_LEN>,
109
+ reader.readArray(numTransientDataSquashingHints, TransientDataSquashingHint) as Tuple<
110
+ TransientDataSquashingHint,
111
+ TRANSIENT_DATA_HINTS_LEN
112
+ >,
110
113
  );
111
114
  }
112
115
  }
@@ -158,11 +158,11 @@ export class ReadRequestResetHints<
158
158
  > {
159
159
  const reader = BufferReader.asReader(buffer);
160
160
  return new ReadRequestResetHints(
161
- reader.readArray(readRequestLen, ReadRequestAction),
162
- reader.readArray(numPendingReads, PendingReadHint),
161
+ reader.readArray(readRequestLen, ReadRequestAction) as Tuple<ReadRequestAction, READ_REQUEST_LEN>,
162
+ reader.readArray(numPendingReads, PendingReadHint) as Tuple<PendingReadHint, PENDING_READ_HINTS_LEN>,
163
163
  reader.readArray(numSettledReads, {
164
164
  fromBuffer: r => SettledReadHint.fromBuffer(r, treeHeight, leafPreimageFromBuffer),
165
- }),
165
+ }) as Tuple<SettledReadHint<TREE_HEIGHT, LEAF_PREIMAGE>, SETTLED_READ_HINTS_LEN>,
166
166
  );
167
167
  }
168
168
 
@@ -19,9 +19,9 @@ export class PaddedSideEffects {
19
19
  static fromBuffer(buffer: Buffer | BufferReader) {
20
20
  const reader = BufferReader.asReader(buffer);
21
21
  return new PaddedSideEffects(
22
- reader.readArray(MAX_NOTE_HASHES_PER_TX, Fr),
23
- reader.readArray(MAX_NULLIFIERS_PER_TX, Fr),
24
- reader.readArray(MAX_PRIVATE_LOGS_PER_TX, PrivateLog),
22
+ reader.readTuple(MAX_NOTE_HASHES_PER_TX, Fr),
23
+ reader.readTuple(MAX_NULLIFIERS_PER_TX, Fr),
24
+ reader.readTuple(MAX_PRIVATE_LOGS_PER_TX, PrivateLog),
25
25
  );
26
26
  }
27
27
 
@@ -73,7 +73,7 @@ export class PrivateToAvmAccumulatedData {
73
73
  return new this(
74
74
  reader.readFieldArray(MAX_NOTE_HASHES_PER_TX),
75
75
  reader.readFieldArray(MAX_NULLIFIERS_PER_TX),
76
- reader.readArray(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
76
+ reader.readTuple(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
77
77
  );
78
78
  }
79
79
 
@@ -94,9 +94,9 @@ export class PrivateToAvmAccumulatedData {
94
94
  static fromBuffer(buffer: Buffer | BufferReader) {
95
95
  const reader = BufferReader.asReader(buffer);
96
96
  return new PrivateToAvmAccumulatedData(
97
- reader.readArray(MAX_NOTE_HASHES_PER_TX, Fr),
98
- reader.readArray(MAX_NULLIFIERS_PER_TX, Fr),
99
- reader.readArray(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
97
+ reader.readTuple(MAX_NOTE_HASHES_PER_TX, Fr),
98
+ reader.readTuple(MAX_NULLIFIERS_PER_TX, Fr),
99
+ reader.readTuple(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
100
100
  );
101
101
  }
102
102
 
@@ -62,10 +62,10 @@ export class PrivateToPublicAccumulatedData {
62
62
  return new this(
63
63
  reader.readFieldArray(MAX_NOTE_HASHES_PER_TX),
64
64
  reader.readFieldArray(MAX_NULLIFIERS_PER_TX),
65
- reader.readArray(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
66
- reader.readArray(MAX_PRIVATE_LOGS_PER_TX, PrivateLog),
67
- reader.readArray(MAX_CONTRACT_CLASS_LOGS_PER_TX, ScopedLogHash),
68
- reader.readArray(MAX_ENQUEUED_CALLS_PER_TX, PublicCallRequest),
65
+ reader.readTuple(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
66
+ reader.readTuple(MAX_PRIVATE_LOGS_PER_TX, PrivateLog),
67
+ reader.readTuple(MAX_CONTRACT_CLASS_LOGS_PER_TX, ScopedLogHash),
68
+ reader.readTuple(MAX_ENQUEUED_CALLS_PER_TX, PublicCallRequest),
69
69
  );
70
70
  }
71
71
 
@@ -76,12 +76,12 @@ export class PrivateToPublicAccumulatedData {
76
76
  static fromBuffer(buffer: Buffer | BufferReader) {
77
77
  const reader = BufferReader.asReader(buffer);
78
78
  return new PrivateToPublicAccumulatedData(
79
- reader.readArray(MAX_NOTE_HASHES_PER_TX, Fr),
80
- reader.readArray(MAX_NULLIFIERS_PER_TX, Fr),
81
- reader.readArray(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
82
- reader.readArray(MAX_PRIVATE_LOGS_PER_TX, PrivateLog),
83
- reader.readArray(MAX_CONTRACT_CLASS_LOGS_PER_TX, ScopedLogHash),
84
- reader.readArray(MAX_ENQUEUED_CALLS_PER_TX, PublicCallRequest),
79
+ reader.readTuple(MAX_NOTE_HASHES_PER_TX, Fr),
80
+ reader.readTuple(MAX_NULLIFIERS_PER_TX, Fr),
81
+ reader.readTuple(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
82
+ reader.readTuple(MAX_PRIVATE_LOGS_PER_TX, PrivateLog),
83
+ reader.readTuple(MAX_CONTRACT_CLASS_LOGS_PER_TX, ScopedLogHash),
84
+ reader.readTuple(MAX_ENQUEUED_CALLS_PER_TX, PublicCallRequest),
85
85
  );
86
86
  }
87
87
 
@@ -95,11 +95,11 @@ export class PrivateToRollupAccumulatedData {
95
95
  static fromBuffer(buffer: Buffer | BufferReader): PrivateToRollupAccumulatedData {
96
96
  const reader = BufferReader.asReader(buffer);
97
97
  return new PrivateToRollupAccumulatedData(
98
- reader.readArray(MAX_NOTE_HASHES_PER_TX, Fr),
99
- reader.readArray(MAX_NULLIFIERS_PER_TX, Fr),
100
- reader.readArray(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
101
- reader.readArray(MAX_PRIVATE_LOGS_PER_TX, PrivateLog),
102
- reader.readArray(MAX_CONTRACT_CLASS_LOGS_PER_TX, ScopedLogHash),
98
+ reader.readTuple(MAX_NOTE_HASHES_PER_TX, Fr),
99
+ reader.readTuple(MAX_NULLIFIERS_PER_TX, Fr),
100
+ reader.readTuple(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
101
+ reader.readTuple(MAX_PRIVATE_LOGS_PER_TX, PrivateLog),
102
+ reader.readTuple(MAX_CONTRACT_CLASS_LOGS_PER_TX, ScopedLogHash),
103
103
  );
104
104
  }
105
105
 
@@ -23,14 +23,14 @@ import { computeAddressSecret, computePreaddress } from '../keys/derivation.js';
23
23
  * doesn't seem to be a good way around this.
24
24
  */
25
25
  export class ExtendedDirectionalAppTaggingSecret {
26
- private constructor(
26
+ constructor(
27
27
  public readonly secret: Fr,
28
28
  public readonly app: AztecAddress,
29
29
  ) {}
30
30
 
31
31
  /**
32
32
  * Derives shared tagging secret and from that, the app address and recipient derives the directional app tagging
33
- * secret.
33
+ * secret. Returns undefined if `externalAddress` is an invalid address.
34
34
  *
35
35
  * @param localAddress - The complete address of entity A in the shared tagging secret derivation scheme
36
36
  * @param localIvsk - The incoming viewing secret key of entity A
@@ -45,8 +45,12 @@ export class ExtendedDirectionalAppTaggingSecret {
45
45
  externalAddress: AztecAddress,
46
46
  app: AztecAddress,
47
47
  recipient: AztecAddress,
48
- ): Promise<ExtendedDirectionalAppTaggingSecret> {
48
+ ): Promise<ExtendedDirectionalAppTaggingSecret | undefined> {
49
49
  const taggingSecretPoint = await computeSharedTaggingSecret(localAddress, localIvsk, externalAddress);
50
+ if (!taggingSecretPoint) {
51
+ return undefined;
52
+ }
53
+
50
54
  const appTaggingSecret = await poseidon2Hash([taggingSecretPoint.x, taggingSecretPoint.y, app]);
51
55
  const directionalAppTaggingSecret = await poseidon2Hash([appTaggingSecret, recipient]);
52
56
 
@@ -63,18 +67,25 @@ export class ExtendedDirectionalAppTaggingSecret {
63
67
  }
64
68
  }
65
69
 
66
- // Returns shared tagging secret computed with Diffie-Hellman key exchange.
70
+ // Returns shared tagging secret computed with Diffie-Hellman key exchange, or undefined if `externalAddress` is an
71
+ // invalid address.
67
72
  async function computeSharedTaggingSecret(
68
73
  localAddress: CompleteAddress,
69
74
  localIvsk: Fq,
70
75
  externalAddress: AztecAddress,
71
- ): Promise<Point> {
72
- const knownPreaddress = await computePreaddress(await localAddress.publicKeys.hash(), localAddress.partialAddress);
73
- // TODO: #8970 - Computation of address point from x coordinate might fail
74
- const externalAddressPoint = await externalAddress.toAddressPoint();
76
+ ): Promise<Point | undefined> {
75
77
  // Given A (local complete address) -> B (external address) and h == preaddress
76
78
  // Compute shared secret as S = (h_A + local_ivsk_A) * Addr_Point_B
77
79
 
80
+ const knownPreaddress = await computePreaddress(await localAddress.publicKeys.hash(), localAddress.partialAddress);
81
+
82
+ // An invalid address has no corresponding address point
83
+ if (!(await externalAddress.isValid())) {
84
+ return undefined;
85
+ }
86
+
87
+ const externalAddressPoint = await externalAddress.toAddressPoint();
88
+
78
89
  // Beware! h_a + local_ivsk_a (also known as the address secret) can lead to an address point with a negative
79
90
  // y-coordinate, since there's two possible candidates computeAddressSecret takes care of selecting the one that
80
91
  // leads to a positive y-coordinate, which is the only valid address point