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

Revert "Optimize merkle proofs for efficient verification in Solidity (#12857)" #14176

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions frame/beefy-mmr/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn should_contain_mmr_digest() {
ValidatorSet::new(vec![mock_beefy_id(1), mock_beefy_id(2)], 1).unwrap()
)),
beefy_log(ConsensusLog::MmrRoot(array_bytes::hex_n_into_unchecked(
"200e73880940ac0b66735ffb560fa0a3989292463d262deac6ad61e78a3e46a4"
"95803defe6ea9f41e7ec6afa497064f21bfded027d8812efacbdf984e630cbdc"
)))
]
);
Expand All @@ -85,13 +85,13 @@ fn should_contain_mmr_digest() {
ValidatorSet::new(vec![mock_beefy_id(1), mock_beefy_id(2)], 1).unwrap()
)),
beefy_log(ConsensusLog::MmrRoot(array_bytes::hex_n_into_unchecked(
"200e73880940ac0b66735ffb560fa0a3989292463d262deac6ad61e78a3e46a4"
"95803defe6ea9f41e7ec6afa497064f21bfded027d8812efacbdf984e630cbdc"
))),
beefy_log(ConsensusLog::AuthoritiesChange(
ValidatorSet::new(vec![mock_beefy_id(3), mock_beefy_id(4)], 2).unwrap()
)),
beefy_log(ConsensusLog::MmrRoot(array_bytes::hex_n_into_unchecked(
"ba37d8d5d195ac8caec391da35472f9ecf1116ff1642409148b62e08896d3884"
"a73271a0974f1e67d6e9b8dd58e506177a2e556519a330796721e98279a753e2"
))),
]
);
Expand Down Expand Up @@ -124,7 +124,7 @@ fn should_contain_valid_leaf_data() {
)
},
leaf_extra: array_bytes::hex2bytes_unchecked(
"5572d58c82bddf323f4fc7aecab8a8f0ad6ed2f06ab2bfb8ade36a77a45fcc68"
"55b8e9e1cc9f0db7776fac0ca66318ef8acfb8ec26db11e373120583e07ee648"
)
}
);
Expand All @@ -149,7 +149,7 @@ fn should_contain_valid_leaf_data() {
)
},
leaf_extra: array_bytes::hex2bytes_unchecked(
"5572d58c82bddf323f4fc7aecab8a8f0ad6ed2f06ab2bfb8ade36a77a45fcc68"
"55b8e9e1cc9f0db7776fac0ca66318ef8acfb8ec26db11e373120583e07ee648"
)
}
);
Expand Down
3 changes: 1 addition & 2 deletions frame/merkle-mountain-range/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,7 @@ pub mod pallet {
+ codec::Codec
+ codec::EncodeLike
+ scale_info::TypeInfo
+ MaxEncodedLen
+ PartialOrd;
+ MaxEncodedLen;

/// Data stored in the leaf nodes.
///
Expand Down
46 changes: 22 additions & 24 deletions utils/binary-merkle-tree/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
//! 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
//! sorts each pair of hashes before every hash operation. This makes proof verification more
//! efficient by removing the need to track which side each intermediate hash is concatenated on.
//! 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"))]
Expand All @@ -48,7 +47,7 @@ use hash_db::Hasher;
pub fn merkle_root<H, I>(leaves: I) -> H::Out
where
H: Hasher,
H::Out: Default + AsRef<[u8]> + PartialOrd,
H::Out: Default + AsRef<[u8]>,
I: IntoIterator,
I::Item: AsRef<[u8]>,
{
Expand All @@ -59,7 +58,7 @@ where
fn merkelize<H, V, I>(leaves: I, visitor: &mut V) -> H::Out
where
H: Hasher,
H::Out: Default + AsRef<[u8]> + PartialOrd,
H::Out: Default + AsRef<[u8]>,
V: Visitor<H::Out>,
I: Iterator<Item = H::Out>,
{
Expand Down Expand Up @@ -144,7 +143,7 @@ impl<T> Visitor<T> for () {
pub fn merkle_proof<H, I, T>(leaves: I, leaf_index: usize) -> MerkleProof<H::Out, T>
where
H: Hasher,
H::Out: Default + Copy + AsRef<[u8]> + PartialOrd,
H::Out: Default + Copy + AsRef<[u8]>,
I: IntoIterator<Item = T>,
I::IntoIter: ExactSizeIterator,
T: AsRef<[u8]>,
Expand Down Expand Up @@ -244,7 +243,7 @@ pub fn verify_proof<'a, H, P, L>(
) -> bool
where
H: Hasher,
H::Out: PartialEq + AsRef<[u8]> + PartialOrd,
H::Out: PartialEq + AsRef<[u8]>,
P: IntoIterator<Item = H::Out>,
L: Into<Leaf<'a, H::Out>>,
{
Expand All @@ -259,13 +258,15 @@ where

let hash_len = <H as Hasher>::LENGTH;
let mut combined = vec![0_u8; hash_len * 2];
let mut position = leaf_index;
let mut width = number_of_leaves;
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 {
if position % 2 == 1 || position + 1 == width {
combined[..hash_len].copy_from_slice(&b.as_ref());
combined[hash_len..].copy_from_slice(&a.as_ref());
} else {
combined[..hash_len].copy_from_slice(&a.as_ref());
combined[hash_len..].copy_from_slice(&b.as_ref());
}
let hash = <H as Hasher>::hash(&combined);
#[cfg(feature = "debug")]
Expand All @@ -276,6 +277,8 @@ where
array_bytes::bytes2hex("", &hash.as_ref()),
array_bytes::bytes2hex("", &combined.as_ref())
);
position /= 2;
width = ((width - 1) / 2) + 1;
hash
});

Expand All @@ -294,7 +297,7 @@ fn merkelize_row<H, V, I>(
) -> Result<H::Out, Vec<H::Out>>
where
H: Hasher,
H::Out: AsRef<[u8]> + PartialOrd,
H::Out: AsRef<[u8]>,
V: Visitor<H::Out>,
I: Iterator<Item = H::Out>,
{
Expand All @@ -320,13 +323,8 @@ where
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());
}
combined[..hash_len].copy_from_slice(a.as_ref());
combined[hash_len..].copy_from_slice(b.as_ref());

next.push(<H as Hasher>::hash(&combined));
},
Expand Down Expand Up @@ -419,12 +417,12 @@ mod tests {
};

