mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 00:31:07 +00:00
pallet-mmr: RPC API and Runtime API work with block numbers (#12345)
* pallet-mmr: RPC API works with block_numbers * fixes * update rpc * fmt * final touches in the rpc * temporary fix * fix * fmt * docs * Update lib.rs * use NumberFor * validate input * update runtime * convert block_number to u64 * small edit * update runtime api * test fix * runtime fix * update test function * fmt * fix nits * remove block_num_to_leaf_index from runtime api * Update frame/merkle-mountain-range/src/lib.rs Co-authored-by: Robert Hambrock <roberthambrock@gmail.com> * fix tests * get the code to compile after merge * get the tests to compile * fix in tests? * fix test * Update frame/merkle-mountain-range/src/tests.rs Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update frame/merkle-mountain-range/src/lib.rs Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update primitives/merkle-mountain-range/src/lib.rs Co-authored-by: Adrian Catangiu <adrian@parity.io> * fix errors & nits * change block_num_to_leaf_index * don't make any assumptions * Update frame/merkle-mountain-range/src/tests.rs Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update frame/merkle-mountain-range/src/tests.rs Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update frame/merkle-mountain-range/src/tests.rs Co-authored-by: Adrian Catangiu <adrian@parity.io> * fix * small fix * use best_known_block_number * best_known_block_number instead of leaves_count * more readable? * remove warning * Update frame/merkle-mountain-range/src/lib.rs Co-authored-by: Robert Hambrock <roberthambrock@gmail.com> * simplify * update docs * nits * fmt & fix * merge fixes * fix * small fix * docs & nit fixes * Nit fixes * remove leaf_indices_to_block_numbers() * fmt Co-authored-by: Robert Hambrock <roberthambrock@gmail.com> Co-authored-by: Adrian Catangiu <adrian@parity.io>
This commit is contained in:
@@ -108,7 +108,11 @@ where
|
|||||||
+ Send
|
+ Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
|
C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
|
||||||
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: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
|
||||||
C::Api: BabeApi<Block>,
|
C::Api: BabeApi<Block>,
|
||||||
C::Api: BlockBuilder<Block>,
|
C::Api: BlockBuilder<Block>,
|
||||||
|
|||||||
@@ -2016,11 +2016,15 @@ impl_runtime_apis! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl pallet_mmr::primitives::MmrApi<Block, mmr::Hash> for Runtime {
|
impl pallet_mmr::primitives::MmrApi<
|
||||||
fn generate_proof(leaf_index: pallet_mmr::primitives::LeafIndex)
|
Block,
|
||||||
|
mmr::Hash,
|
||||||
|
BlockNumber,
|
||||||
|
> for Runtime {
|
||||||
|
fn generate_proof(block_number: BlockNumber)
|
||||||
-> Result<(mmr::EncodableOpaqueLeaf, mmr::Proof<mmr::Hash>), mmr::Error>
|
-> Result<(mmr::EncodableOpaqueLeaf, mmr::Proof<mmr::Hash>), mmr::Error>
|
||||||
{
|
{
|
||||||
Mmr::generate_batch_proof(vec![leaf_index]).and_then(|(leaves, proof)|
|
Mmr::generate_batch_proof(vec![block_number]).and_then(|(leaves, proof)|
|
||||||
Ok((
|
Ok((
|
||||||
mmr::EncodableOpaqueLeaf::from_leaf(&leaves[0]),
|
mmr::EncodableOpaqueLeaf::from_leaf(&leaves[0]),
|
||||||
mmr::BatchProof::into_single_leaf_proof(proof)?
|
mmr::BatchProof::into_single_leaf_proof(proof)?
|
||||||
@@ -2052,9 +2056,9 @@ impl_runtime_apis! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate_batch_proof(
|
fn generate_batch_proof(
|
||||||
leaf_indices: Vec<pallet_mmr::primitives::LeafIndex>,
|
block_numbers: Vec<BlockNumber>,
|
||||||
) -> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::BatchProof<mmr::Hash>), mmr::Error> {
|
) -> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::BatchProof<mmr::Hash>), mmr::Error> {
|
||||||
Mmr::generate_batch_proof(leaf_indices).map(|(leaves, proof)| {
|
Mmr::generate_batch_proof(block_numbers).map(|(leaves, proof)| {
|
||||||
(
|
(
|
||||||
leaves
|
leaves
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -2066,10 +2070,10 @@ impl_runtime_apis! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate_historical_batch_proof(
|
fn generate_historical_batch_proof(
|
||||||
leaf_indices: Vec<pallet_mmr::primitives::LeafIndex>,
|
block_numbers: Vec<BlockNumber>,
|
||||||
leaves_count: pallet_mmr::primitives::LeafIndex,
|
best_known_block_number: BlockNumber,
|
||||||
) -> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::BatchProof<mmr::Hash>), mmr::Error> {
|
) -> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::BatchProof<mmr::Hash>), mmr::Error> {
|
||||||
Mmr::generate_historical_batch_proof(leaf_indices, leaves_count).map(
|
Mmr::generate_historical_batch_proof(block_numbers, best_known_block_number).map(
|
||||||
|(leaves, proof)| {
|
|(leaves, proof)| {
|
||||||
(
|
(
|
||||||
leaves
|
leaves
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ use sc_consensus::BlockImport;
|
|||||||
use sc_network::ProtocolName;
|
use sc_network::ProtocolName;
|
||||||
use sc_network_common::service::NetworkRequest;
|
use sc_network_common::service::NetworkRequest;
|
||||||
use sc_network_gossip::Network as GossipNetwork;
|
use sc_network_gossip::Network as GossipNetwork;
|
||||||
use sp_api::ProvideRuntimeApi;
|
use sp_api::{NumberFor, ProvideRuntimeApi};
|
||||||
use sp_blockchain::HeaderBackend;
|
use sp_blockchain::HeaderBackend;
|
||||||
use sp_consensus::{Error as ConsensusError, SyncOracle};
|
use sp_consensus::{Error as ConsensusError, SyncOracle};
|
||||||
use sp_keystore::SyncCryptoStorePtr;
|
use sp_keystore::SyncCryptoStorePtr;
|
||||||
@@ -200,7 +200,7 @@ where
|
|||||||
C: Client<B, BE> + BlockBackend<B>,
|
C: Client<B, BE> + BlockBackend<B>,
|
||||||
P: PayloadProvider<B>,
|
P: PayloadProvider<B>,
|
||||||
R: ProvideRuntimeApi<B>,
|
R: ProvideRuntimeApi<B>,
|
||||||
R::Api: BeefyApi<B> + MmrApi<B, MmrRootHash>,
|
R::Api: BeefyApi<B> + MmrApi<B, MmrRootHash, NumberFor<B>>,
|
||||||
N: GossipNetwork<B> + NetworkRequest + SyncOracle + Send + Sync + 'static,
|
N: GossipNetwork<B> + NetworkRequest + SyncOracle + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let BeefyParams {
|
let BeefyParams {
|
||||||
|
|||||||
@@ -43,9 +43,7 @@ use beefy_primitives::{
|
|||||||
KEY_TYPE as BeefyKeyType,
|
KEY_TYPE as BeefyKeyType,
|
||||||
};
|
};
|
||||||
use sc_network::{config::RequestResponseConfig, ProtocolName};
|
use sc_network::{config::RequestResponseConfig, ProtocolName};
|
||||||
use sp_mmr_primitives::{
|
use sp_mmr_primitives::{BatchProof, EncodableOpaqueLeaf, Error as MmrError, MmrApi, Proof};
|
||||||
BatchProof, EncodableOpaqueLeaf, Error as MmrError, LeafIndex, MmrApi, Proof,
|
|
||||||
};
|
|
||||||
|
|
||||||
use sp_api::{ApiRef, ProvideRuntimeApi};
|
use sp_api::{ApiRef, ProvideRuntimeApi};
|
||||||
use sp_consensus::BlockOrigin;
|
use sp_consensus::BlockOrigin;
|
||||||
@@ -247,8 +245,8 @@ macro_rules! create_test_api {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MmrApi<Block, MmrRootHash> for RuntimeApi {
|
impl MmrApi<Block, MmrRootHash, NumberFor<Block>> for RuntimeApi {
|
||||||
fn generate_proof(_leaf_index: LeafIndex)
|
fn generate_proof(_block_number: u64)
|
||||||
-> Result<(EncodableOpaqueLeaf, Proof<MmrRootHash>), MmrError> {
|
-> Result<(EncodableOpaqueLeaf, Proof<MmrRootHash>), MmrError> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
@@ -270,13 +268,13 @@ macro_rules! create_test_api {
|
|||||||
Ok($mmr_root)
|
Ok($mmr_root)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_batch_proof(_leaf_indices: Vec<LeafIndex>) -> Result<(Vec<EncodableOpaqueLeaf>, BatchProof<MmrRootHash>), MmrError> {
|
fn generate_batch_proof(_block_numbers: Vec<u64>) -> Result<(Vec<EncodableOpaqueLeaf>, BatchProof<MmrRootHash>), MmrError> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_historical_batch_proof(
|
fn generate_historical_batch_proof(
|
||||||
_leaf_indices: Vec<LeafIndex>,
|
_block_numbers: Vec<u64>,
|
||||||
_leaves_count: LeafIndex
|
_best_known_block_number: u64
|
||||||
) -> Result<(Vec<EncodableOpaqueLeaf>, BatchProof<MmrRootHash>), MmrError> {
|
) -> Result<(Vec<EncodableOpaqueLeaf>, BatchProof<MmrRootHash>), MmrError> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
@@ -349,7 +347,7 @@ fn initialize_beefy<API>(
|
|||||||
) -> impl Future<Output = ()>
|
) -> impl Future<Output = ()>
|
||||||
where
|
where
|
||||||
API: ProvideRuntimeApi<Block> + Default + Sync + Send,
|
API: ProvideRuntimeApi<Block> + Default + Sync + Send,
|
||||||
API::Api: BeefyApi<Block> + MmrApi<Block, MmrRootHash>,
|
API::Api: BeefyApi<Block> + MmrApi<Block, MmrRootHash, NumberFor<Block>>,
|
||||||
{
|
{
|
||||||
let tasks = FuturesUnordered::new();
|
let tasks = FuturesUnordered::new();
|
||||||
|
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ where
|
|||||||
C: Client<B, BE>,
|
C: Client<B, BE>,
|
||||||
P: PayloadProvider<B>,
|
P: PayloadProvider<B>,
|
||||||
R: ProvideRuntimeApi<B>,
|
R: ProvideRuntimeApi<B>,
|
||||||
R::Api: BeefyApi<B> + MmrApi<B, MmrRootHash>,
|
R::Api: BeefyApi<B> + MmrApi<B, MmrRootHash, NumberFor<B>>,
|
||||||
N: NetworkEventStream + NetworkRequest + SyncOracle + Send + Sync + Clone + 'static,
|
N: NetworkEventStream + NetworkRequest + SyncOracle + Send + Sync + Clone + 'static,
|
||||||
{
|
{
|
||||||
/// Return a new BEEFY worker instance.
|
/// Return a new BEEFY worker instance.
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ use jsonrpsee::{
|
|||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use sp_api::ProvideRuntimeApi;
|
use sp_api::{NumberFor, ProvideRuntimeApi};
|
||||||
use sp_blockchain::HeaderBackend;
|
use sp_blockchain::HeaderBackend;
|
||||||
use sp_core::Bytes;
|
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};
|
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
|
||||||
|
|
||||||
pub use sp_mmr_primitives::MmrApi as MmrRuntimeApi;
|
pub use sp_mmr_primitives::MmrApi as MmrRuntimeApi;
|
||||||
@@ -96,11 +96,11 @@ impl<BlockHash> LeafBatchProof<BlockHash> {
|
|||||||
|
|
||||||
/// MMR RPC methods.
|
/// MMR RPC methods.
|
||||||
#[rpc(client, server)]
|
#[rpc(client, server)]
|
||||||
pub trait MmrApi<BlockHash> {
|
pub trait MmrApi<BlockHash, BlockNumber> {
|
||||||
/// 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
|
/// 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 a block with a specified `block_number`.
|
||||||
/// Optionally, a block hash at which the runtime should be queried can be specified.
|
/// 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
|
/// Returns the (full) leaf itself and a proof for this leaf (compact encoding, i.e. hash of
|
||||||
@@ -108,49 +108,49 @@ pub trait MmrApi<BlockHash> {
|
|||||||
#[method(name = "mmr_generateProof")]
|
#[method(name = "mmr_generateProof")]
|
||||||
fn generate_proof(
|
fn generate_proof(
|
||||||
&self,
|
&self,
|
||||||
leaf_index: LeafIndex,
|
block_number: BlockNumber,
|
||||||
at: Option<BlockHash>,
|
at: Option<BlockHash>,
|
||||||
) -> RpcResult<LeafProof<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
|
/// 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`.
|
/// 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.
|
/// 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
|
/// Returns the leaves and a proof for these leaves (compact encoding, i.e. hash of
|
||||||
/// the leaves). Both parameters are SCALE-encoded.
|
/// the leaves). Both parameters are SCALE-encoded.
|
||||||
/// The order of entries in the `leaves` field of the returned struct
|
/// 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")]
|
#[method(name = "mmr_generateBatchProof")]
|
||||||
fn generate_batch_proof(
|
fn generate_batch_proof(
|
||||||
&self,
|
&self,
|
||||||
leaf_indices: Vec<LeafIndex>,
|
block_numbers: Vec<BlockNumber>,
|
||||||
at: Option<BlockHash>,
|
at: Option<BlockHash>,
|
||||||
) -> RpcResult<LeafBatchProof<BlockHash>>;
|
) -> RpcResult<LeafBatchProof<BlockHash>>;
|
||||||
|
|
||||||
/// 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` given the `best_known_block_number`.
|
||||||
///
|
///
|
||||||
/// This method calls into a runtime with MMR pallet included and attempts to generate
|
/// 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
|
/// a MMR proof for the set of blocks that have the given `block_numbers` with MMR given the
|
||||||
/// with exactly `leaves_count` leaves. `leaves_count` must be larger than all `leaf_indices`
|
/// `best_known_block_number`. `best_known_block_number` must be larger than all the
|
||||||
/// for the function to succeed.
|
/// `block_numbers` for the function to succeed.
|
||||||
///
|
///
|
||||||
/// Optionally, a block hash at which the runtime should be queried can be specified.
|
/// 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
|
/// 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
|
/// 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
|
/// MMR state will be fixed to the state with `best_known_block_number`, which already points to
|
||||||
/// historical block.
|
/// some historical block.
|
||||||
///
|
///
|
||||||
/// Returns the leaves and a proof for these leaves (compact encoding, i.e. hash of
|
/// Returns the leaves and a proof for these leaves (compact encoding, i.e. hash of
|
||||||
/// the leaves). Both parameters are SCALE-encoded.
|
/// the leaves). Both parameters are SCALE-encoded.
|
||||||
/// The order of entries in the `leaves` field of the returned struct
|
/// 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")]
|
#[method(name = "mmr_generateHistoricalBatchProof")]
|
||||||
fn generate_historical_batch_proof(
|
fn generate_historical_batch_proof(
|
||||||
&self,
|
&self,
|
||||||
leaf_indices: Vec<LeafIndex>,
|
block_numbers: Vec<BlockNumber>,
|
||||||
leaves_count: LeafIndex,
|
best_known_block_number: BlockNumber,
|
||||||
at: Option<BlockHash>,
|
at: Option<BlockHash>,
|
||||||
) -> RpcResult<LeafBatchProof<BlockHash>>;
|
) -> RpcResult<LeafBatchProof<BlockHash>>;
|
||||||
}
|
}
|
||||||
@@ -169,16 +169,17 @@ impl<C, B> Mmr<C, B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<Client, Block, MmrHash> MmrApiServer<<Block as BlockT>::Hash> for Mmr<Client, (Block, MmrHash)>
|
impl<Client, Block, MmrHash> MmrApiServer<<Block as BlockT>::Hash, NumberFor<Block>>
|
||||||
|
for Mmr<Client, (Block, MmrHash)>
|
||||||
where
|
where
|
||||||
Block: BlockT,
|
Block: BlockT,
|
||||||
Client: Send + Sync + 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
|
Client: Send + Sync + 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
|
||||||
Client::Api: MmrRuntimeApi<Block, MmrHash>,
|
Client::Api: MmrRuntimeApi<Block, MmrHash, NumberFor<Block>>,
|
||||||
MmrHash: Codec + Send + Sync + 'static,
|
MmrHash: Codec + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
fn generate_proof(
|
fn generate_proof(
|
||||||
&self,
|
&self,
|
||||||
leaf_index: LeafIndex,
|
block_number: NumberFor<Block>,
|
||||||
at: Option<<Block as BlockT>::Hash>,
|
at: Option<<Block as BlockT>::Hash>,
|
||||||
) -> RpcResult<LeafProof<Block::Hash>> {
|
) -> RpcResult<LeafProof<Block::Hash>> {
|
||||||
let api = self.client.runtime_api();
|
let api = self.client.runtime_api();
|
||||||
@@ -188,7 +189,7 @@ where
|
|||||||
.generate_proof_with_context(
|
.generate_proof_with_context(
|
||||||
&BlockId::hash(block_hash),
|
&BlockId::hash(block_hash),
|
||||||
sp_core::ExecutionContext::OffchainCall(None),
|
sp_core::ExecutionContext::OffchainCall(None),
|
||||||
leaf_index,
|
block_number,
|
||||||
)
|
)
|
||||||
.map_err(runtime_error_into_rpc_error)?
|
.map_err(runtime_error_into_rpc_error)?
|
||||||
.map_err(mmr_error_into_rpc_error)?;
|
.map_err(mmr_error_into_rpc_error)?;
|
||||||
@@ -198,7 +199,7 @@ where
|
|||||||
|
|
||||||
fn generate_batch_proof(
|
fn generate_batch_proof(
|
||||||
&self,
|
&self,
|
||||||
leaf_indices: Vec<LeafIndex>,
|
block_numbers: Vec<NumberFor<Block>>,
|
||||||
at: Option<<Block as BlockT>::Hash>,
|
at: Option<<Block as BlockT>::Hash>,
|
||||||
) -> RpcResult<LeafBatchProof<<Block as BlockT>::Hash>> {
|
) -> RpcResult<LeafBatchProof<<Block as BlockT>::Hash>> {
|
||||||
let api = self.client.runtime_api();
|
let api = self.client.runtime_api();
|
||||||
@@ -210,7 +211,7 @@ where
|
|||||||
.generate_batch_proof_with_context(
|
.generate_batch_proof_with_context(
|
||||||
&BlockId::hash(block_hash),
|
&BlockId::hash(block_hash),
|
||||||
sp_core::ExecutionContext::OffchainCall(None),
|
sp_core::ExecutionContext::OffchainCall(None),
|
||||||
leaf_indices,
|
block_numbers,
|
||||||
)
|
)
|
||||||
.map_err(runtime_error_into_rpc_error)?
|
.map_err(runtime_error_into_rpc_error)?
|
||||||
.map_err(mmr_error_into_rpc_error)?;
|
.map_err(mmr_error_into_rpc_error)?;
|
||||||
@@ -220,8 +221,8 @@ where
|
|||||||
|
|
||||||
fn generate_historical_batch_proof(
|
fn generate_historical_batch_proof(
|
||||||
&self,
|
&self,
|
||||||
leaf_indices: Vec<LeafIndex>,
|
block_numbers: Vec<NumberFor<Block>>,
|
||||||
leaves_count: LeafIndex,
|
best_known_block_number: NumberFor<Block>,
|
||||||
at: Option<<Block as BlockT>::Hash>,
|
at: Option<<Block as BlockT>::Hash>,
|
||||||
) -> RpcResult<LeafBatchProof<<Block as BlockT>::Hash>> {
|
) -> RpcResult<LeafBatchProof<<Block as BlockT>::Hash>> {
|
||||||
let api = self.client.runtime_api();
|
let api = self.client.runtime_api();
|
||||||
@@ -233,8 +234,8 @@ where
|
|||||||
.generate_historical_batch_proof_with_context(
|
.generate_historical_batch_proof_with_context(
|
||||||
&BlockId::hash(block_hash),
|
&BlockId::hash(block_hash),
|
||||||
sp_core::ExecutionContext::OffchainCall(None),
|
sp_core::ExecutionContext::OffchainCall(None),
|
||||||
leaf_indices,
|
block_numbers,
|
||||||
leaves_count,
|
best_known_block_number,
|
||||||
)
|
)
|
||||||
.map_err(runtime_error_into_rpc_error)?
|
.map_err(runtime_error_into_rpc_error)?
|
||||||
.map_err(mmr_error_into_rpc_error)?;
|
.map_err(mmr_error_into_rpc_error)?;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use frame_support::weights::Weight;
|
use frame_support::weights::Weight;
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
traits::{self, One, Saturating},
|
traits::{self, CheckedSub, One, Saturating},
|
||||||
SaturatedConversion,
|
SaturatedConversion,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -318,37 +318,73 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
|||||||
.saturating_add(leaf_index.saturated_into())
|
.saturating_add(leaf_index.saturated_into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a MMR proof for the given `leaf_indices`.
|
/// Convert a `block_num` into a leaf index.
|
||||||
|
fn block_num_to_leaf_index(block_num: T::BlockNumber) -> Result<LeafIndex, primitives::Error>
|
||||||
|
where
|
||||||
|
T: frame_system::Config,
|
||||||
|
{
|
||||||
|
// leaf_idx = (leaves_count - 1) - (current_block_num - block_num);
|
||||||
|
let best_block_num = <frame_system::Pallet<T>>::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 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`.
|
||||||
///
|
///
|
||||||
/// Note this method can only be used from an off-chain context
|
/// Note this method can only be used from an off-chain context
|
||||||
/// (Offchain Worker or Runtime API call), since it requires
|
/// (Offchain Worker or Runtime API call), since it requires
|
||||||
/// all the leaves to be present.
|
/// all the leaves to be present.
|
||||||
/// It may return an error or panic if used incorrectly.
|
/// It may return an error or panic if used incorrectly.
|
||||||
pub fn generate_batch_proof(
|
pub fn generate_batch_proof(
|
||||||
leaf_indices: Vec<LeafIndex>,
|
block_numbers: Vec<T::BlockNumber>,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
(Vec<LeafOf<T, I>>, primitives::BatchProof<<T as Config<I>>::Hash>),
|
(Vec<LeafOf<T, I>>, primitives::BatchProof<<T as Config<I>>::Hash>),
|
||||||
primitives::Error,
|
primitives::Error,
|
||||||
> {
|
> {
|
||||||
Self::generate_historical_batch_proof(leaf_indices, Self::mmr_leaves())
|
Self::generate_historical_batch_proof(
|
||||||
|
block_numbers,
|
||||||
|
<frame_system::Pallet<T>>::block_number(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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` given the `best_known_block_number`.
|
||||||
///
|
///
|
||||||
/// Note this method can only be used from an off-chain context
|
/// Note this method can only be used from an off-chain context
|
||||||
/// (Offchain Worker or Runtime API call), since it requires
|
/// (Offchain Worker or Runtime API call), since it requires
|
||||||
/// all the leaves to be present.
|
/// all the leaves to be present.
|
||||||
/// It may return an error or panic if used incorrectly.
|
/// It may return an error or panic if used incorrectly.
|
||||||
pub fn generate_historical_batch_proof(
|
pub fn generate_historical_batch_proof(
|
||||||
leaf_indices: Vec<LeafIndex>,
|
block_numbers: Vec<T::BlockNumber>,
|
||||||
leaves_count: LeafIndex,
|
best_known_block_number: T::BlockNumber,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
(Vec<LeafOf<T, I>>, primitives::BatchProof<<T as Config<I>>::Hash>),
|
(Vec<LeafOf<T, I>>, primitives::BatchProof<<T as Config<I>>::Hash>),
|
||||||
primitives::Error,
|
primitives::Error,
|
||||||
> {
|
> {
|
||||||
if leaves_count > Self::mmr_leaves() {
|
let leaves_count =
|
||||||
return Err(Error::InvalidLeavesCount)
|
Self::block_num_to_leaf_index(best_known_block_number)?.saturating_add(1);
|
||||||
}
|
|
||||||
|
// we need to translate the block_numbers into leaf indices.
|
||||||
|
let leaf_indices = block_numbers
|
||||||
|
.iter()
|
||||||
|
.map(|block_num| -> Result<LeafIndex, primitives::Error> {
|
||||||
|
Self::block_num_to_leaf_index(*block_num)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<LeafIndex>, _>>()?;
|
||||||
|
|
||||||
let mmr: ModuleMmr<mmr::storage::OffchainStorage, T, I> = mmr::Mmr::new(leaves_count);
|
let mmr: ModuleMmr<mmr::storage::OffchainStorage, T, I> = mmr::Mmr::new(leaves_count);
|
||||||
mmr.generate_batch_proof(leaf_indices)
|
mmr.generate_batch_proof(leaf_indices)
|
||||||
|
|||||||
@@ -235,22 +235,21 @@ fn should_generate_proofs_correctly() {
|
|||||||
// to retrieve full leaf data.
|
// to retrieve full leaf data.
|
||||||
register_offchain_ext(&mut ext);
|
register_offchain_ext(&mut ext);
|
||||||
ext.execute_with(|| {
|
ext.execute_with(|| {
|
||||||
// when generate proofs for all leaves
|
let best_block_number = frame_system::Pallet::<Test>::block_number();
|
||||||
let proofs = (0_u64..crate::NumberOfLeaves::<Test>::get())
|
// when generate proofs for all leaves.
|
||||||
|
let proofs = (1_u64..=best_block_number)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|leaf_index| {
|
.map(|block_num| crate::Pallet::<Test>::generate_batch_proof(vec![block_num]).unwrap())
|
||||||
crate::Pallet::<Test>::generate_batch_proof(vec![leaf_index]).unwrap()
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
// when generate historical proofs for all leaves
|
// when generate historical proofs for all leaves
|
||||||
let historical_proofs = (0_u64..crate::NumberOfLeaves::<Test>::get())
|
let historical_proofs = (1_u64..best_block_number)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|leaf_index| {
|
.map(|block_num| {
|
||||||
let mut proofs = vec![];
|
let mut proofs = vec![];
|
||||||
for leaves_count in leaf_index + 1..=num_blocks {
|
for leaves_count in block_num..=num_blocks {
|
||||||
proofs.push(
|
proofs.push(
|
||||||
crate::Pallet::<Test>::generate_historical_batch_proof(
|
crate::Pallet::<Test>::generate_historical_batch_proof(
|
||||||
vec![leaf_index],
|
vec![block_num],
|
||||||
leaves_count,
|
leaves_count,
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@@ -321,7 +320,7 @@ fn should_generate_proofs_correctly() {
|
|||||||
leaf_count: 3,
|
leaf_count: 3,
|
||||||
items: vec![hex(
|
items: vec![hex(
|
||||||
"672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854"
|
"672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854"
|
||||||
),],
|
)],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -352,6 +351,7 @@ fn should_generate_proofs_correctly() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
proofs[4],
|
proofs[4],
|
||||||
(
|
(
|
||||||
|
// 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(((4, H256::repeat_byte(5)).into(), LeafData::new(5).into(),))],
|
||||||
BatchProof {
|
BatchProof {
|
||||||
leaf_indices: vec![4],
|
leaf_indices: vec![4],
|
||||||
@@ -393,7 +393,7 @@ fn should_generate_proofs_correctly() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(historical_proofs[6][0], proofs[6]);
|
assert_eq!(historical_proofs[5][1], proofs[5]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,11 +410,12 @@ fn should_generate_batch_proof_correctly() {
|
|||||||
register_offchain_ext(&mut ext);
|
register_offchain_ext(&mut ext);
|
||||||
ext.execute_with(|| {
|
ext.execute_with(|| {
|
||||||
// when generate proofs for a batch of leaves
|
// when generate proofs for a batch of leaves
|
||||||
let (.., proof) = crate::Pallet::<Test>::generate_batch_proof(vec![0, 4, 5]).unwrap();
|
let (.., proof) = crate::Pallet::<Test>::generate_batch_proof(vec![1, 5, 6]).unwrap();
|
||||||
// then
|
// then
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
proof,
|
proof,
|
||||||
BatchProof {
|
BatchProof {
|
||||||
|
// the leaf indices are equivalent to the above specified block numbers - 1.
|
||||||
leaf_indices: vec![0, 4, 5],
|
leaf_indices: vec![0, 4, 5],
|
||||||
leaf_count: 7,
|
leaf_count: 7,
|
||||||
items: vec![
|
items: vec![
|
||||||
@@ -427,7 +428,7 @@ fn should_generate_batch_proof_correctly() {
|
|||||||
|
|
||||||
// when generate historical proofs for a batch of leaves
|
// when generate historical proofs for a batch of leaves
|
||||||
let (.., historical_proof) =
|
let (.., historical_proof) =
|
||||||
crate::Pallet::<Test>::generate_historical_batch_proof(vec![0, 4, 5], 6).unwrap();
|
crate::Pallet::<Test>::generate_historical_batch_proof(vec![1, 5, 6], 6).unwrap();
|
||||||
// then
|
// then
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
historical_proof,
|
historical_proof,
|
||||||
@@ -443,7 +444,7 @@ fn should_generate_batch_proof_correctly() {
|
|||||||
|
|
||||||
// when generate historical proofs for a batch of leaves
|
// when generate historical proofs for a batch of leaves
|
||||||
let (.., historical_proof) =
|
let (.., historical_proof) =
|
||||||
crate::Pallet::<Test>::generate_historical_batch_proof(vec![0, 4, 5], 7).unwrap();
|
crate::Pallet::<Test>::generate_historical_batch_proof(vec![1, 5, 6], 7).unwrap();
|
||||||
// then
|
// then
|
||||||
assert_eq!(historical_proof, proof);
|
assert_eq!(historical_proof, proof);
|
||||||
});
|
});
|
||||||
@@ -500,15 +501,15 @@ fn should_verify() {
|
|||||||
fn should_verify_batch_proofs() {
|
fn should_verify_batch_proofs() {
|
||||||
fn generate_and_verify_batch_proof(
|
fn generate_and_verify_batch_proof(
|
||||||
ext: &mut sp_io::TestExternalities,
|
ext: &mut sp_io::TestExternalities,
|
||||||
leaf_indices: &Vec<u64>,
|
block_numbers: &Vec<u64>,
|
||||||
blocks_to_add: usize,
|
blocks_to_add: usize,
|
||||||
) {
|
) {
|
||||||
let (leaves, proof) = ext.execute_with(|| {
|
let (leaves, proof) = ext.execute_with(|| {
|
||||||
crate::Pallet::<Test>::generate_batch_proof(leaf_indices.to_vec()).unwrap()
|
crate::Pallet::<Test>::generate_batch_proof(block_numbers.to_vec()).unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
let mmr_size = ext.execute_with(|| crate::Pallet::<Test>::mmr_leaves());
|
let mmr_size = ext.execute_with(|| crate::Pallet::<Test>::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,
|
// generate historical proofs for all possible mmr sizes,
|
||||||
// lower bound being index of highest leaf to be proven
|
// lower bound being index of highest leaf to be proven
|
||||||
@@ -516,7 +517,7 @@ fn should_verify_batch_proofs() {
|
|||||||
.map(|mmr_size| {
|
.map(|mmr_size| {
|
||||||
ext.execute_with(|| {
|
ext.execute_with(|| {
|
||||||
crate::Pallet::<Test>::generate_historical_batch_proof(
|
crate::Pallet::<Test>::generate_historical_batch_proof(
|
||||||
leaf_indices.to_vec(),
|
block_numbers.to_vec(),
|
||||||
mmr_size,
|
mmr_size,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -546,39 +547,41 @@ fn should_verify_batch_proofs() {
|
|||||||
// to retrieve full leaf data when generating proofs
|
// to retrieve full leaf data when generating proofs
|
||||||
register_offchain_ext(&mut ext);
|
register_offchain_ext(&mut ext);
|
||||||
|
|
||||||
// verify that up to n=10, valid proofs are generated for all possible leaf combinations
|
// verify that up to n=10, valid proofs are generated for all possible block number
|
||||||
for n in 0..10 {
|
// combinations.
|
||||||
|
for n in 1..=10 {
|
||||||
ext.execute_with(|| new_block());
|
ext.execute_with(|| new_block());
|
||||||
ext.persist_offchain_overlay();
|
ext.persist_offchain_overlay();
|
||||||
|
|
||||||
// generate powerset (skipping empty set) of all possible leaf combinations for mmr size n
|
// generate powerset (skipping empty set) of all possible block number combinations for mmr
|
||||||
let leaves_set: Vec<Vec<u64>> = (0..=n).into_iter().powerset().skip(1).collect();
|
// size n.
|
||||||
|
let blocks_set: Vec<Vec<u64>> = (1..=n).into_iter().powerset().skip(1).collect();
|
||||||
|
|
||||||
leaves_set.iter().for_each(|leaves_subset| {
|
blocks_set.iter().for_each(|blocks_subset| {
|
||||||
generate_and_verify_batch_proof(&mut ext, leaves_subset, 0);
|
generate_and_verify_batch_proof(&mut ext, &blocks_subset, 0);
|
||||||
ext.persist_offchain_overlay();
|
ext.persist_offchain_overlay();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify that up to n=15, valid proofs are generated for all possible 2-leaf combinations
|
// verify that up to n=15, valid proofs are generated for all possible 2-block number
|
||||||
for n in 10..15 {
|
// combinations.
|
||||||
// (MMR Leafs)
|
for n in 11..=15 {
|
||||||
ext.execute_with(|| new_block());
|
ext.execute_with(|| new_block());
|
||||||
ext.persist_offchain_overlay();
|
ext.persist_offchain_overlay();
|
||||||
|
|
||||||
// generate all possible 2-leaf combinations for mmr size n
|
// generate all possible 2-block number combinations for mmr size n.
|
||||||
let leaves_set: Vec<Vec<u64>> = (0..=n).into_iter().combinations(2).collect();
|
let blocks_set: Vec<Vec<u64>> = (1..=n).into_iter().combinations(2).collect();
|
||||||
|
|
||||||
leaves_set.iter().for_each(|leaves_subset| {
|
blocks_set.iter().for_each(|blocks_subset| {
|
||||||
generate_and_verify_batch_proof(&mut ext, leaves_subset, 0);
|
generate_and_verify_batch_proof(&mut ext, &blocks_subset, 0);
|
||||||
ext.persist_offchain_overlay();
|
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.execute_with(|| add_blocks(1000));
|
||||||
ext.persist_offchain_overlay();
|
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]
|
#[test]
|
||||||
@@ -650,11 +653,11 @@ fn should_verify_batch_proof_statelessly() {
|
|||||||
register_offchain_ext(&mut ext);
|
register_offchain_ext(&mut ext);
|
||||||
let (leaves, proof) = ext.execute_with(|| {
|
let (leaves, proof) = ext.execute_with(|| {
|
||||||
// when
|
// when
|
||||||
crate::Pallet::<Test>::generate_batch_proof(vec![0, 4, 5]).unwrap()
|
crate::Pallet::<Test>::generate_batch_proof(vec![1, 4, 5]).unwrap()
|
||||||
});
|
});
|
||||||
let (historical_leaves, historical_proof) = ext.execute_with(|| {
|
let (historical_leaves, historical_proof) = ext.execute_with(|| {
|
||||||
// when
|
// when
|
||||||
crate::Pallet::<Test>::generate_historical_batch_proof(vec![0, 4, 5], 6).unwrap()
|
crate::Pallet::<Test>::generate_historical_batch_proof(vec![1, 4, 5], 6).unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verify proof without relying on any on-chain data.
|
// Verify proof without relying on any on-chain data.
|
||||||
@@ -920,7 +923,7 @@ fn should_verify_canonicalized() {
|
|||||||
|
|
||||||
// Generate proofs for some blocks.
|
// Generate proofs for some blocks.
|
||||||
let (leaves, proofs) =
|
let (leaves, proofs) =
|
||||||
ext.execute_with(|| crate::Pallet::<Test>::generate_batch_proof(vec![0, 4, 5, 7]).unwrap());
|
ext.execute_with(|| crate::Pallet::<Test>::generate_batch_proof(vec![1, 4, 5, 7]).unwrap());
|
||||||
// Verify all previously generated proofs.
|
// Verify all previously generated proofs.
|
||||||
ext.execute_with(|| {
|
ext.execute_with(|| {
|
||||||
assert_eq!(crate::Pallet::<Test>::verify_leaves(leaves, proofs), Ok(()));
|
assert_eq!(crate::Pallet::<Test>::verify_leaves(leaves, proofs), Ok(()));
|
||||||
@@ -953,19 +956,19 @@ fn does_not_panic_when_generating_historical_proofs() {
|
|||||||
// when leaf index is invalid
|
// when leaf index is invalid
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
crate::Pallet::<Test>::generate_historical_batch_proof(vec![10], 7),
|
crate::Pallet::<Test>::generate_historical_batch_proof(vec![10], 7),
|
||||||
Err(Error::LeafNotFound),
|
Err(Error::BlockNumToLeafIndex),
|
||||||
);
|
);
|
||||||
|
|
||||||
// when leaves count is invalid
|
// when leaves count is invalid
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
crate::Pallet::<Test>::generate_historical_batch_proof(vec![3], 100),
|
crate::Pallet::<Test>::generate_historical_batch_proof(vec![3], 100),
|
||||||
Err(Error::InvalidLeavesCount),
|
Err(Error::BlockNumToLeafIndex),
|
||||||
);
|
);
|
||||||
|
|
||||||
// when both leaf index and leaves count are invalid
|
// when both leaf index and leaves count are invalid
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
crate::Pallet::<Test>::generate_historical_batch_proof(vec![10], 100),
|
crate::Pallet::<Test>::generate_historical_batch_proof(vec![10], 100),
|
||||||
Err(Error::InvalidLeavesCount),
|
Err(Error::BlockNumToLeafIndex),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ pub use mmr_root_provider::MmrRootProvider;
|
|||||||
mod mmr_root_provider {
|
mod mmr_root_provider {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{known_payloads, payload::PayloadProvider, Payload};
|
use crate::{known_payloads, payload::PayloadProvider, Payload};
|
||||||
use sp_api::ProvideRuntimeApi;
|
use sp_api::{NumberFor, ProvideRuntimeApi};
|
||||||
use sp_mmr_primitives::MmrApi;
|
use sp_mmr_primitives::MmrApi;
|
||||||
use sp_runtime::generic::BlockId;
|
use sp_runtime::generic::BlockId;
|
||||||
use sp_std::{marker::PhantomData, sync::Arc};
|
use sp_std::{marker::PhantomData, sync::Arc};
|
||||||
@@ -159,7 +159,7 @@ mod mmr_root_provider {
|
|||||||
where
|
where
|
||||||
B: Block,
|
B: Block,
|
||||||
R: ProvideRuntimeApi<B>,
|
R: ProvideRuntimeApi<B>,
|
||||||
R::Api: MmrApi<B, MmrRootHash>,
|
R::Api: MmrApi<B, MmrRootHash, NumberFor<B>>,
|
||||||
{
|
{
|
||||||
/// Create new BEEFY Payload provider with MMR Root as payload.
|
/// Create new BEEFY Payload provider with MMR Root as payload.
|
||||||
pub fn new(runtime: Arc<R>) -> Self {
|
pub fn new(runtime: Arc<R>) -> Self {
|
||||||
@@ -182,7 +182,7 @@ mod mmr_root_provider {
|
|||||||
where
|
where
|
||||||
B: Block,
|
B: Block,
|
||||||
R: ProvideRuntimeApi<B>,
|
R: ProvideRuntimeApi<B>,
|
||||||
R::Api: MmrApi<B, MmrRootHash>,
|
R::Api: MmrApi<B, MmrRootHash, NumberFor<B>>,
|
||||||
{
|
{
|
||||||
fn payload(&self, header: &B::Header) -> Option<Payload> {
|
fn payload(&self, header: &B::Header) -> Option<Payload> {
|
||||||
self.mmr_root_from_digest_or_runtime(header).map(|mmr_root| {
|
self.mmr_root_from_digest_or_runtime(header).map(|mmr_root| {
|
||||||
|
|||||||
@@ -387,6 +387,8 @@ impl<Hash> Proof<Hash> {
|
|||||||
/// Merkle Mountain Range operation error.
|
/// Merkle Mountain Range operation error.
|
||||||
#[derive(RuntimeDebug, codec::Encode, codec::Decode, PartialEq, Eq)]
|
#[derive(RuntimeDebug, codec::Encode, codec::Decode, PartialEq, Eq)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
/// Error during translation of a block number into a leaf index.
|
||||||
|
BlockNumToLeafIndex,
|
||||||
/// Error while pushing new node.
|
/// Error while pushing new node.
|
||||||
Push,
|
Push,
|
||||||
/// Error getting the new root.
|
/// Error getting the new root.
|
||||||
@@ -403,8 +405,8 @@ pub enum Error {
|
|||||||
PalletNotIncluded,
|
PalletNotIncluded,
|
||||||
/// Cannot find the requested leaf index
|
/// Cannot find the requested leaf index
|
||||||
InvalidLeafIndex,
|
InvalidLeafIndex,
|
||||||
/// The provided leaves count is larger than the actual leaves count.
|
/// The provided best know block number is invalid.
|
||||||
InvalidLeavesCount,
|
InvalidBestKnownBlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
@@ -434,9 +436,9 @@ impl Error {
|
|||||||
|
|
||||||
sp_api::decl_runtime_apis! {
|
sp_api::decl_runtime_apis! {
|
||||||
/// API to interact with MMR pallet.
|
/// 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.
|
/// Generate MMR proof for a block with a specified `block_number`.
|
||||||
fn generate_proof(leaf_index: LeafIndex) -> Result<(EncodableOpaqueLeaf, Proof<Hash>), Error>;
|
fn generate_proof(block_number: BlockNumber) -> Result<(EncodableOpaqueLeaf, Proof<Hash>), Error>;
|
||||||
|
|
||||||
/// Verify MMR proof against on-chain MMR.
|
/// Verify MMR proof against on-chain MMR.
|
||||||
///
|
///
|
||||||
@@ -457,14 +459,13 @@ sp_api::decl_runtime_apis! {
|
|||||||
/// Return the on-chain MMR root hash.
|
/// Return the on-chain MMR root hash.
|
||||||
fn mmr_root() -> Result<Hash, Error>;
|
fn mmr_root() -> Result<Hash, Error>;
|
||||||
|
|
||||||
/// Generate MMR proof for a series of leaves under given indices.
|
/// Generate MMR proof for a series of blocks with the specified block numbers.
|
||||||
fn generate_batch_proof(leaf_indices: Vec<LeafIndex>)
|
fn generate_batch_proof(block_numbers: Vec<BlockNumber>) -> Result<(Vec<EncodableOpaqueLeaf>, BatchProof<Hash>), Error>;
|
||||||
-> Result<(Vec<EncodableOpaqueLeaf>, BatchProof<Hash>), 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`, given the `best_known_block_number`.
|
||||||
fn generate_historical_batch_proof(
|
fn generate_historical_batch_proof(
|
||||||
leaf_indices: Vec<LeafIndex>,
|
block_numbers: Vec<BlockNumber>,
|
||||||
leaves_count: LeafIndex
|
best_known_block_number: BlockNumber
|
||||||
) -> Result<(Vec<EncodableOpaqueLeaf>, BatchProof<Hash>), Error>;
|
) -> Result<(Vec<EncodableOpaqueLeaf>, BatchProof<Hash>), Error>;
|
||||||
|
|
||||||
/// Verify MMR proof against on-chain MMR for a batch of leaves.
|
/// Verify MMR proof against on-chain MMR for a batch of leaves.
|
||||||
|
|||||||
Reference in New Issue
Block a user