From 1b8a251d4b955ec61aee6b65318854363f598ebd Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 24 Sep 2022 19:27:40 +0200 Subject: [PATCH 01/55] pallet-mmr: RPC API works with block_numbers --- bin/node/runtime/src/lib.rs | 5 +++++ frame/merkle-mountain-range/rpc/src/lib.rs | 21 ++++++++++++++++----- frame/merkle-mountain-range/src/mmr/mmr.rs | 17 ++++++++++++++++- primitives/merkle-mountain-range/src/lib.rs | 4 +++- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 8ed5f1c847f5e..63eb87c4dd675 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -2013,6 +2013,7 @@ impl_runtime_apis! { impl pallet_mmr::primitives::MmrApi< Block, mmr::Hash, + BlockNumber, > for Runtime { fn generate_proof(leaf_index: pallet_mmr::primitives::LeafIndex) -> Result<(mmr::EncodableOpaqueLeaf, mmr::Proof), mmr::Error> @@ -2073,6 +2074,10 @@ impl_runtime_apis! { let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect(); pallet_mmr::verify_leaves_proof::(root, nodes, proof) } + + fn block_num_to_leaf_index(block_num: BlockNumber) -> mmr::LeafIndex { + pallet_mmr::block_num_to_leaf_index(block_num) + } } impl sp_session::SessionKeys for Runtime { diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index 75032d40f492a..815d7eae1839d 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -96,7 +96,7 @@ impl LeafBatchProof { /// MMR RPC methods. #[rpc(client, server)] -pub trait MmrApi { +pub trait MmrApi { /// Generate MMR proof for given leaf index. /// /// This method calls into a runtime with MMR pallet included and attempts to generate @@ -125,7 +125,7 @@ pub trait MmrApi { #[method(name = "mmr_generateBatchProof")] fn generate_batch_proof( &self, - leaf_indices: Vec, + leaf_indices: Vec, at: Option, ) -> RpcResult>; } @@ -144,12 +144,14 @@ impl Mmr { } #[async_trait] -impl MmrApiServer<::Hash> for Mmr +impl MmrApiServer<::Hash, BlockNumber> + for Mmr where Block: BlockT, Client: Send + Sync + 'static + ProvideRuntimeApi + HeaderBackend, - Client::Api: MmrRuntimeApi, + Client::Api: MmrRuntimeApi, MmrHash: Codec + Send + Sync + 'static, + BlockNumber: Codec, { fn generate_proof( &self, @@ -173,7 +175,7 @@ where fn generate_batch_proof( &self, - leaf_indices: Vec, + block_numbers: Vec, at: Option<::Hash>, ) -> RpcResult::Hash>> { let api = self.client.runtime_api(); @@ -181,6 +183,15 @@ where // If the block hash is not supplied assume the best block. self.client.info().best_hash); + let leaf_indices: Vec = block_numbers + .iter() + .map(|n| { + api.block_num_to_leaf_index(&BlockId::hash(block_hash), *n) + .map_err(runtime_error_into_rpc_error)? + .map_err(mmr_error_into_rpc_error) + }) + .collect::>(); + let (leaves, proof) = api .generate_batch_proof_with_context( &BlockId::hash(block_hash), diff --git a/frame/merkle-mountain-range/src/mmr/mmr.rs b/frame/merkle-mountain-range/src/mmr/mmr.rs index 44e684c1bdcac..7e415c89d6f5a 100644 --- a/frame/merkle-mountain-range/src/mmr/mmr.rs +++ b/frame/merkle-mountain-range/src/mmr/mmr.rs @@ -22,7 +22,7 @@ use crate::{ Hasher, Node, NodeOf, }, primitives::{self, Error, NodeIndex}, - Config, HashingOf, + Config, HashingOf, LeafIndex, Saturating, }; use sp_std::prelude::*; @@ -117,6 +117,21 @@ where .map_err(|e| Error::Verify.log_debug(e)) } + /// Convert `block_num` into a leaf index. + pub fn block_num_to_leaf_indx( + &self, + block_num: ::BlockNumber, + ) -> LeafIndex { + // leaf_indx = block_num - (current_block_num - leaves_count) - 1; + let leaves_count = self.leaves; + let current_block_num = >::block_number(); + let diff = current_block_num.saturating_sub((leaves_count as u32).into()); + + // TODO: Somehow convert BlockNumber into LeafIndex. + block_num.saturating_sub(diff).saturating_sub(1u32.into()); + 0 + } + /// Return the internal size of the MMR (number of nodes). #[cfg(test)] pub fn size(&self) -> NodeIndex { diff --git a/primitives/merkle-mountain-range/src/lib.rs b/primitives/merkle-mountain-range/src/lib.rs index 29a7e3d1a6fb6..ed2d1c64878b1 100644 --- a/primitives/merkle-mountain-range/src/lib.rs +++ b/primitives/merkle-mountain-range/src/lib.rs @@ -431,7 +431,7 @@ impl Error { sp_api::decl_runtime_apis! { /// API to interact with MMR pallet. - pub trait MmrApi { + pub trait MmrApi { /// Generate MMR proof for a leaf under given index. fn generate_proof(leaf_index: LeafIndex) -> Result<(EncodableOpaqueLeaf, Proof), Error>; @@ -474,6 +474,8 @@ sp_api::decl_runtime_apis! { /// same position in both the `leaves` vector and the `leaf_indices` vector contained in the [BatchProof] fn verify_batch_proof_stateless(root: Hash, leaves: Vec, proof: BatchProof) -> Result<(), Error>; + + fn block_num_to_leaf_index(block_num: BlockNumber) -> Result; } } From fe3f2f3428b3d4e12f6b54e108daef7c668a0f66 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 24 Sep 2022 22:17:53 +0200 Subject: [PATCH 02/55] fixes --- bin/node/runtime/src/lib.rs | 4 ++-- frame/merkle-mountain-range/rpc/src/lib.rs | 12 ++++++++++-- frame/merkle-mountain-range/src/lib.rs | 16 ++++++++++++++++ frame/merkle-mountain-range/src/mmr/mmr.rs | 17 +---------------- primitives/merkle-mountain-range/src/lib.rs | 3 ++- 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 63eb87c4dd675..2312abc2b6b29 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -2075,8 +2075,8 @@ impl_runtime_apis! { pallet_mmr::verify_leaves_proof::(root, nodes, proof) } - fn block_num_to_leaf_index(block_num: BlockNumber) -> mmr::LeafIndex { - pallet_mmr::block_num_to_leaf_index(block_num) + fn block_num_to_leaf_index(block_num: &BlockNumber) -> Result { + Ok(Mmr::block_num_to_leaf_index(*block_num)) } } diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index 815d7eae1839d..d6ecc8636c568 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -183,13 +183,21 @@ where // If the block hash is not supplied assume the best block. self.client.info().best_hash); - let leaf_indices: Vec = block_numbers + let res: Vec> = block_numbers .iter() .map(|n| { - api.block_num_to_leaf_index(&BlockId::hash(block_hash), *n) + api.block_num_to_leaf_index(&BlockId::hash(block_hash), n) .map_err(runtime_error_into_rpc_error)? .map_err(mmr_error_into_rpc_error) }) + .collect(); + + let leaf_indices = res + .iter() + .map(|indx| match indx { + Ok(i) => *i, + Err(_) => LeafIndex::default(), + }) .collect::>(); let (leaves, proof) = api diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 9f989847af0f9..b879c3b1380a9 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -365,4 +365,20 @@ impl, I: 'static> Pallet { Err(primitives::Error::Verify.log_debug("The proof is incorrect.")) } } + + /// Convert `block_num` into a leaf index. + pub fn block_num_to_leaf_index(block_num: ::BlockNumber) -> LeafIndex + where + T: frame_system::Config, + T: pallet::Config, + { + // leaf_indx = block_num - (current_block_num - leaves_count) - 1; + let leaves_count = Pallet::::mmr_leaves(); + let current_block_num = >::block_number(); + let diff = current_block_num.saturating_sub((leaves_count as u32).into()); + + // TODO: Somehow convert BlockNumber into LeafIndex. + block_num.saturating_sub(diff).saturating_sub(1u32.into()); + 0 + } } diff --git a/frame/merkle-mountain-range/src/mmr/mmr.rs b/frame/merkle-mountain-range/src/mmr/mmr.rs index 7e415c89d6f5a..44e684c1bdcac 100644 --- a/frame/merkle-mountain-range/src/mmr/mmr.rs +++ b/frame/merkle-mountain-range/src/mmr/mmr.rs @@ -22,7 +22,7 @@ use crate::{ Hasher, Node, NodeOf, }, primitives::{self, Error, NodeIndex}, - Config, HashingOf, LeafIndex, Saturating, + Config, HashingOf, }; use sp_std::prelude::*; @@ -117,21 +117,6 @@ where .map_err(|e| Error::Verify.log_debug(e)) } - /// Convert `block_num` into a leaf index. - pub fn block_num_to_leaf_indx( - &self, - block_num: ::BlockNumber, - ) -> LeafIndex { - // leaf_indx = block_num - (current_block_num - leaves_count) - 1; - let leaves_count = self.leaves; - let current_block_num = >::block_number(); - let diff = current_block_num.saturating_sub((leaves_count as u32).into()); - - // TODO: Somehow convert BlockNumber into LeafIndex. - block_num.saturating_sub(diff).saturating_sub(1u32.into()); - 0 - } - /// Return the internal size of the MMR (number of nodes). #[cfg(test)] pub fn size(&self) -> NodeIndex { diff --git a/primitives/merkle-mountain-range/src/lib.rs b/primitives/merkle-mountain-range/src/lib.rs index ed2d1c64878b1..54a1df6749a3e 100644 --- a/primitives/merkle-mountain-range/src/lib.rs +++ b/primitives/merkle-mountain-range/src/lib.rs @@ -475,7 +475,8 @@ sp_api::decl_runtime_apis! { fn verify_batch_proof_stateless(root: Hash, leaves: Vec, proof: BatchProof) -> Result<(), Error>; - fn block_num_to_leaf_index(block_num: BlockNumber) -> Result; + /// Converts `block_num` into a leaf index. + fn block_num_to_leaf_index(block_num: &BlockNumber) -> Result; } } From f01b68bcaac019e2d9decee04e1838e10e79c6cb Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sun, 25 Sep 2022 08:16:49 +0200 Subject: [PATCH 03/55] update rpc --- frame/merkle-mountain-range/rpc/src/lib.rs | 32 ++++++++++------------ 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index d6ecc8636c568..26dfde71be978 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -33,7 +33,7 @@ use serde::{Deserialize, Serialize}; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_core::Bytes; -use sp_mmr_primitives::{BatchProof, Error as MmrError, LeafIndex, Proof}; +use sp_mmr_primitives::{BatchProof, Error as MmrError, Proof}; use sp_runtime::{generic::BlockId, traits::Block as BlockT}; pub use sp_mmr_primitives::MmrApi as MmrRuntimeApi; @@ -108,7 +108,7 @@ pub trait MmrApi { #[method(name = "mmr_generateProof")] fn generate_proof( &self, - leaf_index: LeafIndex, + block_number: BlockNumber, at: Option, ) -> RpcResult>; @@ -155,12 +155,16 @@ where { fn generate_proof( &self, - leaf_index: LeafIndex, + block_number: BlockNumber, at: Option<::Hash>, ) -> RpcResult> { let api = self.client.runtime_api(); let block_hash = at.unwrap_or_else(|| self.client.info().best_hash); + let leaf_index = api.block_num_to_leaf_index(&BlockId::hash(block_hash), &block_number) + .map_err(runtime_error_into_rpc_error)? + .map_err(mmr_error_into_rpc_error)?; + let (leaf, proof) = api .generate_proof_with_context( &BlockId::hash(block_hash), @@ -183,22 +187,16 @@ where // If the block hash is not supplied assume the best block. self.client.info().best_hash); - let res: Vec> = block_numbers + let mut leaf_indices = vec![]; + let _ = block_numbers .iter() - .map(|n| { - api.block_num_to_leaf_index(&BlockId::hash(block_hash), n) + .map(|n| -> Result { + let leaf_index = api.block_num_to_leaf_index(&BlockId::hash(block_hash), &n) .map_err(runtime_error_into_rpc_error)? - .map_err(mmr_error_into_rpc_error) - }) - .collect(); - - let leaf_indices = res - .iter() - .map(|indx| match indx { - Ok(i) => *i, - Err(_) => LeafIndex::default(), - }) - .collect::>(); + .map_err(mmr_error_into_rpc_error)?; + leaf_indices.push(leaf_index.clone()); + Ok(leaf_index) + }).collect::>>(); let (leaves, proof) = api .generate_batch_proof_with_context( From 1b572ad813d200326ca26ebace7f0fd015e0f0a1 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sun, 25 Sep 2022 08:17:37 +0200 Subject: [PATCH 04/55] fmt --- frame/merkle-mountain-range/rpc/src/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index 26dfde71be978..e8e70e8df1871 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -161,7 +161,8 @@ where let api = self.client.runtime_api(); let block_hash = at.unwrap_or_else(|| self.client.info().best_hash); - let leaf_index = api.block_num_to_leaf_index(&BlockId::hash(block_hash), &block_number) + let leaf_index = api + .block_num_to_leaf_index(&BlockId::hash(block_hash), &block_number) .map_err(runtime_error_into_rpc_error)? .map_err(mmr_error_into_rpc_error)?; @@ -191,12 +192,14 @@ where let _ = block_numbers .iter() .map(|n| -> Result { - let leaf_index = api.block_num_to_leaf_index(&BlockId::hash(block_hash), &n) + let leaf_index = api + .block_num_to_leaf_index(&BlockId::hash(block_hash), &n) .map_err(runtime_error_into_rpc_error)? .map_err(mmr_error_into_rpc_error)?; leaf_indices.push(leaf_index.clone()); Ok(leaf_index) - }).collect::>>(); + }) + .collect::>>(); let (leaves, proof) = api .generate_batch_proof_with_context( From 2a760ba2e3807941bf8f9dbadd965429b0624050 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sun, 25 Sep 2022 08:28:55 +0200 Subject: [PATCH 05/55] final touches in the rpc --- frame/merkle-mountain-range/rpc/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index e8e70e8df1871..36494933dcea8 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -188,18 +188,16 @@ where // If the block hash is not supplied assume the best block. self.client.info().best_hash); - let mut leaf_indices = vec![]; - let _ = block_numbers + let leaf_indices = block_numbers .iter() .map(|n| -> Result { let leaf_index = api .block_num_to_leaf_index(&BlockId::hash(block_hash), &n) .map_err(runtime_error_into_rpc_error)? .map_err(mmr_error_into_rpc_error)?; - leaf_indices.push(leaf_index.clone()); Ok(leaf_index) }) - .collect::>>(); + .collect::, _>>()?; let (leaves, proof) = api .generate_batch_proof_with_context( From d7e50cabea376dbd64178c76f4185b96ff7a5486 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sun, 25 Sep 2022 09:43:26 +0200 Subject: [PATCH 06/55] temporary fix --- client/beefy/src/lib.rs | 4 ++-- client/beefy/src/tests.rs | 4 ++-- client/beefy/src/worker.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/beefy/src/lib.rs b/client/beefy/src/lib.rs index 41eeec43d64bd..9bab641ecc95c 100644 --- a/client/beefy/src/lib.rs +++ b/client/beefy/src/lib.rs @@ -187,7 +187,7 @@ where BE: Backend, C: Client, R: ProvideRuntimeApi, - R::Api: BeefyApi + MmrApi, + R::Api: BeefyApi + MmrApi, N: GossipNetwork + Clone + SyncOracle + Send + Sync + 'static, { /// BEEFY client @@ -219,7 +219,7 @@ where BE: Backend, C: Client, R: ProvideRuntimeApi, - R::Api: BeefyApi + MmrApi, + R::Api: BeefyApi + MmrApi, N: GossipNetwork + Clone + SyncOracle + Send + Sync + 'static, { let BeefyParams { diff --git a/client/beefy/src/tests.rs b/client/beefy/src/tests.rs index 26c85592ecb85..2d23ac1c33b6a 100644 --- a/client/beefy/src/tests.rs +++ b/client/beefy/src/tests.rs @@ -250,7 +250,7 @@ macro_rules! create_test_api { } } - impl MmrApi for RuntimeApi { + impl MmrApi for RuntimeApi { fn generate_proof(_leaf_index: LeafIndex) -> Result<(EncodableOpaqueLeaf, Proof), MmrError> { unimplemented!() @@ -345,7 +345,7 @@ fn initialize_beefy( ) -> impl Future where API: ProvideRuntimeApi + Default + Sync + Send, - API::Api: BeefyApi + MmrApi, + API::Api: BeefyApi + MmrApi, { let voters = FuturesUnordered::new(); diff --git a/client/beefy/src/worker.rs b/client/beefy/src/worker.rs index 6e8c89d804984..05b4d0dfbc5b3 100644 --- a/client/beefy/src/worker.rs +++ b/client/beefy/src/worker.rs @@ -224,7 +224,7 @@ where BE: Backend, C: Client, R: ProvideRuntimeApi, - R::Api: BeefyApi + MmrApi, + R::Api: BeefyApi + MmrApi, SO: SyncOracle + Send + Sync + Clone + 'static, { /// Return a new BEEFY worker instance. From e37e32a5214ffcf349e51db7a3befb40638fff21 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sun, 25 Sep 2022 09:46:11 +0200 Subject: [PATCH 07/55] fix --- bin/node/rpc/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/rpc/src/lib.rs b/bin/node/rpc/src/lib.rs index 0e6b04087fa63..a42fbb409da46 100644 --- a/bin/node/rpc/src/lib.rs +++ b/bin/node/rpc/src/lib.rs @@ -109,7 +109,7 @@ where + 'static, C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: pallet_contracts_rpc::ContractsRuntimeApi, - C::Api: pallet_mmr_rpc::MmrRuntimeApi::Hash>, + C::Api: pallet_mmr_rpc::MmrRuntimeApi::Hash, BlockNumber>, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, C::Api: BabeApi, C::Api: BlockBuilder, From 02b0cfac0c2cf5a7676044dc7727746b7b1b9f8f Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sun, 25 Sep 2022 09:48:40 +0200 Subject: [PATCH 08/55] fmt --- bin/node/rpc/src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/node/rpc/src/lib.rs b/bin/node/rpc/src/lib.rs index a42fbb409da46..05071b3cae007 100644 --- a/bin/node/rpc/src/lib.rs +++ b/bin/node/rpc/src/lib.rs @@ -109,7 +109,11 @@ where + 'static, C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: pallet_contracts_rpc::ContractsRuntimeApi, - C::Api: pallet_mmr_rpc::MmrRuntimeApi::Hash, BlockNumber>, + C::Api: pallet_mmr_rpc::MmrRuntimeApi< + Block, + ::Hash, + BlockNumber, + >, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, C::Api: BabeApi, C::Api: BlockBuilder, From f39fc8d7268ee45330222dab1490db7a478ddf0a Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sun, 25 Sep 2022 10:01:35 +0200 Subject: [PATCH 09/55] docs --- frame/merkle-mountain-range/rpc/src/lib.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index 36494933dcea8..8a1ed5dbbd16a 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -97,10 +97,10 @@ impl LeafBatchProof { /// MMR RPC methods. #[rpc(client, server)] pub trait MmrApi { - /// Generate MMR proof for given leaf index. + /// Generate MMR proof for given block number. /// /// This method calls into a runtime with MMR pallet included and attempts to generate - /// MMR proof for leaf at given `leaf_index`. + /// MMR proof for leaf at given leaf index that was calculated from the `block_number`. /// Optionally, a block hash at which the runtime should be queried can be specified. /// /// Returns the (full) leaf itself and a proof for this leaf (compact encoding, i.e. hash of @@ -112,11 +112,12 @@ pub trait MmrApi { at: Option, ) -> RpcResult>; - /// Generate MMR proof for the given leaf indices. + /// Generate MMR proof for the given block numbers. /// /// This method calls into a runtime with MMR pallet included and attempts to generate - /// MMR proof for a set of leaves at the given `leaf_indices`. - /// Optionally, a block hash at which the runtime should be queried can be specified. + /// MMR proof for a set of leaves at the given leaf indices that were calculated from the + /// `block_numbers`. Optionally, a block hash at which the runtime should be queried can be + /// specified. /// /// Returns the leaves and a proof for these leaves (compact encoding, i.e. hash of /// the leaves). Both parameters are SCALE-encoded. From fa8155d59d5ef24d5fa4f36f081ae966cabb3dca Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Sun, 25 Sep 2022 10:02:46 +0200 Subject: [PATCH 10/55] Update lib.rs --- frame/merkle-mountain-range/rpc/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index 8a1ed5dbbd16a..94107662d97df 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -115,7 +115,7 @@ pub trait MmrApi { /// Generate MMR proof for the given block numbers. /// /// This method calls into a runtime with MMR pallet included and attempts to generate - /// MMR proof for a set of leaves at the given leaf indices that were calculated from the + /// MMR proof for a set of leaves at the given leaf indices that are calculated from the /// `block_numbers`. Optionally, a block hash at which the runtime should be queried can be /// specified. /// From 32bb71394f48db999a102218bfbe9999788a7f78 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 26 Sep 2022 16:31:25 +0200 Subject: [PATCH 11/55] use NumberFor --- client/beefy/src/lib.rs | 6 +++--- client/beefy/src/worker.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/beefy/src/lib.rs b/client/beefy/src/lib.rs index 9bab641ecc95c..0d28db24f20ca 100644 --- a/client/beefy/src/lib.rs +++ b/client/beefy/src/lib.rs @@ -22,7 +22,7 @@ use sc_client_api::{Backend, BlockchainEvents, Finalizer}; use sc_consensus::BlockImport; use sc_network::ProtocolName; use sc_network_gossip::Network as GossipNetwork; -use sp_api::ProvideRuntimeApi; +use sp_api::{ProvideRuntimeApi, NumberFor}; use sp_blockchain::HeaderBackend; use sp_consensus::{Error as ConsensusError, SyncOracle}; use sp_keystore::SyncCryptoStorePtr; @@ -187,7 +187,7 @@ where BE: Backend, C: Client, R: ProvideRuntimeApi, - R::Api: BeefyApi + MmrApi, + R::Api: BeefyApi + MmrApi>, N: GossipNetwork + Clone + SyncOracle + Send + Sync + 'static, { /// BEEFY client @@ -219,7 +219,7 @@ where BE: Backend, C: Client, R: ProvideRuntimeApi, - R::Api: BeefyApi + MmrApi, + R::Api: BeefyApi + MmrApi>, N: GossipNetwork + Clone + SyncOracle + Send + Sync + 'static, { let BeefyParams { diff --git a/client/beefy/src/worker.rs b/client/beefy/src/worker.rs index 05b4d0dfbc5b3..b5cf4a4f0c1ae 100644 --- a/client/beefy/src/worker.rs +++ b/client/beefy/src/worker.rs @@ -224,7 +224,7 @@ where BE: Backend, C: Client, R: ProvideRuntimeApi, - R::Api: BeefyApi + MmrApi, + R::Api: BeefyApi + MmrApi>, SO: SyncOracle + Send + Sync + Clone + 'static, { /// Return a new BEEFY worker instance. From ae03943902b03e636a241aaf69f51e1f6002d7ca Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 26 Sep 2022 16:46:34 +0200 Subject: [PATCH 12/55] validate input --- client/beefy/src/lib.rs | 2 +- client/beefy/src/tests.rs | 4 ++-- frame/merkle-mountain-range/src/lib.rs | 12 ++++++++++-- primitives/merkle-mountain-range/src/lib.rs | 2 ++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/client/beefy/src/lib.rs b/client/beefy/src/lib.rs index 0d28db24f20ca..b23e166b84a5a 100644 --- a/client/beefy/src/lib.rs +++ b/client/beefy/src/lib.rs @@ -22,7 +22,7 @@ use sc_client_api::{Backend, BlockchainEvents, Finalizer}; use sc_consensus::BlockImport; use sc_network::ProtocolName; use sc_network_gossip::Network as GossipNetwork; -use sp_api::{ProvideRuntimeApi, NumberFor}; +use sp_api::{NumberFor, ProvideRuntimeApi}; use sp_blockchain::HeaderBackend; use sp_consensus::{Error as ConsensusError, SyncOracle}; use sp_keystore::SyncCryptoStorePtr; diff --git a/client/beefy/src/tests.rs b/client/beefy/src/tests.rs index 2d23ac1c33b6a..d3fc428b99dbc 100644 --- a/client/beefy/src/tests.rs +++ b/client/beefy/src/tests.rs @@ -250,7 +250,7 @@ macro_rules! create_test_api { } } - impl MmrApi for RuntimeApi { + impl MmrApi> for RuntimeApi { fn generate_proof(_leaf_index: LeafIndex) -> Result<(EncodableOpaqueLeaf, Proof), MmrError> { unimplemented!() @@ -345,7 +345,7 @@ fn initialize_beefy( ) -> impl Future where API: ProvideRuntimeApi + Default + Sync + Send, - API::Api: BeefyApi + MmrApi, + API::Api: BeefyApi + MmrApi>, { let voters = FuturesUnordered::new(); diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index b879c3b1380a9..b7b29f62090de 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -367,7 +367,9 @@ impl, I: 'static> Pallet { } /// Convert `block_num` into a leaf index. - pub fn block_num_to_leaf_index(block_num: ::BlockNumber) -> LeafIndex + pub fn block_num_to_leaf_index( + block_num: ::BlockNumber, + ) -> Result where T: frame_system::Config, T: pallet::Config, @@ -377,8 +379,14 @@ impl, I: 'static> Pallet { let current_block_num = >::block_number(); let diff = current_block_num.saturating_sub((leaves_count as u32).into()); + if block_num < diff { + return Err( + primitives::Error::BlockNumToLeafIndex.log_debug("The block_number is incorrect.") + ) + } + // TODO: Somehow convert BlockNumber into LeafIndex. block_num.saturating_sub(diff).saturating_sub(1u32.into()); - 0 + Ok(0) } } diff --git a/primitives/merkle-mountain-range/src/lib.rs b/primitives/merkle-mountain-range/src/lib.rs index 54a1df6749a3e..b0a0dc917eab9 100644 --- a/primitives/merkle-mountain-range/src/lib.rs +++ b/primitives/merkle-mountain-range/src/lib.rs @@ -396,6 +396,8 @@ pub enum Error { GenerateProof, /// Proof verification error. Verify, + /// Error while converting a block number to leaf index. + BlockNumToLeafIndex, /// Leaf not found in the storage. LeafNotFound, /// Mmr Pallet not included in runtime From 8dc459eaf4644ebe19d52e86c3c1d11198550ae8 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 26 Sep 2022 17:19:38 +0200 Subject: [PATCH 13/55] update runtime --- bin/node/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 2312abc2b6b29..544ded218b30c 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -2076,7 +2076,7 @@ impl_runtime_apis! { } fn block_num_to_leaf_index(block_num: &BlockNumber) -> Result { - Ok(Mmr::block_num_to_leaf_index(*block_num)) + Mmr::block_num_to_leaf_index(*block_num) } } From 78d2ea18f93193e93b1939cd950959d5aa1de31f Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 26 Sep 2022 17:38:45 +0200 Subject: [PATCH 14/55] convert block_number to u64 --- frame/merkle-mountain-range/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index b7b29f62090de..dd885cb314b37 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -385,8 +385,8 @@ impl, I: 'static> Pallet { ) } - // TODO: Somehow convert BlockNumber into LeafIndex. - block_num.saturating_sub(diff).saturating_sub(1u32.into()); - Ok(0) + let leaf_index = + (block_num.saturating_sub(diff).saturating_sub(1u32.into())).saturated_into::(); + Ok(leaf_index) } } From 9a3bfe95cdcafdcfae5f2d7f1731271d6d395cc2 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 26 Sep 2022 17:40:42 +0200 Subject: [PATCH 15/55] small edit --- frame/merkle-mountain-range/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index dd885cb314b37..774004b5f5c27 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -385,8 +385,8 @@ impl, I: 'static> Pallet { ) } - let leaf_index = - (block_num.saturating_sub(diff).saturating_sub(1u32.into())).saturated_into::(); + let leaf_index = (block_num.saturating_sub(diff).saturating_sub(1u32.into())) + .saturated_into::(); Ok(leaf_index) } } From 3c8c396506d822fd42929bcc5384524cf4b3e3c6 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Wed, 28 Sep 2022 16:22:05 +0200 Subject: [PATCH 16/55] update runtime api --- bin/node/runtime/src/lib.rs | 8 ++++---- frame/merkle-mountain-range/rpc/src/lib.rs | 22 +++------------------ frame/merkle-mountain-range/src/lib.rs | 13 +++++++++--- primitives/merkle-mountain-range/src/lib.rs | 8 ++++---- 4 files changed, 21 insertions(+), 30 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 544ded218b30c..073f0d7c92388 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -2015,10 +2015,10 @@ impl_runtime_apis! { mmr::Hash, BlockNumber, > for Runtime { - fn generate_proof(leaf_index: pallet_mmr::primitives::LeafIndex) + fn generate_proof(block_number: BlockNumber) -> Result<(mmr::EncodableOpaqueLeaf, mmr::Proof), mmr::Error> { - Mmr::generate_batch_proof(vec![leaf_index]).and_then(|(leaves, proof)| + Mmr::generate_batch_proof(vec![block_number.into()]).and_then(|(leaves, proof)| Ok(( mmr::EncodableOpaqueLeaf::from_leaf(&leaves[0]), mmr::BatchProof::into_single_leaf_proof(proof)? @@ -2049,10 +2049,10 @@ impl_runtime_apis! { Ok(Mmr::mmr_root()) } - fn generate_batch_proof(leaf_indices: Vec) + fn generate_batch_proof(block_numbers: Vec) -> Result<(Vec, mmr::BatchProof), mmr::Error> { - Mmr::generate_batch_proof(leaf_indices) + Mmr::generate_batch_proof(block_numbers.iter().map(|n| -> u64 {(*n).into()}).collect()) .map(|(leaves, proof)| (leaves.into_iter().map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf)).collect(), proof)) } diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index 94107662d97df..b0a7147a72ba4 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -126,7 +126,7 @@ pub trait MmrApi { #[method(name = "mmr_generateBatchProof")] fn generate_batch_proof( &self, - leaf_indices: Vec, + block_numbers: Vec, at: Option, ) -> RpcResult>; } @@ -162,16 +162,11 @@ where let api = self.client.runtime_api(); let block_hash = at.unwrap_or_else(|| self.client.info().best_hash); - let leaf_index = api - .block_num_to_leaf_index(&BlockId::hash(block_hash), &block_number) - .map_err(runtime_error_into_rpc_error)? - .map_err(mmr_error_into_rpc_error)?; - let (leaf, proof) = api .generate_proof_with_context( &BlockId::hash(block_hash), sp_core::ExecutionContext::OffchainCall(None), - leaf_index, + block_number, ) .map_err(runtime_error_into_rpc_error)? .map_err(mmr_error_into_rpc_error)?; @@ -189,22 +184,11 @@ where // If the block hash is not supplied assume the best block. self.client.info().best_hash); - let leaf_indices = block_numbers - .iter() - .map(|n| -> Result { - let leaf_index = api - .block_num_to_leaf_index(&BlockId::hash(block_hash), &n) - .map_err(runtime_error_into_rpc_error)? - .map_err(mmr_error_into_rpc_error)?; - Ok(leaf_index) - }) - .collect::, _>>()?; - let (leaves, proof) = api .generate_batch_proof_with_context( &BlockId::hash(block_hash), sp_core::ExecutionContext::OffchainCall(None), - leaf_indices, + block_numbers, ) .map_err(runtime_error_into_rpc_error)? .map_err(mmr_error_into_rpc_error)?; diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 774004b5f5c27..5216d9e505bc3 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -325,11 +325,19 @@ impl, I: 'static> Pallet { /// all the leaves to be present. /// It may return an error or panic if used incorrectly. pub fn generate_batch_proof( - leaf_indices: Vec, + block_numbers: Vec, ) -> Result< (Vec>, primitives::BatchProof<>::Hash>), primitives::Error, > { + let leaf_indices = block_numbers + .iter() + .map(|n| -> Result { + let leaf_index = Self::block_num_to_leaf_index(*n)?; + Ok(leaf_index) + }) + .collect::, _>>()?; + let mmr: ModuleMmr = mmr::Mmr::new(Self::mmr_leaves()); mmr.generate_batch_proof(leaf_indices) } @@ -372,10 +380,9 @@ impl, I: 'static> Pallet { ) -> Result where T: frame_system::Config, - T: pallet::Config, { // leaf_indx = block_num - (current_block_num - leaves_count) - 1; - let leaves_count = Pallet::::mmr_leaves(); + let leaves_count = Self::mmr_leaves(); let current_block_num = >::block_number(); let diff = current_block_num.saturating_sub((leaves_count as u32).into()); diff --git a/primitives/merkle-mountain-range/src/lib.rs b/primitives/merkle-mountain-range/src/lib.rs index b0a0dc917eab9..18185fc8c46ee 100644 --- a/primitives/merkle-mountain-range/src/lib.rs +++ b/primitives/merkle-mountain-range/src/lib.rs @@ -434,8 +434,8 @@ impl Error { sp_api::decl_runtime_apis! { /// API to interact with MMR pallet. pub trait MmrApi { - /// Generate MMR proof for a leaf under given index. - fn generate_proof(leaf_index: LeafIndex) -> Result<(EncodableOpaqueLeaf, Proof), Error>; + /// Generate MMR proof for a block with a specified `block_number`. + fn generate_proof(block_number: BlockNumber) -> Result<(EncodableOpaqueLeaf, Proof), Error>; /// Verify MMR proof against on-chain MMR. /// @@ -456,8 +456,8 @@ sp_api::decl_runtime_apis! { /// Return the on-chain MMR root hash. fn mmr_root() -> Result; - /// Generate MMR proof for a series of leaves under given indices. - fn generate_batch_proof(leaf_indices: Vec) -> Result<(Vec, BatchProof), Error>; + /// Generate MMR proof for a series of blocks with the specified block numbers. + fn generate_batch_proof(block_numbers: Vec) -> Result<(Vec, BatchProof), Error>; /// Verify MMR proof against on-chain MMR for a batch of leaves. /// From 850c78240c4bc40598719141e1a9c64afacf1b67 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Wed, 28 Sep 2022 17:02:19 +0200 Subject: [PATCH 17/55] test fix --- frame/merkle-mountain-range/src/lib.rs | 2 +- frame/merkle-mountain-range/src/tests.rs | 51 ++++++++++++++++-------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 5216d9e505bc3..6525f4b929709 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -337,7 +337,7 @@ impl, I: 'static> Pallet { Ok(leaf_index) }) .collect::, _>>()?; - + let mmr: ModuleMmr = mmr::Mmr::new(Self::mmr_leaves()); mmr.generate_batch_proof(leaf_indices) } diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index d6886f90a5da7..b51a050bd1da6 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -83,6 +83,18 @@ fn add_blocks(blocks: usize) { } } +fn leaf_indices_to_block_numbers(leaf_indices: &Vec) -> Vec { + leaf_indices + .iter() + .map(|l| { + if *l == 0 { + return 0 + } + *l + 1 + }) + .collect() +} + #[test] fn should_start_empty() { let _ = env_logger::try_init(); @@ -234,12 +246,11 @@ fn should_generate_proofs_correctly() { // to retrieve full leaf data. register_offchain_ext(&mut ext); ext.execute_with(|| { - // when generate proofs for all leaves - let proofs = (0_u64..crate::NumberOfLeaves::::get()) + // when generate proofs for all the blocks. + let now = frame_system::Pallet::::block_number(); + let proofs = (0_u64..now) .into_iter() - .map(|leaf_index| { - crate::Pallet::::generate_batch_proof(vec![leaf_index]).unwrap() - }) + .map(|block_num| crate::Pallet::::generate_batch_proof(vec![block_num]).unwrap()) .collect::>(); // then @@ -259,8 +270,9 @@ fn should_generate_proofs_correctly() { ) ); assert_eq!( - proofs[4], + proofs[5], ( + // the leaf index is equivalent to the block number(in this case 5) - 1 vec![Compact::new(((4, H256::repeat_byte(5)).into(), LeafData::new(5).into(),))], BatchProof { leaf_indices: vec![4], @@ -276,13 +288,14 @@ fn should_generate_proofs_correctly() { assert_eq!( proofs[6], ( - vec![Compact::new(((6, H256::repeat_byte(7)).into(), LeafData::new(7).into(),))], + vec![Compact::new(((5, H256::repeat_byte(6)).into(), LeafData::new(6).into(),))], BatchProof { - leaf_indices: vec![6], + leaf_indices: vec![5], leaf_count: 7, items: vec![ hex("ae88a0825da50e953e7a359c55fe13c8015e48d03d301b8bdfc9193874da9252"), - hex("7e4316ae2ebf7c3b6821cb3a46ca8b7a4f9351a9b40fcf014bb0a4fd8e8f29da"), + hex("3b031d22e24f1126c8f7d2f394b663f9b960ed7abbedb7152e17ce16112656d0"), + hex("611c2174c6164952a66d985cfe1ec1a623794393e3acff96b136d198f37a648c"), ], } ) @@ -303,12 +316,13 @@ fn should_generate_batch_proof_correctly() { register_offchain_ext(&mut ext); ext.execute_with(|| { // when generate proofs for all leaves - let (.., proof) = crate::Pallet::::generate_batch_proof(vec![0, 4, 5]).unwrap(); + let (.., proof) = crate::Pallet::::generate_batch_proof(vec![0, 5, 6]).unwrap(); // then assert_eq!( proof, BatchProof { + // the leaf indices are equivalent to the above specified block numbers - 1. leaf_indices: vec![0, 4, 5], leaf_count: 7, items: vec![ @@ -350,11 +364,12 @@ fn should_verify() { fn should_verify_batch_proofs() { fn generate_and_verify_batch_proof( ext: &mut sp_io::TestExternalities, - leaves: &Vec, + block_numbers: &Vec, blocks_to_add: usize, ) { - let (leaves, proof) = ext - .execute_with(|| crate::Pallet::::generate_batch_proof(leaves.to_vec()).unwrap()); + let (leaves, proof) = ext.execute_with(|| { + crate::Pallet::::generate_batch_proof(block_numbers.to_vec()).unwrap() + }); ext.execute_with(|| { add_blocks(blocks_to_add); @@ -381,7 +396,8 @@ fn should_verify_batch_proofs() { let leaves_set: Vec> = (0..n).into_iter().powerset().skip(1).collect(); leaves_set.iter().for_each(|leaves_subset| { - generate_and_verify_batch_proof(&mut ext, leaves_subset, 0); + let block_numbers = leaf_indices_to_block_numbers(leaves_subset); + generate_and_verify_batch_proof(&mut ext, &block_numbers, 0); ext.persist_offchain_overlay(); }); } @@ -396,15 +412,16 @@ fn should_verify_batch_proofs() { let leaves_set: Vec> = (0..n).into_iter().combinations(2).collect(); leaves_set.iter().for_each(|leaves_subset| { - generate_and_verify_batch_proof(&mut ext, leaves_subset, 0); + let block_numbers = leaf_indices_to_block_numbers(leaves_subset); + generate_and_verify_batch_proof(&mut ext, &block_numbers, 0); ext.persist_offchain_overlay(); }); } - generate_and_verify_batch_proof(&mut ext, &vec![7, 11], 20); + generate_and_verify_batch_proof(&mut ext, &vec![8, 12], 20); ext.execute_with(|| add_blocks(1000)); ext.persist_offchain_overlay(); - generate_and_verify_batch_proof(&mut ext, &vec![7, 11, 100, 800], 100); + generate_and_verify_batch_proof(&mut ext, &vec![8, 12, 100, 800], 100); } #[test] From 098c88b332611e405894ba57a4208f43a82bfa10 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Wed, 28 Sep 2022 17:07:08 +0200 Subject: [PATCH 18/55] runtime fix --- bin/node/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 073f0d7c92388..01c65f7528ea4 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -2052,7 +2052,7 @@ impl_runtime_apis! { fn generate_batch_proof(block_numbers: Vec) -> Result<(Vec, mmr::BatchProof), mmr::Error> { - Mmr::generate_batch_proof(block_numbers.iter().map(|n| -> u64 {(*n).into()}).collect()) + Mmr::generate_batch_proof(block_numbers) .map(|(leaves, proof)| (leaves.into_iter().map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf)).collect(), proof)) } From 5e2eb39ba2bc0a7a1cb7ef54bbc06f081f659cc7 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Wed, 28 Sep 2022 17:11:27 +0200 Subject: [PATCH 19/55] update test function --- frame/merkle-mountain-range/src/tests.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index b51a050bd1da6..b76ca804c088f 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -86,12 +86,7 @@ fn add_blocks(blocks: usize) { fn leaf_indices_to_block_numbers(leaf_indices: &Vec) -> Vec { leaf_indices .iter() - .map(|l| { - if *l == 0 { - return 0 - } - *l + 1 - }) + .map(|l| *l + 1) .collect() } From 3bd4b725d9e77f6df7c78b3112c6fa53a66a5123 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Wed, 28 Sep 2022 17:13:20 +0200 Subject: [PATCH 20/55] fmt --- frame/merkle-mountain-range/src/tests.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index b76ca804c088f..afb3bd64d157b 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -84,10 +84,7 @@ fn add_blocks(blocks: usize) { } fn leaf_indices_to_block_numbers(leaf_indices: &Vec) -> Vec { - leaf_indices - .iter() - .map(|l| *l + 1) - .collect() + leaf_indices.iter().map(|l| *l + 1).collect() } #[test] From 6295c514612c8c552864794be4061acb192726e1 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Wed, 28 Sep 2022 17:25:32 +0200 Subject: [PATCH 21/55] fix nits --- bin/node/runtime/src/lib.rs | 2 +- frame/merkle-mountain-range/rpc/src/lib.rs | 7 +++---- frame/merkle-mountain-range/src/lib.rs | 5 +++-- frame/merkle-mountain-range/src/tests.rs | 4 ++-- primitives/merkle-mountain-range/src/lib.rs | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 01c65f7528ea4..fc670926cb8c1 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -2018,7 +2018,7 @@ impl_runtime_apis! { fn generate_proof(block_number: BlockNumber) -> Result<(mmr::EncodableOpaqueLeaf, mmr::Proof), mmr::Error> { - Mmr::generate_batch_proof(vec![block_number.into()]).and_then(|(leaves, proof)| + Mmr::generate_batch_proof(vec![block_number]).and_then(|(leaves, proof)| Ok(( mmr::EncodableOpaqueLeaf::from_leaf(&leaves[0]), mmr::BatchProof::into_single_leaf_proof(proof)? diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index b0a7147a72ba4..1b786adfc0615 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -100,7 +100,7 @@ pub trait MmrApi { /// Generate MMR proof for given block number. /// /// This method calls into a runtime with MMR pallet included and attempts to generate - /// MMR proof for leaf at given leaf index that was calculated from the `block_number`. + /// MMR proof for a block with a specified `block_number`. /// Optionally, a block hash at which the runtime should be queried can be specified. /// /// Returns the (full) leaf itself and a proof for this leaf (compact encoding, i.e. hash of @@ -115,9 +115,8 @@ pub trait MmrApi { /// Generate MMR proof for the given block numbers. /// /// This method calls into a runtime with MMR pallet included and attempts to generate - /// MMR proof for a set of leaves at the given leaf indices that are calculated from the - /// `block_numbers`. Optionally, a block hash at which the runtime should be queried can be - /// specified. + /// MMR proof for a set of blocks with the specific `block_numbers`. + /// Optionally, a block hash at which the runtime should be queried can be specified. /// /// Returns the leaves and a proof for these leaves (compact encoding, i.e. hash of /// the leaves). Both parameters are SCALE-encoded. diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 6525f4b929709..276934b931b3b 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -318,7 +318,7 @@ impl, I: 'static> Pallet { .saturating_add(leaf_index.saturated_into()) } - /// Generate a MMR proof for the given `leaf_indices`. + /// Generate a MMR proof for the given `block_numbers`. /// /// Note this method can only be used from an off-chain context /// (Offchain Worker or Runtime API call), since it requires @@ -330,6 +330,7 @@ impl, I: 'static> Pallet { (Vec>, primitives::BatchProof<>::Hash>), primitives::Error, > { + // we need to translate the block_numbers into leaf indices. let leaf_indices = block_numbers .iter() .map(|n| -> Result { @@ -374,7 +375,7 @@ impl, I: 'static> Pallet { } } - /// Convert `block_num` into a leaf index. + /// Convert a `block_num` into a leaf index. pub fn block_num_to_leaf_index( block_num: ::BlockNumber, ) -> Result diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index afb3bd64d157b..5d0d827feefcc 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -238,8 +238,8 @@ fn should_generate_proofs_correctly() { // to retrieve full leaf data. register_offchain_ext(&mut ext); ext.execute_with(|| { - // when generate proofs for all the blocks. let now = frame_system::Pallet::::block_number(); + // when generate proofs for all leaves. let proofs = (0_u64..now) .into_iter() .map(|block_num| crate::Pallet::::generate_batch_proof(vec![block_num]).unwrap()) @@ -264,7 +264,7 @@ fn should_generate_proofs_correctly() { assert_eq!( proofs[5], ( - // the leaf index is equivalent to the block number(in this case 5) - 1 + // NOTE: the leaf index is equivalent to the block number(in this case 5) - 1 vec![Compact::new(((4, H256::repeat_byte(5)).into(), LeafData::new(5).into(),))], BatchProof { leaf_indices: vec![4], diff --git a/primitives/merkle-mountain-range/src/lib.rs b/primitives/merkle-mountain-range/src/lib.rs index 18185fc8c46ee..1b0be5a1caf48 100644 --- a/primitives/merkle-mountain-range/src/lib.rs +++ b/primitives/merkle-mountain-range/src/lib.rs @@ -396,7 +396,7 @@ pub enum Error { GenerateProof, /// Proof verification error. Verify, - /// Error while converting a block number to leaf index. + /// Error during translation of a block number into a leaf index. BlockNumToLeafIndex, /// Leaf not found in the storage. LeafNotFound, From 5f909e34995fef2eafc071fa097c645a028e0e6e Mon Sep 17 00:00:00 2001 From: Szegoo Date: Wed, 28 Sep 2022 17:30:15 +0200 Subject: [PATCH 22/55] remove block_num_to_leaf_index from runtime api --- bin/node/runtime/src/lib.rs | 4 ---- primitives/merkle-mountain-range/src/lib.rs | 3 --- 2 files changed, 7 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index fc670926cb8c1..1b468fb9d6976 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -2074,10 +2074,6 @@ impl_runtime_apis! { let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect(); pallet_mmr::verify_leaves_proof::(root, nodes, proof) } - - fn block_num_to_leaf_index(block_num: &BlockNumber) -> Result { - Mmr::block_num_to_leaf_index(*block_num) - } } impl sp_session::SessionKeys for Runtime { diff --git a/primitives/merkle-mountain-range/src/lib.rs b/primitives/merkle-mountain-range/src/lib.rs index 1b0be5a1caf48..dd25ab13e3080 100644 --- a/primitives/merkle-mountain-range/src/lib.rs +++ b/primitives/merkle-mountain-range/src/lib.rs @@ -476,9 +476,6 @@ sp_api::decl_runtime_apis! { /// same position in both the `leaves` vector and the `leaf_indices` vector contained in the [BatchProof] fn verify_batch_proof_stateless(root: Hash, leaves: Vec, proof: BatchProof) -> Result<(), Error>; - - /// Converts `block_num` into a leaf index. - fn block_num_to_leaf_index(block_num: &BlockNumber) -> Result; } } From 97152b61192ee9be785834005b02c66acb0088cc Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Fri, 30 Sep 2022 07:46:39 +0200 Subject: [PATCH 23/55] Update frame/merkle-mountain-range/src/lib.rs Co-authored-by: Robert Hambrock --- frame/merkle-mountain-range/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 276934b931b3b..a5703d173734a 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -387,7 +387,7 @@ impl, I: 'static> Pallet { let current_block_num = >::block_number(); let diff = current_block_num.saturating_sub((leaves_count as u32).into()); - if block_num < diff { + if block_num <= diff { return Err( primitives::Error::BlockNumToLeafIndex.log_debug("The block_number is incorrect.") ) From 28e4437a2145d912c20f1d58e3d3f57aa92cdc6b Mon Sep 17 00:00:00 2001 From: Szegoo Date: Fri, 30 Sep 2022 09:31:58 +0200 Subject: [PATCH 24/55] fix tests --- frame/merkle-mountain-range/src/tests.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index 5d0d827feefcc..33e9d93a3c21c 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -240,7 +240,7 @@ fn should_generate_proofs_correctly() { ext.execute_with(|| { let now = frame_system::Pallet::::block_number(); // when generate proofs for all leaves. - let proofs = (0_u64..now) + let proofs = (1_u64..=now) .into_iter() .map(|block_num| crate::Pallet::::generate_batch_proof(vec![block_num]).unwrap()) .collect::>(); @@ -265,13 +265,13 @@ fn should_generate_proofs_correctly() { proofs[5], ( // NOTE: the leaf index is equivalent to the block number(in this case 5) - 1 - vec![Compact::new(((4, H256::repeat_byte(5)).into(), LeafData::new(5).into(),))], + vec![Compact::new(((5, H256::repeat_byte(6)).into(), LeafData::new(6).into(),))], BatchProof { - leaf_indices: vec![4], + leaf_indices: vec![5], leaf_count: 7, items: vec![ hex("ae88a0825da50e953e7a359c55fe13c8015e48d03d301b8bdfc9193874da9252"), - hex("8ed25570209d8f753d02df07c1884ddb36a3d9d4770e4608b188322151c657fe"), + hex("3b031d22e24f1126c8f7d2f394b663f9b960ed7abbedb7152e17ce16112656d0"), hex("611c2174c6164952a66d985cfe1ec1a623794393e3acff96b136d198f37a648c"), ], } @@ -280,14 +280,13 @@ fn should_generate_proofs_correctly() { assert_eq!( proofs[6], ( - vec![Compact::new(((5, H256::repeat_byte(6)).into(), LeafData::new(6).into(),))], + vec![Compact::new(((6, H256::repeat_byte(7)).into(), LeafData::new(7).into(),))], BatchProof { - leaf_indices: vec![5], + leaf_indices: vec![6], leaf_count: 7, items: vec![ hex("ae88a0825da50e953e7a359c55fe13c8015e48d03d301b8bdfc9193874da9252"), - hex("3b031d22e24f1126c8f7d2f394b663f9b960ed7abbedb7152e17ce16112656d0"), - hex("611c2174c6164952a66d985cfe1ec1a623794393e3acff96b136d198f37a648c"), + hex("7e4316ae2ebf7c3b6821cb3a46ca8b7a4f9351a9b40fcf014bb0a4fd8e8f29da"), ], } ) @@ -308,7 +307,7 @@ fn should_generate_batch_proof_correctly() { register_offchain_ext(&mut ext); ext.execute_with(|| { // when generate proofs for all leaves - let (.., proof) = crate::Pallet::::generate_batch_proof(vec![0, 5, 6]).unwrap(); + let (.., proof) = crate::Pallet::::generate_batch_proof(vec![1, 5, 6]).unwrap(); // then assert_eq!( @@ -458,7 +457,7 @@ fn should_verify_batch_proof_statelessly() { register_offchain_ext(&mut ext); let (leaves, proof) = ext.execute_with(|| { // when - crate::Pallet::::generate_batch_proof(vec![0, 4, 5]).unwrap() + crate::Pallet::::generate_batch_proof(vec![1, 4, 5]).unwrap() }); let root = ext.execute_with(|| crate::Pallet::::mmr_root_hash()); @@ -714,7 +713,7 @@ fn should_verify_canonicalized() { // Generate proofs for some blocks. let (leaves, proofs) = - ext.execute_with(|| crate::Pallet::::generate_batch_proof(vec![0, 4, 5, 7]).unwrap()); + ext.execute_with(|| crate::Pallet::::generate_batch_proof(vec![1, 4, 5, 7]).unwrap()); // Verify all previously generated proofs. ext.execute_with(|| { assert_eq!(crate::Pallet::::verify_leaves(leaves, proofs), Ok(())); From 3da0a908d8a51cfacdb6da2159cd3da4159e772b Mon Sep 17 00:00:00 2001 From: Szegoo Date: Fri, 30 Sep 2022 18:06:15 +0200 Subject: [PATCH 25/55] get the code to compile after merge --- bin/node/runtime/src/lib.rs | 4 ++-- frame/merkle-mountain-range/rpc/src/lib.rs | 8 +++---- frame/merkle-mountain-range/src/lib.rs | 23 ++++++++++----------- primitives/merkle-mountain-range/src/lib.rs | 2 +- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index ebafaa500eba7..fec3ee353478c 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -2065,10 +2065,10 @@ impl_runtime_apis! { } fn generate_historical_batch_proof( - leaf_indices: Vec, + block_numbers: Vec, leaves_count: pallet_mmr::primitives::LeafIndex, ) -> Result<(Vec, mmr::BatchProof), mmr::Error> { - Mmr::generate_historical_batch_proof(leaf_indices, leaves_count).map( + Mmr::generate_historical_batch_proof(block_numbers, leaves_count).map( |(leaves, proof)| { ( leaves diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index f18bbdc28c958..2ad1658ddb0e9 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -33,7 +33,7 @@ use serde::{Deserialize, Serialize}; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_core::Bytes; -use sp_mmr_primitives::{BatchProof, Error as MmrError, Proof}; +use sp_mmr_primitives::{BatchProof, Error as MmrError, LeafIndex, Proof}; use sp_runtime::{generic::BlockId, traits::Block as BlockT}; pub use sp_mmr_primitives::MmrApi as MmrRuntimeApi; @@ -149,7 +149,7 @@ pub trait MmrApi { #[method(name = "mmr_generateHistoricalBatchProof")] fn generate_historical_batch_proof( &self, - leaf_indices: Vec, + block_numbers: Vec, leaves_count: LeafIndex, at: Option, ) -> RpcResult>; @@ -222,7 +222,7 @@ where fn generate_historical_batch_proof( &self, - leaf_indices: Vec, + block_numbers: Vec, leaves_count: LeafIndex, at: Option<::Hash>, ) -> RpcResult::Hash>> { @@ -235,7 +235,7 @@ where .generate_historical_batch_proof_with_context( &BlockId::hash(block_hash), sp_core::ExecutionContext::OffchainCall(None), - leaf_indices, + block_numbers, leaves_count, ) .map_err(runtime_error_into_rpc_error)? diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 8bf63fd84a707..97f46753d1f77 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -330,17 +330,7 @@ impl, I: 'static> Pallet { (Vec>, primitives::BatchProof<>::Hash>), primitives::Error, > { - // we need to translate the block_numbers into leaf indices. - let leaf_indices = block_numbers - .iter() - .map(|n| -> Result { - let leaf_index = Self::block_num_to_leaf_index(*n)?; - Ok(leaf_index) - }) - .collect::, _>>()?; - - let mmr: ModuleMmr = mmr::Mmr::new(Self::mmr_leaves()); - Self::generate_historical_batch_proof(leaf_indices, Self::mmr_leaves()) + Self::generate_historical_batch_proof(block_numbers, Self::mmr_leaves()) } /// Generate a MMR proof for the given `leaf_indices` for the MMR of `leaves_count` size. @@ -350,7 +340,7 @@ impl, I: 'static> Pallet { /// all the leaves to be present. /// It may return an error or panic if used incorrectly. pub fn generate_historical_batch_proof( - leaf_indices: Vec, + block_numbers: Vec, leaves_count: LeafIndex, ) -> Result< (Vec>, primitives::BatchProof<>::Hash>), @@ -360,6 +350,15 @@ impl, I: 'static> Pallet { return Err(Error::InvalidLeavesCount) } + // we need to translate the block_numbers into leaf indices. + let leaf_indices = block_numbers + .iter() + .map(|n| -> Result { + let leaf_index = Self::block_num_to_leaf_index(*n)?; + Ok(leaf_index) + }) + .collect::, _>>()?; + let mmr: ModuleMmr = mmr::Mmr::new(leaves_count); mmr.generate_batch_proof(leaf_indices) } diff --git a/primitives/merkle-mountain-range/src/lib.rs b/primitives/merkle-mountain-range/src/lib.rs index 8167ab9603582..9780ed9cbe068 100644 --- a/primitives/merkle-mountain-range/src/lib.rs +++ b/primitives/merkle-mountain-range/src/lib.rs @@ -463,7 +463,7 @@ sp_api::decl_runtime_apis! { /// Generate MMR proof for a series of leaves under given indices, using MMR at given `leaves_count` size. fn generate_historical_batch_proof( - leaf_indices: Vec, + block_numbers: Vec, leaves_count: LeafIndex ) -> Result<(Vec, BatchProof), Error>; From 245d9671f38cc50d238edd6b2670f851bbba91d6 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Fri, 30 Sep 2022 19:37:40 +0200 Subject: [PATCH 26/55] get the tests to compile --- frame/merkle-mountain-range/src/tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index 86c66b2d0dc44..5158bde70bd5f 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -513,7 +513,7 @@ fn should_verify_batch_proofs() { }); let mmr_size = ext.execute_with(|| crate::Pallet::::mmr_leaves()); - let min_mmr_size = leaf_indices.iter().max().unwrap() + 1; + let min_mmr_size = block_numbers.iter().max().unwrap() + 1; // generate historical proofs for all possible mmr sizes, // lower bound being index of highest leaf to be proven @@ -521,7 +521,7 @@ fn should_verify_batch_proofs() { .map(|mmr_size| { ext.execute_with(|| { crate::Pallet::::generate_historical_batch_proof( - leaf_indices.to_vec(), + block_numbers.to_vec(), mmr_size, ) .unwrap() From 3c355a0c28e69162ec8d28c770e5e94f66f8b8df Mon Sep 17 00:00:00 2001 From: Szegoo Date: Fri, 30 Sep 2022 21:52:58 +0200 Subject: [PATCH 27/55] fix in tests? --- frame/merkle-mountain-range/src/tests.rs | 62 ++++++++++++++---------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index 5158bde70bd5f..a99bb7aa54fdc 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -246,7 +246,7 @@ fn should_generate_proofs_correctly() { .map(|block_num| crate::Pallet::::generate_batch_proof(vec![block_num]).unwrap()) .collect::>(); // when generate historical proofs for all leaves - let historical_proofs = (0_u64..crate::NumberOfLeaves::::get()) + let historical_proofs = (1_u64..now) .into_iter() .map(|leaf_index| { let mut proofs = vec![]; @@ -283,7 +283,13 @@ fn should_generate_proofs_correctly() { historical_proofs[0][0], ( vec![Compact::new(((0, H256::repeat_byte(1)).into(), LeafData::new(1).into(),))], - BatchProof { leaf_indices: vec![0], leaf_count: 1, items: vec![] } + BatchProof { + leaf_indices: vec![0], + leaf_count: 2, + items: vec![hex( + "ad4cbc033833612ccd4626d5f023b9dfc50a35e838514dd1f3c86f8506728705" + )] + } ) ); @@ -321,10 +327,11 @@ fn should_generate_proofs_correctly() { vec![Compact::new(((2, H256::repeat_byte(3)).into(), LeafData::new(3).into(),))], BatchProof { leaf_indices: vec![2], - leaf_count: 3, - items: vec![hex( - "672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854" - ),], + leaf_count: 4, + items: vec![ + hex("1b14c1dc7d3e4def11acdf31be0584f4b85c3673f1ff72a3af467b69a3b0d9d0"), + hex("672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854") + ], } ) ); @@ -341,28 +348,28 @@ fn should_generate_proofs_correctly() { vec![Compact::new(((2, H256::repeat_byte(3)).into(), LeafData::new(3).into(),))], BatchProof { leaf_indices: vec![2], - leaf_count: 5, + leaf_count: 6, items: vec![ hex("1b14c1dc7d3e4def11acdf31be0584f4b85c3673f1ff72a3af467b69a3b0d9d0"), hex("672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854"), - hex("3b031d22e24f1126c8f7d2f394b663f9b960ed7abbedb7152e17ce16112656d0") + hex("7e4316ae2ebf7c3b6821cb3a46ca8b7a4f9351a9b40fcf014bb0a4fd8e8f29da") ], } ) ); - assert_eq!(historical_proofs[2][4], proofs[2]); + assert_eq!(historical_proofs[2][3], proofs[2]); assert_eq!( proofs[4], ( // NOTE: the leaf index is equivalent to the block number(in this case 5) - 1 - vec![Compact::new(((5, H256::repeat_byte(6)).into(), LeafData::new(6).into(),))], + vec![Compact::new(((4, H256::repeat_byte(5)).into(), LeafData::new(5).into(),))], BatchProof { - leaf_indices: vec![5], + leaf_indices: vec![4], leaf_count: 7, items: vec![ hex("ae88a0825da50e953e7a359c55fe13c8015e48d03d301b8bdfc9193874da9252"), - hex("3b031d22e24f1126c8f7d2f394b663f9b960ed7abbedb7152e17ce16112656d0"), + hex("8ed25570209d8f753d02df07c1884ddb36a3d9d4770e4608b188322151c657fe"), hex("611c2174c6164952a66d985cfe1ec1a623794393e3acff96b136d198f37a648c"), ], } @@ -374,14 +381,15 @@ fn should_generate_proofs_correctly() { vec![Compact::new(((4, H256::repeat_byte(5)).into(), LeafData::new(5).into(),))], BatchProof { leaf_indices: vec![4], - leaf_count: 5, - items: vec![hex( - "ae88a0825da50e953e7a359c55fe13c8015e48d03d301b8bdfc9193874da9252" - ),], + leaf_count: 6, + items: vec![ + hex("ae88a0825da50e953e7a359c55fe13c8015e48d03d301b8bdfc9193874da9252"), + hex("8ed25570209d8f753d02df07c1884ddb36a3d9d4770e4608b188322151c657fe") + ], } ) ); - assert_eq!(historical_proofs[4][2], proofs[4]); + assert_eq!(historical_proofs[4][1], proofs[4]); assert_eq!( proofs[6], @@ -397,7 +405,7 @@ fn should_generate_proofs_correctly() { } ) ); - assert_eq!(historical_proofs[6][0], proofs[6]); + assert_eq!(historical_proofs[5][0], proofs[5]); }); } @@ -414,17 +422,18 @@ fn should_generate_batch_proof_correctly() { register_offchain_ext(&mut ext); ext.execute_with(|| { // when generate proofs for a batch of leaves - let (.., proof) = crate::Pallet::::generate_batch_proof(vec![0, 4, 5]).unwrap(); + let (.., proof) = crate::Pallet::::generate_batch_proof(vec![1, 4, 5]).unwrap(); // then assert_eq!( proof, BatchProof { // the leaf indices are equivalent to the above specified block numbers - 1. - leaf_indices: vec![0, 4, 5], + leaf_indices: vec![0, 3, 4], leaf_count: 7, items: vec![ hex("ad4cbc033833612ccd4626d5f023b9dfc50a35e838514dd1f3c86f8506728705"), - hex("cb24f4614ad5b2a5430344c99545b421d9af83c46fd632d70a332200884b4d46"), + hex("9ba3bd51dcd2547a0155cf13411beeed4e2b640163bbea02806984f3fcbf822e"), + hex("8ed25570209d8f753d02df07c1884ddb36a3d9d4770e4608b188322151c657fe"), hex("611c2174c6164952a66d985cfe1ec1a623794393e3acff96b136d198f37a648c"), ], } @@ -432,23 +441,24 @@ fn should_generate_batch_proof_correctly() { // when generate historical proofs for a batch of leaves let (.., historical_proof) = - crate::Pallet::::generate_historical_batch_proof(vec![0, 4, 5], 6).unwrap(); + crate::Pallet::::generate_historical_batch_proof(vec![1, 4, 5], 6).unwrap(); // then assert_eq!( historical_proof, BatchProof { - leaf_indices: vec![0, 4, 5], + leaf_indices: vec![0, 3, 4], leaf_count: 6, items: vec![ hex("ad4cbc033833612ccd4626d5f023b9dfc50a35e838514dd1f3c86f8506728705"), - hex("cb24f4614ad5b2a5430344c99545b421d9af83c46fd632d70a332200884b4d46"), + hex("9ba3bd51dcd2547a0155cf13411beeed4e2b640163bbea02806984f3fcbf822e"), + hex("8ed25570209d8f753d02df07c1884ddb36a3d9d4770e4608b188322151c657fe"), ], } ); // when generate historical proofs for a batch of leaves let (.., historical_proof) = - crate::Pallet::::generate_historical_batch_proof(vec![0, 4, 5], 7).unwrap(); + crate::Pallet::::generate_historical_batch_proof(vec![1, 4, 5], 7).unwrap(); // then assert_eq!(historical_proof, proof); }); @@ -661,7 +671,7 @@ fn should_verify_batch_proof_statelessly() { }); let (historical_leaves, historical_proof) = ext.execute_with(|| { // when - crate::Pallet::::generate_historical_batch_proof(vec![0, 4, 5], 6).unwrap() + crate::Pallet::::generate_historical_batch_proof(vec![1, 4, 5], 6).unwrap() }); // Verify proof without relying on any on-chain data. From f54c3a726bf268298734f3f5bc9fb5e5f097942d Mon Sep 17 00:00:00 2001 From: Szegoo Date: Fri, 30 Sep 2022 22:10:33 +0200 Subject: [PATCH 28/55] fix test --- frame/merkle-mountain-range/src/tests.rs | 42 ++++++++++-------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index a99bb7aa54fdc..c86906eac434a 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -248,12 +248,12 @@ fn should_generate_proofs_correctly() { // when generate historical proofs for all leaves let historical_proofs = (1_u64..now) .into_iter() - .map(|leaf_index| { + .map(|block_num| { let mut proofs = vec![]; - for leaves_count in leaf_index + 1..=num_blocks { + for leaves_count in block_num..=num_blocks { proofs.push( crate::Pallet::::generate_historical_batch_proof( - vec![leaf_index], + vec![block_num], leaves_count, ) .unwrap(), @@ -283,13 +283,7 @@ fn should_generate_proofs_correctly() { historical_proofs[0][0], ( vec![Compact::new(((0, H256::repeat_byte(1)).into(), LeafData::new(1).into(),))], - BatchProof { - leaf_indices: vec![0], - leaf_count: 2, - items: vec![hex( - "ad4cbc033833612ccd4626d5f023b9dfc50a35e838514dd1f3c86f8506728705" - )] - } + BatchProof { leaf_indices: vec![0], leaf_count: 1, items: vec![] } ) ); @@ -327,11 +321,10 @@ fn should_generate_proofs_correctly() { vec![Compact::new(((2, H256::repeat_byte(3)).into(), LeafData::new(3).into(),))], BatchProof { leaf_indices: vec![2], - leaf_count: 4, - items: vec![ - hex("1b14c1dc7d3e4def11acdf31be0584f4b85c3673f1ff72a3af467b69a3b0d9d0"), - hex("672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854") - ], + leaf_count: 3, + items: vec![hex( + "672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854" + )], } ) ); @@ -348,16 +341,16 @@ fn should_generate_proofs_correctly() { vec![Compact::new(((2, H256::repeat_byte(3)).into(), LeafData::new(3).into(),))], BatchProof { leaf_indices: vec![2], - leaf_count: 6, + leaf_count: 5, items: vec![ hex("1b14c1dc7d3e4def11acdf31be0584f4b85c3673f1ff72a3af467b69a3b0d9d0"), hex("672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854"), - hex("7e4316ae2ebf7c3b6821cb3a46ca8b7a4f9351a9b40fcf014bb0a4fd8e8f29da") + hex("3b031d22e24f1126c8f7d2f394b663f9b960ed7abbedb7152e17ce16112656d0") ], } ) ); - assert_eq!(historical_proofs[2][3], proofs[2]); + assert_eq!(historical_proofs[2][4], proofs[2]); assert_eq!( proofs[4], @@ -381,15 +374,14 @@ fn should_generate_proofs_correctly() { vec![Compact::new(((4, H256::repeat_byte(5)).into(), LeafData::new(5).into(),))], BatchProof { leaf_indices: vec![4], - leaf_count: 6, - items: vec![ - hex("ae88a0825da50e953e7a359c55fe13c8015e48d03d301b8bdfc9193874da9252"), - hex("8ed25570209d8f753d02df07c1884ddb36a3d9d4770e4608b188322151c657fe") - ], + leaf_count: 5, + items: vec![hex( + "ae88a0825da50e953e7a359c55fe13c8015e48d03d301b8bdfc9193874da9252" + ),], } ) ); - assert_eq!(historical_proofs[4][1], proofs[4]); + assert_eq!(historical_proofs[4][2], proofs[4]); assert_eq!( proofs[6], @@ -405,7 +397,7 @@ fn should_generate_proofs_correctly() { } ) ); - assert_eq!(historical_proofs[5][0], proofs[5]); + assert_eq!(historical_proofs[5][1], proofs[5]); }); } From 0dba52b256ec6c60726a6761d453fa14c94a6e19 Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Mon, 3 Oct 2022 18:19:53 +0200 Subject: [PATCH 29/55] Update frame/merkle-mountain-range/src/tests.rs Co-authored-by: Adrian Catangiu --- frame/merkle-mountain-range/src/tests.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index c86906eac434a..8cd7c7b20b499 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -83,8 +83,14 @@ fn add_blocks(blocks: usize) { } } -fn leaf_indices_to_block_numbers(leaf_indices: &Vec) -> Vec { - leaf_indices.iter().map(|l| *l + 1).collect() +fn leaf_indices_to_block_numbers( + ext: &mut sp_io::TestExternalities, + leaf_indices: &Vec +) -> Vec { + leaf_indices.iter().map(|l| { + let mmr_size = ext.execute_with(|| crate::Pallet::::mmr_leaves()); + ext.execute_with(|| crate::Pallet::::leaf_index_to_parent_block_num(*l, mmr_size)) + }).collect() } #[test] From d68aaaea4a7693571a5bf46ed99fb1e87a28c8d3 Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Mon, 3 Oct 2022 18:20:20 +0200 Subject: [PATCH 30/55] Update frame/merkle-mountain-range/src/lib.rs Co-authored-by: Adrian Catangiu --- frame/merkle-mountain-range/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 97f46753d1f77..20e9076dbee08 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -333,7 +333,7 @@ impl, I: 'static> Pallet { Self::generate_historical_batch_proof(block_numbers, Self::mmr_leaves()) } - /// Generate a MMR proof for the given `leaf_indices` for the MMR of `leaves_count` size. + /// Generate a MMR proof for the given `block_numbers` for the MMR of `leaves_count` size. /// /// Note this method can only be used from an off-chain context /// (Offchain Worker or Runtime API call), since it requires From a792fc4e680a831d8472cee40e808f6311d7c2ea Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Mon, 3 Oct 2022 18:21:05 +0200 Subject: [PATCH 31/55] Update primitives/merkle-mountain-range/src/lib.rs Co-authored-by: Adrian Catangiu --- primitives/merkle-mountain-range/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/merkle-mountain-range/src/lib.rs b/primitives/merkle-mountain-range/src/lib.rs index 9780ed9cbe068..531eccda04334 100644 --- a/primitives/merkle-mountain-range/src/lib.rs +++ b/primitives/merkle-mountain-range/src/lib.rs @@ -461,7 +461,7 @@ sp_api::decl_runtime_apis! { /// Generate MMR proof for a series of blocks with the specified block numbers. fn generate_batch_proof(block_numbers: Vec) -> Result<(Vec, BatchProof), Error>; - /// Generate MMR proof for a series of leaves under given indices, using MMR at given `leaves_count` size. + /// Generate MMR proof for a series of `block_numbers`, using MMR at given `leaves_count` size. fn generate_historical_batch_proof( block_numbers: Vec, leaves_count: LeafIndex From dbd7edb45a392cb2eaef6ed54cb0c3913a4eceb1 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 3 Oct 2022 21:51:22 +0200 Subject: [PATCH 32/55] fix errors & nits --- frame/merkle-mountain-range/src/lib.rs | 46 ++++++++++----------- frame/merkle-mountain-range/src/tests.rs | 21 ++++++---- primitives/merkle-mountain-range/src/lib.rs | 4 +- 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 20e9076dbee08..0ae00072777be 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -318,6 +318,29 @@ impl, I: 'static> Pallet { .saturating_add(leaf_index.saturated_into()) } + /// Convert a `block_num` into a leaf index. + fn block_num_to_leaf_index( + block_num: T::BlockNumber, + ) -> Result + where + T: frame_system::Config, + { + // leaf_indx = block_num - (current_block_num - leaves_count) - 1; + let leaves_count = Self::mmr_leaves(); + let current_block_num = >::block_number(); + let diff = current_block_num.saturating_sub((leaves_count as u32).into()); + + if block_num <= diff { + return Err( + primitives::Error::BlockNumToLeafIndex.log_debug("The block_number is incorrect.") + ) + } + + let leaf_index = (block_num.saturating_sub(diff).saturating_sub(1u32.into())) + .saturated_into::(); + Ok(leaf_index) + } + /// Generate a MMR proof for the given `block_numbers`. /// /// Note this method can only be used from an off-chain context @@ -394,27 +417,4 @@ impl, I: 'static> Pallet { Err(primitives::Error::Verify.log_debug("The proof is incorrect.")) } } - - /// Convert a `block_num` into a leaf index. - pub fn block_num_to_leaf_index( - block_num: ::BlockNumber, - ) -> Result - where - T: frame_system::Config, - { - // leaf_indx = block_num - (current_block_num - leaves_count) - 1; - let leaves_count = Self::mmr_leaves(); - let current_block_num = >::block_number(); - let diff = current_block_num.saturating_sub((leaves_count as u32).into()); - - if block_num <= diff { - return Err( - primitives::Error::BlockNumToLeafIndex.log_debug("The block_number is incorrect.") - ) - } - - let leaf_index = (block_num.saturating_sub(diff).saturating_sub(1u32.into())) - .saturated_into::(); - Ok(leaf_index) - } } diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index 8cd7c7b20b499..65f6294e6cc8c 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -85,12 +85,15 @@ fn add_blocks(blocks: usize) { fn leaf_indices_to_block_numbers( ext: &mut sp_io::TestExternalities, - leaf_indices: &Vec + leaf_indices: &Vec, ) -> Vec { - leaf_indices.iter().map(|l| { - let mmr_size = ext.execute_with(|| crate::Pallet::::mmr_leaves()); - ext.execute_with(|| crate::Pallet::::leaf_index_to_parent_block_num(*l, mmr_size)) - }).collect() + leaf_indices + .iter() + .map(|l| { + let mmr_size = ext.execute_with(|| crate::Pallet::::mmr_leaves()); + ext.execute_with(|| crate::Pallet::::leaf_index_to_parent_block_num(*l, mmr_size)) + }) + .collect() } #[test] @@ -565,10 +568,10 @@ fn should_verify_batch_proofs() { ext.persist_offchain_overlay(); // generate powerset (skipping empty set) of all possible leaf combinations for mmr size n - let leaves_set: Vec> = (0..=n).into_iter().powerset().skip(1).collect(); + let leaves_set: Vec> = (1..=n).into_iter().powerset().skip(1).collect(); leaves_set.iter().for_each(|leaves_subset| { - let block_numbers = leaf_indices_to_block_numbers(leaves_subset); + let block_numbers = leaf_indices_to_block_numbers(&mut ext, leaves_subset); generate_and_verify_batch_proof(&mut ext, &block_numbers, 0); ext.persist_offchain_overlay(); }); @@ -581,10 +584,10 @@ fn should_verify_batch_proofs() { ext.persist_offchain_overlay(); // generate all possible 2-leaf combinations for mmr size n - let leaves_set: Vec> = (0..=n).into_iter().combinations(2).collect(); + let leaves_set: Vec> = (1..=n).into_iter().combinations(2).collect(); leaves_set.iter().for_each(|leaves_subset| { - let block_numbers = leaf_indices_to_block_numbers(leaves_subset); + let block_numbers = leaf_indices_to_block_numbers(&mut ext, leaves_subset); generate_and_verify_batch_proof(&mut ext, &block_numbers, 0); ext.persist_offchain_overlay(); }); diff --git a/primitives/merkle-mountain-range/src/lib.rs b/primitives/merkle-mountain-range/src/lib.rs index 531eccda04334..f47ae8346c734 100644 --- a/primitives/merkle-mountain-range/src/lib.rs +++ b/primitives/merkle-mountain-range/src/lib.rs @@ -386,6 +386,8 @@ impl Proof { /// Merkle Mountain Range operation error. #[derive(RuntimeDebug, codec::Encode, codec::Decode, PartialEq, Eq)] pub enum Error { + /// Error during translation of a block number into a leaf index. + BlockNumToLeafIndex, /// Error while pushing new node. Push, /// Error getting the new root. @@ -396,8 +398,6 @@ pub enum Error { GenerateProof, /// Proof verification error. Verify, - /// Error during translation of a block number into a leaf index. - BlockNumToLeafIndex, /// Leaf not found in the storage. LeafNotFound, /// Mmr Pallet not included in runtime From 2004425959510f322881179b3f17bc58b68d369b Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 3 Oct 2022 22:00:51 +0200 Subject: [PATCH 33/55] change block_num_to_leaf_index --- frame/merkle-mountain-range/src/lib.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 0ae00072777be..d7932110efb4f 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -319,24 +319,24 @@ impl, I: 'static> Pallet { } /// Convert a `block_num` into a leaf index. - fn block_num_to_leaf_index( - block_num: T::BlockNumber, - ) -> Result + fn block_num_to_leaf_index(block_num: T::BlockNumber) -> Result where T: frame_system::Config, { // leaf_indx = block_num - (current_block_num - leaves_count) - 1; - let leaves_count = Self::mmr_leaves(); - let current_block_num = >::block_number(); - let diff = current_block_num.saturating_sub((leaves_count as u32).into()); + let leaves_count = Self::mmr_leaves().saturated_into::(); + let current_block_num = >::block_number().saturated_into::(); + let diff = current_block_num.saturating_sub(leaves_count); - if block_num <= diff { + let block_num_as_u64 = block_num.saturated_into::(); + + if block_num_as_u64 <= diff { return Err( primitives::Error::BlockNumToLeafIndex.log_debug("The block_number is incorrect.") ) } - let leaf_index = (block_num.saturating_sub(diff).saturating_sub(1u32.into())) + let leaf_index = (block_num_as_u64.saturating_sub(diff).saturating_sub(1u32.into())) .saturated_into::(); Ok(leaf_index) } From 2778f7ab9e08b43e1a5b070d208ea084fe763ebd Mon Sep 17 00:00:00 2001 From: Szegoo Date: Tue, 4 Oct 2022 07:52:47 +0200 Subject: [PATCH 34/55] don't make any assumptions --- frame/merkle-mountain-range/src/lib.rs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index d7932110efb4f..d1b240b433063 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -322,21 +322,20 @@ impl, I: 'static> Pallet { fn block_num_to_leaf_index(block_num: T::BlockNumber) -> Result where T: frame_system::Config, + T::BlockNumber: From, { // leaf_indx = block_num - (current_block_num - leaves_count) - 1; - let leaves_count = Self::mmr_leaves().saturated_into::(); - let current_block_num = >::block_number().saturated_into::(); - let diff = current_block_num.saturating_sub(leaves_count); + let leaves_count = Self::mmr_leaves(); + let current_block_num = >::block_number(); + let diff = current_block_num.saturating_sub(leaves_count.into()); - let block_num_as_u64 = block_num.saturated_into::(); - - if block_num_as_u64 <= diff { + if block_num <= diff { return Err( primitives::Error::BlockNumToLeafIndex.log_debug("The block_number is incorrect.") ) } - let leaf_index = (block_num_as_u64.saturating_sub(diff).saturating_sub(1u32.into())) + let leaf_index = (block_num.saturating_sub(diff).saturating_sub(1u32.into())) .saturated_into::(); Ok(leaf_index) } @@ -352,7 +351,10 @@ impl, I: 'static> Pallet { ) -> Result< (Vec>, primitives::BatchProof<>::Hash>), primitives::Error, - > { + > + where + T::BlockNumber: From, + { Self::generate_historical_batch_proof(block_numbers, Self::mmr_leaves()) } @@ -368,7 +370,10 @@ impl, I: 'static> Pallet { ) -> Result< (Vec>, primitives::BatchProof<>::Hash>), primitives::Error, - > { + > + where + T::BlockNumber: From, + { if leaves_count > Self::mmr_leaves() { return Err(Error::InvalidLeavesCount) } From 0a17093cf9ddf80f63ed9241a0a22e46e05d935e Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Tue, 4 Oct 2022 09:37:56 +0200 Subject: [PATCH 35/55] Update frame/merkle-mountain-range/src/tests.rs Co-authored-by: Adrian Catangiu --- frame/merkle-mountain-range/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index 65f6294e6cc8c..822d08bf731bd 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -91,7 +91,7 @@ fn leaf_indices_to_block_numbers( .iter() .map(|l| { let mmr_size = ext.execute_with(|| crate::Pallet::::mmr_leaves()); - ext.execute_with(|| crate::Pallet::::leaf_index_to_parent_block_num(*l, mmr_size)) + ext.execute_with(|| crate::Pallet::::leaf_index_to_parent_block_num(*l, mmr_size)).saturating_add(1u32.into()) }) .collect() } From e7d2dff2ab7764d9944609da14d542702796d6f7 Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Tue, 4 Oct 2022 09:38:03 +0200 Subject: [PATCH 36/55] Update frame/merkle-mountain-range/src/tests.rs Co-authored-by: Adrian Catangiu --- frame/merkle-mountain-range/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index 822d08bf731bd..fd9eb2c790db8 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -568,7 +568,7 @@ fn should_verify_batch_proofs() { ext.persist_offchain_overlay(); // generate powerset (skipping empty set) of all possible leaf combinations for mmr size n - let leaves_set: Vec> = (1..=n).into_iter().powerset().skip(1).collect(); + let leaves_set: Vec> = (0..=n).into_iter().powerset().skip(1).collect(); leaves_set.iter().for_each(|leaves_subset| { let block_numbers = leaf_indices_to_block_numbers(&mut ext, leaves_subset); From 701e6d3f6516b3df6cfada15dbf2b4e2500329d3 Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Tue, 4 Oct 2022 09:38:10 +0200 Subject: [PATCH 37/55] Update frame/merkle-mountain-range/src/tests.rs Co-authored-by: Adrian Catangiu --- frame/merkle-mountain-range/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index fd9eb2c790db8..e711b931a0e96 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -584,7 +584,7 @@ fn should_verify_batch_proofs() { ext.persist_offchain_overlay(); // generate all possible 2-leaf combinations for mmr size n - let leaves_set: Vec> = (1..=n).into_iter().combinations(2).collect(); + let leaves_set: Vec> = (0..=n).into_iter().combinations(2).collect(); leaves_set.iter().for_each(|leaves_subset| { let block_numbers = leaf_indices_to_block_numbers(&mut ext, leaves_subset); From eb3235671386786f63de762edacc595527ea4731 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Tue, 4 Oct 2022 11:25:17 +0200 Subject: [PATCH 38/55] fix --- frame/merkle-mountain-range/src/lib.rs | 11 ++++++----- frame/merkle-mountain-range/src/tests.rs | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index d1b240b433063..bcc68e33c75fe 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -322,20 +322,21 @@ impl, I: 'static> Pallet { fn block_num_to_leaf_index(block_num: T::BlockNumber) -> Result where T: frame_system::Config, - T::BlockNumber: From, { // leaf_indx = block_num - (current_block_num - leaves_count) - 1; - let leaves_count = Self::mmr_leaves(); - let current_block_num = >::block_number(); + let leaves_count = Self::mmr_leaves().saturated_into::(); + let current_block_num = >::block_number().saturated_into::(); let diff = current_block_num.saturating_sub(leaves_count.into()); - if block_num <= diff { + let block_num_as_u64 = block_num.saturated_into::(); + + if block_num_as_u64 <= diff { return Err( primitives::Error::BlockNumToLeafIndex.log_debug("The block_number is incorrect.") ) } - let leaf_index = (block_num.saturating_sub(diff).saturating_sub(1u32.into())) + let leaf_index = (block_num_as_u64.saturating_sub(diff).saturating_sub(1u32.into())) .saturated_into::(); Ok(leaf_index) } diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index e711b931a0e96..5bf973cc07784 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -91,7 +91,8 @@ fn leaf_indices_to_block_numbers( .iter() .map(|l| { let mmr_size = ext.execute_with(|| crate::Pallet::::mmr_leaves()); - ext.execute_with(|| crate::Pallet::::leaf_index_to_parent_block_num(*l, mmr_size)).saturating_add(1u32.into()) + ext.execute_with(|| crate::Pallet::::leaf_index_to_parent_block_num(*l, mmr_size)) + .saturating_add(1u32.into()) }) .collect() } From 900db49407db9a11e2dd4561cf513ac61b6f85b2 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Tue, 4 Oct 2022 11:48:24 +0200 Subject: [PATCH 39/55] small fix --- frame/merkle-mountain-range/src/lib.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index bcc68e33c75fe..ccec675417309 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -352,10 +352,7 @@ impl, I: 'static> Pallet { ) -> Result< (Vec>, primitives::BatchProof<>::Hash>), primitives::Error, - > - where - T::BlockNumber: From, - { + > { Self::generate_historical_batch_proof(block_numbers, Self::mmr_leaves()) } @@ -371,10 +368,7 @@ impl, I: 'static> Pallet { ) -> Result< (Vec>, primitives::BatchProof<>::Hash>), primitives::Error, - > - where - T::BlockNumber: From, - { + > { if leaves_count > Self::mmr_leaves() { return Err(Error::InvalidLeavesCount) } From 3a6b998d0c33f9efd86e0e77eca86cad63cde915 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Wed, 5 Oct 2022 10:49:49 +0200 Subject: [PATCH 40/55] use best_known_block_number --- bin/node/runtime/src/lib.rs | 4 ++-- frame/merkle-mountain-range/rpc/src/lib.rs | 9 +++++---- frame/merkle-mountain-range/src/lib.rs | 8 ++++++-- primitives/merkle-mountain-range/src/lib.rs | 4 ++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index f6e0091917cba..0f075b07aa3ea 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -2066,9 +2066,9 @@ impl_runtime_apis! { fn generate_historical_batch_proof( block_numbers: Vec, - leaves_count: pallet_mmr::primitives::LeafIndex, + best_known_block_number: BlockNumber, ) -> Result<(Vec, mmr::BatchProof), mmr::Error> { - Mmr::generate_historical_batch_proof(block_numbers, leaves_count).map( + Mmr::generate_historical_batch_proof(block_numbers, best_known_block_number).map( |(leaves, proof)| { ( leaves diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index 2ad1658ddb0e9..fddd6ce85a6d6 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -129,7 +129,8 @@ pub trait MmrApi { at: Option, ) -> RpcResult>; - /// Generate a MMR proof for the given `leaf_indices` of the MMR that had `leaves_count` leaves. + /// Generate a MMR proof for the given `block_numbers` of the MMR that had `leaves_count` + /// leaves. /// /// This method calls into a runtime with MMR pallet included and attempts to generate /// a MMR proof for the set of leaves at the given `leaf_indices` with MMR fixed to the state @@ -150,7 +151,7 @@ pub trait MmrApi { fn generate_historical_batch_proof( &self, block_numbers: Vec, - leaves_count: LeafIndex, + best_known_block_number: BlockNumber, at: Option, ) -> RpcResult>; } @@ -223,7 +224,7 @@ where fn generate_historical_batch_proof( &self, block_numbers: Vec, - leaves_count: LeafIndex, + best_known_block_number: BlockNumber, at: Option<::Hash>, ) -> RpcResult::Hash>> { let api = self.client.runtime_api(); @@ -236,7 +237,7 @@ where &BlockId::hash(block_hash), sp_core::ExecutionContext::OffchainCall(None), block_numbers, - leaves_count, + best_known_block_number, ) .map_err(runtime_error_into_rpc_error)? .map_err(mmr_error_into_rpc_error)?; diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index ccec675417309..ca148921e850f 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -353,7 +353,10 @@ impl, I: 'static> Pallet { (Vec>, primitives::BatchProof<>::Hash>), primitives::Error, > { - Self::generate_historical_batch_proof(block_numbers, Self::mmr_leaves()) + Self::generate_historical_batch_proof( + block_numbers, + Self::leaf_index_to_parent_block_num(Self::mmr_leaves(), Self::mmr_leaves()), + ) } /// Generate a MMR proof for the given `block_numbers` for the MMR of `leaves_count` size. @@ -364,11 +367,12 @@ impl, I: 'static> Pallet { /// It may return an error or panic if used incorrectly. pub fn generate_historical_batch_proof( block_numbers: Vec, - leaves_count: LeafIndex, + best_known_block_number: T::BlockNumber, ) -> Result< (Vec>, primitives::BatchProof<>::Hash>), primitives::Error, > { + let leaves_count = Self::block_num_to_leaf_index(best_known_block_number)?; if leaves_count > Self::mmr_leaves() { return Err(Error::InvalidLeavesCount) } diff --git a/primitives/merkle-mountain-range/src/lib.rs b/primitives/merkle-mountain-range/src/lib.rs index f47ae8346c734..5373a81bc0232 100644 --- a/primitives/merkle-mountain-range/src/lib.rs +++ b/primitives/merkle-mountain-range/src/lib.rs @@ -461,10 +461,10 @@ sp_api::decl_runtime_apis! { /// Generate MMR proof for a series of blocks with the specified block numbers. fn generate_batch_proof(block_numbers: Vec) -> Result<(Vec, BatchProof), Error>; - /// Generate MMR proof for a series of `block_numbers`, using MMR at given `leaves_count` size. + /// Generate MMR proof for a series of `block_numbers`, using MMR at given `best_known_block_number` size. fn generate_historical_batch_proof( block_numbers: Vec, - leaves_count: LeafIndex + best_known_block_number: BlockNumber ) -> Result<(Vec, BatchProof), Error>; /// Verify MMR proof against on-chain MMR for a batch of leaves. From 66b8c331d49182b0d42b112a14ab37278530e626 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Wed, 5 Oct 2022 19:46:52 +0200 Subject: [PATCH 41/55] best_known_block_number instead of leaves_count --- frame/merkle-mountain-range/src/lib.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index ca148921e850f..b238d2a0ac105 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -372,7 +372,14 @@ impl, I: 'static> Pallet { (Vec>, primitives::BatchProof<>::Hash>), primitives::Error, > { - let leaves_count = Self::block_num_to_leaf_index(best_known_block_number)?; + let now = frame_system::Pallet::::block_number().saturated_into::(); + let leaves = Self::mmr_leaves().saturated_into::(); + let best_block_as_u64 = best_known_block_number.saturated_into::(); + + let leaves_count = now + .saturating_sub(leaves) + .saturating_add(best_block_as_u64) + .saturated_into::(); if leaves_count > Self::mmr_leaves() { return Err(Error::InvalidLeavesCount) } From 75088ff9d3168a09511a7f321d071f1d0555be83 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Wed, 5 Oct 2022 20:01:12 +0200 Subject: [PATCH 42/55] more readable? --- frame/merkle-mountain-range/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index b238d2a0ac105..24c1b7ad38500 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -376,8 +376,8 @@ impl, I: 'static> Pallet { let leaves = Self::mmr_leaves().saturated_into::(); let best_block_as_u64 = best_known_block_number.saturated_into::(); - let leaves_count = now - .saturating_sub(leaves) + let leaves_count = leaves + .saturating_sub(now) .saturating_add(best_block_as_u64) .saturated_into::(); if leaves_count > Self::mmr_leaves() { From 3dc78382318b65ade249fbb2466255600e6cd9ab Mon Sep 17 00:00:00 2001 From: Szegoo Date: Wed, 5 Oct 2022 20:03:58 +0200 Subject: [PATCH 43/55] remove warning --- frame/merkle-mountain-range/rpc/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index fddd6ce85a6d6..f560c3c3e9aca 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -33,7 +33,7 @@ use serde::{Deserialize, Serialize}; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_core::Bytes; -use sp_mmr_primitives::{BatchProof, Error as MmrError, LeafIndex, Proof}; +use sp_mmr_primitives::{BatchProof, Error as MmrError, Proof}; use sp_runtime::{generic::BlockId, traits::Block as BlockT}; pub use sp_mmr_primitives::MmrApi as MmrRuntimeApi; From 2ae0e2010331244489f88ae2d2957e6f21bf2969 Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Thu, 6 Oct 2022 08:08:19 +0200 Subject: [PATCH 44/55] Update frame/merkle-mountain-range/src/lib.rs Co-authored-by: Robert Hambrock --- frame/merkle-mountain-range/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 24c1b7ad38500..89023f50ab609 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -355,7 +355,7 @@ impl, I: 'static> Pallet { > { Self::generate_historical_batch_proof( block_numbers, - Self::leaf_index_to_parent_block_num(Self::mmr_leaves(), Self::mmr_leaves()), + >::block_number(), ) } From e8c364b5dc8930de9b665085a15f6058ee092a2d Mon Sep 17 00:00:00 2001 From: Szegoo Date: Thu, 6 Oct 2022 09:15:04 +0200 Subject: [PATCH 45/55] simplify --- frame/merkle-mountain-range/src/lib.rs | 12 +++--------- frame/merkle-mountain-range/src/tests.rs | 4 ++-- primitives/merkle-mountain-range/src/lib.rs | 4 ++-- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 89023f50ab609..9f35036178318 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -372,16 +372,10 @@ impl, I: 'static> Pallet { (Vec>, primitives::BatchProof<>::Hash>), primitives::Error, > { - let now = frame_system::Pallet::::block_number().saturated_into::(); - let leaves = Self::mmr_leaves().saturated_into::(); - let best_block_as_u64 = best_known_block_number.saturated_into::(); - - let leaves_count = leaves - .saturating_sub(now) - .saturating_add(best_block_as_u64) - .saturated_into::(); + let leaves_count = + Self::block_num_to_leaf_index(best_known_block_number)?.saturating_add(1); if leaves_count > Self::mmr_leaves() { - return Err(Error::InvalidLeavesCount) + return Err(Error::InvalidBestKnownBlock) } // we need to translate the block_numbers into leaf indices. diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index 5bf973cc07784..3cd2d62cae1a3 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -978,13 +978,13 @@ fn does_not_panic_when_generating_historical_proofs() { // when leaves count is invalid assert_eq!( crate::Pallet::::generate_historical_batch_proof(vec![3], 100), - Err(Error::InvalidLeavesCount), + Err(Error::InvalidBestKnownBlock), ); // when both leaf index and leaves count are invalid assert_eq!( crate::Pallet::::generate_historical_batch_proof(vec![10], 100), - Err(Error::InvalidLeavesCount), + Err(Error::InvalidBestKnownBlock), ); }); } diff --git a/primitives/merkle-mountain-range/src/lib.rs b/primitives/merkle-mountain-range/src/lib.rs index 144c00846bf53..a48eaf9d0422d 100644 --- a/primitives/merkle-mountain-range/src/lib.rs +++ b/primitives/merkle-mountain-range/src/lib.rs @@ -405,8 +405,8 @@ pub enum Error { PalletNotIncluded, /// Cannot find the requested leaf index InvalidLeafIndex, - /// The provided leaves count is larger than the actual leaves count. - InvalidLeavesCount, + /// The provided best know block number is invalid. + InvalidBestKnownBlock, } impl Error { From 4538c0832e81d1bff5df9ff821c5515326bcc54e Mon Sep 17 00:00:00 2001 From: Szegoo Date: Thu, 6 Oct 2022 10:18:15 +0200 Subject: [PATCH 46/55] update docs --- frame/merkle-mountain-range/src/lib.rs | 2 +- primitives/merkle-mountain-range/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 9f35036178318..b96de635da234 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -359,7 +359,7 @@ impl, I: 'static> Pallet { ) } - /// Generate a MMR proof for the given `block_numbers` for the MMR of `leaves_count` size. + /// Generate a MMR proof for the given `block_numbers` given the `best_known_block_number`. /// /// Note this method can only be used from an off-chain context /// (Offchain Worker or Runtime API call), since it requires diff --git a/primitives/merkle-mountain-range/src/lib.rs b/primitives/merkle-mountain-range/src/lib.rs index a48eaf9d0422d..06bc1f4bffe84 100644 --- a/primitives/merkle-mountain-range/src/lib.rs +++ b/primitives/merkle-mountain-range/src/lib.rs @@ -462,7 +462,7 @@ sp_api::decl_runtime_apis! { /// Generate MMR proof for a series of blocks with the specified block numbers. fn generate_batch_proof(block_numbers: Vec) -> Result<(Vec, BatchProof), Error>; - /// Generate MMR proof for a series of `block_numbers`, using MMR at given `best_known_block_number` size. + /// Generate MMR proof for a series of `block_numbers`, given the `best_known_block_number`. fn generate_historical_batch_proof( block_numbers: Vec, best_known_block_number: BlockNumber From 42ec4d2cf5e56e1f0bd8ed17958e2a05746669d4 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Thu, 6 Oct 2022 18:45:00 +0200 Subject: [PATCH 47/55] nits --- frame/merkle-mountain-range/src/lib.rs | 44 ++++++++++++------------ frame/merkle-mountain-range/src/tests.rs | 6 ++-- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index b96de635da234..ea1911ae7492f 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -59,7 +59,7 @@ use codec::Encode; use frame_support::weights::Weight; use sp_runtime::{ - traits::{self, One, Saturating}, + traits::{self, One, Saturating, CheckedSub}, SaturatedConversion, }; @@ -323,22 +323,26 @@ impl, I: 'static> Pallet { where T: frame_system::Config, { - // leaf_indx = block_num - (current_block_num - leaves_count) - 1; - let leaves_count = Self::mmr_leaves().saturated_into::(); - let current_block_num = >::block_number().saturated_into::(); - let diff = current_block_num.saturating_sub(leaves_count.into()); - - let block_num_as_u64 = block_num.saturated_into::(); - - if block_num_as_u64 <= diff { - return Err( - primitives::Error::BlockNumToLeafIndex.log_debug("The block_number is incorrect.") + // leaf_idx = (leaves_count - 1) - (current_block_num - block_num); + let best_block_num = >::block_number(); + let blocks_diff = best_block_num.checked_sub(&block_num).ok_or_else(|| { + primitives::Error::BlockNumToLeafIndex.log_debug( + "The provided block_number is greater than the best block number.", ) - } - - let leaf_index = (block_num_as_u64.saturating_sub(diff).saturating_sub(1u32.into())) - .saturated_into::(); - Ok(leaf_index) + })?; + let blocks_diff_as_leaf_idx = blocks_diff.try_into().map_err(|_| { + primitives::Error::BlockNumToLeafIndex + .log_debug("The `blocks_diff` couldn't be converted to `LeafIndex`.") + })?; + + let leaf_idx = Self::mmr_leaves() + .checked_sub(1) + .and_then(|last_leaf_idx| last_leaf_idx.checked_sub(blocks_diff_as_leaf_idx)) + .ok_or_else(|| { + primitives::Error::BlockNumToLeafIndex + .log_debug("There aren't enough leaves in the chain.") + })?; + Ok(leaf_idx) } /// Generate a MMR proof for the given `block_numbers`. @@ -374,16 +378,12 @@ impl, I: 'static> Pallet { > { let leaves_count = Self::block_num_to_leaf_index(best_known_block_number)?.saturating_add(1); - if leaves_count > Self::mmr_leaves() { - return Err(Error::InvalidBestKnownBlock) - } // we need to translate the block_numbers into leaf indices. let leaf_indices = block_numbers .iter() - .map(|n| -> Result { - let leaf_index = Self::block_num_to_leaf_index(*n)?; - Ok(leaf_index) + .map(|block_num| -> Result { + Self::block_num_to_leaf_index(*block_num) }) .collect::, _>>()?; diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index 3cd2d62cae1a3..0bd98ff6ed7a6 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -972,19 +972,19 @@ fn does_not_panic_when_generating_historical_proofs() { // when leaf index is invalid assert_eq!( crate::Pallet::::generate_historical_batch_proof(vec![10], 7), - Err(Error::LeafNotFound), + Err(Error::BlockNumToLeafIndex), ); // when leaves count is invalid assert_eq!( crate::Pallet::::generate_historical_batch_proof(vec![3], 100), - Err(Error::InvalidBestKnownBlock), + Err(Error::BlockNumToLeafIndex), ); // when both leaf index and leaves count are invalid assert_eq!( crate::Pallet::::generate_historical_batch_proof(vec![10], 100), - Err(Error::InvalidBestKnownBlock), + Err(Error::BlockNumToLeafIndex), ); }); } From 95262954dc3b005ddee8a4a747fe3beeb001603e Mon Sep 17 00:00:00 2001 From: Szegoo Date: Fri, 7 Oct 2022 11:21:31 +0200 Subject: [PATCH 48/55] fmt & fix --- frame/merkle-mountain-range/src/lib.rs | 7 +++---- test-utils/runtime/src/lib.rs | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index ea1911ae7492f..ad3ce340496e8 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -59,7 +59,7 @@ use codec::Encode; use frame_support::weights::Weight; use sp_runtime::{ - traits::{self, One, Saturating, CheckedSub}, + traits::{self, CheckedSub, One, Saturating}, SaturatedConversion, }; @@ -326,9 +326,8 @@ impl, I: 'static> Pallet { // leaf_idx = (leaves_count - 1) - (current_block_num - block_num); let best_block_num = >::block_number(); let blocks_diff = best_block_num.checked_sub(&block_num).ok_or_else(|| { - primitives::Error::BlockNumToLeafIndex.log_debug( - "The provided block_number is greater than the best block number.", - ) + primitives::Error::BlockNumToLeafIndex + .log_debug("The provided block_number is greater than the best block number.") })?; let blocks_diff_as_leaf_idx = blocks_diff.try_into().map_err(|_| { primitives::Error::BlockNumToLeafIndex diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 3db0e5510057b..91653f9927483 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -972,7 +972,7 @@ cfg_if! { } } - impl beefy_merkle_tree::BeefyMmrApi for RuntimeApi { + impl beefy_merkle_tree::BeefyMmrApi for RuntimeApi { fn authority_set_proof() -> beefy_primitives::mmr::BeefyAuthoritySet { Default::default() } From ba84f7bccd443004194eaaa64961f3b0cd45ed39 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Fri, 7 Oct 2022 11:25:40 +0200 Subject: [PATCH 49/55] merge fixes --- primitives/beefy/src/mmr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/primitives/beefy/src/mmr.rs b/primitives/beefy/src/mmr.rs index b479d979f13f3..75c491fda083f 100644 --- a/primitives/beefy/src/mmr.rs +++ b/primitives/beefy/src/mmr.rs @@ -159,7 +159,7 @@ mod mmr_root_provider { where B: Block, R: ProvideRuntimeApi, - R::Api: MmrApi, + R::Api: MmrApi, { /// Create new BEEFY Payload provider with MMR Root as payload. pub fn new(runtime: Arc) -> Self { @@ -182,7 +182,7 @@ mod mmr_root_provider { where B: Block, R: ProvideRuntimeApi, - R::Api: MmrApi, + R::Api: MmrApi, { fn payload(&self, header: &B::Header) -> Option { self.mmr_root_from_digest_or_runtime(header).map(|mmr_root| { From 0c01e2adcb5ae9c1ee9bc3674ab6bf5bbd42fe66 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Fri, 7 Oct 2022 11:32:44 +0200 Subject: [PATCH 50/55] fix --- primitives/beefy/src/mmr.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/primitives/beefy/src/mmr.rs b/primitives/beefy/src/mmr.rs index 75c491fda083f..0edb8babd608e 100644 --- a/primitives/beefy/src/mmr.rs +++ b/primitives/beefy/src/mmr.rs @@ -142,7 +142,7 @@ pub use mmr_root_provider::MmrRootProvider; mod mmr_root_provider { use super::*; use crate::{known_payloads, payload::PayloadProvider, Payload}; - use sp_api::ProvideRuntimeApi; + use sp_api::{NumberFor, ProvideRuntimeApi}; use sp_mmr_primitives::MmrApi; use sp_runtime::generic::BlockId; use sp_std::{marker::PhantomData, sync::Arc}; @@ -159,7 +159,7 @@ mod mmr_root_provider { where B: Block, R: ProvideRuntimeApi, - R::Api: MmrApi, + R::Api: MmrApi>, { /// Create new BEEFY Payload provider with MMR Root as payload. pub fn new(runtime: Arc) -> Self { @@ -182,7 +182,7 @@ mod mmr_root_provider { where B: Block, R: ProvideRuntimeApi, - R::Api: MmrApi, + R::Api: MmrApi>, { fn payload(&self, header: &B::Header) -> Option { self.mmr_root_from_digest_or_runtime(header).map(|mmr_root| { From 47dfdfb790881b677f400d131d624d99a5b56a3c Mon Sep 17 00:00:00 2001 From: Szegoo Date: Fri, 7 Oct 2022 11:37:27 +0200 Subject: [PATCH 51/55] small fix --- test-utils/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 91653f9927483..3db0e5510057b 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -972,7 +972,7 @@ cfg_if! { } } - impl beefy_merkle_tree::BeefyMmrApi for RuntimeApi { + impl beefy_merkle_tree::BeefyMmrApi for RuntimeApi { fn authority_set_proof() -> beefy_primitives::mmr::BeefyAuthoritySet { Default::default() } From 5abad1dfd6f1f3448201465515e49d4619c56b0e Mon Sep 17 00:00:00 2001 From: Szegoo Date: Fri, 7 Oct 2022 18:29:32 +0200 Subject: [PATCH 52/55] docs & nit fixes --- client/beefy/src/tests.rs | 12 +++++------- frame/merkle-mountain-range/rpc/src/lib.rs | 13 ++++++------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/client/beefy/src/tests.rs b/client/beefy/src/tests.rs index 3c13a80d89d34..89be1cac4f886 100644 --- a/client/beefy/src/tests.rs +++ b/client/beefy/src/tests.rs @@ -43,9 +43,7 @@ use beefy_primitives::{ KEY_TYPE as BeefyKeyType, }; use sc_network::{config::RequestResponseConfig, ProtocolName}; -use sp_mmr_primitives::{ - BatchProof, EncodableOpaqueLeaf, Error as MmrError, LeafIndex, MmrApi, Proof, -}; +use sp_mmr_primitives::{BatchProof, EncodableOpaqueLeaf, Error as MmrError, MmrApi, Proof}; use sp_api::{ApiRef, ProvideRuntimeApi}; use sp_consensus::BlockOrigin; @@ -248,7 +246,7 @@ macro_rules! create_test_api { } impl MmrApi> for RuntimeApi { - fn generate_proof(_leaf_index: LeafIndex) + fn generate_proof(_block_number: u64) -> Result<(EncodableOpaqueLeaf, Proof), MmrError> { unimplemented!() } @@ -270,13 +268,13 @@ macro_rules! create_test_api { Ok($mmr_root) } - fn generate_batch_proof(_leaf_indices: Vec) -> Result<(Vec, BatchProof), MmrError> { + fn generate_batch_proof(_block_numbers: Vec) -> Result<(Vec, BatchProof), MmrError> { unimplemented!() } fn generate_historical_batch_proof( - _leaf_indices: Vec, - _leaves_count: LeafIndex + _block_numbers: Vec, + _best_known_block_number: u64 ) -> Result<(Vec, BatchProof), MmrError> { unimplemented!() } diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index f560c3c3e9aca..021d62d226b29 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -129,19 +129,18 @@ pub trait MmrApi { at: Option, ) -> RpcResult>; - /// Generate a MMR proof for the given `block_numbers` of the MMR that had `leaves_count` - /// leaves. + /// Generate a MMR proof for the given `block_numbers` given the `best_known_block_number`. /// /// This method calls into a runtime with MMR pallet included and attempts to generate - /// a MMR proof for the set of leaves at the given `leaf_indices` with MMR fixed to the state - /// with exactly `leaves_count` leaves. `leaves_count` must be larger than all `leaf_indices` - /// for the function to succeed. + /// a MMR proof for the set of blocks that have the given `block_numbers` with MMR given the + /// `best_known_block_number`. `best_known_block_number` must be larger than all the + /// `block_numbers` for the function to succeed. /// /// Optionally, a block hash at which the runtime should be queried can be specified. /// Note that specifying the block hash isn't super-useful here, unless you're generating /// proof using non-finalized blocks where there are several competing forks. That's because - /// MMR state will be fixed to the state with `leaves_count`, which already points to some - /// historical block. + /// MMR state will be fixed to the state with `best_known_block_number`, which already points to + /// some historical block. /// /// Returns the leaves and a proof for these leaves (compact encoding, i.e. hash of /// the leaves). Both parameters are SCALE-encoded. From 4eb1efe7aa58f86712bfe5e7625701dace62bda7 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Tue, 11 Oct 2022 15:40:59 +0200 Subject: [PATCH 53/55] Nit fixes --- frame/merkle-mountain-range/rpc/src/lib.rs | 19 +++++++++---------- frame/merkle-mountain-range/src/tests.rs | 22 ++++++++++------------ 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/frame/merkle-mountain-range/rpc/src/lib.rs b/frame/merkle-mountain-range/rpc/src/lib.rs index 021d62d226b29..ffc7ac2da56bf 100644 --- a/frame/merkle-mountain-range/rpc/src/lib.rs +++ b/frame/merkle-mountain-range/rpc/src/lib.rs @@ -30,7 +30,7 @@ use jsonrpsee::{ }; use serde::{Deserialize, Serialize}; -use sp_api::ProvideRuntimeApi; +use sp_api::{NumberFor, ProvideRuntimeApi}; use sp_blockchain::HeaderBackend; use sp_core::Bytes; use sp_mmr_primitives::{BatchProof, Error as MmrError, Proof}; @@ -121,7 +121,7 @@ pub trait MmrApi { /// Returns the leaves and a proof for these leaves (compact encoding, i.e. hash of /// the leaves). Both parameters are SCALE-encoded. /// The order of entries in the `leaves` field of the returned struct - /// is the same as the order of the entries in `leaf_indices` supplied + /// is the same as the order of the entries in `block_numbers` supplied #[method(name = "mmr_generateBatchProof")] fn generate_batch_proof( &self, @@ -145,7 +145,7 @@ pub trait MmrApi { /// Returns the leaves and a proof for these leaves (compact encoding, i.e. hash of /// the leaves). Both parameters are SCALE-encoded. /// The order of entries in the `leaves` field of the returned struct - /// is the same as the order of the entries in `leaf_indices` supplied + /// is the same as the order of the entries in `block_numbers` supplied #[method(name = "mmr_generateHistoricalBatchProof")] fn generate_historical_batch_proof( &self, @@ -169,18 +169,17 @@ impl Mmr { } #[async_trait] -impl MmrApiServer<::Hash, BlockNumber> +impl MmrApiServer<::Hash, NumberFor> for Mmr where Block: BlockT, Client: Send + Sync + 'static + ProvideRuntimeApi + HeaderBackend, - Client::Api: MmrRuntimeApi, + Client::Api: MmrRuntimeApi>, MmrHash: Codec + Send + Sync + 'static, - BlockNumber: Codec, { fn generate_proof( &self, - block_number: BlockNumber, + block_number: NumberFor, at: Option<::Hash>, ) -> RpcResult> { let api = self.client.runtime_api(); @@ -200,7 +199,7 @@ where fn generate_batch_proof( &self, - block_numbers: Vec, + block_numbers: Vec>, at: Option<::Hash>, ) -> RpcResult::Hash>> { let api = self.client.runtime_api(); @@ -222,8 +221,8 @@ where fn generate_historical_batch_proof( &self, - block_numbers: Vec, - best_known_block_number: BlockNumber, + block_numbers: Vec>, + best_known_block_number: NumberFor, at: Option<::Hash>, ) -> RpcResult::Hash>> { let api = self.client.runtime_api(); diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index 0bd98ff6ed7a6..63780edc2b2ac 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -249,14 +249,14 @@ fn should_generate_proofs_correctly() { // to retrieve full leaf data. register_offchain_ext(&mut ext); ext.execute_with(|| { - let now = frame_system::Pallet::::block_number(); + let best_block_number = frame_system::Pallet::::block_number(); // when generate proofs for all leaves. - let proofs = (1_u64..=now) + let proofs = (1_u64..=best_block_number) .into_iter() .map(|block_num| crate::Pallet::::generate_batch_proof(vec![block_num]).unwrap()) .collect::>(); // when generate historical proofs for all leaves - let historical_proofs = (1_u64..now) + let historical_proofs = (1_u64..best_block_number) .into_iter() .map(|block_num| { let mut proofs = vec![]; @@ -424,18 +424,17 @@ fn should_generate_batch_proof_correctly() { register_offchain_ext(&mut ext); ext.execute_with(|| { // when generate proofs for a batch of leaves - let (.., proof) = crate::Pallet::::generate_batch_proof(vec![1, 4, 5]).unwrap(); + let (.., proof) = crate::Pallet::::generate_batch_proof(vec![1, 5, 6]).unwrap(); // then assert_eq!( proof, BatchProof { // the leaf indices are equivalent to the above specified block numbers - 1. - leaf_indices: vec![0, 3, 4], + leaf_indices: vec![0, 4, 5], leaf_count: 7, items: vec![ hex("ad4cbc033833612ccd4626d5f023b9dfc50a35e838514dd1f3c86f8506728705"), - hex("9ba3bd51dcd2547a0155cf13411beeed4e2b640163bbea02806984f3fcbf822e"), - hex("8ed25570209d8f753d02df07c1884ddb36a3d9d4770e4608b188322151c657fe"), + hex("cb24f4614ad5b2a5430344c99545b421d9af83c46fd632d70a332200884b4d46"), hex("611c2174c6164952a66d985cfe1ec1a623794393e3acff96b136d198f37a648c"), ], } @@ -443,24 +442,23 @@ fn should_generate_batch_proof_correctly() { // when generate historical proofs for a batch of leaves let (.., historical_proof) = - crate::Pallet::::generate_historical_batch_proof(vec![1, 4, 5], 6).unwrap(); + crate::Pallet::::generate_historical_batch_proof(vec![1, 5, 6], 6).unwrap(); // then assert_eq!( historical_proof, BatchProof { - leaf_indices: vec![0, 3, 4], + leaf_indices: vec![0, 4, 5], leaf_count: 6, items: vec![ hex("ad4cbc033833612ccd4626d5f023b9dfc50a35e838514dd1f3c86f8506728705"), - hex("9ba3bd51dcd2547a0155cf13411beeed4e2b640163bbea02806984f3fcbf822e"), - hex("8ed25570209d8f753d02df07c1884ddb36a3d9d4770e4608b188322151c657fe"), + hex("cb24f4614ad5b2a5430344c99545b421d9af83c46fd632d70a332200884b4d46"), ], } ); // when generate historical proofs for a batch of leaves let (.., historical_proof) = - crate::Pallet::::generate_historical_batch_proof(vec![1, 4, 5], 7).unwrap(); + crate::Pallet::::generate_historical_batch_proof(vec![1, 5, 6], 7).unwrap(); // then assert_eq!(historical_proof, proof); }); From c73691716f95d53a04adc2a6890079dfa468abe8 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Tue, 11 Oct 2022 15:55:33 +0200 Subject: [PATCH 54/55] remove leaf_indices_to_block_numbers() --- frame/merkle-mountain-range/src/tests.rs | 41 +++++++----------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index 63780edc2b2ac..0bed68cd39c31 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -83,20 +83,6 @@ fn add_blocks(blocks: usize) { } } -fn leaf_indices_to_block_numbers( - ext: &mut sp_io::TestExternalities, - leaf_indices: &Vec, -) -> Vec { - leaf_indices - .iter() - .map(|l| { - let mmr_size = ext.execute_with(|| crate::Pallet::::mmr_leaves()); - ext.execute_with(|| crate::Pallet::::leaf_index_to_parent_block_num(*l, mmr_size)) - .saturating_add(1u32.into()) - }) - .collect() -} - #[test] fn should_start_empty() { let _ = env_logger::try_init(); @@ -561,33 +547,30 @@ fn should_verify_batch_proofs() { // to retrieve full leaf data when generating proofs register_offchain_ext(&mut ext); - // verify that up to n=10, valid proofs are generated for all possible leaf combinations - for n in 0..10 { + // verify that up to n=10, valid proofs are generated for all possible block number combinations. + for n in 1..=10 { ext.execute_with(|| new_block()); ext.persist_offchain_overlay(); - // generate powerset (skipping empty set) of all possible leaf combinations for mmr size n - let leaves_set: Vec> = (0..=n).into_iter().powerset().skip(1).collect(); + // generate powerset (skipping empty set) of all possible block number combinations for mmr size n. + let blocks_set: Vec> = (1..=n).into_iter().powerset().skip(1).collect(); - leaves_set.iter().for_each(|leaves_subset| { - let block_numbers = leaf_indices_to_block_numbers(&mut ext, leaves_subset); - generate_and_verify_batch_proof(&mut ext, &block_numbers, 0); + blocks_set.iter().for_each(|blocks_subset| { + generate_and_verify_batch_proof(&mut ext, &blocks_subset, 0); ext.persist_offchain_overlay(); }); } - // verify that up to n=15, valid proofs are generated for all possible 2-leaf combinations - for n in 10..15 { - // (MMR Leafs) + // verify that up to n=15, valid proofs are generated for all possible 2-block number combinations. + for n in 11..=15 { ext.execute_with(|| new_block()); ext.persist_offchain_overlay(); - // generate all possible 2-leaf combinations for mmr size n - let leaves_set: Vec> = (0..=n).into_iter().combinations(2).collect(); + // generate all possible 2-block number combinations for mmr size n. + let blocks_set: Vec> = (1..=n).into_iter().combinations(2).collect(); - leaves_set.iter().for_each(|leaves_subset| { - let block_numbers = leaf_indices_to_block_numbers(&mut ext, leaves_subset); - generate_and_verify_batch_proof(&mut ext, &block_numbers, 0); + blocks_set.iter().for_each(|blocks_subset| { + generate_and_verify_batch_proof(&mut ext, &blocks_subset, 0); ext.persist_offchain_overlay(); }); } From ac636bdb3565482cf1ebc0ca5d079b00a887043b Mon Sep 17 00:00:00 2001 From: Szegoo Date: Tue, 11 Oct 2022 15:59:41 +0200 Subject: [PATCH 55/55] fmt --- frame/merkle-mountain-range/src/tests.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index 0bed68cd39c31..a63a433029295 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -547,12 +547,14 @@ fn should_verify_batch_proofs() { // to retrieve full leaf data when generating proofs register_offchain_ext(&mut ext); - // verify that up to n=10, valid proofs are generated for all possible block number combinations. + // verify that up to n=10, valid proofs are generated for all possible block number + // combinations. for n in 1..=10 { ext.execute_with(|| new_block()); ext.persist_offchain_overlay(); - // generate powerset (skipping empty set) of all possible block number combinations for mmr size n. + // generate powerset (skipping empty set) of all possible block number combinations for mmr + // size n. let blocks_set: Vec> = (1..=n).into_iter().powerset().skip(1).collect(); blocks_set.iter().for_each(|blocks_subset| { @@ -561,7 +563,8 @@ fn should_verify_batch_proofs() { }); } - // verify that up to n=15, valid proofs are generated for all possible 2-block number combinations. + // verify that up to n=15, valid proofs are generated for all possible 2-block number + // combinations. for n in 11..=15 { ext.execute_with(|| new_block()); ext.persist_offchain_overlay();