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

pallet-mmr: RPC API and Runtime API work with block numbers #12345

Merged
merged 65 commits into from
Oct 13, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
1b8a251
pallet-mmr: RPC API works with block_numbers
Szegoo Sep 24, 2022
fe3f2f3
fixes
Szegoo Sep 24, 2022
f01b68b
update rpc
Szegoo Sep 25, 2022
1b572ad
fmt
Szegoo Sep 25, 2022
2a760ba
final touches in the rpc
Szegoo Sep 25, 2022
d7e50ca
temporary fix
Szegoo Sep 25, 2022
e37e32a
fix
Szegoo Sep 25, 2022
02b0cfa
fmt
Szegoo Sep 25, 2022
f39fc8d
docs
Szegoo Sep 25, 2022
fa8155d
Update lib.rs
Szegoo Sep 25, 2022
32bb713
use NumberFor
Szegoo Sep 26, 2022
ae03943
validate input
Szegoo Sep 26, 2022
8dc459e
update runtime
Szegoo Sep 26, 2022
78d2ea1
convert block_number to u64
Szegoo Sep 26, 2022
9a3bfe9
small edit
Szegoo Sep 26, 2022
3c8c396
update runtime api
Szegoo Sep 28, 2022
850c782
test fix
Szegoo Sep 28, 2022
098c88b
runtime fix
Szegoo Sep 28, 2022
5e2eb39
update test function
Szegoo Sep 28, 2022
3bd4b72
fmt
Szegoo Sep 28, 2022
6295c51
fix nits
Szegoo Sep 28, 2022
5f909e3
remove block_num_to_leaf_index from runtime api
Szegoo Sep 28, 2022
379021e
Merge branch 'paritytech:master' into mmr-rpc
Szegoo Sep 28, 2022
6b7b4bb
Merge branch 'paritytech:master' into mmr-rpc
Szegoo Sep 29, 2022
97152b6
Update frame/merkle-mountain-range/src/lib.rs
Szegoo Sep 30, 2022
28e4437
fix tests
Szegoo Sep 30, 2022
f863814
merge
Szegoo Sep 30, 2022
3da0a90
get the code to compile after merge
Szegoo Sep 30, 2022
245d967
get the tests to compile
Szegoo Sep 30, 2022
3c355a0
fix in tests?
Szegoo Sep 30, 2022
f54c3a7
fix test
Szegoo Sep 30, 2022
e3d046b
Merge branch 'master' into mmr-rpc
Szegoo Oct 2, 2022
0dba52b
Update frame/merkle-mountain-range/src/tests.rs
Szegoo Oct 3, 2022
d68aaae
Update frame/merkle-mountain-range/src/lib.rs
Szegoo Oct 3, 2022
a792fc4
Update primitives/merkle-mountain-range/src/lib.rs
Szegoo Oct 3, 2022
e3d304a
Merge branch 'master' into mmr-rpc
Szegoo Oct 3, 2022
dbd7edb
fix errors & nits
Szegoo Oct 3, 2022
2004425
change block_num_to_leaf_index
Szegoo Oct 3, 2022
2778f7a
don't make any assumptions
Szegoo Oct 4, 2022
0a17093
Update frame/merkle-mountain-range/src/tests.rs
Szegoo Oct 4, 2022
e7d2dff
Update frame/merkle-mountain-range/src/tests.rs
Szegoo Oct 4, 2022
701e6d3
Update frame/merkle-mountain-range/src/tests.rs
Szegoo Oct 4, 2022
eb32356
fix
Szegoo Oct 4, 2022
900db49
small fix
Szegoo Oct 4, 2022
5232ef9
Merge branch 'paritytech:master' into mmr-rpc
Szegoo Oct 4, 2022
d57f6f4
Merge branch 'master' into mmr-rpc
Szegoo Oct 5, 2022
3a6b998
use best_known_block_number
Szegoo Oct 5, 2022
66b8c33
best_known_block_number instead of leaves_count
Szegoo Oct 5, 2022
75088ff
more readable?
Szegoo Oct 5, 2022
3dc7838
remove warning
Szegoo Oct 5, 2022
cad6805
Merge branch 'paritytech:master' into mmr-rpc
Szegoo Oct 5, 2022
2ae0e20
Update frame/merkle-mountain-range/src/lib.rs
Szegoo Oct 6, 2022
e8c364b
simplify
Szegoo Oct 6, 2022
4538c08
update docs
Szegoo Oct 6, 2022
42ec4d2
nits
Szegoo Oct 6, 2022
9526295
fmt & fix
Szegoo Oct 7, 2022
e78e3a4
Merge branch 'paritytech:master' into mmr-rpc
Szegoo Oct 7, 2022
ba84f7b
merge fixes
Szegoo Oct 7, 2022
0c01e2a
fix
Szegoo Oct 7, 2022
47dfdfb
small fix
Szegoo Oct 7, 2022
5abad1d
docs & nit fixes
Szegoo Oct 7, 2022
4eb1efe
Nit fixes
Szegoo Oct 11, 2022
c736917
remove leaf_indices_to_block_numbers()
Szegoo Oct 11, 2022
876daf2
Merge branch 'paritytech:master' into mmr-rpc
Szegoo Oct 11, 2022
ac636bd
fmt
Szegoo Oct 11, 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
6 changes: 5 additions & 1 deletion bin/node/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ where
+ 'static,
C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
C::Api: pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber, Hash>,
C::Api: pallet_mmr_rpc::MmrRuntimeApi<Block, <Block as sp_runtime::traits::Block>::Hash>,
C::Api: pallet_mmr_rpc::MmrRuntimeApi<
Block,
<Block as sp_runtime::traits::Block>::Hash,
BlockNumber,
>,
C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
C::Api: BabeApi<Block>,
C::Api: BlockBuilder<Block>,
Expand Down
5 changes: 5 additions & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::Hash>), mmr::Error>
Expand Down Expand Up @@ -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::<mmr::Hashing, _>(root, nodes, proof)
}

