Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 5d0867c

Browse files
authored
Move beefy-merkle-tree to utils/binary-merkle-tree and make it generic (#13076)
* move BeefyMmrApi to pallet-beefy-mmr * fix test_utils use pallet-beefy-mmr BeefyMmrApi * Move beefy-merkle-tree to utils and Rename to Merkle-tree * fix fmt and test * Update merkle-tree to binary-merkle-tree and Remove Keccak256 mod from merkle-tree * change merkle-tree name to binary-merkle-tree * mirr fix
1 parent 68d00e2 commit 5d0867c

File tree

9 files changed

+75
-71
lines changed

9 files changed

+75
-71
lines changed

Cargo.lock

+6-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ members = [
8585
"frame/balances",
8686
"frame/beefy",
8787
"frame/beefy-mmr",
88-
"frame/beefy-mmr/primitives",
8988
"frame/benchmarking",
9089
"frame/benchmarking/pov",
9190
"frame/bounties",
@@ -246,6 +245,7 @@ members = [
246245
"utils/frame/rpc/client",
247246
"utils/prometheus",
248247
"utils/wasm-builder",
248+
"utils/binary-merkle-tree",
249249
]
250250

251251
# The list of dependencies below (which can be both direct and indirect dependencies) are crates

frame/beefy-mmr/Cargo.toml

+4-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ codec = { package = "parity-scale-codec", version = "3.2.2", default-features =
1414
log = { version = "0.4.17", default-features = false }
1515
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
1616
serde = { version = "1.0.136", optional = true }
17-
beefy-merkle-tree = { version = "4.0.0-dev", default-features = false, path = "./primitives" }
17+
binary-merkle-tree = { version = "4.0.0-dev", default-features = false, path = "../../utils/binary-merkle-tree" }
1818
beefy-primitives = { version = "4.0.0-dev", default-features = false, path = "../../primitives/beefy", package = "sp-beefy" }
1919
frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" }
2020
frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" }
@@ -25,6 +25,7 @@ sp-core = { version = "7.0.0", default-features = false, path = "../../primitive
2525
sp-io = { version = "7.0.0", default-features = false, path = "../../primitives/io" }
2626
sp-runtime = { version = "7.0.0", default-features = false, path = "../../primitives/runtime" }
2727
sp-std = { version = "5.0.0", default-features = false, path = "../../primitives/std" }
28+
sp-api = { version = "4.0.0-dev", default-features = false, path = "../../primitives/api" }
2829

2930
[dev-dependencies]
3031
array-bytes = "4.1"
@@ -34,7 +35,7 @@ sp-staking = { version = "4.0.0-dev", path = "../../primitives/staking" }
3435
default = ["std"]
3536
std = [
3637
"array-bytes",
37-
"beefy-merkle-tree/std",
38+
"binary-merkle-tree/std",
3839
"beefy-primitives/std",
3940
"codec/std",
4041
"frame-support/std",
@@ -49,5 +50,6 @@ std = [
4950
"sp-io/std",
5051
"sp-runtime/std",
5152
"sp-std/std",
53+
"sp-api/std",
5254
]
5355
try-runtime = ["frame-support/try-runtime"]

frame/beefy-mmr/src/lib.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,24 @@ impl<T: Config> Pallet<T> {
200200
.map(T::BeefyAuthorityToMerkleLeaf::convert)
201201
.collect::<Vec<_>>();
202202
let len = beefy_addresses.len() as u32;
203-
let root = beefy_merkle_tree::merkle_root::<<T as pallet_mmr::Config>::Hashing, _>(
203+
let root = binary_merkle_tree::merkle_root::<<T as pallet_mmr::Config>::Hashing, _>(
204204
beefy_addresses,
205205
)
206206
.into();
207207
BeefyAuthoritySet { id, len, root }
208208
}
209209
}
210+
211+
sp_api::decl_runtime_apis! {
212+
/// API useful for BEEFY light clients.
213+
pub trait BeefyMmrApi<H>
214+
where
215+
BeefyAuthoritySet<H>: sp_api::Decode,
216+
{
217+
/// Return the currently active BEEFY authority set proof.
218+
fn authority_set_proof() -> BeefyAuthoritySet<H>;
219+
220+
/// Return the next/queued BEEFY authority set proof.
221+
fn next_authority_set_proof() -> BeefyNextAuthoritySet<H>;
222+
}
223+
}

frame/beefy-mmr/src/mock.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ impl BeefyDataProvider<Vec<u8>> for DummyDataProvider {
147147
fn extra_data() -> Vec<u8> {
148148
let mut col = vec![(15, vec![1, 2, 3]), (5, vec![4, 5, 6])];
149149
col.sort();
150-
beefy_merkle_tree::merkle_root::<<Test as pallet_mmr::Config>::Hashing, _>(
150+
binary_merkle_tree::merkle_root::<<Test as pallet_mmr::Config>::Hashing, _>(
151151
col.into_iter().map(|pair| pair.encode()),
152152
)
153153
.as_ref()

test-utils/runtime/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"]
1414

1515
[dependencies]
1616
beefy-primitives = { version = "4.0.0-dev", default-features = false, path = "../../primitives/beefy", package = "sp-beefy" }
17-
beefy-merkle-tree = { version = "4.0.0-dev", default-features = false, path = "../../frame/beefy-mmr/primitives" }
17+
pallet-beefy-mmr = { version = "4.0.0-dev", default-features = false, path = "../../frame/beefy-mmr" }
1818
sp-application-crypto = { version = "7.0.0", default-features = false, path = "../../primitives/application-crypto" }
1919
sp-consensus-aura = { version = "0.10.0-dev", default-features = false, path = "../../primitives/consensus/aura" }
2020
sp-consensus-babe = { version = "0.10.0-dev", default-features = false, path = "../../primitives/consensus/babe" }
@@ -67,7 +67,7 @@ default = [
6767
]
6868
std = [
6969
"beefy-primitives/std",
70-
"beefy-merkle-tree/std",
70+
"pallet-beefy-mmr/std",
7171
"sp-application-crypto/std",
7272
"sp-consensus-aura/std",
7373
"sp-consensus-babe/std",

test-utils/runtime/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,7 @@ cfg_if! {
978978
}
979979
}
980980

981-
impl beefy_merkle_tree::BeefyMmrApi<Block, beefy_primitives::MmrRootHash> for Runtime {
981+
impl pallet_beefy_mmr::BeefyMmrApi<Block, beefy_primitives::MmrRootHash> for Runtime {
982982
fn authority_set_proof() -> beefy_primitives::mmr::BeefyAuthoritySet<beefy_primitives::MmrRootHash> {
983983
Default::default()
984984
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "beefy-merkle-tree"
2+
name = "binary-merkle-tree"
33
version = "4.0.0-dev"
44
authors = ["Parity Technologies <admin@parity.io>"]
55
edition = "2021"
@@ -11,20 +11,18 @@ homepage = "https://substrate.io"
1111
[dependencies]
1212
array-bytes = { version = "4.1", optional = true }
1313
log = { version = "0.4", default-features = false, optional = true }
14-
15-
beefy-primitives = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/beefy", package = "sp-beefy" }
16-
sp-api = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/api" }
17-
sp-runtime = { version = "7.0.0", default-features = false, path = "../../../primitives/runtime" }
14+
hash-db = { version = "0.15.2", default-features = false }
1815

1916
[dev-dependencies]
2017
array-bytes = "4.1"
2118
env_logger = "0.9"
19+
sp-core = { version = "7.0.0", path = "../../primitives/core" }
20+
sp-runtime = { version = "7.0.0", path = "../../primitives/runtime" }
2221

2322
[features]
2423
debug = ["array-bytes", "log"]
2524
default = ["debug", "std"]
2625
std = [
27-
"beefy-primitives/std",
28-
"sp-api/std",
29-
"sp-runtime/std"
26+
"log/std",
27+
"hash-db/std"
3028
]

frame/beefy-mmr/primitives/src/lib.rs utils/binary-merkle-tree/src/lib.rs

+39-50
Original file line numberDiff line numberDiff line change
@@ -31,40 +31,42 @@
3131
//! efficient by removing the need to track which side each intermediate hash is concatenated on.
3232
//!
3333
//! If the number of leaves is not even, last leaf (hash of) is promoted to the upper layer.
34+
#[cfg(not(feature = "std"))]
35+
extern crate alloc;
36+
#[cfg(not(feature = "std"))]
37+
use alloc::vec;
38+
#[cfg(not(feature = "std"))]
39+
use alloc::vec::Vec;
3440

35-
pub use sp_runtime::traits::Keccak256;
36-
use sp_runtime::{app_crypto::sp_core, sp_std, traits::Hash as HashT};
37-
use sp_std::{vec, vec::Vec};
38-
39-
use beefy_primitives::mmr::{BeefyAuthoritySet, BeefyNextAuthoritySet};
41+
use hash_db::Hasher;
4042

4143
/// Construct a root hash of a Binary Merkle Tree created from given leaves.
4244
///
4345
/// See crate-level docs for details about Merkle Tree construction.
4446
///
4547
/// In case an empty list of leaves is passed the function returns a 0-filled hash.
46-
pub fn merkle_root<H, I>(leaves: I) -> H::Output
48+
pub fn merkle_root<H, I>(leaves: I) -> H::Out
4749
where
48-
H: HashT,
49-
H::Output: Default + AsRef<[u8]> + PartialOrd,
50+
H: Hasher,
51+
H::Out: Default + AsRef<[u8]> + PartialOrd,
5052
I: IntoIterator,
5153
I::Item: AsRef<[u8]>,
5254
{
53-
let iter = leaves.into_iter().map(|l| <H as HashT>::hash(l.as_ref()));
55+
let iter = leaves.into_iter().map(|l| <H as Hasher>::hash(l.as_ref()));
5456
merkelize::<H, _, _>(iter, &mut ()).into()
5557
}
5658

57-
fn merkelize<H, V, I>(leaves: I, visitor: &mut V) -> H::Output
59+
fn merkelize<H, V, I>(leaves: I, visitor: &mut V) -> H::Out
5860
where
59-
H: HashT,
60-
H::Output: Default + AsRef<[u8]> + PartialOrd,
61-
V: Visitor<H::Output>,
62-
I: Iterator<Item = H::Output>,
61+
H: Hasher,
62+
H::Out: Default + AsRef<[u8]> + PartialOrd,
63+
V: Visitor<H::Out>,
64+
I: Iterator<Item = H::Out>,
6365
{
6466
let upper = Vec::with_capacity((leaves.size_hint().1.unwrap_or(0).saturating_add(1)) / 2);
6567
let mut next = match merkelize_row::<H, _, _>(leaves, upper, visitor) {
6668
Ok(root) => return root,
67-
Err(next) if next.is_empty() => return H::Output::default(),
69+
Err(next) if next.is_empty() => return H::Out::default(),
6870
Err(next) => next,
6971
};
7072

@@ -139,17 +141,17 @@ impl<T> Visitor<T> for () {
139141
/// # Panic
140142
///
141143
/// The function will panic if given `leaf_index` is greater than the number of leaves.
142-
pub fn merkle_proof<H, I, T>(leaves: I, leaf_index: usize) -> MerkleProof<H::Output, T>
144+
pub fn merkle_proof<H, I, T>(leaves: I, leaf_index: usize) -> MerkleProof<H::Out, T>
143145
where
144-
H: HashT,
145-
H::Output: Default + Copy + AsRef<[u8]> + PartialOrd,
146+
H: Hasher,
147+
H::Out: Default + Copy + AsRef<[u8]> + PartialOrd,
146148
I: IntoIterator<Item = T>,
147149
I::IntoIter: ExactSizeIterator,
148150
T: AsRef<[u8]>,
149151
{
150152
let mut leaf = None;
151153
let iter = leaves.into_iter().enumerate().map(|(idx, l)| {
152-
let hash = <H as HashT>::hash(l.as_ref());
154+
let hash = <H as Hasher>::hash(l.as_ref());
153155
if idx == leaf_index {
154156
leaf = Some(l);
155157
}
@@ -234,28 +236,28 @@ impl<'a, H, T: AsRef<[u8]>> From<&'a T> for Leaf<'a, H> {
234236
///
235237
/// The proof must not contain the root hash.
236238
pub fn verify_proof<'a, H, P, L>(
237-
root: &'a H::Output,
239+
root: &'a H::Out,
238240
proof: P,
239241
number_of_leaves: usize,
240242
leaf_index: usize,
241243
leaf: L,
242244
) -> bool
243245
where
244-
H: HashT,
245-
H::Output: PartialEq + AsRef<[u8]> + PartialOrd,
246-
P: IntoIterator<Item = H::Output>,
247-
L: Into<Leaf<'a, H::Output>>,
246+
H: Hasher,
247+
H::Out: PartialEq + AsRef<[u8]> + PartialOrd,
248+
P: IntoIterator<Item = H::Out>,
249+
L: Into<Leaf<'a, H::Out>>,
248250
{
249251
if leaf_index >= number_of_leaves {
250252
return false
251253
}
252254

253255
let leaf_hash = match leaf.into() {
254-
Leaf::Value(content) => <H as HashT>::hash(content),
256+
Leaf::Value(content) => <H as Hasher>::hash(content),
255257
Leaf::Hash(hash) => hash,
256258
};
257259

258-
let hash_len = <H as sp_core::Hasher>::LENGTH;
260+
let hash_len = <H as Hasher>::LENGTH;
259261
let mut combined = vec![0_u8; hash_len * 2];
260262
let computed = proof.into_iter().fold(leaf_hash, |a, b| {
261263
if a < b {
@@ -265,7 +267,7 @@ where
265267
combined[..hash_len].copy_from_slice(&b.as_ref());
266268
combined[hash_len..].copy_from_slice(&a.as_ref());
267269
}
268-
let hash = <H as HashT>::hash(&combined);
270+
let hash = <H as Hasher>::hash(&combined);
269271
#[cfg(feature = "debug")]
270272
log::debug!(
271273
"[verify_proof]: (a, b) {:?}, {:?} => {:?} ({:?}) hash",
@@ -287,20 +289,20 @@ where
287289
/// empty iterator) an `Err` with the inner nodes of upper layer is returned.
288290
fn merkelize_row<H, V, I>(
289291
mut iter: I,
290-
mut next: Vec<H::Output>,
292+
mut next: Vec<H::Out>,
291293
visitor: &mut V,
292-
) -> Result<H::Output, Vec<H::Output>>
294+
) -> Result<H::Out, Vec<H::Out>>
293295
where
294-
H: HashT,
295-
H::Output: AsRef<[u8]> + PartialOrd,
296-
V: Visitor<H::Output>,
297-
I: Iterator<Item = H::Output>,
296+
H: Hasher,
297+
H::Out: AsRef<[u8]> + PartialOrd,
298+
V: Visitor<H::Out>,
299+
I: Iterator<Item = H::Out>,
298300
{
299301
#[cfg(feature = "debug")]
300302
log::debug!("[merkelize_row]");
301303
next.clear();
302304

303-
let hash_len = <H as sp_core::Hasher>::LENGTH;
305+
let hash_len = <H as Hasher>::LENGTH;
304306
let mut index = 0;
305307
let mut combined = vec![0_u8; hash_len * 2];
306308
loop {
@@ -326,7 +328,7 @@ where
326328
combined[hash_len..].copy_from_slice(a.as_ref());
327329
}
328330

329-
next.push(<H as HashT>::hash(&combined));
331+
next.push(<H as Hasher>::hash(&combined));
330332
},
331333
// Odd number of items. Promote the item to the upper layer.
332334
(Some(a), None) if !next.is_empty() => {
@@ -347,24 +349,11 @@ where
347349
}
348350
}
349351

350-
sp_api::decl_runtime_apis! {
351-
/// API useful for BEEFY light clients.
352-
pub trait BeefyMmrApi<H>
353-
where
354-
BeefyAuthoritySet<H>: sp_api::Decode,
355-
{
356-
/// Return the currently active BEEFY authority set proof.
357-
fn authority_set_proof() -> BeefyAuthoritySet<H>;
358-
359-
/// Return the next/queued BEEFY authority set proof.
360-
fn next_authority_set_proof() -> BeefyNextAuthoritySet<H>;
361-
}
362-
}
363-
364352
#[cfg(test)]
365353
mod tests {
366354
use super::*;
367-
use crate::sp_core::H256;
355+
use sp_core::H256;
356+
use sp_runtime::traits::Keccak256;
368357

369358
#[test]
370359
fn should_generate_empty_root() {

0 commit comments

Comments
 (0)