From 2deb1bb279e397b22dd9ee4c1319045330f5099f Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Wed, 10 Jul 2024 17:16:06 +0000 Subject: [PATCH 1/2] init --- .../shared_mutable/shared_mutable.nr | 9 ++- .../src/state_vars/shared_mutable/test.nr | 57 +++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr index 2bf0d0001de..6e2f88cc08a 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr @@ -3,7 +3,7 @@ use dep::protocol_types::{ traits::{FromField, ToField} }; -use crate::context::{PrivateContext, PublicContext}; +use crate::context::{PrivateContext, PublicContext, UnconstrainedContext}; use crate::state_vars::{ storage::Storage, shared_mutable::{scheduled_value_change::ScheduledValueChange, scheduled_delay_change::ScheduledDelayChange} @@ -225,6 +225,13 @@ impl SharedMutable wher } } +impl SharedMutable where T: ToField + FromField + Eq { + unconstrained pub fn get_current_value_in_unconstrained(self) -> T { + let block_number = self.context.block_number() as u32; + self.read_value_change().get_current_at(block_number) + } +} + unconstrained fn get_public_storage_hints( address: AztecAddress, storage_slot: Field, diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/test.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/test.nr index 3bbe4121dc8..a22f612e87a 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/test.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/test.nr @@ -341,3 +341,60 @@ fn test_get_current_value_in_private_bad_zero_hash_delay_hints() { let _ = state_var.get_current_value_in_private(); } + +#[test] +fn test_get_current_value_in_unconstrained_initial() { + let env = setup(); + let state_var = in_unconstrained(env); + + assert_eq(state_var.get_current_value_in_unconstrained(), zeroed()); +} + +#[test] +fn test_get_current_value_in_unconstrained_before_scheduled_change() { + let mut env = setup(); + let state_var_public = in_public(env); + + state_var_public.schedule_value_change(new_value); + + let (_, block_of_change) = state_var_public.get_scheduled_value_in_public(); + + let original_value = zeroed(); + + let state_var_unconstrained = in_unconstrained(env); + + // The current value has not changed + assert_eq(state_var_unconstrained.get_current_value_in_unconstrained(), original_value); + + // The current value still does not change right before the block of change + env.advance_block_to(block_of_change - 1); + assert_eq(state_var_unconstrained.get_current_value_in_unconstrained(), original_value); +} + +#[test] +fn test_get_current_value_in_unconstrained_at_scheduled_change() { + let mut env = setup(); + let state_var_public = in_public(env); + + state_var_public.schedule_value_change(new_value); + + let (_, block_of_change) = state_var_public.get_scheduled_value_in_public(); + + env.advance_block_to(block_of_change); + let state_var_unconstrained = in_unconstrained(env); + assert_eq(state_var_unconstrained.get_current_value_in_unconstrained(), new_value); +} + +#[test] +fn test_get_current_value_in_unconstrained_after_scheduled_change() { + let mut env = setup(); + let state_var_public = in_public(env); + + state_var_public.schedule_value_change(new_value); + + let (_, block_of_change) = state_var_public.get_scheduled_value_in_public(); + + env.advance_block_to(block_of_change + 10); + let state_var_unconstrained = in_unconstrained(env); + assert_eq(state_var_unconstrained.get_current_value_in_unconstrained(), new_value); +} From c391ca7c6866dd2795f7335c3fd66b6c875833ee Mon Sep 17 00:00:00 2001 From: sklppy88 Date: Fri, 12 Jul 2024 11:38:56 +0000 Subject: [PATCH 2/2] init --- .../src/context/unconstrained_context.nr | 16 +++-- .../aztec/src/state_vars/public_immutable.nr | 2 +- .../aztec/src/state_vars/public_mutable.nr | 2 +- .../aztec/src/state_vars/shared_immutable.nr | 2 +- .../shared_mutable/shared_mutable.nr | 58 +++++++++++++++++-- .../contracts/test_contract/src/main.nr | 18 +++++- 6 files changed, 84 insertions(+), 14 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr b/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr index eedd97aa8d6..9c039a69d93 100644 --- a/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr @@ -37,12 +37,20 @@ impl UnconstrainedContext { self.chain_id } - unconstrained fn raw_storage_read(self: Self, storage_slot: Field) -> [Field; N] { - storage_read(self.this_address(), storage_slot, self.block_number()) + unconstrained fn raw_storage_read( + self: Self, + address: AztecAddress, + storage_slot: Field + ) -> [Field; N] { + storage_read(address, storage_slot, self.block_number()) } - unconstrained fn storage_read(self, storage_slot: Field) -> T where T: Deserialize { - T::deserialize(self.raw_storage_read(storage_slot)) + unconstrained fn storage_read( + self, + address: AztecAddress, + storage_slot: Field + ) -> T where T: Deserialize { + T::deserialize(self.raw_storage_read(address, storage_slot)) } } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr index 0ee3326bd84..d0f3a1a3182 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr @@ -51,6 +51,6 @@ impl PublicImmutable where T: Seria impl PublicImmutablewhere T: Deserialize { unconstrained pub fn read(self) -> T { - self.context.storage_read(self.storage_slot) + self.context.storage_read(self.context.this_address(), self.storage_slot) } } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr index 6c300e7575f..b4e22ccd84f 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr @@ -41,6 +41,6 @@ impl PublicMutable where T: Serializ impl PublicMutable where T: Deserialize { unconstrained pub fn read(self) -> T { - self.context.storage_read(self.storage_slot) + self.context.storage_read(self.context.this_address(), self.storage_slot) } } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr index 39848738dbb..7ad10a6dfe6 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr @@ -43,7 +43,7 @@ impl SharedImmutable where T: Serial impl SharedImmutable where T: Serialize + Deserialize { unconstrained pub fn read_public(self) -> T { - self.context.storage_read(self.storage_slot) + self.context.storage_read(self.context.this_address(), self.storage_slot) } } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr index 6e2f88cc08a..960692e4fe2 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr @@ -171,6 +171,28 @@ impl SharedMutable where self.read_delay_change().get_scheduled() } + // The AVM currently does not support reading from other contract addresses + // pub fn get_current_value_in_public_other(context: &mut PublicContext, address: AztecAddress, storage_slot: Field) -> T { + // let block_number = context.block_number() as u32; + + // let dummy = SharedMutable::new(context, storage_slot); + + // dummy.read_value_change().get_current_at(block_number) + // } + + // pub fn get_current_delay_in_public_other(context: &mut PublicContext, address: AztecAddress, storage_slot: Field) -> u32 { + // let block_number = context.block_number() as u32; + // self.read_delay_change().get_current(block_number) + // } + + // pub fn get_scheduled_value_in_public_other(context: &mut PublicContext, address: AztecAddress, storage_slot: Field) -> (T, u32) { + // self.read_value_change().get_scheduled() + // } + + // pub fn get_scheduled_delay_in_public_other(context: &mut PublicContext, address: AztecAddress, storage_slot: Field) -> (u32, u32) { + // self.read_delay_change().get_scheduled() + // } + fn read_value_change(self) -> ScheduledValueChange { self.context.storage_read(self.get_value_change_storage_slot()) } @@ -199,14 +221,23 @@ impl SharedMutable where } } -impl SharedMutable where T: ToField + FromField + Eq { - pub fn get_current_value_in_private(self) -> T { +impl SharedMutable { + pub fn get_current_value_in_private(self) -> T where T: ToField + FromField + Eq { + SharedMutable::get_current_value_in_private_other::(self.context, self.context.this_address(), self.storage_slot) + } + + pub fn get_current_value_in_private_other( + context: &mut PrivateContext, + address: AztecAddress, + storage_slot: Field + ) -> T_OTHER where T_OTHER: FromField + ToField + Eq { // When reading the current value in private we construct a historical state proof for the public value. // However, since this value might change, we must constrain the maximum transaction block number as this proof // will only be valid for however many blocks we can ensure the value will not change, which will depend on the // current delay and any scheduled delay changes. + let dummy: SharedMutable = SharedMutable::new((), storage_slot); - let (value_change, delay_change, historical_block_number) = self.historical_read_from_public_storage(self.context.get_header(), self.context.this_address()); + let (value_change, delay_change, historical_block_number): (ScheduledValueChange, ScheduledDelayChange, u32) = dummy.historical_read_from_public_storage(context.get_header(), address); // We use the effective minimum delay as opposed to the current delay at the historical block as this one also // takes into consideration any scheduled delay changes. @@ -220,15 +251,30 @@ impl SharedMutable wher // We prevent this transaction from being included in any block after the block horizon, ensuring that the // historical public value matches the current one, since it can only change after the horizon. - self.context.set_tx_max_block_number(block_horizon); + context.set_tx_max_block_number(block_horizon); value_change.get_current_at(historical_block_number) } } impl SharedMutable where T: ToField + FromField + Eq { unconstrained pub fn get_current_value_in_unconstrained(self) -> T { - let block_number = self.context.block_number() as u32; - self.read_value_change().get_current_at(block_number) + SharedMutable::get_current_value_in_unconstrained_other(self.context, self.context.this_address(), self.storage_slot) + } + + unconstrained pub fn get_current_value_in_unconstrained_other( + context: UnconstrainedContext, + address: AztecAddress, + storage_slot: Field + ) -> T { + let block_number = context.block_number() as u32; + + let dummy = SharedMutable::new(context, storage_slot); + + dummy.read_value_change(address).get_current_at(block_number) + } + + fn read_value_change(self, address: AztecAddress) -> ScheduledValueChange { + self.context.storage_read(address, self.get_value_change_storage_slot()) } } diff --git a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr index f0d020e3c61..324e964d4d9 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -23,7 +23,7 @@ contract Test { use dep::aztec::note::constants::MAX_NOTES_PER_PAGE; - use dep::aztec::state_vars::{shared_mutable::SharedMutablePrivateGetter}; + use dep::aztec::state_vars::{shared_mutable::{SharedMutable, SharedMutablePrivateGetter}}; use dep::aztec::{ context::inputs::private_context_inputs::PrivateContextInputs, @@ -482,6 +482,22 @@ contract Test { constant.value } + // This function is used in the e2e_state_vars to test the SharedMutablePrivateGetter in isolation + #[aztec(private)] + fn test_shared_mutable_getter( + contract_address_to_read: AztecAddress, + storage_slot_of_shared_mutable: Field + ) -> Field { + // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly + let test = SharedMutable::get_current_value_in_private_other::( + &mut context, + contract_address_to_read, + storage_slot_of_shared_mutable + ); + + test.to_field() + } + // This function is used in the e2e_state_vars to test the SharedMutablePrivateGetter in isolation #[aztec(private)] fn test_shared_mutable_private_getter(