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

Consolidate and deduplicate MMR API methods #12530

Merged
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
2ccf7c0
histor. batch proof: make best block arg optional
Lederstrumpf Oct 17, 2022
019d5cd
correct testing range
Lederstrumpf Oct 17, 2022
deb12a4
make generate_batch_proof stub for historical
Lederstrumpf Oct 18, 2022
5ffff01
merge generate_{historical_}batch_proof functions
Lederstrumpf Oct 18, 2022
ed0f1fa
merge generate_{batch_}proof functions
Lederstrumpf Oct 18, 2022
0730e9a
merge verify_{batch_}proof functions
Lederstrumpf Oct 18, 2022
e617095
merge verify_{batch_}proof_stateless functions
Lederstrumpf Oct 18, 2022
f08f6f0
remove {Leaf}Proof
Lederstrumpf Oct 19, 2022
2657723
rename BatchProof->Proof
Lederstrumpf Oct 19, 2022
f0454e5
cleanup
Lederstrumpf Oct 19, 2022
e77bcd9
expose verify_proof rpc api
Lederstrumpf Nov 6, 2022
1c599ef
document verify_proof
Lederstrumpf Nov 6, 2022
159712e
expose verify_proof_stateless rpc api
Lederstrumpf Nov 6, 2022
d576d3a
add optional BlockHash to mmr_root rpc api
Lederstrumpf Nov 7, 2022
087c77e
fixup! expose verify_proof rpc api
Lederstrumpf Nov 7, 2022
39f3676
fix documentation phrasing
Lederstrumpf Nov 7, 2022
212161d
documentation grammar
Lederstrumpf Nov 7, 2022
5ae856a
Merge remote-tracking branch 'origin/master' into consolidate-and-ded…
Nov 8, 2022
d5f4cf7
define mmr error msgs together with error enum
Lederstrumpf Nov 8, 2022
a7069fd
fixup! define mmr error msgs together with error enum
Lederstrumpf Nov 8, 2022
63d7694
map decoding errors to CallError::InvalidParams
Lederstrumpf Nov 8, 2022
95aa689
fixup! map decoding errors to CallError::InvalidParams
Lederstrumpf Nov 8, 2022
bfaaa06
Merge remote-tracking branch 'origin/master' into consolidate-and-ded…
Nov 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 53 additions & 3 deletions frame/merkle-mountain-range/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,11 @@ impl<BlockHash> LeavesProof<BlockHash> {

/// MMR RPC methods.
#[rpc(client, server)]
pub trait MmrApi<BlockHash, BlockNumber> {
/// Generate a MMR proof for the given `block_numbers`.
pub trait MmrApi<BlockHash, BlockNumber, MmrHash> {
/// Get the MMR root hash for the current best block.
#[method(name = "mmr_root")]
fn mmr_root(&self) -> RpcResult<MmrHash>;
/// Generate an MMR proof for the given `block_numbers`.
Lederstrumpf marked this conversation as resolved.
Show resolved Hide resolved
///
/// This method calls into a runtime with MMR pallet included and attempts to generate
/// a MMR proof for the set of blocks that have the given `block_numbers` with MMR given the
Expand Down Expand Up @@ -115,6 +118,19 @@ pub trait MmrApi<BlockHash, BlockNumber> {
&self,
proof: LeavesProof<BlockHash>,
) -> RpcResult<bool>;

/// Verify an MMR `proof` statelessly given an `mmr_root`.
///
/// This method calls into a runtime with MMR pallet included and attempts to verify
/// a MMR proof against a provided mmr root.
///
/// Returns `true` if the proof is valid, else returns the verification error.
#[method(name = "mmr_verifyProofStateless")]
fn verify_proof_stateless(
&self,
mmr_root: MmrHash,
proof: LeavesProof<BlockHash>,
) -> RpcResult<bool>;
}

/// MMR RPC methods.
Expand All @@ -131,14 +147,23 @@ impl<C, B> Mmr<C, B> {
}

#[async_trait]
impl<Client, Block, MmrHash> MmrApiServer<<Block as BlockT>::Hash, NumberFor<Block>>
impl<Client, Block, MmrHash> MmrApiServer<<Block as BlockT>::Hash, NumberFor<Block>, MmrHash>
for Mmr<Client, (Block, MmrHash)>
where
Block: BlockT,
Client: Send + Sync + 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
Client::Api: MmrRuntimeApi<Block, MmrHash, NumberFor<Block>>,
MmrHash: Codec + Send + Sync + 'static,
{
fn mmr_root(&self) -> RpcResult<MmrHash> {
let best_block_hash = self.client.info().best_hash;
let api = self.client.runtime_api();
let mmr_root = api.mmr_root(&BlockId::Hash(best_block_hash))
.map_err(runtime_error_into_rpc_error)?
.map_err(mmr_error_into_rpc_error)?;
Ok(mmr_root)
}

fn generate_proof(
&self,
block_numbers: Vec<NumberFor<Block>>,
Expand Down Expand Up @@ -185,6 +210,31 @@ where

Ok(true)
}

fn verify_proof_stateless(
&self,
mmr_root: MmrHash,
proof: LeavesProof<<Block as BlockT>::Hash>,
) -> RpcResult<bool> {
let api = self.client.runtime_api();

let leaves =
Decode::decode(&mut &proof.leaves.0[..]).map_err(runtime_error_into_rpc_error)?;

let decoded_proof =
Decode::decode(&mut &proof.proof.0[..]).map_err(runtime_error_into_rpc_error)?;

api.verify_proof_stateless(
&BlockId::hash(proof.block_hash),
mmr_root,
leaves,
decoded_proof,
)
.map_err(runtime_error_into_rpc_error)?
.map_err(mmr_error_into_rpc_error)?;
acatangiu marked this conversation as resolved.
Show resolved Hide resolved

Ok(true)
}
}

/// Converts a mmr-specific error into a [`CallError`].
Expand Down