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..87cd38f1b12 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,17 @@ 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 read_value_change(self) -> ScheduledValueChange { + self.context.storage_read(self.get_value_change_storage_slot()) + } +} + 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..8d5923a7f20 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,63 @@ 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 mut 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); + + state_var_unconstrained = in_unconstrained(env); + 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); +}