diff --git a/core/src/ledger/storage/merkle_tree.rs b/core/src/ledger/storage/merkle_tree.rs index eb690356e5..dc65a12540 100644 --- a/core/src/ledger/storage/merkle_tree.rs +++ b/core/src/ledger/storage/merkle_tree.rs @@ -19,8 +19,8 @@ use crate::ledger::storage::types; use crate::types::address::{Address, InternalAddress}; use crate::types::hash::Hash; use crate::types::storage::{ - self, DbKeySeg, Error as StorageError, Key, MerkleValue, StringKey, - TreeBytes, TreeKeyError, IBC_KEY_LIMIT, + self, DbKeySeg, Error as StorageError, Key, StringKey, TreeBytes, + TreeKeyError, IBC_KEY_LIMIT, }; #[allow(missing_docs)] @@ -51,8 +51,10 @@ pub enum Error { /// Result for functions that may fail type Result = std::result::Result; -// Type aliases for the different merkle trees and backing stores -/// Sparse-merkle-tree store +/// Type alias for bytes to be put into the Merkle storage +pub(super) type StorageBytes<'a> = &'a [u8]; + +/// Type aliases for the different merkle trees and backing stores pub type SmtStore = DefaultStore; /// Arse-merkle-tree store pub type AmtStore = DefaultStore; @@ -284,9 +286,11 @@ impl MerkleTree { &mut self, store_type: &StoreType, key: &Key, - value: MerkleValue, + value: impl AsRef<[u8]>, ) -> Result<()> { - let sub_root = self.tree_mut(store_type).subtree_update(key, value)?; + let sub_root = self + .tree_mut(store_type) + .subtree_update(key, value.as_ref())?; // update the base tree with the updated sub root without hashing if *store_type != StoreType::Base { let base_key = H::hash(store_type.to_string()); @@ -302,13 +306,9 @@ impl MerkleTree { } /// Update the tree with the given key and value - pub fn update( - &mut self, - key: &Key, - value: impl Into, - ) -> Result<()> { + pub fn update(&mut self, key: &Key, value: impl AsRef<[u8]>) -> Result<()> { let (store_type, sub_key) = StoreType::sub_key(key)?; - self.update_tree(&store_type, &sub_key, value.into()) + self.update_tree(&store_type, &sub_key, value) } /// Delete the value corresponding to the given key @@ -341,7 +341,7 @@ impl MerkleTree { pub fn get_sub_tree_existence_proof( &self, keys: &[Key], - values: Vec, + values: Vec, ) -> Result { let first_key = keys.iter().next().ok_or_else(|| { Error::InvalidMerkleKey( @@ -721,7 +721,7 @@ mod test { let MembershipProof::ICS23(proof) = tree .get_sub_tree_existence_proof( std::array::from_ref(&ibc_key), - vec![ibc_val.clone().into()], + vec![&ibc_val], ) .unwrap(); let proof = tree.get_sub_tree_proof(&ibc_key, proof).unwrap(); @@ -778,7 +778,7 @@ mod test { let MembershipProof::ICS23(proof) = tree .get_sub_tree_existence_proof( std::array::from_ref(&pos_key), - vec![pos_val.clone().into()], + vec![&pos_val], ) .unwrap(); let proof = tree.get_sub_tree_proof(&pos_key, proof).unwrap(); diff --git a/core/src/ledger/storage/mod.rs b/core/src/ledger/storage/mod.rs index 9944dc3804..e4a8077ed8 100644 --- a/core/src/ledger/storage/mod.rs +++ b/core/src/ledger/storage/mod.rs @@ -624,7 +624,7 @@ where pub fn get_existence_proof( &self, key: &Key, - value: crate::types::storage::MerkleValue, + value: &[u8], height: BlockHeight, ) -> Result { use std::array; diff --git a/core/src/ledger/storage/traits.rs b/core/src/ledger/storage/traits.rs index 79427c06fb..c4ee39c257 100644 --- a/core/src/ledger/storage/traits.rs +++ b/core/src/ledger/storage/traits.rs @@ -9,10 +9,11 @@ use ics23::commitment_proof::Proof as Ics23Proof; use ics23::{CommitmentProof, ExistenceProof}; use sha2::{Digest, Sha256}; -use super::ics23_specs; -use super::merkle_tree::{Amt, Error, MembershipProof, Smt}; +use super::merkle_tree::{Amt, Error, Smt}; +use super::{ics23_specs, MembershipProof}; +use crate::ledger::storage::merkle_tree::StorageBytes; use crate::types::hash::Hash; -use crate::types::storage::{Key, MerkleValue, StringKey, TreeBytes}; +use crate::types::storage::{Key, StringKey, TreeBytes}; /// Trait for reading from a merkle tree that is a sub-tree /// of the global merkle tree. @@ -23,7 +24,7 @@ pub trait SubTreeRead { fn subtree_membership_proof( &self, keys: &[Key], - values: Vec, + values: Vec, ) -> Result; } @@ -34,7 +35,7 @@ pub trait SubTreeWrite { fn subtree_update( &mut self, key: &Key, - value: MerkleValue, + value: StorageBytes, ) -> Result; /// Delete a key from the sub-tree fn subtree_delete(&mut self, key: &Key) -> Result; @@ -51,20 +52,20 @@ impl<'a, H: StorageHasher + Default> SubTreeRead for &'a Smt { fn subtree_membership_proof( &self, keys: &[Key], - mut values: Vec, + mut values: Vec, ) -> Result { if keys.len() != 1 || values.len() != 1 { return Err(Error::Ics23MultiLeaf); } let key: &Key = &keys[0]; - let MerkleValue::Bytes(value) = values.remove(0); + let value = values.remove(0); let cp = self.membership_proof(&H::hash(key.to_string()).into())?; // Replace the values and the leaf op for the verification match cp.proof.expect("The proof should exist") { Ics23Proof::Exist(ep) => Ok(CommitmentProof { proof: Some(Ics23Proof::Exist(ExistenceProof { key: key.to_string().as_bytes().to_vec(), - value, + value: value.to_vec(), leaf: Some(ics23_specs::leaf_spec::()), ..ep })), @@ -80,11 +81,9 @@ impl<'a, H: StorageHasher + Default> SubTreeWrite for &'a mut Smt { fn subtree_update( &mut self, key: &Key, - value: MerkleValue, + value: StorageBytes, ) -> Result { - let value = match value { - MerkleValue::Bytes(bytes) => H::hash(bytes.as_slice()), - }; + let value = H::hash(value); self.update(H::hash(key.to_string()).into(), value.into()) .map(Hash::from) .map_err(|err| Error::MerkleTree(err.to_string())) @@ -110,7 +109,7 @@ impl<'a, H: StorageHasher + Default> SubTreeRead for &'a Amt { fn subtree_membership_proof( &self, keys: &[Key], - _: Vec, + _: Vec, ) -> Result { if keys.len() != 1 { return Err(Error::Ics23MultiLeaf); @@ -137,12 +136,10 @@ impl<'a, H: StorageHasher + Default> SubTreeWrite for &'a mut Amt { fn subtree_update( &mut self, key: &Key, - value: MerkleValue, + value: StorageBytes, ) -> Result { let key = StringKey::try_from_bytes(key.to_string().as_bytes())?; - let value = match value { - MerkleValue::Bytes(bytes) => TreeBytes::from(bytes), - }; + let value = TreeBytes::from(value.as_ref().to_owned()); self.update(key, value) .map(Into::into) .map_err(|err| Error::MerkleTree(err.to_string())) diff --git a/core/src/types/storage.rs b/core/src/types/storage.rs index 099fd2ba51..c61c0450ae 100644 --- a/core/src/types/storage.rs +++ b/core/src/types/storage.rs @@ -356,27 +356,6 @@ impl FromStr for Key { } } -/// An enum representing the different types of values -/// that can be passed into Namada's storage. -/// -/// This is a multi-store organized as -/// several Merkle trees, each of which is -/// responsible for understanding how to parse -/// this value. -pub enum MerkleValue { - /// raw bytes - Bytes(Vec), -} - -impl From for MerkleValue -where - T: AsRef<[u8]>, -{ - fn from(bytes: T) -> Self { - Self::Bytes(bytes.as_ref().to_owned()) - } -} - /// Storage keys that are utf8 encoded strings #[derive(Eq, PartialEq, Copy, Clone, Hash)] pub struct StringKey { diff --git a/shared/src/ledger/queries/shell.rs b/shared/src/ledger/queries/shell.rs index f428a2e572..4883294c78 100644 --- a/shared/src/ledger/queries/shell.rs +++ b/shared/src/ledger/queries/shell.rs @@ -206,11 +206,7 @@ where let proof = if request.prove { let proof = ctx .storage - .get_existence_proof( - &storage_key, - value.clone().into(), - request.height, - ) + .get_existence_proof(&storage_key, &value, request.height) .into_storage_result()?; Some(proof) } else { @@ -265,7 +261,7 @@ where for PrefixValue { key, value } in &data { let mut proof: crate::tendermint::merkle::proof::Proof = ctx .storage - .get_existence_proof(key, value.clone().into(), request.height) + .get_existence_proof(key, value, request.height) .into_storage_result()?; ops.append(&mut proof.ops); }