diff --git a/Cargo.lock b/Cargo.lock index e99401b5b77..deaae011fe7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4457,8 +4457,13 @@ dependencies = [ name = "namada_merkle_tree" version = "0.28.1" dependencies = [ + "borsh", + "ics23", "namada_core", + "namada_ethereum_bridge", + "prost 0.12.3", "sparse-merkle-tree", + "thiserror", ] [[package]] diff --git a/merkle_tree/Cargo.toml b/merkle_tree/Cargo.toml index 6edfa3e1d6d..be842fb452d 100644 --- a/merkle_tree/Cargo.toml +++ b/merkle_tree/Cargo.toml @@ -13,6 +13,11 @@ repository.workspace = true version.workspace = true [dependencies] -namada_core = {path = "../core", default-features = false} +namada_core = { path = "../core", default-features = false } +namada_ethereum_bridge = { path = "../ethereum_bridge" } -arse-merkle-tree.workspace = true \ No newline at end of file +arse-merkle-tree.workspace = true +borsh.workspace = true +ics23.workspace = true +prost.workspace = true +thiserror.workspace = true diff --git a/merkle_tree/src/ics23_specs.rs b/merkle_tree/src/ics23_specs.rs index 00691bd30e8..130735d33a5 100644 --- a/merkle_tree/src/ics23_specs.rs +++ b/merkle_tree/src/ics23_specs.rs @@ -2,8 +2,7 @@ use arse_merkle_tree::H256; use ics23::{HashOp, LeafOp, LengthOp, ProofSpec}; - -use super::traits::StorageHasher; +use namada_core::types::hash::StorageHasher; /// Get the leaf spec for the base tree. The key is stored after hashing, /// but the stored value is the subtree's root without hashing. diff --git a/merkle_tree/src/lib.rs b/merkle_tree/src/lib.rs index ac983f66cf4..d13898a247d 100644 --- a/merkle_tree/src/lib.rs +++ b/merkle_tree/src/lib.rs @@ -10,27 +10,52 @@ use arse_merkle_tree::error::Error as MtError; use arse_merkle_tree::{ Hash as SmtHash, Key as TreeKey, SparseMerkleTree as ArseMerkleTree, H256, }; -use borsh::{BorshDeserialize, BorshSerialize}; -use borsh_ext::BorshSerializeExt; use ics23::commitment_proof::Proof as Ics23Proof; use ics23::{CommitmentProof, ExistenceProof, NonExistenceProof}; -use namada_core::ledger::eth_bridge::storage::bridge_pool::BridgePoolProof; -use thiserror::Error; - -use super::traits::{StorageHasher, SubTreeRead, SubTreeWrite}; -use crate::bytes::ByteBuf; -use crate::ledger::eth_bridge::storage::bridge_pool::{ - is_pending_transfer_key, BridgePoolTree, +use ics23_specs::ibc_leaf_spec; +use namada_core::borsh::{BorshDeserialize, BorshSerialize, BorshSerializeExt}; +use namada_core::bytes::ByteBuf; +use namada_core::types::address::{Address, InternalAddress}; +use namada_core::types::hash::{Hash, StorageHasher}; +use namada_core::types::keccak::KeccakHash; +use namada_core::types::storage::{ + self, BlockHeight, DbKeySeg, Epoch, Error as StorageError, Key, KeySeg, + StringKey, TreeBytes, TreeKeyError, IBC_KEY_LIMIT, }; -use crate::ledger::storage::ics23_specs::ibc_leaf_spec; -use crate::ledger::storage::{ics23_specs, types, BlockHeight, Epoch, KeySeg}; -use crate::types::address::{Address, InternalAddress}; -use crate::types::hash::Hash; -use crate::types::keccak::KeccakHash; -use crate::types::storage::{ - self, DbKeySeg, Error as StorageError, Key, StringKey, TreeBytes, - TreeKeyError, IBC_KEY_LIMIT, +use namada_ethereum_bridge::storage::bridge_pool::{ + is_pending_transfer_key, BridgePoolProof, BridgePoolTree, }; +use thiserror::Error; + +/// Trait for reading from a merkle tree that is a sub-tree +/// of the global merkle tree. +pub trait SubTreeRead { + /// Get the root of a subtree in raw bytes. + fn root(&self) -> MerkleRoot; + /// Check if a key is present in the sub-tree + fn subtree_has_key(&self, key: &Key) -> Result; + /// Get the height at which the key is inserted + fn subtree_get(&self, key: &Key) -> Result>; + /// Get a membership proof for various key-value pairs + fn subtree_membership_proof( + &self, + keys: &[Key], + values: Vec, + ) -> Result; +} + +/// Trait for updating a merkle tree that is a sub-tree +/// of the global merkle tree +pub trait SubTreeWrite { + /// Add a key-value pair to the sub-tree + fn subtree_update( + &mut self, + key: &Key, + value: StorageBytes, + ) -> Result; + /// Delete a key from the sub-tree + fn subtree_delete(&mut self, key: &Key) -> Result; +} /// Type of membership proof from a merkle tree pub enum MembershipProof { @@ -81,7 +106,7 @@ pub enum Error { type Result = std::result::Result; /// Type alias for bytes to be put into the Merkle storage -pub(super) type StorageBytes<'a> = &'a [u8]; +pub type StorageBytes<'a> = &'a [u8]; // Type aliases for the different merkle trees and backing stores /// Sparse-merkle-tree store @@ -759,7 +784,7 @@ pub struct Proof { pub base_proof: CommitmentProof, } -impl From for crate::tendermint::merkle::proof::ProofOps { +impl From for namada_core::tendermint::merkle::proof::ProofOps { fn from( Proof { key, @@ -767,10 +792,9 @@ impl From for crate::tendermint::merkle::proof::ProofOps { base_proof, }: Proof, ) -> Self { + use namada_core::tendermint::merkle::proof::ProofOp; use prost::Message; - use crate::tendermint::merkle::proof::ProofOp; - let mut data = vec![]; sub_proof .encode(&mut data) @@ -801,11 +825,13 @@ impl From for crate::tendermint::merkle::proof::ProofOps { #[cfg(test)] mod test { use ics23::HostFunctionsManager; + use namada_core::ledger::storage::ics23_specs::{ + ibc_proof_specs, proof_specs, + }; + use namada_core::ledger::storage::traits::Sha256Hasher; + use namada_core::types::storage::KeySeg; use super::*; - use crate::ledger::storage::ics23_specs::{ibc_proof_specs, proof_specs}; - use crate::ledger::storage::traits::Sha256Hasher; - use crate::types::storage::KeySeg; #[test] fn test_crud_value() { diff --git a/state/src/traits.rs b/state/src/traits.rs index 15504404e81..d2768162881 100644 --- a/state/src/traits.rs +++ b/state/src/traits.rs @@ -22,36 +22,6 @@ use crate::types::storage::{ BlockHeight, Key, MembershipProof, StringKey, TreeBytes, IBC_KEY_LIMIT, }; -/// Trait for reading from a merkle tree that is a sub-tree -/// of the global merkle tree. -pub trait SubTreeRead { - /// Get the root of a subtree in raw bytes. - fn root(&self) -> MerkleRoot; - /// Check if a key is present in the sub-tree - fn subtree_has_key(&self, key: &Key) -> Result; - /// Get the height at which the key is inserted - fn subtree_get(&self, key: &Key) -> Result, Error>; - /// Get a membership proof for various key-value pairs - fn subtree_membership_proof( - &self, - keys: &[Key], - values: Vec, - ) -> Result; -} - -/// Trait for updating a merkle tree that is a sub-tree -/// of the global merkle tree -pub trait SubTreeWrite { - /// Add a key-value pair to the sub-tree - fn subtree_update( - &mut self, - key: &Key, - value: StorageBytes, - ) -> Result; - /// Delete a key from the sub-tree - fn subtree_delete(&mut self, key: &Key) -> Result; -} - impl<'a, H: StorageHasher + Default> SubTreeRead for &'a Smt { fn root(&self) -> MerkleRoot { Smt::::root(self).into()