diff --git a/.github/workflows/publish-main.yml b/.github/workflows/publish-main.yml index f53033f741..9ea8f29fe8 100644 --- a/.github/workflows/publish-main.yml +++ b/.github/workflows/publish-main.yml @@ -17,25 +17,26 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - ref: main + ref: ${{ github.event.release.target_commitish }} - uses: ./.github/actions/install-rocksdb - uses: ./.github/actions/install-protobuf-compiler - # Ensure the release tag refers to the latest commit on main. + # Ensure the release tag refers to the latest commit on the release branch. # Compare the commit SHA that triggered the workflow with the HEAD of the branch we just - # checked out (main). - - name: Verify release was triggered from main HEAD + # checked out. + - name: Verify release was triggered from release branch HEAD run: | tag_sha="${{ github.sha }}" - main_sha="$(git rev-parse HEAD)" + branch_sha="$(git rev-parse HEAD)" + release_branch="${{ github.event.release.target_commitish }}" - echo "Tag points to: $tag_sha" - echo "Current main HEAD is: $main_sha" + echo "Tag points to: $tag_sha" + echo "Current $release_branch HEAD is: $branch_sha" - if [ "$tag_sha" != "$main_sha" ]; then - echo "::error::The release tag was not created from the latest commit on main. Aborting." + if [ "$tag_sha" != "$branch_sha" ]; then + echo "::error::The release tag was not created from the latest commit on $release_branch. Aborting." exit 1 fi - echo "Release tag matches main HEAD — continuing." + echo "Release tag matches $release_branch HEAD — continuing." - name: Cleanup large tools for build space uses: ./.github/actions/cleanup-runner - name: Install dependencies diff --git a/Cargo.lock b/Cargo.lock index d1c6c7e7dc..20388dda10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2628,8 +2628,9 @@ checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "miden-agglayer" -version = "0.14.0" -source = "git+https://github.com/0xMiden/miden-base?branch=next#3154a371939125e5cc3faf39a7c42447db67584f" +version = "0.14.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e492a6044cf8875a64d7eec130d260f2eda1c783795261f00d5d52837ed027bd" dependencies = [ "fs-err", "miden-assembly", @@ -2699,8 +2700,9 @@ dependencies = [ [[package]] name = "miden-block-prover" -version = "0.14.0" -source = "git+https://github.com/0xMiden/miden-base?branch=next#3154a371939125e5cc3faf39a7c42447db67584f" +version = "0.14.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9564dfb23c529aad68369845b6897a6f62bacdeab7c00db432a5f16670764d4" dependencies = [ "miden-protocol", "thiserror 2.0.18", @@ -2873,7 +2875,7 @@ dependencies = [ [[package]] name = "miden-network-monitor" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "anyhow", "axum", @@ -2902,7 +2904,7 @@ dependencies = [ [[package]] name = "miden-node" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "anyhow", "clap", @@ -2923,7 +2925,7 @@ dependencies = [ [[package]] name = "miden-node-block-producer" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "anyhow", "assert_matches", @@ -2959,7 +2961,7 @@ dependencies = [ [[package]] name = "miden-node-db" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "deadpool", "deadpool-diesel", @@ -2972,7 +2974,7 @@ dependencies = [ [[package]] name = "miden-node-grpc-error-macro" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "quote", "syn 2.0.114", @@ -2980,7 +2982,7 @@ dependencies = [ [[package]] name = "miden-node-ntx-builder" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "anyhow", "build-rs", @@ -3011,7 +3013,7 @@ dependencies = [ [[package]] name = "miden-node-proto" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "anyhow", "assert_matches", @@ -3037,7 +3039,7 @@ dependencies = [ [[package]] name = "miden-node-proto-build" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "build-rs", "fs-err", @@ -3048,11 +3050,11 @@ dependencies = [ [[package]] name = "miden-node-rocksdb-cxx-linkage-fix" -version = "0.14.0" +version = "0.14.0-alpha.1" [[package]] name = "miden-node-rpc" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "anyhow", "futures", @@ -3084,7 +3086,7 @@ dependencies = [ [[package]] name = "miden-node-store" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "anyhow", "assert_matches", @@ -3131,7 +3133,7 @@ dependencies = [ [[package]] name = "miden-node-stress-test" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "clap", "fs-err", @@ -3161,7 +3163,7 @@ dependencies = [ [[package]] name = "miden-node-utils" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "anyhow", "bytes", @@ -3188,7 +3190,7 @@ dependencies = [ [[package]] name = "miden-node-validator" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "anyhow", "aws-config", @@ -3233,8 +3235,9 @@ dependencies = [ [[package]] name = "miden-protocol" -version = "0.14.0" -source = "git+https://github.com/0xMiden/miden-base?branch=next#3154a371939125e5cc3faf39a7c42447db67584f" +version = "0.14.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a88effeac994eb55b8dc4f93fbfd71a5d916dfaba1099896e27a0ee42c488c1" dependencies = [ "bech32", "fs-err", @@ -3263,8 +3266,9 @@ dependencies = [ [[package]] name = "miden-protocol-macros" -version = "0.14.0" -source = "git+https://github.com/0xMiden/miden-base?branch=next#3154a371939125e5cc3faf39a7c42447db67584f" +version = "0.14.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb28b730005e5f8b08d615ea9216f8cab77b3a7439fa54d5e39d2ec43ef53a3" dependencies = [ "proc-macro2", "quote", @@ -3287,7 +3291,7 @@ dependencies = [ [[package]] name = "miden-remote-prover" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "anyhow", "assert_matches", @@ -3325,7 +3329,7 @@ dependencies = [ [[package]] name = "miden-remote-prover-client" -version = "0.14.0" +version = "0.14.0-alpha.1" dependencies = [ "build-rs", "fs-err", @@ -3346,8 +3350,9 @@ dependencies = [ [[package]] name = "miden-standards" -version = "0.14.0" -source = "git+https://github.com/0xMiden/miden-base?branch=next#3154a371939125e5cc3faf39a7c42447db67584f" +version = "0.14.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cef036bbfec29acba92751a13d05844bbcf080140201097b419c9ad1927e367" dependencies = [ "fs-err", "miden-assembly", @@ -3363,8 +3368,9 @@ dependencies = [ [[package]] name = "miden-testing" -version = "0.14.0" -source = "git+https://github.com/0xMiden/miden-base?branch=next#3154a371939125e5cc3faf39a7c42447db67584f" +version = "0.14.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e980777d0f7e6069942b14d4e7cb3d4d137b323ddfa15722a3bd21e9d13fdd2e" dependencies = [ "anyhow", "itertools 0.14.0", @@ -3386,8 +3392,9 @@ dependencies = [ [[package]] name = "miden-tx" -version = "0.14.0" -source = "git+https://github.com/0xMiden/miden-base?branch=next#3154a371939125e5cc3faf39a7c42447db67584f" +version = "0.14.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c67e0df9adcf29c9111df65acf408ae05952b8bc6569f571963676f97668d83f" dependencies = [ "miden-processor", "miden-protocol", @@ -3399,8 +3406,9 @@ dependencies = [ [[package]] name = "miden-tx-batch-prover" -version = "0.14.0" -source = "git+https://github.com/0xMiden/miden-base?branch=next#3154a371939125e5cc3faf39a7c42447db67584f" +version = "0.14.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba29f8f6ecae671eff8b52b4c19eca8db5964c0b45b5d68c3ce38a57a8367931" dependencies = [ "miden-protocol", "miden-tx", diff --git a/Cargo.toml b/Cargo.toml index 3e41e9c1dc..f56fc004b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ license = "MIT" readme = "README.md" repository = "https://github.com/0xMiden/miden-node" rust-version = "1.91" -version = "0.14.0" +version = "0.14.0-alpha.1" # Optimize the cryptography for faster tests involving account creation. [profile.test.package.miden-crypto] @@ -45,29 +45,29 @@ debug = true [workspace.dependencies] # Workspace crates. -miden-node-block-producer = { path = "crates/block-producer", version = "0.14" } -miden-node-db = { path = "crates/db", version = "0.14" } -miden-node-grpc-error-macro = { path = "crates/grpc-error-macro", version = "0.14" } -miden-node-ntx-builder = { path = "crates/ntx-builder", version = "0.14" } -miden-node-proto = { path = "crates/proto", version = "0.14" } -miden-node-proto-build = { path = "proto", version = "0.14" } -miden-node-rpc = { path = "crates/rpc", version = "0.14" } -miden-node-store = { path = "crates/store", version = "0.14" } +miden-node-block-producer = { path = "crates/block-producer", version = "=0.14.0-alpha.1" } +miden-node-db = { path = "crates/db", version = "=0.14.0-alpha.1" } +miden-node-grpc-error-macro = { path = "crates/grpc-error-macro", version = "=0.14.0-alpha.1" } +miden-node-ntx-builder = { path = "crates/ntx-builder", version = "=0.14.0-alpha.1" } +miden-node-proto = { path = "crates/proto", version = "=0.14.0-alpha.1" } +miden-node-proto-build = { path = "proto", version = "=0.14.0-alpha.1" } +miden-node-rpc = { path = "crates/rpc", version = "=0.14.0-alpha.1" } +miden-node-store = { path = "crates/store", version = "=0.14.0-alpha.1" } miden-node-test-macro = { path = "crates/test-macro" } -miden-node-utils = { path = "crates/utils", version = "0.14" } -miden-node-validator = { path = "crates/validator", version = "0.14" } -miden-remote-prover-client = { path = "crates/remote-prover-client", version = "0.14" } +miden-node-utils = { path = "crates/utils", version = "=0.14.0-alpha.1" } +miden-node-validator = { path = "crates/validator", version = "=0.14.0-alpha.1" } +miden-remote-prover-client = { path = "crates/remote-prover-client", version = "=0.14.0-alpha.1" } # Temporary workaround until # is part of `rocksdb-rust` release -miden-node-rocksdb-cxx-linkage-fix = { path = "crates/rocksdb-cxx-linkage-fix", version = "0.14" } +miden-node-rocksdb-cxx-linkage-fix = { path = "crates/rocksdb-cxx-linkage-fix", version = "=0.14.0-alpha.1" } # miden-base aka protocol dependencies. These should be updated in sync. -miden-block-prover = { branch = "next", git = "https://github.com/0xMiden/miden-base" } -miden-protocol = { branch = "next", default-features = false, git = "https://github.com/0xMiden/miden-base" } -miden-standards = { branch = "next", git = "https://github.com/0xMiden/miden-base" } -miden-testing = { branch = "next", git = "https://github.com/0xMiden/miden-base" } -miden-tx = { branch = "next", default-features = false, git = "https://github.com/0xMiden/miden-base" } -miden-tx-batch-prover = { branch = "next", git = "https://github.com/0xMiden/miden-base" } +miden-block-prover = { version = "=0.14.0-alpha.1" } +miden-protocol = { default-features = false, version = "=0.14.0-alpha.1" } +miden-standards = { version = "=0.14.0-alpha.1" } +miden-testing = { version = "=0.14.0-alpha.1" } +miden-tx = { default-features = false, version = "=0.14.0-alpha.1" } +miden-tx-batch-prover = { version = "=0.14.0-alpha.1" } # Other miden dependencies. These should align with those expected by miden-base. miden-air = { features = ["std", "testing"], version = "0.20" } diff --git a/bin/network-monitor/src/deploy/mod.rs b/bin/network-monitor/src/deploy/mod.rs index 235905f139..b89c09aa0c 100644 --- a/bin/network-monitor/src/deploy/mod.rs +++ b/bin/network-monitor/src/deploy/mod.rs @@ -11,7 +11,7 @@ use anyhow::{Context, Result}; use miden_node_proto::clients::{Builder, RpcClient}; use miden_node_proto::generated::rpc::BlockHeaderByNumberRequest; use miden_node_proto::generated::transaction::ProvenTransaction; -use miden_protocol::account::{Account, AccountId, PartialAccount, PartialStorage}; +use miden_protocol::account::{Account, AccountId, PartialAccount, PartialStorage, StorageMapKey}; use miden_protocol::assembly::{ DefaultSourceManager, Library, @@ -308,7 +308,7 @@ impl DataStore for MonitorDataStore { &self, _account_id: AccountId, _map_root: Word, - _map_key: Word, + _map_key: StorageMapKey, ) -> Result { unimplemented!("Not needed") } diff --git a/crates/ntx-builder/src/actor/execute.rs b/crates/ntx-builder/src/actor/execute.rs index 09658cd233..9b45a48c2c 100644 --- a/crates/ntx-builder/src/actor/execute.rs +++ b/crates/ntx-builder/src/actor/execute.rs @@ -11,6 +11,7 @@ use miden_protocol::account::{ AccountId, AccountStorageHeader, PartialAccount, + StorageMapKey, StorageMapWitness, StorageSlotName, StorageSlotType, @@ -508,7 +509,7 @@ impl DataStore for NtxDataStore { &self, account_id: AccountId, map_root: Word, - map_key: Word, + map_key: StorageMapKey, ) -> impl FutureMaybeSend> { async move { // The slot name that corresponds to the given account ID and map root must have been diff --git a/crates/ntx-builder/src/store.rs b/crates/ntx-builder/src/store.rs index b04a9d75f3..cef788bf5e 100644 --- a/crates/ntx-builder/src/store.rs +++ b/crates/ntx-builder/src/store.rs @@ -17,6 +17,7 @@ use miden_protocol::account::{ AccountId, PartialAccount, PartialStorage, + StorageMapKey, StorageMapWitness, StorageSlotName, }; @@ -421,13 +422,13 @@ impl StoreClient { &self, account_id: AccountId, slot_name: StorageSlotName, - map_key: Word, + map_key: StorageMapKey, block_num: Option, ) -> Result { // Construct proto request. let request = proto::store::StorageMapWitnessRequest { account_id: Some(proto::account::AccountId { id: account_id.to_bytes() }), - map_key: Some(map_key.into()), + map_key: Some(Word::from(map_key).into()), slot_name: slot_name.to_string(), block_num: block_num.map(|num| num.as_u32()), }; diff --git a/crates/proto/src/domain/account.rs b/crates/proto/src/domain/account.rs index 8e06d33699..6f740d478e 100644 --- a/crates/proto/src/domain/account.rs +++ b/crates/proto/src/domain/account.rs @@ -9,6 +9,7 @@ use miden_protocol::account::{ AccountId, AccountStorageHeader, StorageMap, + StorageMapKey, StorageSlotHeader, StorageSlotName, StorageSlotType, @@ -223,7 +224,7 @@ impl TryFrom), + MapKeys(Vec), } impl @@ -244,8 +245,9 @@ impl return Err(ConversionError::EnumDiscriminantOutOfRange); }, ProtoSlotData::MapKeys(keys) => { - let keys = try_convert(keys.map_keys).collect::, _>>()?; - SlotData::MapKeys(keys) + let keys: Vec = + try_convert(keys.map_keys).collect::, _>>()?; + SlotData::MapKeys(keys.into_iter().map(StorageMapKey::new).collect()) }, }) } @@ -426,7 +428,7 @@ pub enum StorageMapEntries { /// All storage map entries (key-value pairs) without proofs. /// Used when all entries are requested for small maps. - AllEntries(Vec<(Word, Word)>), + AllEntries(Vec<(StorageMapKey, Word)>), /// Specific entries with their SMT proofs for client-side verification. /// Used when specific keys are requested from the storage map. @@ -468,7 +470,10 @@ impl AccountStorageMapDetails { /// Creates storage map details from forest-queried entries. /// /// Returns `LimitExceeded` if too many entries. - pub fn from_forest_entries(slot_name: StorageSlotName, entries: Vec<(Word, Word)>) -> Self { + pub fn from_forest_entries( + slot_name: StorageSlotName, + entries: Vec<(StorageMapKey, Word)>, + ) -> Self { if entries.len() > Self::MAX_RETURN_ENTRIES { Self { slot_name, @@ -548,7 +553,7 @@ impl TryFrom let entries = entries .into_iter() .map(|entry| { - let key = entry + let key: Word = entry .key .ok_or(StorageMapEntry::missing_field(stringify!(key)))? .try_into()?; @@ -556,7 +561,7 @@ impl TryFrom .value .ok_or(StorageMapEntry::missing_field(stringify!(value)))? .try_into()?; - Ok((key, value)) + Ok((StorageMapKey::new(key), value)) }) .collect::, ConversionError>>()?; StorageMapEntries::AllEntries(entries) @@ -598,7 +603,7 @@ impl From let all = AllMapEntries { entries: Vec::from_iter(entries.into_iter().map(|(key, value)| { proto::rpc::account_storage_details::account_storage_map_details::all_map_entries::StorageMapEntry { - key: Some(key.into()), + key: Some(Word::from(key).into()), value: Some(value.into()), } })), diff --git a/crates/proto/src/domain/account/tests.rs b/crates/proto/src/domain/account/tests.rs index 695813d990..720d66ae56 100644 --- a/crates/proto/src/domain/account/tests.rs +++ b/crates/proto/src/domain/account/tests.rs @@ -1,9 +1,15 @@ +use miden_protocol::account::StorageMapKey; + use super::*; fn word_from_u32(arr: [u32; 4]) -> Word { Word::from(arr) } +fn key_from_u32(arr: [u32; 4]) -> StorageMapKey { + StorageMapKey::new(Word::from(arr)) +} + fn test_slot_name() -> StorageSlotName { StorageSlotName::new("miden::test::storage::slot").unwrap() } @@ -12,8 +18,8 @@ fn test_slot_name() -> StorageSlotName { fn account_storage_map_details_from_forest_entries() { let slot_name = test_slot_name(); let entries = vec![ - (word_from_u32([1, 2, 3, 4]), word_from_u32([5, 6, 7, 8])), - (word_from_u32([9, 10, 11, 12]), word_from_u32([13, 14, 15, 16])), + (key_from_u32([1, 2, 3, 4]), word_from_u32([5, 6, 7, 8])), + (key_from_u32([9, 10, 11, 12]), word_from_u32([13, 14, 15, 16])), ]; let details = AccountStorageMapDetails::from_forest_entries(slot_name.clone(), entries.clone()); @@ -28,7 +34,7 @@ fn account_storage_map_details_from_forest_entries_limit_exceeded() { // Create more entries than MAX_RETURN_ENTRIES let entries: Vec<_> = (0..=AccountStorageMapDetails::MAX_RETURN_ENTRIES) .map(|i| { - let key = word_from_u32([i as u32, 0, 0, 0]); + let key = key_from_u32([i as u32, 0, 0, 0]); let value = word_from_u32([0, 0, 0, i as u32]); (key, value) }) diff --git a/crates/store/Cargo.toml b/crates/store/Cargo.toml index 17dcf96196..657f21e9a5 100644 --- a/crates/store/Cargo.toml +++ b/crates/store/Cargo.toml @@ -52,7 +52,7 @@ url = { workspace = true } [build-dependencies] build-rs = { workspace = true } fs-err = { workspace = true } -miden-agglayer = { branch = "next", features = ["testing"], git = "https://github.com/0xMiden/miden-base" } +miden-agglayer = { features = ["testing"], version = "=0.14.0-alpha.1" } miden-node-rocksdb-cxx-linkage-fix = { workspace = true } miden-protocol = { features = ["std"], workspace = true } miden-standards = { workspace = true } diff --git a/crates/store/src/db/models/queries/accounts.rs b/crates/store/src/db/models/queries/accounts.rs index 1b6445c8eb..1c79c6eea8 100644 --- a/crates/store/src/db/models/queries/accounts.rs +++ b/crates/store/src/db/models/queries/accounts.rs @@ -30,6 +30,7 @@ use miden_protocol::account::{ AccountStorageHeader, NonFungibleDeltaAction, StorageMap, + StorageMapKey, StorageSlot, StorageSlotContent, StorageSlotName, @@ -771,12 +772,13 @@ pub(crate) fn select_latest_account_storage( .load(conn)?; // Group map values by slot name - let mut map_entries_by_slot: BTreeMap> = BTreeMap::new(); + let mut map_entries_by_slot: BTreeMap> = + BTreeMap::new(); for (slot_name_str, key_bytes, value_bytes) in map_values { let slot_name: StorageSlotName = slot_name_str.parse().map_err(|_| { DatabaseError::DataCorrupted(format!("Invalid slot name: {slot_name_str}")) })?; - let key = Word::read_from_bytes(&key_bytes)?; + let key = StorageMapKey::new(Word::read_from_bytes(&key_bytes)?); let value = Word::read_from_bytes(&value_bytes)?; map_entries_by_slot.entry(slot_name).or_default().push((key, value)); } @@ -1002,7 +1004,12 @@ pub(crate) fn upsert_accounts( for slot in account.storage().slots() { if let StorageSlotContent::Map(storage_map) = slot.content() { for (key, value) in storage_map.entries() { - storage.push((account_id, slot.name().clone(), *key, *value)); + storage.push(( + account_id, + slot.name().clone(), + Word::from(*key), + *value, + )); } } } @@ -1032,7 +1039,12 @@ pub(crate) fn upsert_accounts( let mut storage = Vec::new(); for (slot_name, map_delta) in delta.storage().maps() { for (key, value) in map_delta.entries() { - storage.push((account_id, slot_name.clone(), (*key).into(), *value)); + storage.push(( + account_id, + slot_name.clone(), + Word::from(*key), + *value, + )); } } diff --git a/crates/store/src/db/models/queries/accounts/tests.rs b/crates/store/src/db/models/queries/accounts/tests.rs index 0065a1e2cf..0a81d491dd 100644 --- a/crates/store/src/db/models/queries/accounts/tests.rs +++ b/crates/store/src/db/models/queries/accounts/tests.rs @@ -28,6 +28,7 @@ use miden_protocol::account::{ AccountStorageMode, AccountType, StorageMap, + StorageMapKey, StorageSlot, StorageSlotName, StorageSlotType, @@ -104,9 +105,13 @@ fn reconstruct_account_storage_at_block( } // Group entries by slot name - let mut map_entries_by_slot: BTreeMap> = BTreeMap::new(); + let mut map_entries_by_slot: BTreeMap> = + BTreeMap::new(); for ((slot_name, key), value) in latest_map_entries { - map_entries_by_slot.entry(slot_name).or_default().push((key, value)); + map_entries_by_slot + .entry(slot_name) + .or_default() + .push((StorageMapKey::new(key), value)); } // Reconstruct StorageSlots from header slots + map entries diff --git a/crates/store/src/db/tests.rs b/crates/store/src/db/tests.rs index 6791860795..ee809559f2 100644 --- a/crates/store/src/db/tests.rs +++ b/crates/store/src/db/tests.rs @@ -19,6 +19,7 @@ use miden_protocol::account::{ AccountStorageMode, AccountType, AccountVaultDelta, + StorageMapKey, StorageSlot, StorageSlotContent, StorageSlotDelta, @@ -920,7 +921,7 @@ fn insert_account_delta( account_id, block_number, slot_name.clone(), - *k.inner(), + Word::from(*k.inner()), *v, ) .unwrap(); @@ -950,8 +951,8 @@ fn sql_account_storage_map_values_insertion() { queries::upsert_accounts(conn, &[mock_block_account_update(account_id, 0)], block2).unwrap(); let slot_name = StorageSlotName::mock(3); - let key1 = Word::from([1u32, 2, 3, 4]); - let key2 = Word::from([5u32, 6, 7, 8]); + let key1 = StorageMapKey::new(Word::from([1u32, 2, 3, 4])); + let key2 = StorageMapKey::new(Word::from([5u32, 6, 7, 8])); let value1 = Word::from([10u32, 11, 12, 13]); let value2 = Word::from([20u32, 21, 22, 23]); let value3 = Word::from([30u32, 31, 32, 33]); @@ -991,14 +992,18 @@ fn sql_account_storage_map_values_insertion() { storage_map_values .values .iter() - .any(|val| val.slot_name == slot_name && val.key == key1 && val.value == value3), + .any(|val| val.slot_name == slot_name + && val.key == Word::from(key1) + && val.value == value3), "key1 should point to new value at block2" ); assert!( storage_map_values .values .iter() - .any(|val| val.slot_name == slot_name && val.key == key2 && val.value == value2), + .any(|val| val.slot_name == slot_name + && val.key == Word::from(key2) + && val.value == value2), "key2 should stay the same (from block1)" ); } @@ -1440,11 +1445,11 @@ async fn genesis_with_account_storage_map() { let storage_map = StorageMap::with_entries(vec![ ( - Word::from([Felt::new(1), Felt::ZERO, Felt::ZERO, Felt::ZERO]), + StorageMapKey::new(Word::from([Felt::new(1), Felt::ZERO, Felt::ZERO, Felt::ZERO])), Word::from([Felt::new(10), Felt::new(20), Felt::new(30), Felt::new(40)]), ), ( - Word::from([Felt::new(2), Felt::ZERO, Felt::ZERO, Felt::ZERO]), + StorageMapKey::new(Word::from([Felt::new(2), Felt::ZERO, Felt::ZERO, Felt::ZERO])), Word::from([Felt::new(50), Felt::new(60), Felt::new(70), Felt::new(80)]), ), ]) @@ -1497,7 +1502,7 @@ async fn genesis_with_account_assets_and_storage() { let fungible_asset = FungibleAsset::new(faucet_id, 5000).unwrap(); let storage_map = StorageMap::with_entries(vec![( - Word::from([Felt::new(100), Felt::ZERO, Felt::ZERO, Felt::ZERO]), + StorageMapKey::new(Word::from([Felt::new(100), Felt::ZERO, Felt::ZERO, Felt::ZERO])), Word::from([Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)]), )]) .unwrap(); @@ -1594,7 +1599,7 @@ async fn genesis_with_multiple_accounts() { .unwrap(); let storage_map = StorageMap::with_entries(vec![( - Word::from([Felt::new(5), Felt::ZERO, Felt::ZERO, Felt::ZERO]), + StorageMapKey::new(Word::from([Felt::new(5), Felt::ZERO, Felt::ZERO, Felt::ZERO])), Word::from([Felt::new(15), Felt::new(25), Felt::new(35), Felt::new(45)]), )]) .unwrap(); @@ -2051,11 +2056,11 @@ fn db_roundtrip_account_storage_with_maps() { // Create storage with both value slots and map slots let storage_map = StorageMap::with_entries(vec![ ( - Word::from([Felt::new(1), Felt::ZERO, Felt::ZERO, Felt::ZERO]), + StorageMapKey::new(Word::from([Felt::new(1), Felt::ZERO, Felt::ZERO, Felt::ZERO])), Word::from([Felt::new(10), Felt::new(20), Felt::new(30), Felt::new(40)]), ), ( - Word::from([Felt::new(2), Felt::ZERO, Felt::ZERO, Felt::ZERO]), + StorageMapKey::new(Word::from([Felt::new(2), Felt::ZERO, Felt::ZERO, Felt::ZERO])), Word::from([Felt::new(50), Felt::new(60), Felt::new(70), Felt::new(80)]), ), ]) diff --git a/crates/store/src/inner_forest/mod.rs b/crates/store/src/inner_forest/mod.rs index dbff597c6f..85c7fc4f2e 100644 --- a/crates/store/src/inner_forest/mod.rs +++ b/crates/store/src/inner_forest/mod.rs @@ -5,7 +5,7 @@ use miden_protocol::account::delta::{AccountDelta, AccountStorageDelta, AccountV use miden_protocol::account::{ AccountId, NonFungibleDeltaAction, - StorageMap, + StorageMapKey, StorageMapWitness, StorageSlotName, }; @@ -70,7 +70,8 @@ pub(crate) struct InnerForest { /// Maps (`account_id`, `slot_name`, `block_num`) to all key-value entries in that storage map. /// Accumulated from deltas - each block's entries include all entries up to that point. - storage_entries: BTreeMap<(AccountId, StorageSlotName, BlockNumber), BTreeMap>, + storage_entries: + BTreeMap<(AccountId, StorageSlotName, BlockNumber), BTreeMap>, /// Maps (`account_id`, `block_num`) to vault SMT root. /// Tracks asset vault versions across all blocks with structural sharing. @@ -142,15 +143,15 @@ impl InnerForest { account_id: AccountId, slot_name: &StorageSlotName, block_num: BlockNumber, - raw_key: Word, + raw_key: StorageMapKey, ) -> Result { - let key = StorageMap::hash_key(raw_key); + let hashed_key = raw_key.hash().as_word(); let root = self .get_storage_map_root(account_id, slot_name, block_num) .ok_or(WitnessError::RootNotFound)?; - let proof = self.forest.open(root, key)?; + let proof = self.forest.open(root, hashed_key)?; - Ok(StorageMapWitness::new(proof, vec![raw_key])?) + Ok(StorageMapWitness::new(proof, [raw_key])?) } /// Retrieves a vault asset witnesses for the specified account and asset keys at the specified @@ -182,14 +183,14 @@ impl InnerForest { account_id: AccountId, slot_name: StorageSlotName, block_num: BlockNumber, - raw_keys: &[Word], + raw_keys: &[StorageMapKey], ) -> Option> { let root = self.get_storage_map_root(account_id, &slot_name, block_num)?; // Collect SMT proofs for each key let proofs = Result::from_iter(raw_keys.iter().map(|raw_key| { - let key = StorageMap::hash_key(*raw_key); - self.forest.open(root, key) + let hashed_key = raw_key.hash().as_word(); + self.forest.open(root, hashed_key) })); Some(proofs.map(|proofs| AccountStorageMapDetails::from_proofs(slot_name, proofs))) @@ -460,7 +461,7 @@ impl InnerForest { &self, account_id: AccountId, slot_name: &StorageSlotName, - ) -> BTreeMap { + ) -> BTreeMap { self.storage_entries .range( (account_id, slot_name.clone(), BlockNumber::GENESIS) @@ -488,14 +489,14 @@ impl InnerForest { // build a vector of raw entries and filter out any empty values; such values // shouldn't be present in full-state deltas, but it is good to exclude them // explicitly - let raw_map_entries: Vec<(Word, Word)> = map_delta + let raw_map_entries: Vec<(StorageMapKey, Word)> = map_delta .entries() .iter() - .filter_map(|(&key, &value)| { + .filter_map(|(key, &value)| { if value == EMPTY_WORD { None } else { - Some((Word::from(key), value)) + Some((*key.inner(), value)) } }) .collect(); @@ -515,7 +516,7 @@ impl InnerForest { // hashes keys before inserting into the SMT. let hashed_entries: Vec<(Word, Word)> = raw_map_entries .iter() - .map(|(key, value)| (StorageMap::hash_key(*key), *value)) + .map(|(key, value)| (key.hash().as_word(), *value)) .collect(); // insert the updates into the forest and update storage map roots map @@ -568,14 +569,17 @@ impl InnerForest { // update the storage map tree in the forest and add an entry to the storage map roots let prev_root = self.get_latest_storage_map_root(account_id, slot_name); - let delta_entries: Vec<(Word, Word)> = - map_delta.entries().iter().map(|(key, value)| ((*key).into(), *value)).collect(); + let delta_entries: Vec<(StorageMapKey, Word)> = map_delta + .entries() + .iter() + .map(|(key, value)| (*key.inner(), *value)) + .collect(); // Hash the keys before inserting into the forest, matching how StorageMap // hashes keys before inserting into the SMT. let hashed_entries: Vec<(Word, Word)> = delta_entries .iter() - .map(|(key, value)| (StorageMap::hash_key(*key), *value)) + .map(|(key, value)| (key.hash().as_word(), *value)) .collect(); let new_root = self diff --git a/crates/store/src/inner_forest/tests.rs b/crates/store/src/inner_forest/tests.rs index 79bdbd0c8c..a62ab2de0c 100644 --- a/crates/store/src/inner_forest/tests.rs +++ b/crates/store/src/inner_forest/tests.rs @@ -1,4 +1,4 @@ -use miden_protocol::account::AccountCode; +use miden_protocol::account::{AccountCode, StorageMapKey}; use miden_protocol::asset::{Asset, AssetVault, FungibleAsset}; use miden_protocol::testing::account_id::{ ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET, @@ -323,7 +323,7 @@ fn test_update_storage_map() { let block_num = BlockNumber::GENESIS.child(); let slot_name = StorageSlotName::mock(3); - let key = Word::from([1u32, 2, 3, 4]); + let key = StorageMapKey::new(Word::from([1u32, 2, 3, 4])); let value = Word::from([5u32, 6, 7, 8]); let mut map_delta = StorageMapDelta::default(); @@ -403,8 +403,8 @@ fn test_storage_map_incremental_updates() { let account_id = dummy_account(); let slot_name = StorageSlotName::mock(3); - let key1 = Word::from([1u32, 0, 0, 0]); - let key2 = Word::from([2u32, 0, 0, 0]); + let key1 = StorageMapKey::new(Word::from([1u32, 0, 0, 0])); + let key2 = StorageMapKey::new(Word::from([2u32, 0, 0, 0])); let value1 = Word::from([10u32, 0, 0, 0]); let value2 = Word::from([20u32, 0, 0, 0]); let value3 = Word::from([30u32, 0, 0, 0]); diff --git a/crates/store/src/server/ntx_builder.rs b/crates/store/src/server/ntx_builder.rs index 495bda8341..c93557aa0c 100644 --- a/crates/store/src/server/ntx_builder.rs +++ b/crates/store/src/server/ntx_builder.rs @@ -7,7 +7,8 @@ use miden_node_proto::generated as proto; use miden_node_proto::generated::rpc::BlockRange; use miden_node_proto::generated::store::ntx_builder_server; use miden_node_utils::ErrorReport; -use miden_protocol::account::StorageSlotName; +use miden_protocol::Word; +use miden_protocol::account::{StorageMapKey, StorageSlotName}; use miden_protocol::asset::AssetVaultKey; use miden_protocol::block::BlockNumber; use miden_protocol::note::Note; @@ -278,9 +279,10 @@ impl ntx_builder_server::NtxBuilder for StoreApi { }; // Retrieve the storage map witness. + let raw_key = StorageMapKey::new(map_key); let storage_witness = self .state - .get_storage_map_witness(account_id, &slot_name, block_num, map_key) + .get_storage_map_witness(account_id, &slot_name, block_num, raw_key) .await .map_err(internal_error)?; @@ -288,7 +290,7 @@ impl ntx_builder_server::NtxBuilder for StoreApi { let proof: SmtProof = storage_witness.into(); Ok(Response::new(proto::store::StorageMapWitnessResponse { witness: Some(proto::store::storage_map_witness_response::StorageWitness { - key: Some(map_key.into()), + key: Some(Word::from(raw_key).into()), proof: Some(proof.into()), }), block_num: self.state.latest_block_num().await.as_u32(), diff --git a/crates/store/src/state/mod.rs b/crates/store/src/state/mod.rs index 40f6f29e60..c19699d006 100644 --- a/crates/store/src/state/mod.rs +++ b/crates/store/src/state/mod.rs @@ -23,7 +23,7 @@ use miden_node_proto::domain::account::{ use miden_node_proto::domain::batch::BatchInputs; use miden_node_utils::formatting::format_array; use miden_protocol::Word; -use miden_protocol::account::{AccountId, StorageMapWitness, StorageSlotName}; +use miden_protocol::account::{AccountId, StorageMapKey, StorageMapWitness, StorageSlotName}; use miden_protocol::asset::{AssetVaultKey, AssetWitness}; use miden_protocol::block::account_tree::AccountWitness; use miden_protocol::block::nullifier_tree::{NullifierTree, NullifierWitness}; @@ -830,7 +830,7 @@ impl State { account_id: AccountId, slot_name: &StorageSlotName, block_num: BlockNumber, - raw_key: Word, + raw_key: StorageMapKey, ) -> Result { let witness = self .forest diff --git a/crates/validator/src/tx_validation/data_store.rs b/crates/validator/src/tx_validation/data_store.rs index ebd382e44a..ac143ef3be 100644 --- a/crates/validator/src/tx_validation/data_store.rs +++ b/crates/validator/src/tx_validation/data_store.rs @@ -3,7 +3,7 @@ use std::collections::BTreeSet; use miden_protocol::Word; -use miden_protocol::account::{AccountId, PartialAccount, StorageMapWitness}; +use miden_protocol::account::{AccountId, PartialAccount, StorageMapKey, StorageMapWitness}; use miden_protocol::asset::{AssetVaultKey, AssetWitness}; use miden_protocol::block::{BlockHeader, BlockNumber}; use miden_protocol::note::NoteScript; @@ -83,7 +83,7 @@ impl DataStore for TransactionInputsDataStore { &self, _account_id: AccountId, _map_root: Word, - _map_key: Word, + _map_key: StorageMapKey, ) -> impl FutureMaybeSend> { async move { unimplemented!(