diff --git a/Cargo.lock b/Cargo.lock index c6261e7735df..431ad1dd74ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2299,6 +2299,7 @@ dependencies = [ "serde_json", "snowbridge-beacon-primitives", "snowbridge-core", + "snowbridge-merkle-tree", "snowbridge-outbound-queue-runtime-api", "snowbridge-pallet-ethereum-client", "snowbridge-pallet-inbound-queue", @@ -15482,7 +15483,6 @@ dependencies = [ "snowbridge-beacon-primitives", "snowbridge-core", "snowbridge-ethereum", - "snowbridge-outbound-queue-merkle-tree", "snowbridge-outbound-queue-runtime-api", "snowbridge-pallet-ethereum-client", "snowbridge-pallet-ethereum-client-fixtures", @@ -20934,12 +20934,15 @@ dependencies = [ name = "snowbridge-merkle-tree" version = "0.2.0" dependencies = [ - "frame-support", + "array-bytes", "hex", + "hex-literal", "parity-scale-codec", "scale-info", "sp-core 28.0.0", + "sp-crypto-hashing 0.1.0", "sp-runtime 31.0.1", + "sp-tracing 16.0.0", ] [[package]] @@ -20957,21 +20960,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "snowbridge-outbound-queue-merkle-tree" -version = "0.3.0" -dependencies = [ - "array-bytes", - "hex", - "hex-literal", - "parity-scale-codec", - "scale-info", - "sp-core 28.0.0", - "sp-crypto-hashing 0.1.0", - "sp-runtime 31.0.1", - "sp-tracing 16.0.0", -] - [[package]] name = "snowbridge-outbound-queue-runtime-api" version = "0.2.0" @@ -20979,7 +20967,7 @@ dependencies = [ "frame-support", "parity-scale-codec", "snowbridge-core", - "snowbridge-outbound-queue-merkle-tree", + "snowbridge-merkle-tree", "sp-api 26.0.0", "sp-std 14.0.0", ] @@ -21128,7 +21116,7 @@ dependencies = [ "scale-info", "serde", "snowbridge-core", - "snowbridge-outbound-queue-merkle-tree", + "snowbridge-merkle-tree", "sp-arithmetic 23.0.0", "sp-core 28.0.0", "sp-io 30.0.0", diff --git a/Cargo.toml b/Cargo.toml index 2c7f399e7bb9..aec739df16b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,6 @@ members = [ "bridges/snowbridge/pallets/outbound-queue", "bridges/snowbridge/pallets/outbound-queue-v2", "bridges/snowbridge/pallets/outbound-queue-v2/runtime-api", - "bridges/snowbridge/pallets/outbound-queue/merkle-tree", "bridges/snowbridge/pallets/outbound-queue/runtime-api", "bridges/snowbridge/pallets/system", "bridges/snowbridge/pallets/system/runtime-api", @@ -1207,7 +1206,6 @@ snowbridge-beacon-primitives = { path = "bridges/snowbridge/primitives/beacon", snowbridge-core = { path = "bridges/snowbridge/primitives/core", default-features = false } snowbridge-ethereum = { path = "bridges/snowbridge/primitives/ethereum", default-features = false } snowbridge-merkle-tree = { path = "bridges/snowbridge/primitives/merkle-tree", default-features = false } -snowbridge-outbound-queue-merkle-tree = { path = "bridges/snowbridge/pallets/outbound-queue/merkle-tree", default-features = false } snowbridge-outbound-queue-runtime-api = { path = "bridges/snowbridge/pallets/outbound-queue/runtime-api", default-features = false } snowbridge-outbound-queue-runtime-api-v2 = { path = "bridges/snowbridge/pallets/outbound-queue-v2/runtime-api", default-features = false } snowbridge-pallet-ethereum-client = { path = "bridges/snowbridge/pallets/ethereum-client", default-features = false } diff --git a/bridges/snowbridge/pallets/outbound-queue-v2/Cargo.toml b/bridges/snowbridge/pallets/outbound-queue-v2/Cargo.toml index 6404c59f2014..8a6afa290189 100644 --- a/bridges/snowbridge/pallets/outbound-queue-v2/Cargo.toml +++ b/bridges/snowbridge/pallets/outbound-queue-v2/Cargo.toml @@ -71,7 +71,6 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-message-queue/runtime-benchmarks", "snowbridge-core/runtime-benchmarks", - "snowbridge-merkle-tree/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] try-runtime = [ diff --git a/bridges/snowbridge/pallets/outbound-queue/Cargo.toml b/bridges/snowbridge/pallets/outbound-queue/Cargo.toml index 78546e258daa..5aa10e69a01e 100644 --- a/bridges/snowbridge/pallets/outbound-queue/Cargo.toml +++ b/bridges/snowbridge/pallets/outbound-queue/Cargo.toml @@ -31,7 +31,7 @@ sp-arithmetic = { workspace = true } bridge-hub-common = { workspace = true } snowbridge-core = { features = ["serde"], workspace = true } -snowbridge-outbound-queue-merkle-tree = { workspace = true } +snowbridge-merkle-tree = { workspace = true } ethabi = { workspace = true } [dev-dependencies] @@ -51,7 +51,7 @@ std = [ "scale-info/std", "serde/std", "snowbridge-core/std", - "snowbridge-outbound-queue-merkle-tree/std", + "snowbridge-merkle-tree/std", "sp-arithmetic/std", "sp-core/std", "sp-io/std", diff --git a/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml b/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml deleted file mode 100644 index 9d4cffc98d78..000000000000 --- a/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -name = "snowbridge-outbound-queue-merkle-tree" -description = "Snowbridge Outbound Queue Merkle Tree" -version = "0.3.0" -authors = ["Snowfork "] -edition.workspace = true -repository.workspace = true -license = "Apache-2.0" -categories = ["cryptography::cryptocurrencies"] - -[lints] -workspace = true - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { features = ["derive"], workspace = true } -scale-info = { features = ["derive"], workspace = true } - -sp-core = { workspace = true } -sp-runtime = { workspace = true } - -[dev-dependencies] -hex-literal = { workspace = true, default-features = true } -hex = { workspace = true, default-features = true } -array-bytes = { workspace = true, default-features = true } -sp-crypto-hashing = { workspace = true, default-features = true } -sp-tracing = { workspace = true, default-features = true } - -[features] -default = ["std"] -std = [ - "codec/std", - "scale-info/std", - "sp-core/std", - "sp-runtime/std", -] diff --git a/bridges/snowbridge/pallets/outbound-queue/merkle-tree/README.md b/bridges/snowbridge/pallets/outbound-queue/merkle-tree/README.md deleted file mode 100644 index a3afef1d6713..000000000000 --- a/bridges/snowbridge/pallets/outbound-queue/merkle-tree/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Snowbridge Outbound Queue Merkle Tree - -This crate implements a simple binary Merkle Tree utilities required for inter-op with Ethereum -bridge & Solidity contract. diff --git a/bridges/snowbridge/pallets/outbound-queue/merkle-tree/src/lib.rs b/bridges/snowbridge/pallets/outbound-queue/merkle-tree/src/lib.rs deleted file mode 100644 index eeeaa6e68cf9..000000000000 --- a/bridges/snowbridge/pallets/outbound-queue/merkle-tree/src/lib.rs +++ /dev/null @@ -1,446 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2023 Snowfork -// SPDX-FileCopyrightText: 2021-2022 Parity Technologies (UK) Ltd. -#![cfg_attr(not(feature = "std"), no_std)] -#![warn(missing_docs)] - -//! This crate implements a simple binary Merkle Tree utilities required for inter-op with Ethereum -//! bridge & Solidity contract. -//! -//! The implementation is optimised for usage within Substrate Runtime and supports no-std -//! compilation targets. -//! -//! Merkle Tree is constructed from arbitrary-length leaves, that are initially hashed using the -//! same `\[`Hasher`\]` as the inner nodes. -//! Inner nodes are created by concatenating child hashes and hashing again. The implementation -//! does not perform any sorting of the input data (leaves) nor when inner nodes are created. -//! -//! If the number of leaves is not even, last leaf (hash of) is promoted to the upper layer. - -#[cfg(not(feature = "std"))] -extern crate alloc; -#[cfg(not(feature = "std"))] -use alloc::vec; -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - -use codec::{Decode, Encode}; -use scale_info::TypeInfo; -use sp_core::{RuntimeDebug, H256}; -use sp_runtime::traits::Hash; - -/// Construct a root hash of a Binary Merkle Tree created from given leaves. -/// -/// See crate-level docs for details about Merkle Tree construction. -/// -/// In case an empty list of leaves is passed the function returns a 0-filled hash. -pub fn merkle_root(leaves: I) -> H256 -where - H: Hash, - I: Iterator, -{ - merkelize::(leaves, &mut ()) -} - -fn merkelize(leaves: I, visitor: &mut V) -> H256 -where - H: Hash, - V: Visitor, - I: Iterator, -{ - let upper = Vec::with_capacity(leaves.size_hint().0); - let mut next = match merkelize_row::(leaves, upper, visitor) { - Ok(root) => return root, - Err(next) if next.is_empty() => return H256::default(), - Err(next) => next, - }; - - let mut upper = Vec::with_capacity((next.len() + 1) / 2); - loop { - visitor.move_up(); - - match merkelize_row::(next.drain(..), upper, visitor) { - Ok(root) => return root, - Err(t) => { - // swap collections to avoid allocations - upper = next; - next = t; - }, - }; - } -} - -/// A generated merkle proof. -/// -/// The structure contains all necessary data to later on verify the proof and the leaf itself. -#[derive(Encode, Decode, RuntimeDebug, PartialEq, Eq, TypeInfo)] -pub struct MerkleProof { - /// Root hash of generated merkle tree. - pub root: H256, - /// Proof items (does not contain the leaf hash, nor the root obviously). - /// - /// This vec contains all inner node hashes necessary to reconstruct the root hash given the - /// leaf hash. - pub proof: Vec, - /// Number of leaves in the original tree. - /// - /// This is needed to detect a case where we have an odd number of leaves that "get promoted" - /// to upper layers. - pub number_of_leaves: u64, - /// Index of the leaf the proof is for (0-based). - pub leaf_index: u64, - /// Leaf content (hashed). - pub leaf: H256, -} - -/// A trait of object inspecting merkle root creation. -/// -/// It can be passed to [`merkelize_row`] or [`merkelize`] functions and will be notified -/// about tree traversal. -trait Visitor { - /// We are moving one level up in the tree. - fn move_up(&mut self); - - /// We are creating an inner node from given `left` and `right` nodes. - /// - /// Note that in case of last odd node in the row `right` might be empty. - /// The method will also visit the `root` hash (level 0). - /// - /// The `index` is an index of `left` item. - fn visit(&mut self, index: u64, left: &Option, right: &Option); -} - -/// No-op implementation of the visitor. -impl Visitor for () { - fn move_up(&mut self) {} - fn visit(&mut self, _index: u64, _left: &Option, _right: &Option) {} -} - -/// Construct a Merkle Proof for leaves given by indices. -/// -/// The function constructs a (partial) Merkle Tree first and stores all elements required -/// to prove the requested item (leaf) given the root hash. -/// -/// Both the Proof and the Root Hash are returned. -/// -/// # Panic -/// -/// The function will panic if given `leaf_index` is greater than the number of leaves. -pub fn merkle_proof(leaves: I, leaf_index: u64) -> MerkleProof -where - H: Hash, - I: Iterator, -{ - let mut leaf = None; - let mut hashes = vec![]; - let mut number_of_leaves = 0; - for (idx, l) in (0u64..).zip(leaves) { - // count the leaves - number_of_leaves = idx + 1; - hashes.push(l); - // find the leaf for the proof - if idx == leaf_index { - leaf = Some(l); - } - } - - /// The struct collects a proof for single leaf. - struct ProofCollection { - proof: Vec, - position: u64, - } - - impl ProofCollection { - fn new(position: u64) -> Self { - ProofCollection { proof: Default::default(), position } - } - } - - impl Visitor for ProofCollection { - fn move_up(&mut self) { - self.position /= 2; - } - - fn visit(&mut self, index: u64, left: &Option, right: &Option) { - // we are at left branch - right goes to the proof. - if self.position == index { - if let Some(right) = right { - self.proof.push(*right); - } - } - // we are at right branch - left goes to the proof. - if self.position == index + 1 { - if let Some(left) = left { - self.proof.push(*left); - } - } - } - } - - let mut collect_proof = ProofCollection::new(leaf_index); - - let root = merkelize::(hashes.into_iter(), &mut collect_proof); - let leaf = leaf.expect("Requested `leaf_index` is greater than number of leaves."); - - MerkleProof { root, proof: collect_proof.proof, number_of_leaves, leaf_index, leaf } -} - -/// Leaf node for proof verification. -/// -/// Can be either a value that needs to be hashed first, -/// or the hash itself. -#[derive(Debug, PartialEq, Eq)] -pub enum Leaf<'a> { - /// Leaf content. - Value(&'a [u8]), - /// Hash of the leaf content. - Hash(H256), -} - -impl<'a, T: AsRef<[u8]>> From<&'a T> for Leaf<'a> { - fn from(v: &'a T) -> Self { - Leaf::Value(v.as_ref()) - } -} - -impl<'a> From for Leaf<'a> { - fn from(v: H256) -> Self { - Leaf::Hash(v) - } -} - -/// Verify Merkle Proof correctness versus given root hash. -/// -/// The proof is NOT expected to contain leaf hash as the first -/// element, but only all adjacent nodes required to eventually by process of -/// concatenating and hashing end up with given root hash. -/// -/// The proof must not contain the root hash. -pub fn verify_proof<'a, H, P, L>( - root: &'a H256, - proof: P, - number_of_leaves: u64, - leaf_index: u64, - leaf: L, -) -> bool -where - H: Hash, - P: IntoIterator, - L: Into>, -{ - if leaf_index >= number_of_leaves { - return false - } - - let leaf_hash = match leaf.into() { - Leaf::Value(content) => ::hash(content), - Leaf::Hash(hash) => hash, - }; - - let hash_len = ::LENGTH; - let mut combined = [0_u8; 64]; - let computed = proof.into_iter().fold(leaf_hash, |a, b| { - if a < b { - combined[..hash_len].copy_from_slice(a.as_ref()); - combined[hash_len..].copy_from_slice(b.as_ref()); - } else { - combined[..hash_len].copy_from_slice(b.as_ref()); - combined[hash_len..].copy_from_slice(a.as_ref()); - } - ::hash(&combined) - }); - - root == &computed -} - -/// Processes a single row (layer) of a tree by taking pairs of elements, -/// concatenating them, hashing and placing into resulting vector. -/// -/// In case only one element is provided it is returned via `Ok` result, in any other case (also an -/// empty iterator) an `Err` with the inner nodes of upper layer is returned. -fn merkelize_row( - mut iter: I, - mut next: Vec, - visitor: &mut V, -) -> Result> -where - H: Hash, - V: Visitor, - I: Iterator, -{ - next.clear(); - - let hash_len = ::LENGTH; - let mut index = 0; - let mut combined = vec![0_u8; hash_len * 2]; - loop { - let a = iter.next(); - let b = iter.next(); - visitor.visit(index, &a, &b); - - index += 2; - match (a, b) { - (Some(a), Some(b)) => { - if a < b { - combined[..hash_len].copy_from_slice(a.as_ref()); - combined[hash_len..].copy_from_slice(b.as_ref()); - } else { - combined[..hash_len].copy_from_slice(b.as_ref()); - combined[hash_len..].copy_from_slice(a.as_ref()); - } - - next.push(::hash(&combined)); - }, - // Odd number of items. Promote the item to the upper layer. - (Some(a), None) if !next.is_empty() => { - next.push(a); - }, - // Last item = root. - (Some(a), None) => return Ok(a), - // Finish up, no more items. - _ => return Err(next), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use hex_literal::hex; - use sp_crypto_hashing::keccak_256; - use sp_runtime::traits::Keccak256; - - fn make_leaves(count: u64) -> Vec { - (0..count).map(|i| keccak_256(&i.to_le_bytes()).into()).collect() - } - - #[test] - fn should_generate_empty_root() { - // given - sp_tracing::init_for_tests(); - let data = vec![]; - - // when - let out = merkle_root::(data.into_iter()); - - // then - assert_eq!( - hex::encode(out), - "0000000000000000000000000000000000000000000000000000000000000000" - ); - } - - #[test] - fn should_generate_single_root() { - // given - sp_tracing::init_for_tests(); - let data = make_leaves(1); - - // when - let out = merkle_root::(data.into_iter()); - - // then - assert_eq!( - hex::encode(out), - "011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce" - ); - } - - #[test] - fn should_generate_root_pow_2() { - // given - sp_tracing::init_for_tests(); - let data = make_leaves(2); - - // when - let out = merkle_root::(data.into_iter()); - - // then - assert_eq!( - hex::encode(out), - "e497bd1c13b13a60af56fa0d2703517c232fde213ad20d2c3dd60735c6604512" - ); - } - - #[test] - fn should_generate_root_complex() { - sp_tracing::init_for_tests(); - let test = |root, data: Vec| { - assert_eq!( - array_bytes::bytes2hex("", merkle_root::(data.into_iter()).as_ref()), - root - ); - }; - - test("816cc37bd8d39f7b0851838ebc875faf2afe58a03e95aca3b1333b3693f39dd3", make_leaves(3)); - - test("7501ea976cb92f305cca65ab11254589ea28bb8b59d3161506350adaa237d22f", make_leaves(4)); - - test("d26ba4eb398747bdd39255b1fadb99b803ce39696021b3b0bff7301ac146ee4e", make_leaves(10)); - } - - #[test] - #[ignore] - fn should_generate_and_verify_proof() { - // given - sp_tracing::init_for_tests(); - let data: Vec = make_leaves(3); - - // when - let proof0 = merkle_proof::(data.clone().into_iter(), 0); - assert!(verify_proof::( - &proof0.root, - proof0.proof.clone(), - data.len() as u64, - proof0.leaf_index, - &data[0], - )); - - let proof1 = merkle_proof::(data.clone().into_iter(), 1); - assert!(verify_proof::( - &proof1.root, - proof1.proof, - data.len() as u64, - proof1.leaf_index, - &proof1.leaf, - )); - - let proof2 = merkle_proof::(data.clone().into_iter(), 2); - assert!(verify_proof::( - &proof2.root, - proof2.proof, - data.len() as u64, - proof2.leaf_index, - &proof2.leaf - )); - - // then - assert_eq!(hex::encode(proof0.root), hex::encode(proof1.root)); - assert_eq!(hex::encode(proof2.root), hex::encode(proof1.root)); - - assert!(!verify_proof::( - &H256::from_slice(&hex!( - "fb3b3be94be9e983ba5e094c9c51a7d96a4fa2e5d8e891df00ca89ba05bb1239" - )), - proof0.proof, - data.len() as u64, - proof0.leaf_index, - &proof0.leaf - )); - - assert!(!verify_proof::( - &proof0.root, - vec![], - data.len() as u64, - proof0.leaf_index, - &proof0.leaf - )); - } - - #[test] - #[should_panic] - fn should_panic_on_invalid_leaf_index() { - sp_tracing::init_for_tests(); - merkle_proof::(make_leaves(1).into_iter(), 5); - } -} diff --git a/bridges/snowbridge/pallets/outbound-queue/runtime-api/Cargo.toml b/bridges/snowbridge/pallets/outbound-queue/runtime-api/Cargo.toml index d35bdde5a81e..f050db9378a9 100644 --- a/bridges/snowbridge/pallets/outbound-queue/runtime-api/Cargo.toml +++ b/bridges/snowbridge/pallets/outbound-queue/runtime-api/Cargo.toml @@ -19,7 +19,7 @@ codec = { features = ["derive"], workspace = true } sp-std = { workspace = true } sp-api = { workspace = true } frame-support = { workspace = true } -snowbridge-outbound-queue-merkle-tree = { workspace = true } +snowbridge-merkle-tree = { workspace = true } snowbridge-core = { workspace = true } [features] @@ -28,7 +28,7 @@ std = [ "codec/std", "frame-support/std", "snowbridge-core/std", - "snowbridge-outbound-queue-merkle-tree/std", + "snowbridge-merkle-tree/std", "sp-api/std", "sp-std/std", ] diff --git a/bridges/snowbridge/pallets/outbound-queue/runtime-api/src/lib.rs b/bridges/snowbridge/pallets/outbound-queue/runtime-api/src/lib.rs index 3e25e481440d..ecd2de682268 100644 --- a/bridges/snowbridge/pallets/outbound-queue/runtime-api/src/lib.rs +++ b/bridges/snowbridge/pallets/outbound-queue/runtime-api/src/lib.rs @@ -7,7 +7,7 @@ use snowbridge_core::{ outbound::v1::{Command, Fee}, PricingParameters, }; -use snowbridge_outbound_queue_merkle_tree::MerkleProof; +use snowbridge_merkle_tree::MerkleProof; sp_api::decl_runtime_apis! { pub trait OutboundQueueApi where Balance: BalanceT diff --git a/bridges/snowbridge/pallets/outbound-queue/src/api.rs b/bridges/snowbridge/pallets/outbound-queue/src/api.rs index 982d32add9ef..08f4f1561968 100644 --- a/bridges/snowbridge/pallets/outbound-queue/src/api.rs +++ b/bridges/snowbridge/pallets/outbound-queue/src/api.rs @@ -8,7 +8,7 @@ use snowbridge_core::{ outbound::v1::{Command, Fee, GasMeter}, PricingParameters, }; -use snowbridge_outbound_queue_merkle_tree::{merkle_proof, MerkleProof}; +use snowbridge_merkle_tree::{merkle_proof, MerkleProof}; use sp_core::Get; pub fn prove_message(leaf_index: u64) -> Option diff --git a/bridges/snowbridge/pallets/outbound-queue/src/lib.rs b/bridges/snowbridge/pallets/outbound-queue/src/lib.rs index 75cecc28d720..0d43519167af 100644 --- a/bridges/snowbridge/pallets/outbound-queue/src/lib.rs +++ b/bridges/snowbridge/pallets/outbound-queue/src/lib.rs @@ -114,8 +114,7 @@ use snowbridge_core::{ outbound::v1::{Fee, GasMeter, QueuedMessage, VersionedQueuedMessage, ETHER_DECIMALS}, BasicOperatingMode, ChannelId, }; -use snowbridge_outbound_queue_merkle_tree::merkle_root; -pub use snowbridge_outbound_queue_merkle_tree::MerkleProof; +use snowbridge_merkle_tree::merkle_root; use sp_core::{H256, U256}; use sp_runtime::{ traits::{CheckedDiv, Hash}, diff --git a/bridges/snowbridge/pallets/outbound-queue/src/types.rs b/bridges/snowbridge/pallets/outbound-queue/src/types.rs index f65a15d3d2f9..76d32fab462a 100644 --- a/bridges/snowbridge/pallets/outbound-queue/src/types.rs +++ b/bridges/snowbridge/pallets/outbound-queue/src/types.rs @@ -4,15 +4,13 @@ use codec::{Decode, Encode}; use ethabi::Token; use frame_support::traits::ProcessMessage; use scale_info::TypeInfo; +use snowbridge_core::ChannelId; use sp_core::H256; use sp_runtime::RuntimeDebug; use sp_std::prelude::*; use super::Pallet; -use snowbridge_core::ChannelId; -pub use snowbridge_outbound_queue_merkle_tree::MerkleProof; - pub type ProcessMessageOriginOf = as ProcessMessage>::Origin; pub const LOG_TARGET: &str = "snowbridge-outbound-queue"; diff --git a/bridges/snowbridge/primitives/merkle-tree/Cargo.toml b/bridges/snowbridge/primitives/merkle-tree/Cargo.toml index 89dc8633cbd4..b3e659de7e14 100644 --- a/bridges/snowbridge/primitives/merkle-tree/Cargo.toml +++ b/bridges/snowbridge/primitives/merkle-tree/Cargo.toml @@ -16,21 +16,19 @@ codec = { workspace = true } scale-info = { features = ["derive"], workspace = true } sp-runtime = { workspace = true } sp-core = { workspace = true } -frame-support = { workspace = true } [dev-dependencies] +hex-literal = { workspace = true, default-features = true } hex = { workspace = true, default-features = true } +array-bytes = { workspace = true, default-features = true } +sp-crypto-hashing = { workspace = true, default-features = true } +sp-tracing = { workspace = true, default-features = true } [features] default = ["std"] std = [ "codec/std", - "frame-support/std", "scale-info/std", "sp-core/std", "sp-runtime/std", ] -runtime-benchmarks = [ - "frame-support/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", -] diff --git a/bridges/snowbridge/primitives/router/src/inbound/v1.rs b/bridges/snowbridge/primitives/router/src/inbound/v1.rs index 20adf4bddab0..05c054080620 100644 --- a/bridges/snowbridge/primitives/router/src/inbound/v1.rs +++ b/bridges/snowbridge/primitives/router/src/inbound/v1.rs @@ -448,6 +448,7 @@ where #[cfg(test)] mod tests { + use crate::inbound::{CallIndex, GlobalConsensusEthereumConvertsFor}; use frame_support::{assert_ok, parameter_types}; use hex_literal::hex; use xcm::prelude::*; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml index 9a76e61ecb20..1ce3c84f8b5e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml @@ -117,6 +117,7 @@ snowbridge-pallet-ethereum-client = { workspace = true } snowbridge-pallet-inbound-queue = { workspace = true } snowbridge-pallet-outbound-queue = { workspace = true } snowbridge-outbound-queue-runtime-api = { workspace = true } +snowbridge-merkle-tree = { workspace = true } snowbridge-router-primitives = { workspace = true } snowbridge-runtime-common = { workspace = true } @@ -195,6 +196,7 @@ std = [ "serde_json/std", "snowbridge-beacon-primitives/std", "snowbridge-core/std", + "snowbridge-merkle-tree/std", "snowbridge-outbound-queue-runtime-api/std", "snowbridge-pallet-ethereum-client/std", "snowbridge-pallet-inbound-queue/std", diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index e9fd8fe19226..3c33fc3f2bb3 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -994,7 +994,7 @@ impl_runtime_apis! { } impl snowbridge_outbound_queue_runtime_api::OutboundQueueApi for Runtime { - fn prove_message(leaf_index: u64) -> Option { + fn prove_message(leaf_index: u64) -> Option { snowbridge_pallet_outbound_queue::api::prove_message::(leaf_index) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml index 60e932829e87..7cf210f51cac 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml @@ -253,7 +253,6 @@ runtime-benchmarks = [ "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "snowbridge-core/runtime-benchmarks", - "snowbridge-merkle-tree/runtime-benchmarks", "snowbridge-pallet-ethereum-client/runtime-benchmarks", "snowbridge-pallet-inbound-queue-v2/runtime-benchmarks", "snowbridge-pallet-inbound-queue/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index d34e37a0ecfa..38cbe2337a32 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -886,7 +886,7 @@ impl_runtime_apis! { } impl snowbridge_outbound_queue_runtime_api::OutboundQueueApi for Runtime { - fn prove_message(leaf_index: u64) -> Option { + fn prove_message(leaf_index: u64) -> Option { snowbridge_pallet_outbound_queue::api::prove_message::(leaf_index) } diff --git a/umbrella/Cargo.toml b/umbrella/Cargo.toml index 3e7edc739821..9a7a2938eafa 100644 --- a/umbrella/Cargo.toml +++ b/umbrella/Cargo.toml @@ -168,7 +168,6 @@ std = [ "snowbridge-beacon-primitives?/std", "snowbridge-core?/std", "snowbridge-ethereum?/std", - "snowbridge-outbound-queue-merkle-tree?/std", "snowbridge-outbound-queue-runtime-api?/std", "snowbridge-pallet-ethereum-client-fixtures?/std", "snowbridge-pallet-ethereum-client?/std", @@ -536,7 +535,7 @@ with-tracing = [ "sp-tracing?/with-tracing", "sp-tracing?/with-tracing", ] -runtime-full = ["assets-common", "binary-merkle-tree", "bp-header-chain", "bp-messages", "bp-parachains", "bp-polkadot", "bp-polkadot-core", "bp-relayers", "bp-runtime", "bp-test-utils", "bp-xcm-bridge-hub", "bp-xcm-bridge-hub-router", "bridge-hub-common", "bridge-runtime-common", "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", "cumulus-pallet-parachain-system-proc-macro", "cumulus-pallet-session-benchmarking", "cumulus-pallet-solo-to-para", "cumulus-pallet-xcm", "cumulus-pallet-xcmp-queue", "cumulus-ping", "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", "cumulus-primitives-proof-size-hostfunction", "cumulus-primitives-storage-weight-reclaim", "cumulus-primitives-timestamp", "cumulus-primitives-utility", "frame-benchmarking", "frame-benchmarking-pallet-pov", "frame-election-provider-solution-type", "frame-election-provider-support", "frame-executive", "frame-metadata-hash-extension", "frame-support", "frame-support-procedural", "frame-support-procedural-tools-derive", "frame-system", "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", "pallet-alliance", "pallet-asset-conversion", "pallet-asset-conversion-ops", "pallet-asset-conversion-tx-payment", "pallet-asset-rate", "pallet-asset-tx-payment", "pallet-assets", "pallet-assets-freezer", "pallet-atomic-swap", "pallet-aura", "pallet-authority-discovery", "pallet-authorship", "pallet-babe", "pallet-bags-list", "pallet-balances", "pallet-beefy", "pallet-beefy-mmr", "pallet-bounties", "pallet-bridge-grandpa", "pallet-bridge-messages", "pallet-bridge-parachains", "pallet-bridge-relayers", "pallet-broker", "pallet-child-bounties", "pallet-collator-selection", "pallet-collective", "pallet-collective-content", "pallet-contracts", "pallet-contracts-proc-macro", "pallet-contracts-uapi", "pallet-conviction-voting", "pallet-core-fellowship", "pallet-delegated-staking", "pallet-democracy", "pallet-dev-mode", "pallet-election-provider-multi-phase", "pallet-election-provider-support-benchmarking", "pallet-elections-phragmen", "pallet-fast-unstake", "pallet-glutton", "pallet-grandpa", "pallet-identity", "pallet-im-online", "pallet-indices", "pallet-insecure-randomness-collective-flip", "pallet-lottery", "pallet-membership", "pallet-message-queue", "pallet-migrations", "pallet-mixnet", "pallet-mmr", "pallet-multisig", "pallet-nft-fractionalization", "pallet-nfts", "pallet-nfts-runtime-api", "pallet-nis", "pallet-node-authorization", "pallet-nomination-pools", "pallet-nomination-pools-benchmarking", "pallet-nomination-pools-runtime-api", "pallet-offences", "pallet-offences-benchmarking", "pallet-paged-list", "pallet-parameters", "pallet-preimage", "pallet-proxy", "pallet-ranked-collective", "pallet-recovery", "pallet-referenda", "pallet-remark", "pallet-revive", "pallet-revive-fixtures", "pallet-revive-proc-macro", "pallet-revive-uapi", "pallet-root-offences", "pallet-root-testing", "pallet-safe-mode", "pallet-salary", "pallet-scheduler", "pallet-scored-pool", "pallet-session", "pallet-session-benchmarking", "pallet-skip-feeless-payment", "pallet-society", "pallet-staking", "pallet-staking-reward-curve", "pallet-staking-reward-fn", "pallet-staking-runtime-api", "pallet-state-trie-migration", "pallet-statement", "pallet-sudo", "pallet-timestamp", "pallet-tips", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "pallet-transaction-storage", "pallet-treasury", "pallet-tx-pause", "pallet-uniques", "pallet-utility", "pallet-vesting", "pallet-whitelist", "pallet-xcm", "pallet-xcm-benchmarks", "pallet-xcm-bridge-hub", "pallet-xcm-bridge-hub-router", "parachains-common", "polkadot-core-primitives", "polkadot-parachain-primitives", "polkadot-primitives", "polkadot-runtime-common", "polkadot-runtime-metrics", "polkadot-runtime-parachains", "polkadot-sdk-frame", "sc-chain-spec-derive", "sc-tracing-proc-macro", "slot-range-helper", "snowbridge-beacon-primitives", "snowbridge-core", "snowbridge-ethereum", "snowbridge-outbound-queue-merkle-tree", "snowbridge-outbound-queue-runtime-api", "snowbridge-pallet-ethereum-client", "snowbridge-pallet-ethereum-client-fixtures", "snowbridge-pallet-inbound-queue", "snowbridge-pallet-inbound-queue-fixtures", "snowbridge-pallet-outbound-queue", "snowbridge-pallet-system", "snowbridge-router-primitives", "snowbridge-runtime-common", "snowbridge-system-runtime-api", "sp-api", "sp-api-proc-macro", "sp-application-crypto", "sp-arithmetic", "sp-authority-discovery", "sp-block-builder", "sp-consensus-aura", "sp-consensus-babe", "sp-consensus-beefy", "sp-consensus-grandpa", "sp-consensus-pow", "sp-consensus-slots", "sp-core", "sp-crypto-ec-utils", "sp-crypto-hashing", "sp-crypto-hashing-proc-macro", "sp-debug-derive", "sp-externalities", "sp-genesis-builder", "sp-inherents", "sp-io", "sp-keyring", "sp-keystore", "sp-metadata-ir", "sp-mixnet", "sp-mmr-primitives", "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-runtime-interface", "sp-runtime-interface-proc-macro", "sp-session", "sp-staking", "sp-state-machine", "sp-statement-store", "sp-std", "sp-storage", "sp-timestamp", "sp-tracing", "sp-transaction-pool", "sp-transaction-storage-proof", "sp-trie", "sp-version", "sp-version-proc-macro", "sp-wasm-interface", "sp-weights", "staging-parachain-info", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", "substrate-bip39", "testnet-parachains-constants", "tracing-gum-proc-macro", "xcm-procedural", "xcm-runtime-apis"] +runtime-full = ["assets-common", "binary-merkle-tree", "bp-header-chain", "bp-messages", "bp-parachains", "bp-polkadot", "bp-polkadot-core", "bp-relayers", "bp-runtime", "bp-test-utils", "bp-xcm-bridge-hub", "bp-xcm-bridge-hub-router", "bridge-hub-common", "bridge-runtime-common", "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", "cumulus-pallet-parachain-system-proc-macro", "cumulus-pallet-session-benchmarking", "cumulus-pallet-solo-to-para", "cumulus-pallet-xcm", "cumulus-pallet-xcmp-queue", "cumulus-ping", "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", "cumulus-primitives-proof-size-hostfunction", "cumulus-primitives-storage-weight-reclaim", "cumulus-primitives-timestamp", "cumulus-primitives-utility", "frame-benchmarking", "frame-benchmarking-pallet-pov", "frame-election-provider-solution-type", "frame-election-provider-support", "frame-executive", "frame-metadata-hash-extension", "frame-support", "frame-support-procedural", "frame-support-procedural-tools-derive", "frame-system", "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", "pallet-alliance", "pallet-asset-conversion", "pallet-asset-conversion-ops", "pallet-asset-conversion-tx-payment", "pallet-asset-rate", "pallet-asset-tx-payment", "pallet-assets", "pallet-assets-freezer", "pallet-atomic-swap", "pallet-aura", "pallet-authority-discovery", "pallet-authorship", "pallet-babe", "pallet-bags-list", "pallet-balances", "pallet-beefy", "pallet-beefy-mmr", "pallet-bounties", "pallet-bridge-grandpa", "pallet-bridge-messages", "pallet-bridge-parachains", "pallet-bridge-relayers", "pallet-broker", "pallet-child-bounties", "pallet-collator-selection", "pallet-collective", "pallet-collective-content", "pallet-contracts", "pallet-contracts-proc-macro", "pallet-contracts-uapi", "pallet-conviction-voting", "pallet-core-fellowship", "pallet-delegated-staking", "pallet-democracy", "pallet-dev-mode", "pallet-election-provider-multi-phase", "pallet-election-provider-support-benchmarking", "pallet-elections-phragmen", "pallet-fast-unstake", "pallet-glutton", "pallet-grandpa", "pallet-identity", "pallet-im-online", "pallet-indices", "pallet-insecure-randomness-collective-flip", "pallet-lottery", "pallet-membership", "pallet-message-queue", "pallet-migrations", "pallet-mixnet", "pallet-mmr", "pallet-multisig", "pallet-nft-fractionalization", "pallet-nfts", "pallet-nfts-runtime-api", "pallet-nis", "pallet-node-authorization", "pallet-nomination-pools", "pallet-nomination-pools-benchmarking", "pallet-nomination-pools-runtime-api", "pallet-offences", "pallet-offences-benchmarking", "pallet-paged-list", "pallet-parameters", "pallet-preimage", "pallet-proxy", "pallet-ranked-collective", "pallet-recovery", "pallet-referenda", "pallet-remark", "pallet-revive", "pallet-revive-fixtures", "pallet-revive-proc-macro", "pallet-revive-uapi", "pallet-root-offences", "pallet-root-testing", "pallet-safe-mode", "pallet-salary", "pallet-scheduler", "pallet-scored-pool", "pallet-session", "pallet-session-benchmarking", "pallet-skip-feeless-payment", "pallet-society", "pallet-staking", "pallet-staking-reward-curve", "pallet-staking-reward-fn", "pallet-staking-runtime-api", "pallet-state-trie-migration", "pallet-statement", "pallet-sudo", "pallet-timestamp", "pallet-tips", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "pallet-transaction-storage", "pallet-treasury", "pallet-tx-pause", "pallet-uniques", "pallet-utility", "pallet-vesting", "pallet-whitelist", "pallet-xcm", "pallet-xcm-benchmarks", "pallet-xcm-bridge-hub", "pallet-xcm-bridge-hub-router", "parachains-common", "polkadot-core-primitives", "polkadot-parachain-primitives", "polkadot-primitives", "polkadot-runtime-common", "polkadot-runtime-metrics", "polkadot-runtime-parachains", "polkadot-sdk-frame", "sc-chain-spec-derive", "sc-tracing-proc-macro", "slot-range-helper", "snowbridge-beacon-primitives", "snowbridge-core", "snowbridge-ethereum", "snowbridge-outbound-queue-runtime-api", "snowbridge-pallet-ethereum-client", "snowbridge-pallet-ethereum-client-fixtures", "snowbridge-pallet-inbound-queue", "snowbridge-pallet-inbound-queue-fixtures", "snowbridge-pallet-outbound-queue", "snowbridge-pallet-system", "snowbridge-router-primitives", "snowbridge-runtime-common", "snowbridge-system-runtime-api", "sp-api", "sp-api-proc-macro", "sp-application-crypto", "sp-arithmetic", "sp-authority-discovery", "sp-block-builder", "sp-consensus-aura", "sp-consensus-babe", "sp-consensus-beefy", "sp-consensus-grandpa", "sp-consensus-pow", "sp-consensus-slots", "sp-core", "sp-crypto-ec-utils", "sp-crypto-hashing", "sp-crypto-hashing-proc-macro", "sp-debug-derive", "sp-externalities", "sp-genesis-builder", "sp-inherents", "sp-io", "sp-keyring", "sp-keystore", "sp-metadata-ir", "sp-mixnet", "sp-mmr-primitives", "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-runtime-interface", "sp-runtime-interface-proc-macro", "sp-session", "sp-staking", "sp-state-machine", "sp-statement-store", "sp-std", "sp-storage", "sp-timestamp", "sp-tracing", "sp-transaction-pool", "sp-transaction-storage-proof", "sp-trie", "sp-version", "sp-version-proc-macro", "sp-wasm-interface", "sp-weights", "staging-parachain-info", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", "substrate-bip39", "testnet-parachains-constants", "tracing-gum-proc-macro", "xcm-procedural", "xcm-runtime-apis"] runtime = [ "frame-benchmarking", "frame-benchmarking-pallet-pov", @@ -1432,11 +1431,6 @@ path = "../bridges/snowbridge/primitives/ethereum" default-features = false optional = true -[dependencies.snowbridge-outbound-queue-merkle-tree] -path = "../bridges/snowbridge/pallets/outbound-queue/merkle-tree" -default-features = false -optional = true - [dependencies.snowbridge-outbound-queue-runtime-api] path = "../bridges/snowbridge/pallets/outbound-queue/runtime-api" default-features = false diff --git a/umbrella/src/lib.rs b/umbrella/src/lib.rs index 656273029fe8..f25e4e4255e7 100644 --- a/umbrella/src/lib.rs +++ b/umbrella/src/lib.rs @@ -1180,10 +1180,6 @@ pub use snowbridge_core; #[cfg(feature = "snowbridge-ethereum")] pub use snowbridge_ethereum; -/// Snowbridge Outbound Queue Merkle Tree. -#[cfg(feature = "snowbridge-outbound-queue-merkle-tree")] -pub use snowbridge_outbound_queue_merkle_tree; - /// Snowbridge Outbound Queue Runtime API. #[cfg(feature = "snowbridge-outbound-queue-runtime-api")] pub use snowbridge_outbound_queue_runtime_api;