diff --git a/docs/docs/guides/smart_contracts/writing_contracts/storage/storage_slots.md b/docs/docs/guides/smart_contracts/writing_contracts/storage/storage_slots.md
index 35f384bdd250..f8ae4561bf2b 100644
--- a/docs/docs/guides/smart_contracts/writing_contracts/storage/storage_slots.md
+++ b/docs/docs/guides/smart_contracts/writing_contracts/storage/storage_slots.md
@@ -30,26 +30,24 @@ sequenceDiagram
BalanceSet->>Set: insert(note)
Set->>LifeCycle: create_note(derived_slot, note)
LifeCycle->>LifeCycle: note.header = NoteHeader { contract_address,
storage_slot: derived_slot, nonce: 0, note_hash_counter }
- LifeCycle->>Utils: compute_slotted_note_hash(note)
- Utils->>TokenNote: note.compute_note_hiding_point()
- TokenNote->>Utils: note_hiding_point = MSM([G_amt, G_to, G_rand], [amount, to, randomness])
- Utils->>NoteHash: compute_slotted_note_hash(derived_slot, note_hiding_point)
- NoteHash->>LifeCycle: slotted_note_hash = CURVE_ADD(derived_slot_point, note_hiding_point).x
- LifeCycle->>Context: push_note_hash(slotted_note_hash)
+ Utils->>TokenNote: note_hiding_point = note.compute_note_hiding_point()
+ TokenNote->>Utils: note_hash = note_hiding_point.x
+ LifeCycle->>Context: push_note_hash(note_hash)
end
- Context->>Kernel: siloed_note_hash = H(contract_address, slotted_note_hash)
+ Context->>Kernel: unique_note_hash = H(nonce, note_hash)
+ Context->>Kernel: siloed_note_hash = H(contract_address, unique_note_hash)
```
Notice the `siloed_note_hash` at the very end. It's a hash that will be inserted into the note hashes tree. To clarify what this really is, we "unroll" the values to their simplest components. This gives us a better idea around what is actually inserted into the tree.
```rust
-siloed_note_hash = H(contract_address, slotted_note_hash)
-siloed_note_hash = H(contract_address, CURVE_ADD(derived_slot_point, note_hiding_point).x)
-siloed_note_hash = H(contract_address, CURVE_ADD(MSM([G_slot], [derived_slot]), note_hiding_point).x)
-siloed_note_hash = H(contract_address, CURVE_ADD(MSM([G_slot], [derived_slot]), MSM([G_amt, G_to, G_rand], [amount, to, randomness])).x)
+siloed_note_hash = H(contract_address, unique_note_hash)
+siloed_note_hash = H(contract_address, H(nonce, note_hash))
+siloed_note_hash = H(contract_address, H(H(tx_hash, note_index_in_tx), note_hash))
+siloed_note_hash = H(contract_address, H(H(tx_hash, note_index_in_tx), MSM([G_amt, G_to, G_rand, G_slot], [amount, to, randomness, derived_slot]).x))
```
-CURVE_ADD is a point addition and MSM is a multi scalar multiplication on a grumpkin curve and G_* values are generators.
+MSM is a multi scalar multiplication on a grumpkin curve and G_* values are generators.
And `to` is the actor who receives the note, `amount` of the note and `randomness` is the randomness used to make the note hiding. Without the `randomness` the note could just as well be plaintext (computational cost of a preimage attack would be trivial in such a case).
diff --git a/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr b/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr
index 52880c1e67e4..5bcabb1784e5 100644
--- a/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr
+++ b/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr
@@ -1,7 +1,7 @@
use crate::context::{PrivateContext, PublicContext};
use crate::note::{
- note_header::NoteHeader, note_interface::NoteInterface,
- utils::{compute_slotted_note_hash, compute_note_hash_for_consumption}, note_emission::NoteEmission
+ note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption,
+ note_emission::NoteEmission
};
use crate::oracle::notes::{notify_created_note, notify_nullified_note};
@@ -15,7 +15,8 @@ pub fn create_note(
let header = NoteHeader { contract_address, storage_slot, nonce: 0, note_hash_counter };
note.set_header(header);
- let slotted_note_hash = compute_slotted_note_hash(*note);
+ // TODO(#7771): inject compute_note_hash(...) func to notes with macros.
+ let note_hash = note.compute_note_hiding_point().x;
let serialized_note = Note::serialize_content(*note);
assert(
@@ -23,13 +24,13 @@ pub fn create_note(
storage_slot,
Note::get_note_type_id(),
serialized_note,
- slotted_note_hash,
+ note_hash,
note_hash_counter
)
== 0
);
- context.push_note_hash(slotted_note_hash);
+ context.push_note_hash(note_hash);
NoteEmission::new(*note)
}
@@ -43,9 +44,10 @@ pub fn create_note_hash_from_public(
// Public note hashes are transient, but have no side effect counters, so we just need note_hash_counter != 0
let header = NoteHeader { contract_address, storage_slot, nonce: 0, note_hash_counter: 1 };
note.set_header(header);
- let slotted_note_hash = compute_slotted_note_hash(*note);
+ // TODO(#7771): inject compute_note_hash(...) func to notes with macros.
+ let note_hash = note.compute_note_hiding_point().x;
- context.push_note_hash(slotted_note_hash);
+ context.push_note_hash(note_hash);
}
pub fn destroy_note(
diff --git a/noir-projects/aztec-nr/aztec/src/note/utils.nr b/noir-projects/aztec-nr/aztec/src/note/utils.nr
index b40a19d18cb0..8bce7674865c 100644
--- a/noir-projects/aztec-nr/aztec/src/note/utils.nr
+++ b/noir-projects/aztec-nr/aztec/src/note/utils.nr
@@ -12,22 +12,6 @@ use dep::protocol_types::{
};
use dep::std::{embedded_curve_ops::multi_scalar_mul, hash::from_field_unsafe};
-pub fn compute_slotted_note_hash(note: Note) -> Field where Note: NoteInterface {
- let storage_slot = note.get_header().storage_slot;
- let note_hiding_point = note.compute_note_hiding_point();
-
- // 1. We derive the storage slot point by multiplying the storage slot with the generator G_slot.
- // We use the unsafe version because the multi_scalar_mul will constrain the scalars.
- let storage_slot_scalar = from_field_unsafe(storage_slot);
- let storage_slot_point = multi_scalar_mul([G_slot], [storage_slot_scalar]);
-
- // 2. Then we compute the slotted note hiding point by adding the storage slot point to the note hiding point.
- let slotted_note_hiding_point = storage_slot_point + note_hiding_point;
-
- // 3. Finally, we return the slotted note hash which is the x-coordinate of the slotted note hiding point.
- slotted_note_hiding_point.x
-}
-
pub fn compute_siloed_nullifier(
note_with_header: Note,
context: &mut PrivateContext
@@ -39,14 +23,15 @@ pub fn compute_siloed_nullifier(
}
pub fn compute_note_hash_for_read_request(note: Note) -> Field where Note: NoteInterface {
- let slotted_note_hash = compute_slotted_note_hash(note);
+ // TODO(#7771): inject compute_note_hash(...) func to notes with macros.
+ let note_hash = note.compute_note_hiding_point().x;
let nonce = note.get_header().nonce;
let counter = note.get_header().note_hash_counter;
if counter != 0 {
- slotted_note_hash
+ note_hash
} else {
- compute_unique_note_hash(nonce, slotted_note_hash)
+ compute_unique_note_hash(nonce, note_hash)
}
}
@@ -59,12 +44,13 @@ pub fn compute_note_hash_for_consumption(note: Not
// the same transaction: (note_hash_counter != 0) & (nonce != 0)
// 3. The note was inserted in a previous transaction: (note_hash_counter == 0) & (nonce != 0)
- let slotted_note_hash = compute_slotted_note_hash(note);
+ // TODO(#7771): inject compute_note_hash(...) func to notes with macros.
+ let note_hash = note.compute_note_hiding_point().x;
if header.nonce == 0 {
// Case 1.
- // If a note is transient, we just read the slotted_note_hash (kernel will silo by contract address).
- slotted_note_hash
+ // If a note is transient, we just read the note_hash (kernel will hash it with nonce and silo by contract address).
+ note_hash
} else {
// Case 2: If a note is non-revertible, and is nullified by a revertible nullifier, we cannot squash them in the
// private reset circuit. Because if the tx reverts, we will have to keep the note hash and throw away the
@@ -78,7 +64,7 @@ pub fn compute_note_hash_for_consumption(note: Not
// tree) created in a previous TX. So we need the siloed_note_hash which has already been hashed with
// nonce and then contract address. This hash will match the existing leaf in the note hash
// tree, so the kernel can just perform a membership check directly on this hash/leaf.
- let unique_note_hash = compute_unique_note_hash(header.nonce, slotted_note_hash);
+ let unique_note_hash = compute_unique_note_hash(header.nonce, note_hash);
compute_siloed_note_hash(header.contract_address, unique_note_hash)
// IMPORTANT NOTE ON REDUNDANT SILOING BY CONTRACT ADDRESS: The note hash computed above is
// "siloed" by contract address. When a note hash is computed solely for the purpose of
@@ -100,8 +86,9 @@ pub fn compute_note_hash_and_optionally_a_nullifier(
_storage_slot: Field,
_note_type_id: Field,
_serialized_note: [Field; N],
- _slotted_note_hash: Field,
+ _note_hash: Field,
_counter: u32
) -> Field {}
@@ -15,27 +15,21 @@ unconstrained pub fn notify_created_note(
storage_slot: Field,
note_type_id: Field,
serialized_note: [Field; N],
- slotted_note_hash: Field,
+ note_hash: Field,
counter: u32
) -> Field {
- notify_created_note_oracle(
- storage_slot,
- note_type_id,
- serialized_note,
- slotted_note_hash,
- counter
- )
+ notify_created_note_oracle(storage_slot, note_type_id, serialized_note, note_hash, counter)
}
#[oracle(notifyNullifiedNote)]
-unconstrained fn notify_nullified_note_oracle(_nullifier: Field, _slotted_note_hash: Field, _counter: u32) -> Field {}
+unconstrained fn notify_nullified_note_oracle(_nullifier: Field, _note_hash: Field, _counter: u32) -> Field {}
unconstrained pub fn notify_nullified_note(
nullifier: Field,
- slotted_note_hash: Field,
+ note_hash: Field,
counter: u32
) -> Field {
- notify_nullified_note_oracle(nullifier, slotted_note_hash, counter)
+ notify_nullified_note_oracle(nullifier, note_hash, counter)
}
#[oracle(getNotes)]
diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr
index 6ce7feabce5c..12ba6715de84 100644
--- a/noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr
+++ b/noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr
@@ -95,8 +95,8 @@ unconstrained pub fn add_nullifiers(contractAddress: AztecAddress, nullifiers: [
oracle_add_nullifiers(contractAddress, nullifiers)
}
-unconstrained pub fn add_note_hashes(contractAddress: AztecAddress, slotted_note_hashes: [Field]) {
- oracle_add_note_hashes(contractAddress, slotted_note_hashes)
+unconstrained pub fn add_note_hashes(contractAddress: AztecAddress, note_hashes: [Field]) {
+ oracle_add_note_hashes(contractAddress, note_hashes)
}
unconstrained pub fn get_function_selector() -> FunctionSelector {
@@ -180,7 +180,7 @@ unconstrained fn oracle_assert_private_call_fails(
unconstrained fn oracle_add_nullifiers(contractAddress: AztecAddress, nullifiers: [Field]) {}
#[oracle(addNoteHashes)]
-unconstrained fn oracle_add_note_hashes(contractAddress: AztecAddress, slotted_note_hashes: [Field]) {}
+unconstrained fn oracle_add_note_hashes(contractAddress: AztecAddress, note_hashes: [Field]) {}
#[oracle(getFunctionSelector)]
unconstrained fn oracle_get_function_selector() -> FunctionSelector {}
diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr
index 923373f2d23d..5a1437572e1d 100644
--- a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr
+++ b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr
@@ -12,10 +12,7 @@ use crate::test::helpers::{cheatcodes, utils::{apply_side_effects_private, Deplo
use crate::keys::constants::{NULLIFIER_INDEX, INCOMING_INDEX, OUTGOING_INDEX, TAGGING_INDEX};
use crate::hash::{hash_args, hash_args_array};
-use crate::note::{
- note_header::NoteHeader, note_interface::NoteInterface,
- utils::{compute_slotted_note_hash, compute_note_hash_for_consumption}
-};
+use crate::note::{note_header::NoteHeader, note_interface::NoteInterface};
use crate::oracle::{execution::{get_block_number, get_contract_address}, notes::notify_created_note};
struct TestEnvironment {}
@@ -219,14 +216,15 @@ impl TestEnvironment {
let header = NoteHeader { contract_address, storage_slot, nonce: 0, note_hash_counter };
note.set_header(header);
- let slotted_note_hash = compute_slotted_note_hash(*note);
+ // TODO(#7771): inject compute_note_hash(...) func to notes with macros.
+ let note_hash = note.compute_note_hiding_point().x;
let serialized_note = Note::serialize_content(*note);
assert(
notify_created_note(
storage_slot,
Note::get_note_type_id(),
serialized_note,
- slotted_note_hash,
+ note_hash,
note_hash_counter
)
== 0
diff --git a/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr b/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr
index c6fdf0b9da0f..5cd3a8e7cacd 100644
--- a/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr
+++ b/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr
@@ -91,7 +91,7 @@ contract PendingNoteHashes {
// Nested/inner function to create and insert a note
// TESTING: inserts a static randomness value to test notes with
- // the same slotted note hash are dealt with correctly
+ // the same note hash are dealt with correctly
#[aztec(private)]
fn insert_note_static_randomness(
amount: Field,
diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr
index caebffbcf759..6a2d4e94fe25 100644
--- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr
+++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr
@@ -7,7 +7,7 @@ use dep::aztec::{
// TODO(#7738): Nuke the following imports
use dep::aztec::{
- generators::{Ga1 as G_amt, Ga2 as G_npk, Ga3 as G_rnd},
+ generators::{Ga1 as G_amt, Ga2 as G_npk, Ga3 as G_rnd, G_slot},
protocol_types::{point::Point, scalar::Scalar}
};
use dep::std::{embedded_curve_ops::multi_scalar_mul, hash::from_field_unsafe};
@@ -60,16 +60,20 @@ impl NoteInterface for TokenNote {
// TODO(#7738): Nuke this function and have it auto-generated by macros
fn compute_note_hiding_point(self) -> Point {
+ assert(self.header.storage_slot != 0, "Storage slot must be set before computing note hiding point");
+
+ // TODO(#7772): decompose amount with from_field_unsafe or constrain it fits into 1 limb
+ let amount_scalar = Scalar {
+ lo: self.amount.to_integer(),
+ hi: 0
+ };
+ // We use the unsafe version because the multi_scalar_mul will constrain the scalars.
let npk_m_hash_scalar = from_field_unsafe(self.npk_m_hash);
let randomness_scalar = from_field_unsafe(self.randomness);
+ let slot_scalar = from_field_unsafe(self.header.storage_slot);
multi_scalar_mul(
- [G_amt, G_npk, G_rnd],
- [Scalar {
- lo: self.amount.to_integer(),
- hi: 0
- },
- npk_m_hash_scalar,
- randomness_scalar]
+ [G_amt, G_npk, G_rnd, G_slot],
+ [amount_scalar, npk_m_hash_scalar, randomness_scalar, slot_scalar]
)
}
}
diff --git a/noir-projects/noir-contracts/contracts/token_with_refunds_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_with_refunds_contract/src/main.nr
index 716767f2533b..527024d7ea3f 100644
--- a/noir-projects/noir-contracts/contracts/token_with_refunds_contract/src/main.nr
+++ b/noir-projects/noir-contracts/contracts/token_with_refunds_contract/src/main.nr
@@ -469,35 +469,41 @@ contract TokenWithRefunds {
// to the user in the `complete_refund(...)` function.
storage.balances.sub(user, U128::from_integer(funded_amount)).emit(encode_and_encrypt_note_with_keys(&mut context, user_ovpk, user_ivpk, user));
- // 4. We create the partial notes for the fee payer and the user.
+ // 4. Now we "manually" compute the slots (by setting the slots we insert the notes to the balances map under
+ // the correct keys)
+ let fee_payer_balances_slot = derive_storage_slot_in_map(TokenWithRefunds::storage().balances.slot, fee_payer);
+ let user_balances_slot = derive_storage_slot_in_map(TokenWithRefunds::storage().balances.slot, user);
+
+ // 5. We create the partial notes for the fee payer and the user.
// --> Called "partial" because they don't have the amount set yet (that will be done in `complete_refund(...)`).
let fee_payer_partial_note = TokenNote {
- header: NoteHeader::empty(),
+ header: NoteHeader {
+ contract_address: AztecAddress::zero(),
+ nonce: 0,
+ storage_slot: fee_payer_balances_slot,
+ note_hash_counter: 0
+ },
amount: U128::zero(),
npk_m_hash: fee_payer_npk_m_hash,
randomness: fee_payer_randomness
};
let user_partial_note = TokenNote {
- header: NoteHeader::empty(),
+ header: NoteHeader {
+ contract_address: AztecAddress::zero(),
+ nonce: 0,
+ storage_slot: user_balances_slot,
+ note_hash_counter: 0
+ },
amount: U128::zero(),
npk_m_hash: user_npk_m_hash,
randomness: user_randomness
};
- // 5. Now we get the note hiding points.
+ // 6. Now we get the note hiding points.
let mut fee_payer_point = fee_payer_partial_note.to_note_hiding_point();
let mut user_point = user_partial_note.to_note_hiding_point();
- // 6. Now we "manually" compute the slot points and add them to hiding points.
- let fee_payer_balances_slot = derive_storage_slot_in_map(TokenWithRefunds::storage().balances.slot, fee_payer);
- let user_balances_slot = derive_storage_slot_in_map(TokenWithRefunds::storage().balances.slot, user);
-
- // 7. We add the slot to the points --> this way we insert the notes into the balances Map under the respective key.
- // TODO(#7753): Consider making slots part of the initital note hiding point creation.
- fee_payer_point.add_slot(fee_payer_balances_slot);
- user_point.add_slot(user_balances_slot);
-
- // 8. Set the public teardown function to `complete_refund(...)`. Public teardown is the only time when a public
+ // 7. Set the public teardown function to `complete_refund(...)`. Public teardown is the only time when a public
// function has access to the final transaction fee, which is needed to compute the actual refund amount.
context.set_public_teardown_function(
context.this_address(),
@@ -513,14 +519,14 @@ contract TokenWithRefunds {
#[aztec(public)]
#[aztec(internal)]
fn complete_refund(
- // TODO: the following makes macros crash --> try getting it work once we migrate to metaprogramming
+ // TODO(#7771): the following makes macros crash --> try getting it work once we migrate to metaprogramming
// mut fee_payer_point: TokenNoteHidingPoint,
// mut user_point: TokenNoteHidingPoint,
fee_payer_point_immutable: TokenNoteHidingPoint,
user_point_immutable: TokenNoteHidingPoint,
funded_amount: Field
) {
- // TODO: nuke the following 2 lines once we have mutable args
+ // TODO(#7771): nuke the following 2 lines once we have mutable args
let mut fee_payer_point = fee_payer_point_immutable;
let mut user_point = user_point_immutable;
diff --git a/noir-projects/noir-contracts/contracts/token_with_refunds_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_with_refunds_contract/src/types/token_note.nr
index c9daa1239143..f7d4666c7065 100644
--- a/noir-projects/noir-contracts/contracts/token_with_refunds_contract/src/types/token_note.nr
+++ b/noir-projects/noir-contracts/contracts/token_with_refunds_contract/src/types/token_note.nr
@@ -46,20 +46,24 @@ impl NoteInterface for TokenNote {
}
fn compute_note_hiding_point(self) -> Point {
- // We use the unsafe version because the multi_scalar_mul will constrain the scalars.
- let npk_m_hash_scalar = from_field_unsafe(self.npk_m_hash);
- let randomness_scalar = from_field_unsafe(self.randomness);
- // TODO(benesjan): decompose amount with from_field_unsafe or constrain it fits into limb
+ assert(self.header.storage_slot != 0, "Storage slot must be set before computing note hiding point");
+
+ // TODO(#7772): decompose amount with from_field_unsafe or constrain it fits into 1 limb
let amount_scalar = Scalar {
lo: self.amount.to_integer(),
hi: 0
};
- // We compute the note hiding point as `G_amt * amount + G_npk * npk_m_hash + G_rnd * randomness` instead
- // of using pedersen or poseidon2 because it allows us to privately add and subtract from amount in public
- // by leveraging homomorphism.
+ // We use the unsafe version because the multi_scalar_mul will constrain the scalars.
+ let npk_m_hash_scalar = from_field_unsafe(self.npk_m_hash);
+ let randomness_scalar = from_field_unsafe(self.randomness);
+ let slot_scalar = from_field_unsafe(self.header.storage_slot);
+ // We compute the note hiding point as:
+ // `G_amt * amount + G_npk * npk_m_hash + G_rnd * randomness + G_slot * slot`
+ // instead of using pedersen or poseidon2 because it allows us to privately add and subtract from amount
+ // in public by leveraging homomorphism.
multi_scalar_mul(
- [G_amt, G_npk, G_rnd],
- [amount_scalar, npk_m_hash_scalar, randomness_scalar]
+ [G_amt, G_npk, G_rnd, G_slot],
+ [amount_scalar, npk_m_hash_scalar, randomness_scalar, slot_scalar]
)
}
}
@@ -82,7 +86,7 @@ impl TokenNoteHidingPoint {
}
fn add_amount(&mut self, amount: U128) {
- // TODO(benesjan): decompose amount with from_field_unsafe or constrain it fits into limb
+ // TODO(#7772): decompose amount with from_field_unsafe or constrain it fits into 1 limb
let amount_scalar = Scalar { lo: amount.to_integer(), hi: 0 };
self.inner = multi_scalar_mul([G_amt], [amount_scalar]) + self.inner;
}
diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr
index d778c72d5043..a4dd938668be 100644
--- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr
+++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr
@@ -55,21 +55,21 @@ mod tests {
global contract_address = AztecAddress::from_field(123);
// Create 4 note hashes. 10 and 11 are settled. 12 and 13 are pending.
- global slotted_note_hashes = [10, 11, 12, 13];
- global note_hashes = slotted_note_hashes.map(|n| compute_siloed_note_hash(contract_address, n));
+ global note_hashes = [10, 11, 12, 13];
+ global siloed_note_hashes = note_hashes.map(|n| compute_siloed_note_hash(contract_address, n));
// Create 5 read requests. 0 and 3 are reading settled note hashes. 1, 2 and 4 are reading pending note hashes.
global read_requests = [
- ReadRequest { value: slotted_note_hashes[1], counter: 11 }.scope(contract_address), // settled
- ReadRequest { value: slotted_note_hashes[3], counter: 13 }.scope(contract_address), // pending
- ReadRequest { value: slotted_note_hashes[2], counter: 39 }.scope(contract_address), // pending
- ReadRequest { value: slotted_note_hashes[0], counter: 46 }.scope(contract_address), // settled
- ReadRequest { value: slotted_note_hashes[3], counter: 78 }.scope(contract_address), // pending
+ ReadRequest { value: note_hashes[1], counter: 11 }.scope(contract_address), // settled
+ ReadRequest { value: note_hashes[3], counter: 13 }.scope(contract_address), // pending
+ ReadRequest { value: note_hashes[2], counter: 39 }.scope(contract_address), // pending
+ ReadRequest { value: note_hashes[0], counter: 46 }.scope(contract_address), // settled
+ ReadRequest { value: note_hashes[3], counter: 78 }.scope(contract_address), // pending
];
global pending_values = [
- NoteHash { value: slotted_note_hashes[2], counter: 2, }.scope(contract_address),
- NoteHash { value: slotted_note_hashes[3], counter: 8, }.scope(contract_address),
+ NoteHash { value: note_hashes[2], counter: 2, }.scope(contract_address),
+ NoteHash { value: note_hashes[3], counter: 8, }.scope(contract_address),
];
global pending_read_hints = [
PendingReadHint { read_request_index: 1, pending_value_index: 1 },
@@ -78,8 +78,8 @@ mod tests {
];
global leaf_preimages = [
- NoteHashLeafPreimage { value: note_hashes[0] },
- NoteHashLeafPreimage { value: note_hashes[1] },
+ NoteHashLeafPreimage { value: siloed_note_hashes[0] },
+ NoteHashLeafPreimage { value: siloed_note_hashes[1] },
];
fn read_request_statuses() -> [ReadRequestStatus; 5] {
diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr
index bd82a5089529..ae9a9f7d9844 100644
--- a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr
+++ b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr
@@ -45,8 +45,8 @@ fn compute_note_hash_nonce(tx_hash: Field, note_index_in_tx: u32) -> Field {
)
}
-pub fn compute_unique_note_hash(nonce: Field, slotted_note_hash: Field) -> Field {
- let inputs = [nonce, slotted_note_hash];
+pub fn compute_unique_note_hash(nonce: Field, note_hash: Field) -> Field {
+ let inputs = [nonce, note_hash];
poseidon2_hash_with_separator(inputs, GENERATOR_INDEX__UNIQUE_NOTE_HASH)
}
@@ -60,6 +60,8 @@ pub fn compute_siloed_note_hash(app: AztecAddress, unique_note_hash: Field) -> F
)
}
+/// Siloing in the context of Aztec refers to the process of hashing a note hash with a contract address (this way
+/// the note hash is scoped to a specific contract). This is used to prevent intermingling of notes between contracts.
pub fn silo_note_hash(note_hash: ScopedNoteHash, tx_hash: Field, note_index_in_tx: u32) -> Field {
if note_hash.contract_address.is_zero() {
0
diff --git a/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs b/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs
index a65fbc25f168..7f5c0e8b48b3 100644
--- a/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs
+++ b/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs
@@ -522,12 +522,18 @@ fn generate_compute_note_hiding_point(
impl_span: Option,
empty_spans: bool,
) -> Result {
+ // TODO(#7771): update this to do only 1 MSM call
let function_source = format!(
- "
+ r#"
fn compute_note_hiding_point(self: {}) -> aztec::protocol_types::point::Point {{
- aztec::hash::pedersen_commitment(self.serialize_content(), aztec::protocol_types::constants::GENERATOR_INDEX__NOTE_HIDING_POINT)
+ assert(self.header.storage_slot != 0, "Storage slot must be set before computing note hiding point");
+ let slot_scalar = dep::std::hash::from_field_unsafe(self.header.storage_slot);
+
+ let point_before_slotting = aztec::hash::pedersen_commitment(self.serialize_content(), aztec::protocol_types::constants::GENERATOR_INDEX__NOTE_HIDING_POINT);
+ let slot_point = dep::std::embedded_curve_ops::multi_scalar_mul([dep::aztec::generators::G_slot], [slot_scalar]);
+ point_before_slotting + slot_point
}}
- ",
+ "#,
note_type
);
let (function_ast, errors) = parse_program(&function_source, empty_spans);
diff --git a/yarn-project/circuits.js/src/hash/hash.test.ts b/yarn-project/circuits.js/src/hash/hash.test.ts
index 3f808d62a44a..6a9fb665d1e2 100644
--- a/yarn-project/circuits.js/src/hash/hash.test.ts
+++ b/yarn-project/circuits.js/src/hash/hash.test.ts
@@ -27,8 +27,8 @@ describe('hash', () => {
it('computes unique note hash', () => {
const nonce = new Fr(123n);
- const slottedNoteHash = new Fr(456);
- const res = computeUniqueNoteHash(nonce, slottedNoteHash);
+ const noteHash = new Fr(456);
+ const res = computeUniqueNoteHash(nonce, noteHash);
expect(res).toMatchSnapshot();
});
diff --git a/yarn-project/circuits.js/src/hash/hash.ts b/yarn-project/circuits.js/src/hash/hash.ts
index ecb3ac53350a..6226ee72183a 100644
--- a/yarn-project/circuits.js/src/hash/hash.ts
+++ b/yarn-project/circuits.js/src/hash/hash.ts
@@ -55,11 +55,11 @@ export function siloNoteHash(contract: AztecAddress, uniqueNoteHash: Fr): Fr {
* Computes a unique note hash.
* @dev Includes a nonce which contains data that guarantees the resulting note hash will be unique.
* @param nonce - A nonce (typically derived from tx hash and note hash index in the tx).
- * @param slottedNoteHash - A slotted note hash.
+ * @param noteHash - A note hash.
* @returns A unique note hash.
*/
-export function computeUniqueNoteHash(nonce: Fr, slottedNoteHash: Fr): Fr {
- return poseidon2HashWithSeparator([nonce, slottedNoteHash], GeneratorIndex.UNIQUE_NOTE_HASH);
+export function computeUniqueNoteHash(nonce: Fr, noteHash: Fr): Fr {
+ return poseidon2HashWithSeparator([nonce, noteHash], GeneratorIndex.UNIQUE_NOTE_HASH);
}
/**
diff --git a/yarn-project/circuits.js/src/hints/build_note_hash_read_request_hints.test.ts b/yarn-project/circuits.js/src/hints/build_note_hash_read_request_hints.test.ts
index 59638719276f..8117be97c140 100644
--- a/yarn-project/circuits.js/src/hints/build_note_hash_read_request_hints.test.ts
+++ b/yarn-project/circuits.js/src/hints/build_note_hash_read_request_hints.test.ts
@@ -39,7 +39,7 @@ describe('buildNoteHashReadRequestHints', () => {
let numSettledReads = 0;
let futureNoteHashes: ScopedNoteHash[];
- const slottedNoteHash = (index: number) => index + 9999;
+ const getNoteHashValue = (index: number) => index + 9999;
const makeReadRequest = (value: number, counter = 2) =>
new ReadRequest(new Fr(value), counter).scope(contractAddress);
@@ -49,7 +49,7 @@ describe('buildNoteHashReadRequestHints', () => {
const readPendingNoteHash = (noteHashIndex: number) => {
const readRequestIndex = numReadRequests;
const hintIndex = numPendingReads;
- noteHashReadRequests[readRequestIndex] = makeReadRequest(slottedNoteHash(noteHashIndex));
+ noteHashReadRequests[readRequestIndex] = makeReadRequest(getNoteHashValue(noteHashIndex));
expectedHints.readRequestStatuses[readRequestIndex] = ReadRequestStatus.pending(hintIndex);
expectedHints.pendingReadHints[hintIndex] = new PendingReadHint(readRequestIndex, noteHashIndex);
numReadRequests++;
@@ -89,7 +89,7 @@ describe('buildNoteHashReadRequestHints', () => {
beforeEach(() => {
noteHashReadRequests = makeTuple(MAX_NOTE_HASH_READ_REQUESTS_PER_TX, ScopedReadRequest.empty);
- noteHashes = makeTuple(MAX_NOTE_HASHES_PER_TX, i => makeNoteHash(slottedNoteHash(i)));
+ noteHashes = makeTuple(MAX_NOTE_HASHES_PER_TX, i => makeNoteHash(getNoteHashValue(i)));
noteHashLeafIndexMap = new Map();
expectedHints = NoteHashReadRequestHintsBuilder.empty(
MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
@@ -100,7 +100,7 @@ describe('buildNoteHashReadRequestHints', () => {
numSettledReads = 0;
futureNoteHashes = new Array(MAX_NOTE_HASHES_PER_TX)
.fill(null)
- .map((_, i) => makeNoteHash(slottedNoteHash(i + MAX_NOTE_HASHES_PER_TX)));
+ .map((_, i) => makeNoteHash(getNoteHashValue(i + MAX_NOTE_HASHES_PER_TX)));
});
it('builds empty hints', async () => {
diff --git a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts
index 3c369d8bd599..c379ae088aa7 100644
--- a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts
+++ b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts
@@ -188,7 +188,7 @@ describe('e2e_pending_note_hashes_contract', () => {
await expectNoteLogsSquashedExcept(1);
});
- it('Squash! Aztec.nr function can "create" 2 notes with the same slotted note hash and "nullify" 1 in the same TX', async () => {
+ it('Squash! Aztec.nr function can "create" 2 notes with the same note hash and "nullify" 1 in the same TX', async () => {
// Kernel will squash one noteHash and its nullifier, where two notes with the same inner hash exist.
// The other note will become persistent!
// Realistic way to describe this test is "Mint notes A and B, then burn note A in the same transaction"
diff --git a/yarn-project/pxe/src/database/incoming_note_dao.test.ts b/yarn-project/pxe/src/database/incoming_note_dao.test.ts
index 00c70ea296e1..398263165d6f 100644
--- a/yarn-project/pxe/src/database/incoming_note_dao.test.ts
+++ b/yarn-project/pxe/src/database/incoming_note_dao.test.ts
@@ -11,7 +11,7 @@ export const randomIncomingNoteDao = ({
storageSlot = Fr.random(),
noteTypeId = NoteSelector.random(),
nonce = Fr.random(),
- slottedNoteHash = Fr.random(),
+ noteHash = Fr.random(),
siloedNullifier = Fr.random(),
index = Fr.random().toBigInt(),
ivpkM = Point.random(),
@@ -23,7 +23,7 @@ export const randomIncomingNoteDao = ({
noteTypeId,
txHash,
nonce,
- slottedNoteHash,
+ noteHash,
siloedNullifier,
index,
ivpkM,
diff --git a/yarn-project/pxe/src/database/incoming_note_dao.ts b/yarn-project/pxe/src/database/incoming_note_dao.ts
index fb51b025c8f5..cba1df864f6d 100644
--- a/yarn-project/pxe/src/database/incoming_note_dao.ts
+++ b/yarn-project/pxe/src/database/incoming_note_dao.ts
@@ -23,10 +23,10 @@ export class IncomingNoteDao implements NoteData {
/** The nonce of the note. */
public nonce: Fr,
/**
- * Slotted note hash of the note. This is customizable by the app circuit.
+ * A hash of the note. This is customizable by the app circuit.
* We can use this value to compute siloedNoteHash and uniqueSiloedNoteHash.
*/
- public slottedNoteHash: Fr,
+ public noteHash: Fr,
/**
* The nullifier of the note (siloed by contract address).
* Note: Might be set as 0 if the note was added to PXE as nullified.
@@ -46,7 +46,7 @@ export class IncomingNoteDao implements NoteData {
this.noteTypeId,
this.txHash.buffer,
this.nonce,
- this.slottedNoteHash,
+ this.noteHash,
this.siloedNullifier,
this.index,
this.ivpkM,
@@ -61,7 +61,7 @@ export class IncomingNoteDao implements NoteData {
const noteTypeId = reader.readObject(NoteSelector);
const txHash = reader.readObject(TxHash);
const nonce = Fr.fromBuffer(reader);
- const slottedNoteHash = Fr.fromBuffer(reader);
+ const noteHash = Fr.fromBuffer(reader);
const siloedNullifier = Fr.fromBuffer(reader);
const index = toBigIntBE(reader.readBytes(32));
const publicKey = Point.fromBuffer(reader);
@@ -73,7 +73,7 @@ export class IncomingNoteDao implements NoteData {
noteTypeId,
txHash,
nonce,
- slottedNoteHash,
+ noteHash,
siloedNullifier,
index,
publicKey,
diff --git a/yarn-project/pxe/src/database/outgoing_note_dao.test.ts b/yarn-project/pxe/src/database/outgoing_note_dao.test.ts
index cb404be360ba..04b2b2201f7c 100644
--- a/yarn-project/pxe/src/database/outgoing_note_dao.test.ts
+++ b/yarn-project/pxe/src/database/outgoing_note_dao.test.ts
@@ -11,21 +11,11 @@ export const randomOutgoingNoteDao = ({
storageSlot = Fr.random(),
noteTypeId = NoteSelector.random(),
nonce = Fr.random(),
- slottedNoteHash = Fr.random(),
+ noteHash = Fr.random(),
index = Fr.random().toBigInt(),
ovpkM = Point.random(),
}: Partial = {}) => {
- return new OutgoingNoteDao(
- note,
- contractAddress,
- storageSlot,
- noteTypeId,
- txHash,
- nonce,
- slottedNoteHash,
- index,
- ovpkM,
- );
+ return new OutgoingNoteDao(note, contractAddress, storageSlot, noteTypeId, txHash, nonce, noteHash, index, ovpkM);
};
describe('Outgoing Note DAO', () => {
diff --git a/yarn-project/pxe/src/database/outgoing_note_dao.ts b/yarn-project/pxe/src/database/outgoing_note_dao.ts
index 1c038e5dc48e..bfbd309ddf7e 100644
--- a/yarn-project/pxe/src/database/outgoing_note_dao.ts
+++ b/yarn-project/pxe/src/database/outgoing_note_dao.ts
@@ -22,10 +22,10 @@ export class OutgoingNoteDao {
/** The nonce of the note. */
public nonce: Fr,
/**
- * Slotted note hash of the note. This is customizable by the app circuit.
- * We can use this value to compute siloedNoteHash and uniqueSiloedNoteHash.
+ * A hash of the note. This is customizable by the app circuit.
+ * We can use this value to compute unique note hash and then siloed note hash.
*/
- public slottedNoteHash: Fr,
+ public noteHash: Fr,
/** The location of the relevant note in the note hash tree. */
public index: bigint,
/** The public key with which the note was encrypted. */
@@ -40,7 +40,7 @@ export class OutgoingNoteDao {
this.noteTypeId,
this.txHash.buffer,
this.nonce,
- this.slottedNoteHash,
+ this.noteHash,
this.index,
this.ovpkM,
]);
@@ -54,7 +54,7 @@ export class OutgoingNoteDao {
const noteTypeId = reader.readObject(NoteSelector);
const txHash = new TxHash(reader.readBytes(TxHash.SIZE));
const nonce = Fr.fromBuffer(reader);
- const slottedNoteHash = Fr.fromBuffer(reader);
+ const noteHash = Fr.fromBuffer(reader);
const index = toBigIntBE(reader.readBytes(32));
const publicKey = Point.fromBuffer(reader);
@@ -65,7 +65,7 @@ export class OutgoingNoteDao {
noteTypeId,
txHash,
nonce,
- slottedNoteHash,
+ noteHash,
index,
publicKey,
);
diff --git a/yarn-project/pxe/src/note_processor/note_processor.test.ts b/yarn-project/pxe/src/note_processor/note_processor.test.ts
index ea92c4ff4733..2a694b167088 100644
--- a/yarn-project/pxe/src/note_processor/note_processor.test.ts
+++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts
@@ -166,7 +166,7 @@ describe('Note Processor', () => {
simulator.computeNoteHashAndOptionallyANullifier.mockImplementation((...args) =>
Promise.resolve({
- slottedNoteHash: Fr.random(),
+ noteHash: Fr.random(),
uniqueNoteHash: Fr.random(),
siloedNoteHash: pedersenHash(args[5].items), // args[5] is note
innerNullifier: Fr.random(),
diff --git a/yarn-project/pxe/src/note_processor/produce_note_dao.ts b/yarn-project/pxe/src/note_processor/produce_note_dao.ts
index b8325f764154..5ffc396bc6ce 100644
--- a/yarn-project/pxe/src/note_processor/produce_note_dao.ts
+++ b/yarn-project/pxe/src/note_processor/produce_note_dao.ts
@@ -51,7 +51,7 @@ export async function produceNoteDaos(
try {
if (ivpkM) {
- const { noteHashIndex, nonce, slottedNoteHash, siloedNullifier } = await findNoteIndexAndNullifier(
+ const { noteHashIndex, nonce, noteHash, siloedNullifier } = await findNoteIndexAndNullifier(
simulator,
noteHashes,
txHash,
@@ -69,7 +69,7 @@ export async function produceNoteDaos(
payload.noteTypeId,
txHash,
nonce,
- slottedNoteHash,
+ noteHash,
siloedNullifier,
index,
ivpkM,
@@ -108,12 +108,12 @@ export async function produceNoteDaos(
payload.noteTypeId,
txHash,
incomingNote.nonce,
- incomingNote.slottedNoteHash,
+ incomingNote.noteHash,
incomingNote.index,
ovpkM,
);
} else {
- const { noteHashIndex, nonce, slottedNoteHash } = await findNoteIndexAndNullifier(
+ const { noteHashIndex, nonce, noteHash } = await findNoteIndexAndNullifier(
simulator,
noteHashes,
txHash,
@@ -130,7 +130,7 @@ export async function produceNoteDaos(
payload.noteTypeId,
txHash,
nonce,
- slottedNoteHash,
+ noteHash,
index,
ovpkM,
);
@@ -170,7 +170,7 @@ export async function produceNoteDaos(
* @dev Finds the index in the note hash tree by computing the note hash with different nonce and see which hash for
* the current tx matches this value.
* @remarks This method assists in identifying spent notes in the note hash tree.
- * @param noteHashes - Note hashes in the tx. One of them should correspond to the note we are looking for
+ * @param siloedNoteHashes - Note hashes in the tx. One of them should correspond to the note we are looking for
* @param txHash - Hash of a tx the note was emitted in.
* @param l1NotePayload - The note payload.
* @param excludedIndices - Indices that have been assigned a note in the same tx. Notes in a tx can have the same
@@ -181,7 +181,7 @@ export async function produceNoteDaos(
*/
async function findNoteIndexAndNullifier(
simulator: AcirSimulator,
- noteHashes: Fr[],
+ siloedNoteHashes: Fr[],
txHash: TxHash,
{ contractAddress, storageSlot, noteTypeId, note }: L1NotePayload,
excludedIndices: Set,
@@ -189,23 +189,23 @@ async function findNoteIndexAndNullifier(
) {
let noteHashIndex = 0;
let nonce: Fr | undefined;
- let slottedNoteHash: Fr | undefined;
+ let noteHash: Fr | undefined;
let siloedNoteHash: Fr | undefined;
let innerNullifier: Fr | undefined;
const firstNullifier = Fr.fromBuffer(txHash.toBuffer());
- for (; noteHashIndex < noteHashes.length; ++noteHashIndex) {
+ for (; noteHashIndex < siloedNoteHashes.length; ++noteHashIndex) {
if (excludedIndices.has(noteHashIndex)) {
continue;
}
- const noteHash = noteHashes[noteHashIndex];
- if (noteHash.equals(Fr.ZERO)) {
+ const siloedNoteHashFromTxEffect = siloedNoteHashes[noteHashIndex];
+ if (siloedNoteHashFromTxEffect.equals(Fr.ZERO)) {
break;
}
const expectedNonce = computeNoteHashNonce(firstNullifier, noteHashIndex);
- ({ slottedNoteHash, siloedNoteHash, innerNullifier } = await simulator.computeNoteHashAndOptionallyANullifier(
+ ({ noteHash, siloedNoteHash, innerNullifier } = await simulator.computeNoteHashAndOptionallyANullifier(
contractAddress,
expectedNonce,
storageSlot,
@@ -214,7 +214,7 @@ async function findNoteIndexAndNullifier(
note,
));
- if (noteHash.equals(siloedNoteHash)) {
+ if (siloedNoteHashFromTxEffect.equals(siloedNoteHash)) {
nonce = expectedNonce;
break;
}
@@ -229,7 +229,7 @@ async function findNoteIndexAndNullifier(
return {
noteHashIndex,
nonce,
- slottedNoteHash: slottedNoteHash!,
+ noteHash: noteHash!,
siloedNullifier: siloNullifier(contractAddress, innerNullifier!),
};
}
diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts
index 5c61d5f975ac..d6d3e2437a78 100644
--- a/yarn-project/pxe/src/pxe_service/pxe_service.ts
+++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts
@@ -350,15 +350,14 @@ export class PXEService implements PXE {
}
for (const nonce of nonces) {
- const { slottedNoteHash, siloedNoteHash, innerNullifier } =
- await this.simulator.computeNoteHashAndOptionallyANullifier(
- note.contractAddress,
- nonce,
- note.storageSlot,
- note.noteTypeId,
- true,
- note.note,
- );
+ const { noteHash, siloedNoteHash, innerNullifier } = await this.simulator.computeNoteHashAndOptionallyANullifier(
+ note.contractAddress,
+ nonce,
+ note.storageSlot,
+ note.noteTypeId,
+ true,
+ note.note,
+ );
const index = await this.node.findLeafIndex('latest', MerkleTreeId.NOTE_HASH_TREE, siloedNoteHash);
if (index === undefined) {
@@ -379,7 +378,7 @@ export class PXEService implements PXE {
note.noteTypeId,
note.txHash,
nonce,
- slottedNoteHash,
+ noteHash,
siloedNullifier,
index,
owner.publicKeys.masterIncomingViewingPublicKey,
@@ -401,15 +400,14 @@ export class PXEService implements PXE {
}
for (const nonce of nonces) {
- const { slottedNoteHash, siloedNoteHash, innerNullifier } =
- await this.simulator.computeNoteHashAndOptionallyANullifier(
- note.contractAddress,
- nonce,
- note.storageSlot,
- note.noteTypeId,
- false,
- note.note,
- );
+ const { noteHash, siloedNoteHash, innerNullifier } = await this.simulator.computeNoteHashAndOptionallyANullifier(
+ note.contractAddress,
+ nonce,
+ note.storageSlot,
+ note.noteTypeId,
+ false,
+ note.note,
+ );
if (!innerNullifier.equals(Fr.ZERO)) {
throw new Error('Unexpectedly received non-zero nullifier.');
@@ -428,7 +426,7 @@ export class PXEService implements PXE {
note.noteTypeId,
note.txHash,
nonce,
- slottedNoteHash,
+ noteHash,
Fr.ZERO, // We are not able to derive
index,
owner.publicKeys.masterIncomingViewingPublicKey,
diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts
index deab8e878d7a..5798a955888e 100644
--- a/yarn-project/pxe/src/simulator_oracle/index.ts
+++ b/yarn-project/pxe/src/simulator_oracle/index.ts
@@ -84,12 +84,12 @@ export class SimulatorOracle implements DBOracle {
status,
scopes,
});
- return noteDaos.map(({ contractAddress, storageSlot, nonce, note, slottedNoteHash, siloedNullifier, index }) => ({
+ return noteDaos.map(({ contractAddress, storageSlot, nonce, note, noteHash, siloedNullifier, index }) => ({
contractAddress,
storageSlot,
nonce,
note,
- slottedNoteHash,
+ noteHash,
siloedNullifier,
// PXE can use this index to get full MembershipWitness
index,
diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts
index 2c6de5ba7f69..cab30078dc7a 100644
--- a/yarn-project/simulator/src/acvm/oracle/oracle.ts
+++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts
@@ -247,14 +247,14 @@ export class Oracle {
[storageSlot]: ACVMField[],
[noteTypeId]: ACVMField[],
note: ACVMField[],
- [slottedNoteHash]: ACVMField[],
+ [noteHash]: ACVMField[],
[counter]: ACVMField[],
): ACVMField {
this.typedOracle.notifyCreatedNote(
fromACVMField(storageSlot),
NoteSelector.fromField(fromACVMField(noteTypeId)),
note.map(fromACVMField),
- fromACVMField(slottedNoteHash),
+ fromACVMField(noteHash),
+counter,
);
return toACVMField(0);
@@ -262,10 +262,10 @@ export class Oracle {
async notifyNullifiedNote(
[innerNullifier]: ACVMField[],
- [slottedNoteHash]: ACVMField[],
+ [noteHash]: ACVMField[],
[counter]: ACVMField[],
): Promise {
- await this.typedOracle.notifyNullifiedNote(fromACVMField(innerNullifier), fromACVMField(slottedNoteHash), +counter);
+ await this.typedOracle.notifyNullifiedNote(fromACVMField(innerNullifier), fromACVMField(noteHash), +counter);
return toACVMField(0);
}
diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts
index 872e0b2b5afc..1b9dae81e8aa 100644
--- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts
+++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts
@@ -27,8 +27,8 @@ export interface NoteData {
storageSlot: Fr;
/** The nonce of the note. */
nonce: Fr;
- /** The slotted note hash of the note. */
- slottedNoteHash: Fr;
+ /** A hash of the note. */
+ noteHash: Fr;
/** The corresponding nullifier of the note. Undefined for pending notes. */
siloedNullifier?: Fr;
/** The note's leaf index in the note hash tree. Undefined for pending notes. */
@@ -158,17 +158,11 @@ export abstract class TypedOracle {
throw new OracleMethodNotAvailableError('getNotes');
}
- notifyCreatedNote(
- _storageSlot: Fr,
- _noteTypeId: NoteSelector,
- _note: Fr[],
- _slottedNoteHash: Fr,
- _counter: number,
- ): void {
+ notifyCreatedNote(_storageSlot: Fr, _noteTypeId: NoteSelector, _note: Fr[], _noteHash: Fr, _counter: number): void {
throw new OracleMethodNotAvailableError('notifyCreatedNote');
}
- notifyNullifiedNote(_innerNullifier: Fr, _slottedNoteHash: Fr, _counter: number): Promise {
+ notifyNullifiedNote(_innerNullifier: Fr, _noteHash: Fr, _counter: number): Promise {
throw new OracleMethodNotAvailableError('notifyNullifiedNote');
}
diff --git a/yarn-project/simulator/src/client/client_execution_context.ts b/yarn-project/simulator/src/client/client_execution_context.ts
index d682e12553d8..79b1f913ef4d 100644
--- a/yarn-project/simulator/src/client/client_execution_context.ts
+++ b/yarn-project/simulator/src/client/client_execution_context.ts
@@ -136,7 +136,6 @@ export class ClientExecutionContext extends ViewDataOracle {
/**
* Get the data for the newly created notes.
- * @param slottedNoteHashes - Slotted note hashes for the notes.
*/
public getNewNotes(): NoteAndSlot[] {
return this.newNotes;
@@ -277,7 +276,7 @@ export class ClientExecutionContext extends ViewDataOracle {
notes.forEach(n => {
if (n.index !== undefined) {
- const uniqueNoteHash = computeUniqueNoteHash(n.nonce, n.slottedNoteHash);
+ const uniqueNoteHash = computeUniqueNoteHash(n.nonce, n.noteHash);
const siloedNoteHash = siloNoteHash(n.contractAddress, uniqueNoteHash);
this.noteHashLeafIndexMap.set(siloedNoteHash.toBigInt(), n.index);
}
@@ -293,14 +292,14 @@ export class ClientExecutionContext extends ViewDataOracle {
* @param storageSlot - The storage slot.
* @param noteTypeId - The type ID of the note.
* @param noteItems - The items to be included in a Note.
- * @param slottedNoteHash - The slotted note hash of the new note.
+ * @param noteHash - A hash of the new note.
* @returns
*/
public override notifyCreatedNote(
storageSlot: Fr,
noteTypeId: NoteSelector,
noteItems: Fr[],
- slottedNoteHash: Fr,
+ noteHash: Fr,
counter: number,
) {
const note = new Note(noteItems);
@@ -311,7 +310,7 @@ export class ClientExecutionContext extends ViewDataOracle {
nonce: Fr.ZERO, // Nonce cannot be known during private execution.
note,
siloedNullifier: undefined, // Siloed nullifier cannot be known for newly created note.
- slottedNoteHash,
+ noteHash,
},
counter,
);
@@ -326,13 +325,13 @@ export class ClientExecutionContext extends ViewDataOracle {
* Adding a siloed nullifier into the current set of all pending nullifiers created
* within the current transaction/execution.
* @param innerNullifier - The pending nullifier to add in the list (not yet siloed by contract address).
- * @param slottedNoteHash - The slotted note hash of the new note.
+ * @param noteHash - A hash of the new note.
*/
- public override notifyNullifiedNote(innerNullifier: Fr, slottedNoteHash: Fr, counter: number) {
+ public override notifyNullifiedNote(innerNullifier: Fr, noteHash: Fr, counter: number) {
const nullifiedNoteHashCounter = this.noteCache.nullifyNote(
this.callContext.storageContractAddress,
innerNullifier,
- slottedNoteHash,
+ noteHash,
);
if (nullifiedNoteHashCounter !== undefined) {
this.noteHashNullifierCounterMap.set(nullifiedNoteHashCounter, counter);
diff --git a/yarn-project/simulator/src/client/execution_note_cache.ts b/yarn-project/simulator/src/client/execution_note_cache.ts
index b97dfda9aebc..f8e1ec0a670e 100644
--- a/yarn-project/simulator/src/client/execution_note_cache.ts
+++ b/yarn-project/simulator/src/client/execution_note_cache.ts
@@ -51,7 +51,7 @@ export class ExecutionNoteCache {
// The nonces will be used to create the "complete" nullifier.
const updatedNotes = this.notes.map(({ note, counter }, i) => {
const nonce = computeNoteHashNonce(this.txHash, i);
- const uniqueNoteHash = computeUniqueNoteHash(nonce, note.slottedNoteHash);
+ const uniqueNoteHash = computeUniqueNoteHash(nonce, note.noteHash);
return {
counter,
note: { ...note, nonce },
@@ -76,27 +76,27 @@ export class ExecutionNoteCache {
);
}
- this.#addNote({ note, counter, noteHashForConsumption: note.slottedNoteHash });
+ this.#addNote({ note, counter, noteHashForConsumption: note.noteHash });
}
/**
* Add a nullifier to cache. It could be for a db note or a new note created during execution.
* @param contractAddress - Contract address of the note.
* @param innerNullifier - Inner nullifier of the note.
- * @param slottedNoteHash - Slotted note hash of the note. If this value equals 0, it means the
- * note being nullified is from a previous transaction (and thus not a new note).
+ * @param noteHash - A hash of the note. If this value equals 0, it means the note being nullified is from a previous
+ * transaction (and thus not a new note).
*/
- public nullifyNote(contractAddress: AztecAddress, innerNullifier: Fr, slottedNoteHash: Fr) {
+ public nullifyNote(contractAddress: AztecAddress, innerNullifier: Fr, noteHash: Fr) {
const siloedNullifier = siloNullifier(contractAddress, innerNullifier);
const nullifiers = this.getNullifiers(contractAddress);
nullifiers.add(siloedNullifier.value);
this.nullifierMap.set(contractAddress.toBigInt(), nullifiers);
let nullifiedNoteHashCounter: number | undefined = undefined;
- // Find and remove the matching new note and log(s) if the emitted slottedNoteHash is not empty.
- if (!slottedNoteHash.isEmpty()) {
+ // Find and remove the matching new note and log(s) if the emitted noteHash is not empty.
+ if (!noteHash.isEmpty()) {
const notesInContract = this.noteMap.get(contractAddress.toBigInt()) ?? [];
- const noteIndexToRemove = notesInContract.findIndex(n => n.noteHashForConsumption.equals(slottedNoteHash));
+ const noteIndexToRemove = notesInContract.findIndex(n => n.noteHashForConsumption.equals(noteHash));
if (noteIndexToRemove === -1) {
throw new Error('Attempt to remove a pending note that does not exist.');
}
@@ -124,11 +124,11 @@ export class ExecutionNoteCache {
* Check if a note exists in the newNotes array.
* @param contractAddress - Contract address of the note.
* @param storageSlot - Storage slot of the note.
- * @param slottedNoteHash - Slotted note hash of the note.
+ * @param noteHash - A hash of the note.
**/
- public checkNoteExists(contractAddress: AztecAddress, slottedNoteHash: Fr) {
+ public checkNoteExists(contractAddress: AztecAddress, noteHash: Fr) {
const notes = this.noteMap.get(contractAddress.toBigInt()) ?? [];
- return notes.some(n => n.note.slottedNoteHash.equals(slottedNoteHash));
+ return notes.some(n => n.note.noteHash.equals(noteHash));
}
/**
diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts
index 56a8c254d6f8..d668a2130a3f 100644
--- a/yarn-project/simulator/src/client/private_execution.test.ts
+++ b/yarn-project/simulator/src/client/private_execution.test.ts
@@ -74,7 +74,7 @@ import { buildL1ToL2Message } from '../test/utils.js';
import { type DBOracle } from './db_oracle.js';
import { CountedPublicExecutionRequest, type ExecutionResult, collectSortedEncryptedLogs } from './execution_result.js';
import { AcirSimulator } from './simulator.js';
-import { computeNoteHidingPoint, computeSlottedNoteHash } from './test_utils.js';
+import { computeNoteHash } from './test_utils.js';
jest.setTimeout(60_000);
@@ -321,14 +321,14 @@ describe('Private Execution test suite', () => {
const noteHashIndex = randomInt(1); // mock index in TX's final noteHashes array
const nonce = computeNoteHashNonce(mockFirstNullifier, noteHashIndex);
const note = new Note([new Fr(amount), ownerNpkMHash, Fr.random()]);
- const slottedNoteHash = computeSlottedNoteHash(storageSlot, computeNoteHidingPoint(note.items));
+ const noteHash = computeNoteHash(storageSlot, note.items);
return {
contractAddress,
storageSlot,
noteTypeId,
nonce,
note,
- slottedNoteHash,
+ noteHash,
siloedNullifier: new Fr(0),
index: currentNoteIndex++,
};
@@ -360,12 +360,7 @@ describe('Private Execution test suite', () => {
const noteHashes = getNonEmptyItems(result.callStackItem.publicInputs.noteHashes);
expect(noteHashes).toHaveLength(1);
expect(noteHashes[0].value).toEqual(
- await acirSimulator.computeSlottedNoteHash(
- contractAddress,
- newNote.storageSlot,
- newNote.noteTypeId,
- newNote.note,
- ),
+ await acirSimulator.computeNoteHash(contractAddress, newNote.storageSlot, newNote.noteTypeId, newNote.note),
);
const newEncryptedLogs = getNonEmptyItems(result.callStackItem.publicInputs.noteEncryptedLogsHashes);
@@ -390,12 +385,7 @@ describe('Private Execution test suite', () => {
const noteHashes = getNonEmptyItems(result.callStackItem.publicInputs.noteHashes);
expect(noteHashes).toHaveLength(1);
expect(noteHashes[0].value).toEqual(
- await acirSimulator.computeSlottedNoteHash(
- contractAddress,
- newNote.storageSlot,
- newNote.noteTypeId,
- newNote.note,
- ),
+ await acirSimulator.computeNoteHash(contractAddress, newNote.storageSlot, newNote.noteTypeId, newNote.note),
);
const newEncryptedLogs = getNonEmptyItems(result.callStackItem.publicInputs.noteEncryptedLogsHashes);
@@ -448,20 +438,15 @@ describe('Private Execution test suite', () => {
expect(recipientNote.storageSlot).toEqual(recipientStorageSlot);
expect(recipientNote.noteTypeId).toEqual(valueNoteTypeId);
- const noteHashes = getNonEmptyItems(result.callStackItem.publicInputs.noteHashes);
- expect(noteHashes).toHaveLength(2);
- const [changeNoteHash, recipientNoteHash] = noteHashes;
- const [recipientSlottedNoteHash, changeSlottedNoteHash] = [
- await acirSimulator.computeSlottedNoteHash(
- contractAddress,
- recipientStorageSlot,
- valueNoteTypeId,
- recipientNote.note,
- ),
- await acirSimulator.computeSlottedNoteHash(contractAddress, storageSlot, valueNoteTypeId, changeNote.note),
+ const noteHashesFromCallStackItem = getNonEmptyItems(result.callStackItem.publicInputs.noteHashes);
+ expect(noteHashesFromCallStackItem).toHaveLength(2);
+ const [changeNoteHashFromCallStackItem, recipientNoteHashFromCallStackItem] = noteHashesFromCallStackItem;
+ const [changeNoteHash, recipientNoteHash] = [
+ await acirSimulator.computeNoteHash(contractAddress, storageSlot, valueNoteTypeId, changeNote.note),
+ await acirSimulator.computeNoteHash(contractAddress, recipientStorageSlot, valueNoteTypeId, recipientNote.note),
];
- expect(recipientNoteHash.value).toEqual(recipientSlottedNoteHash);
- expect(changeNoteHash.value).toEqual(changeSlottedNoteHash);
+ expect(changeNoteHashFromCallStackItem.value).toEqual(changeNoteHash);
+ expect(recipientNoteHashFromCallStackItem.value).toEqual(recipientNoteHash);
expect(recipientNote.note.items[0]).toEqual(new Fr(amountToTransfer));
expect(changeNote.note.items[0]).toEqual(new Fr(40n));
@@ -471,9 +456,9 @@ describe('Private Execution test suite', () => {
const [encryptedChangeLog, encryptedRecipientLog] = newEncryptedLogs;
expect(encryptedChangeLog.value).toEqual(Fr.fromBuffer(result.noteEncryptedLogs[0].log.hash()));
- expect(encryptedChangeLog.noteHashCounter).toEqual(changeNoteHash.counter);
+ expect(encryptedChangeLog.noteHashCounter).toEqual(changeNoteHashFromCallStackItem.counter);
expect(encryptedRecipientLog.value).toEqual(Fr.fromBuffer(result.noteEncryptedLogs[1].log.hash()));
- expect(encryptedRecipientLog.noteHashCounter).toEqual(recipientNoteHash.counter);
+ expect(encryptedRecipientLog.noteHashCounter).toEqual(recipientNoteHashFromCallStackItem.counter);
expect(encryptedChangeLog.length.add(encryptedRecipientLog.length)).toEqual(
new Fr(getEncryptedNoteSerializedLength(result)),
);
@@ -840,7 +825,7 @@ describe('Private Execution test suite', () => {
storageSlot,
nonce: Fr.ZERO,
note,
- slottedNoteHash: Fr.ZERO,
+ noteHash: Fr.ZERO,
siloedNullifier: Fr.random(),
index: 1n,
},
@@ -963,40 +948,40 @@ describe('Private Execution test suite', () => {
expect(noteAndSlot.note.items[0]).toEqual(new Fr(amountToTransfer));
- const noteHashes = getNonEmptyItems(result.callStackItem.publicInputs.noteHashes);
- expect(noteHashes).toHaveLength(1);
+ const noteHashesFromCallStackItem = getNonEmptyItems(result.callStackItem.publicInputs.noteHashes);
+ expect(noteHashesFromCallStackItem).toHaveLength(1);
- const noteHash = noteHashes[0].value;
+ const noteHashFromCallStackItem = noteHashesFromCallStackItem[0].value;
const storageSlot = deriveStorageSlotInMap(
PendingNoteHashesContractArtifact.storageLayout['balances'].slot,
owner,
);
- const slottedNoteHash = await acirSimulator.computeSlottedNoteHash(
+ const derivedNoteHash = await acirSimulator.computeNoteHash(
contractAddress,
storageSlot,
valueNoteTypeId,
noteAndSlot.note,
);
- expect(noteHash).toEqual(slottedNoteHash);
+ expect(noteHashFromCallStackItem).toEqual(derivedNoteHash);
const newEncryptedLogs = getNonEmptyItems(result.callStackItem.publicInputs.noteEncryptedLogsHashes);
expect(newEncryptedLogs).toHaveLength(1);
const [encryptedLog] = newEncryptedLogs;
- expect(encryptedLog.noteHashCounter).toEqual(noteHashes[0].counter);
+ expect(encryptedLog.noteHashCounter).toEqual(noteHashesFromCallStackItem[0].counter);
expect(encryptedLog.noteHashCounter).toEqual(result.noteEncryptedLogs[0].noteHashCounter);
expect(encryptedLog.value).toEqual(Fr.fromBuffer(result.noteEncryptedLogs[0].log.hash()));
- // read request should match slottedNoteHash for pending notes (there is no nonce, so can't compute "unique" hash)
+ // read request should match a note hash for pending notes (there is no nonce, so can't compute "unique" hash)
const readRequest = getNonEmptyItems(result.callStackItem.publicInputs.noteHashReadRequests)[0];
- expect(readRequest.value).toEqual(slottedNoteHash);
+ expect(readRequest.value).toEqual(derivedNoteHash);
expect(result.returnValues).toEqual([new Fr(amountToTransfer)]);
const nullifier = result.callStackItem.publicInputs.nullifiers[0];
const expectedNullifier = poseidon2HashWithSeparator(
- [slottedNoteHash, computeAppNullifierSecretKey(ownerNskM, contractAddress)],
+ [derivedNoteHash, computeAppNullifierSecretKey(ownerNskM, contractAddress)],
GeneratorIndex.NOTE_NULLIFIER,
);
expect(nullifier.value).toEqual(expectedNullifier);
@@ -1054,14 +1039,14 @@ describe('Private Execution test suite', () => {
const noteHashes = getNonEmptyItems(execInsert.callStackItem.publicInputs.noteHashes);
expect(noteHashes).toHaveLength(1);
- const noteHash = noteHashes[0].value;
- const slottedNoteHash = await acirSimulator.computeSlottedNoteHash(
+ const noteHashFromCallStackItem = noteHashes[0].value;
+ const derivedNoteHash = await acirSimulator.computeNoteHash(
contractAddress,
noteAndSlot.storageSlot,
noteAndSlot.noteTypeId,
noteAndSlot.note,
);
- expect(noteHash).toEqual(slottedNoteHash);
+ expect(noteHashFromCallStackItem).toEqual(derivedNoteHash);
const newEncryptedLogs = getNonEmptyItems(execInsert.callStackItem.publicInputs.noteEncryptedLogsHashes);
expect(newEncryptedLogs).toHaveLength(1);
@@ -1071,15 +1056,15 @@ describe('Private Execution test suite', () => {
expect(encryptedLog.noteHashCounter).toEqual(execInsert.noteEncryptedLogs[0].noteHashCounter);
expect(encryptedLog.value).toEqual(Fr.fromBuffer(execInsert.noteEncryptedLogs[0].log.hash()));
- // read request should match slottedNoteHash for pending notes (there is no nonce, so can't compute "unique" hash)
+ // read request should match a note hash for pending notes (there is no nonce, so can't compute "unique" hash)
const readRequest = execGetThenNullify.callStackItem.publicInputs.noteHashReadRequests[0];
- expect(readRequest.value).toEqual(slottedNoteHash);
+ expect(readRequest.value).toEqual(derivedNoteHash);
expect(execGetThenNullify.returnValues).toEqual([new Fr(amountToTransfer)]);
const nullifier = execGetThenNullify.callStackItem.publicInputs.nullifiers[0];
const expectedNullifier = poseidon2HashWithSeparator(
- [slottedNoteHash, computeAppNullifierSecretKey(ownerNskM, contractAddress)],
+ [derivedNoteHash, computeAppNullifierSecretKey(ownerNskM, contractAddress)],
GeneratorIndex.NOTE_NULLIFIER,
);
expect(nullifier.value).toEqual(expectedNullifier);
diff --git a/yarn-project/simulator/src/client/simulator.test.ts b/yarn-project/simulator/src/client/simulator.test.ts
index 53b4ea3b9ee4..601cb2aa6e6f 100644
--- a/yarn-project/simulator/src/client/simulator.test.ts
+++ b/yarn-project/simulator/src/client/simulator.test.ts
@@ -11,7 +11,7 @@ import { type MockProxy, mock } from 'jest-mock-extended';
import { type DBOracle } from './db_oracle.js';
import { AcirSimulator } from './simulator.js';
-import { computeNoteHidingPoint, computeSlottedNoteHash } from './test_utils.js';
+import { computeNoteHash } from './test_utils.js';
describe('Simulator', () => {
let oracle: MockProxy;
@@ -61,9 +61,8 @@ describe('Simulator', () => {
oracle.getFunctionArtifactByName.mockResolvedValue(artifact);
const note = createNote();
- const noteHidingPoint = computeNoteHidingPoint(note.items);
- const slottedNoteHash = computeSlottedNoteHash(storageSlot, noteHidingPoint);
- const uniqueNoteHash = computeUniqueNoteHash(nonce, slottedNoteHash);
+ const noteHash = computeNoteHash(storageSlot, note.items);
+ const uniqueNoteHash = computeUniqueNoteHash(nonce, noteHash);
const siloedNoteHash = siloNoteHash(contractAddress, uniqueNoteHash);
const innerNullifier = poseidon2HashWithSeparator(
[siloedNoteHash, appNullifierSecretKey],
@@ -80,7 +79,7 @@ describe('Simulator', () => {
);
expect(result).toEqual({
- slottedNoteHash,
+ noteHash,
uniqueNoteHash,
siloedNoteHash,
innerNullifier,
diff --git a/yarn-project/simulator/src/client/simulator.ts b/yarn-project/simulator/src/client/simulator.ts
index 260282c67a1b..4205fa80b4dc 100644
--- a/yarn-project/simulator/src/client/simulator.ts
+++ b/yarn-project/simulator/src/client/simulator.ts
@@ -196,7 +196,7 @@ export class AcirSimulator {
returnTypes: artifact.returnTypes,
};
- const [slottedNoteHash, uniqueNoteHash, siloedNoteHash, innerNullifier] = (await this.runUnconstrained(
+ const [noteHash, uniqueNoteHash, siloedNoteHash, innerNullifier] = (await this.runUnconstrained(
execRequest,
artifact,
contractAddress,
@@ -204,7 +204,7 @@ export class AcirSimulator {
)) as bigint[];
return {
- slottedNoteHash: new Fr(slottedNoteHash),
+ noteHash: new Fr(noteHash),
uniqueNoteHash: new Fr(uniqueNoteHash),
siloedNoteHash: new Fr(siloedNoteHash),
innerNullifier: new Fr(innerNullifier),
@@ -212,20 +212,15 @@ export class AcirSimulator {
}
/**
- * Computes the slotted note hash of a note, which contains storage slot and the custom note hash.
+ * Computes a hash of the note.
* @param contractAddress - The address of the contract.
* @param storageSlot - The storage slot.
* @param noteTypeId - The note type identifier.
* @param note - The note.
* @returns The note hash.
*/
- public async computeSlottedNoteHash(
- contractAddress: AztecAddress,
- storageSlot: Fr,
- noteTypeId: NoteSelector,
- note: Note,
- ) {
- const { slottedNoteHash } = await this.computeNoteHashAndOptionallyANullifier(
+ public async computeNoteHash(contractAddress: AztecAddress, storageSlot: Fr, noteTypeId: NoteSelector, note: Note) {
+ const { noteHash } = await this.computeNoteHashAndOptionallyANullifier(
contractAddress,
Fr.ZERO,
storageSlot,
@@ -233,6 +228,6 @@ export class AcirSimulator {
false,
note,
);
- return slottedNoteHash;
+ return noteHash;
}
}
diff --git a/yarn-project/simulator/src/client/test_utils.ts b/yarn-project/simulator/src/client/test_utils.ts
index f8e34baa86b1..9253a36fcdb0 100644
--- a/yarn-project/simulator/src/client/test_utils.ts
+++ b/yarn-project/simulator/src/client/test_utils.ts
@@ -11,26 +11,20 @@ const G_SLOT = new Point(
/**
* Computes a note hiding point as is done by the default implementation injected by macros.
+ * @param storageSlot - The slot to which the note was inserted.
* @param noteContent - The note content (e.g. note.items).
- * @returns A note hiding point.
+ * @returns A note hash.
*/
-export function computeNoteHidingPoint(noteContent: Fr[]): Point {
+export function computeNoteHash(storageSlot: Fr, noteContent: Fr[]): Fr {
+ // TODO(#7771): update this to do only 1 MSM call
const c = pedersenCommit(
noteContent.map(f => f.toBuffer()),
GeneratorIndex.NOTE_HIDING_POINT,
);
- return new Point(new Fr(c[0]), new Fr(c[1]), false);
-}
+ const noteHidingPointBeforeSlotting = new Point(new Fr(c[0]), new Fr(c[1]), false);
-/**
- * Computes an slotted note hash, given a storage slot and a note hiding point.
- * @param storageSlot - The storage slot.
- * @param noteHidingPoint - The note hiding point.
- * @returns A slotted note hash.
- */
-export function computeSlottedNoteHash(storageSlot: Fr, noteHidingPoint: Point): Fr {
const grumpkin = new Grumpkin();
- const storageSlotPoint = grumpkin.mul(G_SLOT, new Fq(storageSlot.toBigInt()));
- const slottedNoteHidingPoint = grumpkin.add(storageSlotPoint, noteHidingPoint);
- return slottedNoteHidingPoint.x;
+ const slotPoint = grumpkin.mul(G_SLOT, new Fq(storageSlot.toBigInt()));
+ const noteHidingPoint = grumpkin.add(noteHidingPointBeforeSlotting, slotPoint);
+ return noteHidingPoint.x;
}
diff --git a/yarn-project/simulator/src/client/unconstrained_execution.test.ts b/yarn-project/simulator/src/client/unconstrained_execution.test.ts
index e446f01d8b56..b1eb64457a8e 100644
--- a/yarn-project/simulator/src/client/unconstrained_execution.test.ts
+++ b/yarn-project/simulator/src/client/unconstrained_execution.test.ts
@@ -61,7 +61,7 @@ describe('Unconstrained Execution test suite', () => {
nonce: Fr.random(),
isSome: new Fr(1),
note,
- slottedNoteHash: Fr.random(),
+ noteHash: Fr.random(),
siloedNullifier: Fr.random(),
index: BigInt(index),
})),
diff --git a/yarn-project/txe/src/oracle/txe_oracle.ts b/yarn-project/txe/src/oracle/txe_oracle.ts
index 5b9152982edb..e904db3165bb 100644
--- a/yarn-project/txe/src/oracle/txe_oracle.ts
+++ b/yarn-project/txe/src/oracle/txe_oracle.ts
@@ -226,10 +226,10 @@ export class TXE implements TypedOracle {
return Promise.resolve();
}
- async avmOpcodeEmitNoteHash(slottedNoteHash: Fr) {
+ async avmOpcodeEmitNoteHash(noteHash: Fr) {
const db = this.trees.asLatest();
- const noteHash = siloNoteHash(this.contractAddress, slottedNoteHash);
- await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, [noteHash]);
+ const siloedNoteHash = siloNoteHash(this.contractAddress, noteHash);
+ await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, [siloedNoteHash]);
return Promise.resolve();
}
@@ -253,9 +253,9 @@ export class TXE implements TypedOracle {
await db.batchInsert(MerkleTreeId.NULLIFIER_TREE, siloedNullifiers, NULLIFIER_SUBTREE_HEIGHT);
}
- async addNoteHashes(contractAddress: AztecAddress, slottedNoteHashes: Fr[]) {
+ async addNoteHashes(contractAddress: AztecAddress, noteHashes: Fr[]) {
const db = this.trees.asLatest();
- const siloedNoteHashes = slottedNoteHashes.map(slottedNoteHash => siloNoteHash(contractAddress, slottedNoteHash));
+ const siloedNoteHashes = noteHashes.map(noteHash => siloNoteHash(contractAddress, noteHash));
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, siloedNoteHashes);
}
@@ -425,7 +425,7 @@ export class TXE implements TypedOracle {
return Promise.resolve(notes);
}
- notifyCreatedNote(storageSlot: Fr, noteTypeId: NoteSelector, noteItems: Fr[], slottedNoteHash: Fr, counter: number) {
+ notifyCreatedNote(storageSlot: Fr, noteTypeId: NoteSelector, noteItems: Fr[], noteHash: Fr, counter: number) {
const note = new Note(noteItems);
this.noteCache.addNewNote(
{
@@ -434,7 +434,7 @@ export class TXE implements TypedOracle {
nonce: Fr.ZERO, // Nonce cannot be known during private execution.
note,
siloedNullifier: undefined, // Siloed nullifier cannot be known for newly created note.
- slottedNoteHash,
+ noteHash,
},
counter,
);
@@ -442,8 +442,8 @@ export class TXE implements TypedOracle {
return Promise.resolve();
}
- notifyNullifiedNote(innerNullifier: Fr, slottedNoteHash: Fr, counter: number) {
- this.noteCache.nullifyNote(this.contractAddress, innerNullifier, slottedNoteHash);
+ notifyNullifiedNote(innerNullifier: Fr, noteHash: Fr, counter: number) {
+ this.noteCache.nullifyNote(this.contractAddress, innerNullifier, noteHash);
this.sideEffectsCounter = counter + 1;
return Promise.resolve();
}
diff --git a/yarn-project/txe/src/txe_service/txe_service.ts b/yarn-project/txe/src/txe_service/txe_service.ts
index 6c107653368d..86985da26e77 100644
--- a/yarn-project/txe/src/txe_service/txe_service.ts
+++ b/yarn-project/txe/src/txe_service/txe_service.ts
@@ -443,14 +443,14 @@ export class TXEService {
storageSlot: ForeignCallSingle,
noteTypeId: ForeignCallSingle,
note: ForeignCallArray,
- slottedNoteHash: ForeignCallSingle,
+ noteHash: ForeignCallSingle,
counter: ForeignCallSingle,
) {
this.typedOracle.notifyCreatedNote(
fromSingle(storageSlot),
NoteSelector.fromField(fromSingle(noteTypeId)),
fromArray(note),
- fromSingle(slottedNoteHash),
+ fromSingle(noteHash),
fromSingle(counter).toNumber(),
);
return toForeignCallResult([toSingle(new Fr(0))]);
@@ -458,12 +458,12 @@ export class TXEService {
async notifyNullifiedNote(
innerNullifier: ForeignCallSingle,
- slottedNoteHash: ForeignCallSingle,
+ noteHash: ForeignCallSingle,
counter: ForeignCallSingle,
) {
await this.typedOracle.notifyNullifiedNote(
fromSingle(innerNullifier),
- fromSingle(slottedNoteHash),
+ fromSingle(noteHash),
fromSingle(counter).toNumber(),
);
return toForeignCallResult([toSingle(new Fr(0))]);
@@ -512,8 +512,8 @@ export class TXEService {
return toForeignCallResult([]);
}
- async avmOpcodeEmitNoteHash(slottedNoteHash: ForeignCallSingle) {
- await (this.typedOracle as TXE).avmOpcodeEmitNoteHash(fromSingle(slottedNoteHash));
+ async avmOpcodeEmitNoteHash(noteHash: ForeignCallSingle) {
+ await (this.typedOracle as TXE).avmOpcodeEmitNoteHash(fromSingle(noteHash));
return toForeignCallResult([]);
}