Skip to content

Commit

Permalink
Merge branch 'bat/remove-merkle-values' (#846) into main
Browse files Browse the repository at this point in the history
* bat/remove-merkle-values:
  changelog: add #846
  [fix]: Changed Vec<u8> to &[u8] for getting merkle proofs
  [feat]: Removed MerkleValue type
  • Loading branch information
juped committed Dec 13, 2022
2 parents c7c582b + 8465fb9 commit c324544
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 58 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Remove the MerkleValue type and just use byte slices for Merkle tree values.
([#846](https://github.com/anoma/namada/pull/846))
30 changes: 15 additions & 15 deletions core/src/ledger/storage/merkle_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -51,8 +51,10 @@ pub enum Error {
/// Result for functions that may fail
type Result<T> = std::result::Result<T, Error>;

// 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<SmtHash, Hash, 32>;
/// Arse-merkle-tree store
pub type AmtStore = DefaultStore<StringKey, TreeBytes, IBC_KEY_LIMIT>;
Expand Down Expand Up @@ -284,9 +286,11 @@ impl<H: StorageHasher + Default> MerkleTree<H> {
&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());
Expand All @@ -302,13 +306,9 @@ impl<H: StorageHasher + Default> MerkleTree<H> {
}

/// Update the tree with the given key and value
pub fn update(
&mut self,
key: &Key,
value: impl Into<MerkleValue>,
) -> 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
Expand Down Expand Up @@ -341,7 +341,7 @@ impl<H: StorageHasher + Default> MerkleTree<H> {
pub fn get_sub_tree_existence_proof(
&self,
keys: &[Key],
values: Vec<MerkleValue>,
values: Vec<StorageBytes>,
) -> Result<MembershipProof> {
let first_key = keys.iter().next().ok_or_else(|| {
Error::InvalidMerkleKey(
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
3 changes: 2 additions & 1 deletion core/src/ledger/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use masp_primitives::asset_type::AssetType;
use masp_primitives::convert::AllowedConversion;
use masp_primitives::merkle_tree::FrozenCommitmentTree;
use masp_primitives::sapling::Node;
use merkle_tree::StorageBytes;
pub use merkle_tree::{
MembershipProof, MerkleTree, MerkleTreeStoresRead, MerkleTreeStoresWrite,
StoreType,
Expand Down Expand Up @@ -624,7 +625,7 @@ where
pub fn get_existence_proof(
&self,
key: &Key,
value: crate::types::storage::MerkleValue,
value: StorageBytes,
height: BlockHeight,
) -> Result<Proof> {
use std::array;
Expand Down
27 changes: 12 additions & 15 deletions core/src/ledger/storage/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ use sha2::{Digest, Sha256};

use super::ics23_specs;
use super::merkle_tree::{Amt, Error, MembershipProof, Smt};
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.
Expand All @@ -23,7 +24,7 @@ pub trait SubTreeRead {
fn subtree_membership_proof(
&self,
keys: &[Key],
values: Vec<MerkleValue>,
values: Vec<StorageBytes>,
) -> Result<MembershipProof, Error>;
}

Expand All @@ -34,7 +35,7 @@ pub trait SubTreeWrite {
fn subtree_update(
&mut self,
key: &Key,
value: MerkleValue,
value: StorageBytes,
) -> Result<Hash, Error>;
/// Delete a key from the sub-tree
fn subtree_delete(&mut self, key: &Key) -> Result<Hash, Error>;
Expand All @@ -51,20 +52,20 @@ impl<'a, H: StorageHasher + Default> SubTreeRead for &'a Smt<H> {
fn subtree_membership_proof(
&self,
keys: &[Key],
mut values: Vec<MerkleValue>,
mut values: Vec<StorageBytes>,
) -> Result<MembershipProof, Error> {
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::<H>()),
..ep
})),
Expand All @@ -80,11 +81,9 @@ impl<'a, H: StorageHasher + Default> SubTreeWrite for &'a mut Smt<H> {
fn subtree_update(
&mut self,
key: &Key,
value: MerkleValue,
value: StorageBytes,
) -> Result<Hash, Error> {
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()))
Expand All @@ -110,7 +109,7 @@ impl<'a, H: StorageHasher + Default> SubTreeRead for &'a Amt<H> {
fn subtree_membership_proof(
&self,
keys: &[Key],
_: Vec<MerkleValue>,
_: Vec<StorageBytes>,
) -> Result<MembershipProof, Error> {
if keys.len() != 1 {
return Err(Error::Ics23MultiLeaf);
Expand All @@ -137,12 +136,10 @@ impl<'a, H: StorageHasher + Default> SubTreeWrite for &'a mut Amt<H> {
fn subtree_update(
&mut self,
key: &Key,
value: MerkleValue,
value: StorageBytes,
) -> Result<Hash, Error> {
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()))
Expand Down
21 changes: 0 additions & 21 deletions core/src/types/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>),
}

impl<T> From<T> 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 {
Expand Down
8 changes: 2 additions & 6 deletions shared/src/ledger/queries/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit c324544

Please sign in to comment.