fn block_num_to_leaf_index(block_num: &BlockNumber) -> Result<mmr::LeafIndex, mmr::Error> {
Ok(Mmr::block_num_to_leaf_index(*block_num))
}
Szegoo marked this conversation as resolved.
Show resolved Hide resolved
}

impl sp_session::SessionKeys<Block> for Runtime {
Expand Down
4 changes: 2 additions & 2 deletions client/beefy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ where
BE: Backend<B>,
C: Client<B, BE>,
R: ProvideRuntimeApi<B>,
R::Api: BeefyApi<B> + MmrApi<B, MmrRootHash>,
R::Api: BeefyApi<B> + MmrApi<B, MmrRootHash, u64>,
Szegoo marked this conversation as resolved.
Show resolved Hide resolved
N: GossipNetwork<B> + Clone + SyncOracle + Send + Sync + 'static,
{
/// BEEFY client
Expand Down Expand Up @@ -219,7 +219,7 @@ where
BE: Backend<B>,
C: Client<B, BE>,
R: ProvideRuntimeApi<B>,
R::Api: BeefyApi<B> + MmrApi<B, MmrRootHash>,
R::Api: BeefyApi<B> + MmrApi<B, MmrRootHash, u64>,
N: GossipNetwork<B> + Clone + SyncOracle + Send + Sync + 'static,
{
let BeefyParams {
Expand Down
4 changes: 2 additions & 2 deletions client/beefy/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ macro_rules! create_test_api {
}
}

impl MmrApi<Block, MmrRootHash> for RuntimeApi {
impl MmrApi<Block, MmrRootHash, u64> for RuntimeApi {
fn generate_proof(_leaf_index: LeafIndex)
-> Result<(EncodableOpaqueLeaf, Proof<MmrRootHash>), MmrError> {
unimplemented!()
Expand Down Expand Up @@ -345,7 +345,7 @@ fn initialize_beefy<API>(
) -> impl Future<Output = ()>
where
API: ProvideRuntimeApi<Block> + Default + Sync + Send,
API::Api: BeefyApi<Block> + MmrApi<Block, MmrRootHash>,
API::Api: BeefyApi<Block> + MmrApi<Block, MmrRootHash, u64>,
{
let voters = FuturesUnordered::new();

Expand Down
2 changes: 1 addition & 1 deletion client/beefy/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ where
BE: Backend<B>,
C: Client<B, BE>,
R: ProvideRuntimeApi<B>,
R::Api: BeefyApi<B> + MmrApi<B, MmrRootHash>,
R::Api: BeefyApi<B> + MmrApi<B, MmrRootHash, u64>,
SO: SyncOracle + Send + Sync + Clone + 'static,
{
/// Return a new BEEFY worker instance.
Expand Down
45 changes: 32 additions & 13 deletions frame/merkle-mountain-range/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -96,27 +96,28 @@ impl<BlockHash> LeafBatchProof<BlockHash> {

/// MMR RPC methods.
#[rpc(client, server)]
pub trait MmrApi<BlockHash> {
/// Generate MMR proof for given leaf index.
pub trait MmrApi<BlockHash, BlockNumber> {
/// 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
/// the leaf). Both parameters are SCALE-encoded.
#[method(name = "mmr_generateProof")]
fn generate_proof(
&self,
leaf_index: LeafIndex,
block_number: BlockNumber,
at: Option<BlockHash>,
) -> RpcResult<LeafProof<BlockHash>>;

/// 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 are 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.
Expand All @@ -125,7 +126,7 @@ pub trait MmrApi<BlockHash> {
#[method(name = "mmr_generateBatchProof")]
fn generate_batch_proof(
&self,
leaf_indices: Vec<LeafIndex>,
leaf_indices: Vec<BlockNumber>,
at: Option<BlockHash>,
) -> RpcResult<LeafBatchProof<BlockHash>>;
}
Expand All @@ -144,21 +145,28 @@ impl<C, B> Mmr<C, B> {
}

#[async_trait]
impl<Client, Block, MmrHash> MmrApiServer<<Block as BlockT>::Hash> for Mmr<Client, (Block, MmrHash)>
impl<Client, Block, MmrHash, BlockNumber> MmrApiServer<<Block as BlockT>::Hash, BlockNumber>
Szegoo marked this conversation as resolved.
Show resolved Hide resolved
for Mmr<Client, (Block, MmrHash)>
where
Block: BlockT,
Client: Send + Sync + 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
Client::Api: MmrRuntimeApi<Block, MmrHash>,
Client::Api: MmrRuntimeApi<Block, MmrHash, BlockNumber>,
MmrHash: Codec + Send + Sync + 'static,
BlockNumber: Codec,
{
fn generate_proof(
&self,
leaf_index: LeafIndex,
block_number: BlockNumber,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<LeafProof<Block::Hash>> {
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),
Expand All @@ -173,14 +181,25 @@ where

fn generate_batch_proof(
&self,
leaf_indices: Vec<LeafIndex>,
block_numbers: Vec<BlockNumber>,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<LeafBatchProof<<Block as BlockT>::Hash>> {
let api = self.client.runtime_api();
let block_hash = at.unwrap_or_else(||
// 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<u64, CallError> {
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::<Result<Vec<u64>, _>>()?;

let (leaves, proof) = api
.generate_batch_proof_with_context(
&BlockId::hash(block_hash),
Expand Down
16 changes: 16 additions & 0 deletions frame/merkle-mountain-range/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,4 +365,20 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
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: <T as frame_system::Config>::BlockNumber) -> LeafIndex
where
T: frame_system::Config,
T: pallet::Config,
{
// leaf_indx = block_num - (current_block_num - leaves_count) - 1;
let leaves_count = Pallet::<T>::mmr_leaves();
let current_block_num = <frame_system::Pallet<T>>::block_number();
let diff = current_block_num.saturating_sub((leaves_count as u32).into());
Szegoo marked this conversation as resolved.
Show resolved Hide resolved

// TODO: Somehow convert BlockNumber into LeafIndex.
block_num.saturating_sub(diff).saturating_sub(1u32.into());
Szegoo marked this conversation as resolved.
Show resolved Hide resolved
0
Szegoo marked this conversation as resolved.
Show resolved Hide resolved
}
}
5 changes: 4 additions & 1 deletion primitives/merkle-mountain-range/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ impl Error {

sp_api::decl_runtime_apis! {
/// API to interact with MMR pallet.
pub trait MmrApi<Hash: codec::Codec> {
pub trait MmrApi<Hash: codec::Codec, BlockNumber: codec::Codec> {
/// Generate MMR proof for a leaf under given index.
fn generate_proof(leaf_index: LeafIndex) -> Result<(EncodableOpaqueLeaf, Proof<Hash>), Error>;

Expand Down Expand Up @@ -474,6 +474,9 @@ 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<EncodableOpaqueLeaf>, proof: BatchProof<Hash>)
-> Result<(), Error>;

/// Converts `block_num` into a leaf index.
fn block_num_to_leaf_index(block_num: &BlockNumber) -> Result<LeafIndex, Error>;
}
}

Expand Down