test(
"5842148bc6ebeb52af882a317c765fccd3ae80589b21a9b8cbf21abb630e46a7",
"aff1208e69c9e8be9b584b07ebac4e48a1ee9d15ce3afe20b77a4d29e4175aa3",
vec!["a", "b", "c"],
);

test(
"7b84bec68b13c39798c6c50e9e40a0b268e3c1634db8f4cb97314eb243d4c514",
"b8912f7269068901f231a965adfefbc10f0eedcfa61852b103efd54dac7db3d7",
vec!["a", "b", "a"],
);

Expand All @@ -434,7 +432,7 @@ mod tests {
);

test(
"cc50382cfd3c9a617741e9a85efee8752b8feb95a2cbecd6365fb21366ce0c8c",
"fb3b3be94be9e983ba5e094c9c51a7d96a4fa2e5d8e891df00ca89ba05bb1239",
vec!["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"],
);
}
Expand Down Expand Up @@ -752,7 +750,7 @@ mod tests {
"0xc26B34D375533fFc4c5276282Fa5D660F3d8cbcB",
];
let root: H256 = array_bytes::hex2array_unchecked(
"7b2c6eebec6e85b2e272325a11c31af71df52bc0534d2d4f903e0ced191f022e",
"72b0acd7c302a84f1f6b6cefe0ba7194b7398afb440e1b44a9dbbe270394ca53",
)
.into();

Expand Down Expand Up @@ -797,11 +795,11 @@ mod tests {
)
.into(),
array_bytes::hex2array_unchecked(
"1fad92ed8d0504ef6c0231bbbeeda960a40693f297c64e87b582beb92ecfb00f"
"d02609d2bbdb28aa25f58b85afec937d5a4c85d37925bce6d0cf802f9d76ba79"
)
.into(),
array_bytes::hex2array_unchecked(
"0b84c852cbcf839d562d826fd935e1b37975ccaa419e1def8d219df4b83dcbf4"
"ae3f8991955ed884613b0a5f40295902eea0e0abe5858fc520b72959bc016d4e"
)
.into(),
],
Expand Down