Skip to content

Commit

Permalink
Consolidate and deduplicate MMR API methods (paritytech#12530)
Browse files Browse the repository at this point in the history
* histor. batch proof: make best block arg optional

* correct testing range

* make generate_batch_proof stub for historical

* merge generate_{historical_}batch_proof functions

* merge generate_{batch_}proof functions

* merge verify_{batch_}proof functions

* merge verify_{batch_}proof_stateless functions

* remove {Leaf}Proof

Not utilized by API anymore, so superfluous.
Removal consistent with prior changes to just use "batch" proof API.

* rename BatchProof->Proof

no need to qualify if only one universal proof type.

* cleanup

* expose verify_proof rpc api

* document verify_proof

* expose verify_proof_stateless rpc api

* add optional BlockHash to mmr_root rpc api

* fixup! expose verify_proof rpc api

* fix documentation phrasing

Co-authored-by: Adrian Catangiu <adrian@parity.io>

* documentation grammar

Co-authored-by: Adrian Catangiu <adrian@parity.io>

* define mmr error msgs together with error enum

Co-authored-by: Serban Iorga <serban@parity.io>

* fixup! define mmr error msgs together with error enum

* map decoding errors to CallError::InvalidParams

Co-authored-by: Serban Iorga <serban@parity.io>

* fixup! map decoding errors to CallError::InvalidParams

Co-authored-by: Adrian Catangiu <adrian@parity.io>
Co-authored-by: parity-processbot <>
Co-authored-by: Serban Iorga <serban@parity.io>
  • Loading branch information
3 people authored and ark0f committed Feb 27, 2023
1 parent f42248e commit c1052f0
Show file tree
Hide file tree
Showing 13 changed files with 249 additions and 387 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 7 additions & 51 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2055,59 +2055,15 @@ impl_runtime_apis! {
mmr::Hash,
BlockNumber,
> for Runtime {
fn generate_proof(block_number: BlockNumber)
-> Result<(mmr::EncodableOpaqueLeaf, mmr::Proof<mmr::Hash>), mmr::Error>
{
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)?
))
)
}

fn verify_proof(leaf: mmr::EncodableOpaqueLeaf, proof: mmr::Proof<mmr::Hash>)
-> Result<(), mmr::Error>
{
let leaf: mmr::Leaf = leaf
.into_opaque_leaf()
.try_decode()
.ok_or(mmr::Error::Verify)?;
Mmr::verify_leaves(vec![leaf], mmr::Proof::into_batch_proof(proof))
}

fn verify_proof_stateless(
root: mmr::Hash,
leaf: mmr::EncodableOpaqueLeaf,
proof: mmr::Proof<mmr::Hash>
) -> Result<(), mmr::Error> {
let node = mmr::DataOrHash::Data(leaf.into_opaque_leaf());
pallet_mmr::verify_leaves_proof::<mmr::Hashing, _>(root, vec![node], mmr::Proof::into_batch_proof(proof))
}

fn mmr_root() -> Result<mmr::Hash, mmr::Error> {
Ok(Mmr::mmr_root())
}

fn generate_batch_proof(
block_numbers: Vec<BlockNumber>,
) -> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::BatchProof<mmr::Hash>), mmr::Error> {
Mmr::generate_batch_proof(block_numbers).map(|(leaves, proof)| {
(
leaves
.into_iter()
.map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf))
.collect(),
proof,
)
})
}

