Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Jan 31, 2025
1 parent f4e2953 commit 94b1141
Showing 1 changed file with 42 additions and 12 deletions.
54 changes: 42 additions & 12 deletions noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use crate::{
history::public_storage::PublicStorageHistoricalRead,
state_vars::storage::Storage,
};
use dep::protocol_types::{constants::INITIALIZATION_SLOT_SEPARATOR, traits::Packable};
use dep::protocol_types::{
address::AztecAddress, constants::INITIALIZATION_SLOT_SEPARATOR, traits::Packable,
};
use std::hash::pedersen_hash;

/// Stores an immutable value in public state which can be read from public, private and unconstrained execution
/// contexts.
Expand All @@ -14,7 +17,7 @@ pub struct PublicImmutable<T, Context> {
}
// docs:end:public_immutable_struct

impl<T, Context, let N: u32> Storage<N> for PublicImmutable<T, Context>
impl<T, Context, let N: u32> Storage<N + 1> for PublicImmutable<T, Context>
where
T: Packable<N>,
{
Expand Down Expand Up @@ -49,7 +52,18 @@ where

// We populate the initialization slot with a non-zero value to indicate that the struct is initialized
self.context.storage_write(initialization_slot, 0xdead);
self.context.storage_write(self.storage_slot, value);

// Pack the value into fields
let packed = value.pack();

// Compute Pedersen hash of the packed data
let packed_hash = pedersen_hash(packed);

// Write each packed field to storage
self.context.storage_write(self.storage_slot, packed);

// Write the hash to the next slot
self.context.storage_write(self.storage_slot + T_PACKED_LEN as Field, packed_hash);
}
// docs:end:public_immutable_struct_write

Expand All @@ -76,14 +90,30 @@ where
{
pub fn read(self) -> T {
let header = self.context.get_block_header();
let mut fields = [0; T_PACKED_LEN];

for i in 0..fields.len() {
fields[i] = header.public_storage_historical_read(
self.storage_slot + i as Field,
(*self.context).this_address(),
);
}
T::unpack(fields)
let contract_address = (*self.context).this_address();

// Load the packed data in an unconstrained context.
/// @safety We verify that a hash of the packed data matches the stored hash.
let packed = unsafe { read_in_unconstrained(contract_address, self.storage_slot) };

// Read the packed hash from storage_slot + T_PACKED_LEN
let packed_hash = header.public_storage_historical_read(
self.storage_slot + T_PACKED_LEN as Field,
contract_address,
);

// Check that the hash of the packed data matches the stored hash
assert(pedersen_hash(packed) == packed_hash, "Hash mismatch");

// Unpack into T
T::unpack(packed)
}
}

unconstrained fn read_in_unconstrained<let T_PACKED_LEN: u32>(
contract_address: AztecAddress,
storage_slot: Field,
) -> [Field; T_PACKED_LEN] {
let context = UnconstrainedContext::at(contract_address);
context.storage_read(storage_slot)
}

0 comments on commit 94b1141

Please sign in to comment.