From 7783cb7e7ff273036e10e26c252d2ea195bb2bcf Mon Sep 17 00:00:00 2001 From: Robert Hambrock Date: Thu, 18 May 2023 12:07:37 +0200 Subject: [PATCH] Revert "Optimize merkle proofs for efficient verification in Solidity (#12857)" This reverts commit f9d1dcdfa1f0a2edc2b933a0b11ffd499c22c73a since we still require commitment to the leaves - see #12820. --- frame/beefy-mmr/src/tests.rs | 10 ++++---- utils/binary-merkle-tree/src/lib.rs | 36 ++++++++++++++--------------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/frame/beefy-mmr/src/tests.rs b/frame/beefy-mmr/src/tests.rs index dc2e46f31fe64..d7e0ddd98cde0 100644 --- a/frame/beefy-mmr/src/tests.rs +++ b/frame/beefy-mmr/src/tests.rs @@ -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" ))) ] ); @@ -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" ))), ] ); @@ -124,7 +124,7 @@ fn should_contain_valid_leaf_data() { ) }, leaf_extra: array_bytes::hex2bytes_unchecked( - "5572d58c82bddf323f4fc7aecab8a8f0ad6ed2f06ab2bfb8ade36a77a45fcc68" + "55b8e9e1cc9f0db7776fac0ca66318ef8acfb8ec26db11e373120583e07ee648" ) } ); @@ -149,7 +149,7 @@ fn should_contain_valid_leaf_data() { ) }, leaf_extra: array_bytes::hex2bytes_unchecked( - "5572d58c82bddf323f4fc7aecab8a8f0ad6ed2f06ab2bfb8ade36a77a45fcc68" + "55b8e9e1cc9f0db7776fac0ca66318ef8acfb8ec26db11e373120583e07ee648" ) } ); diff --git a/utils/binary-merkle-tree/src/lib.rs b/utils/binary-merkle-tree/src/lib.rs index 43c07cb60a045..b2b61b189619a 100644 --- a/utils/binary-merkle-tree/src/lib.rs +++ b/utils/binary-merkle-tree/src/lib.rs @@ -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"))] @@ -259,13 +258,15 @@ where let hash_len = ::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 = ::hash(&combined); #[cfg(feature = "debug")] @@ -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 }); @@ -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(::hash(&combined)); }, @@ -419,12 +417,12 @@ mod tests { }; test( - "5842148bc6ebeb52af882a317c765fccd3ae80589b21a9b8cbf21abb630e46a7", + "aff1208e69c9e8be9b584b07ebac4e48a1ee9d15ce3afe20b77a4d29e4175aa3", vec!["a", "b", "c"], ); test( - "7b84bec68b13c39798c6c50e9e40a0b268e3c1634db8f4cb97314eb243d4c514", + "b8912f7269068901f231a965adfefbc10f0eedcfa61852b103efd54dac7db3d7", vec!["a", "b", "a"], ); @@ -434,7 +432,7 @@ mod tests { ); test( - "cc50382cfd3c9a617741e9a85efee8752b8feb95a2cbecd6365fb21366ce0c8c", + "fb3b3be94be9e983ba5e094c9c51a7d96a4fa2e5d8e891df00ca89ba05bb1239", vec!["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"], ); } @@ -752,7 +750,7 @@ mod tests { "0xc26B34D375533fFc4c5276282Fa5D660F3d8cbcB", ]; let root: H256 = array_bytes::hex2array_unchecked( - "7b2c6eebec6e85b2e272325a11c31af71df52bc0534d2d4f903e0ced191f022e", + "72b0acd7c302a84f1f6b6cefe0ba7194b7398afb440e1b44a9dbbe270394ca53", ) .into(); @@ -797,11 +795,11 @@ mod tests { ) .into(), array_bytes::hex2array_unchecked( - "1fad92ed8d0504ef6c0231bbbeeda960a40693f297c64e87b582beb92ecfb00f" + "d02609d2bbdb28aa25f58b85afec937d5a4c85d37925bce6d0cf802f9d76ba79" ) .into(), array_bytes::hex2array_unchecked( - "0b84c852cbcf839d562d826fd935e1b37975ccaa419e1def8d219df4b83dcbf4" + "ae3f8991955ed884613b0a5f40295902eea0e0abe5858fc520b72959bc016d4e" ) .into(), ],