fn generate_historical_batch_proof(
fn generate_proof(
block_numbers: Vec<BlockNumber>,
best_known_block_number: BlockNumber,
) -> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::BatchProof<mmr::Hash>), mmr::Error> {
Mmr::generate_historical_batch_proof(block_numbers, best_known_block_number).map(
best_known_block_number: Option<BlockNumber>,
) -> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::Proof<mmr::Hash>), mmr::Error> {
Mmr::generate_proof(block_numbers, best_known_block_number).map(
|(leaves, proof)| {
(
leaves
Expand All @@ -2120,7 +2076,7 @@ impl_runtime_apis! {
)
}

fn verify_batch_proof(leaves: Vec<mmr::EncodableOpaqueLeaf>, proof: mmr::BatchProof<mmr::Hash>)
fn verify_proof(leaves: Vec<mmr::EncodableOpaqueLeaf>, proof: mmr::Proof<mmr::Hash>)
-> Result<(), mmr::Error>
{
let leaves = leaves.into_iter().map(|leaf|
Expand All @@ -2130,10 +2086,10 @@ impl_runtime_apis! {
Mmr::verify_leaves(leaves, proof)
}

fn verify_batch_proof_stateless(
fn verify_proof_stateless(
root: mmr::Hash,
leaves: Vec<mmr::EncodableOpaqueLeaf>,
proof: mmr::BatchProof<mmr::Hash>
proof: mmr::Proof<mmr::Hash>
) -> Result<(), mmr::Error> {
let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect();
pallet_mmr::verify_leaves_proof::<mmr::Hashing, _>(root, nodes, proof)
Expand Down
36 changes: 7 additions & 29 deletions client/beefy/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use beefy_primitives::{
KEY_TYPE as BeefyKeyType,
};
use sc_network::{config::RequestResponseConfig, ProtocolName};
use sp_mmr_primitives::{BatchProof, EncodableOpaqueLeaf, Error as MmrError, MmrApi, Proof};
use sp_mmr_primitives::{EncodableOpaqueLeaf, Error as MmrError, MmrApi, Proof};

use sp_api::{ApiRef, ProvideRuntimeApi};
use sp_consensus::BlockOrigin;
Expand Down Expand Up @@ -246,47 +246,25 @@ macro_rules! create_test_api {
}

impl MmrApi<Block, MmrRootHash, NumberFor<Block>> for RuntimeApi {
fn generate_proof(_block_number: u64)
-> Result<(EncodableOpaqueLeaf, Proof<MmrRootHash>), MmrError> {
unimplemented!()
}

fn verify_proof(_leaf: EncodableOpaqueLeaf, _proof: Proof<MmrRootHash>)
-> Result<(), MmrError> {
unimplemented!()
}

fn verify_proof_stateless(
_root: MmrRootHash,
_leaf: EncodableOpaqueLeaf,
_proof: Proof<MmrRootHash>
) -> Result<(), MmrError> {
unimplemented!()
}

fn mmr_root() -> Result<MmrRootHash, MmrError> {
Ok($mmr_root)
}

fn generate_batch_proof(_block_numbers: Vec<u64>) -> Result<(Vec<EncodableOpaqueLeaf>, BatchProof<MmrRootHash>), MmrError> {
unimplemented!()
}

fn generate_historical_batch_proof(
fn generate_proof(
_block_numbers: Vec<u64>,
_best_known_block_number: u64
) -> Result<(Vec<EncodableOpaqueLeaf>, BatchProof<MmrRootHash>), MmrError> {
_best_known_block_number: Option<u64>
) -> Result<(Vec<EncodableOpaqueLeaf>, Proof<MmrRootHash>), MmrError> {
unimplemented!()
}

fn verify_batch_proof(_leaves: Vec<EncodableOpaqueLeaf>, _proof: BatchProof<MmrRootHash>) -> Result<(), MmrError> {
fn verify_proof(_leaves: Vec<EncodableOpaqueLeaf>, _proof: Proof<MmrRootHash>) -> Result<(), MmrError> {
unimplemented!()
}

fn verify_batch_proof_stateless(
fn verify_proof_stateless(
_root: MmrRootHash,
_leaves: Vec<EncodableOpaqueLeaf>,
_proof: BatchProof<MmrRootHash>
_proof: Proof<MmrRootHash>
) -> Result<(), MmrError> {
unimplemented!()
}
Expand Down
2 changes: 1 addition & 1 deletion frame/beefy-mmr/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
//! Inner nodes are created by concatenating child hashes and hashing again. The implementation
//! does not perform any sorting of the input data (leaves) nor when inner nodes are created.
//!
//! If the number of leaves is not even, last leave (hash of) is promoted to the upper layer.
//! If the number of leaves is not even, last leaf (hash of) is promoted to the upper layer.

pub use sp_runtime::traits::Keccak256;
use sp_runtime::{app_crypto::sp_core, sp_std, traits::Hash as HashT};
Expand Down
1 change: 1 addition & 0 deletions frame/merkle-mountain-range/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ sp-blockchain = { version = "4.0.0-dev", path = "../../../primitives/blockchain"
sp-core = { version = "6.0.0", path = "../../../primitives/core" }
sp-mmr-primitives = { version = "4.0.0-dev", path = "../../../primitives/merkle-mountain-range" }
sp-runtime = { version = "6.0.0", path = "../../../primitives/runtime" }
anyhow = "1"

[dev-dependencies]
serde_json = "1.0.85"
Loading

0 comments on commit c1052f0

Please sign in to comment.