Return cumulative dispatch weight of messages from the messageLane_proveMessages (#469)

* implement OutboundLaneApi and InboundLaneApi for Millau /Rialto runtimes

* fixed typo
This commit is contained in:
Svyatoslav Nikolsky
2020-10-28 21:35:29 +03:00
committed by Bastian Köcher
parent 51f39c4427
commit ef9357596f
8 changed files with 129 additions and 12 deletions
+1
View File
@@ -222,6 +222,7 @@ pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
finality_proof_provider.clone(), finality_proof_provider.clone(),
))); )));
io.extend_with(MessageLaneApi::to_delegate(MessageLaneRpcHandler::new( io.extend_with(MessageLaneApi::to_delegate(MessageLaneRpcHandler::new(
client.clone(),
backend.clone(), backend.clone(),
Arc::new(MillauMessageLaneKeys), Arc::new(MillauMessageLaneKeys),
))); )));
+31
View File
@@ -31,6 +31,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
pub mod rialto; pub mod rialto;
pub mod rialto_messages; pub mod rialto_messages;
use codec::Decode;
use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList}; use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
use sp_api::impl_runtime_apis; use sp_api::impl_runtime_apis;
use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_consensus_aura::sr25519::AuthorityId as AuraId;
@@ -538,4 +539,34 @@ impl_runtime_apis! {
BridgeRialto::is_finalized_header(hash) BridgeRialto::is_finalized_header(hash)
} }
} }
// TODO: runtime should support several chains (https://github.com/paritytech/parity-bridges-common/issues/457)
impl bp_message_lane::OutboundLaneApi<Block> for Runtime {
fn messages_dispatch_weight(lane: bp_message_lane::LaneId, begin: bp_message_lane::MessageNonce, end: bp_message_lane::MessageNonce) -> Weight {
(begin..=end)
.filter_map(|nonce| BridgeRialtoMessageLane::outbound_message_payload(lane, nonce))
.filter_map(|encoded_payload| rialto_messages::ToRialtoMessagePayload::decode(&mut &encoded_payload[..]).ok())
.map(|decoded_payload| decoded_payload.weight)
.fold(0, |sum, weight| sum.saturating_add(weight))
}
fn latest_received_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
BridgeRialtoMessageLane::outbound_latest_received_nonce(lane)
}
fn latest_generated_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
BridgeRialtoMessageLane::outbound_latest_generated_nonce(lane)
}
}
// TODO: runtime should support several chains (https://github.com/paritytech/parity-bridges-common/issues/457)
impl bp_message_lane::InboundLaneApi<Block> for Runtime {
fn latest_received_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
BridgeRialtoMessageLane::inbound_latest_received_nonce(lane)
}
fn latest_confirmed_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
BridgeRialtoMessageLane::inbound_latest_confirmed_nonce(lane)
}
}
} }
+1
View File
@@ -206,6 +206,7 @@ pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
DenyUnsafe::No, DenyUnsafe::No,
))); )));
io.extend_with(MessageLaneApi::to_delegate(MessageLaneRpcHandler::new( io.extend_with(MessageLaneApi::to_delegate(MessageLaneRpcHandler::new(
client.clone(),
backend.clone(), backend.clone(),
Arc::new(RialtoMessageLaneKeys), Arc::new(RialtoMessageLaneKeys),
))); )));
+31
View File
@@ -37,6 +37,7 @@ pub mod millau;
pub mod millau_messages; pub mod millau_messages;
pub mod rialto_poa; pub mod rialto_poa;
use codec::Decode;
use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList}; use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
use sp_api::impl_runtime_apis; use sp_api::impl_runtime_apis;
use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_consensus_aura::sr25519::AuthorityId as AuraId;
@@ -702,6 +703,36 @@ impl_runtime_apis! {
} }
} }
// TODO: runtime should support several chains (https://github.com/paritytech/parity-bridges-common/issues/457)
impl bp_message_lane::OutboundLaneApi<Block> for Runtime {
fn messages_dispatch_weight(lane: bp_message_lane::LaneId, begin: bp_message_lane::MessageNonce, end: bp_message_lane::MessageNonce) -> Weight {
(begin..=end)
.filter_map(|nonce| BridgeMillauMessageLane::outbound_message_payload(lane, nonce))
.filter_map(|encoded_payload| millau_messages::ToMillauMessagePayload::decode(&mut &encoded_payload[..]).ok())
.map(|decoded_payload| decoded_payload.weight)
.fold(0, |sum, weight| sum.saturating_add(weight))
}
fn latest_received_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
BridgeMillauMessageLane::outbound_latest_received_nonce(lane)
}
fn latest_generated_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
BridgeMillauMessageLane::outbound_latest_generated_nonce(lane)
}
}
// TODO: runtime should support several chains (https://github.com/paritytech/parity-bridges-common/issues/457)
impl bp_message_lane::InboundLaneApi<Block> for Runtime {
fn latest_received_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
BridgeMillauMessageLane::inbound_latest_received_nonce(lane)
}
fn latest_confirmed_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
BridgeMillauMessageLane::inbound_latest_confirmed_nonce(lane)
}
}
#[cfg(feature = "runtime-benchmarks")] #[cfg(feature = "runtime-benchmarks")]
impl frame_benchmarking::Benchmark<Block> for Runtime { impl frame_benchmarking::Benchmark<Block> for Runtime {
fn dispatch_benchmark( fn dispatch_benchmark(
@@ -20,7 +20,9 @@ bp-message-lane = { path = "../../../primitives/message-lane" }
# Substrate Dependencies # Substrate Dependencies
frame-support = "2.0"
sc-client-api = "2.0" sc-client-api = "2.0"
sp-api = "2.0"
sp-blockchain = "2.0" sp-blockchain = "2.0"
sp-core = "2.0" sp-core = "2.0"
sp-runtime = "2.0" sp-runtime = "2.0"
+32 -10
View File
@@ -18,12 +18,14 @@
use crate::error::{Error, FutureResult}; use crate::error::{Error, FutureResult};
use bp_message_lane::{LaneId, MessageNonce}; use bp_message_lane::{LaneId, MessageNonce, OutboundLaneApi};
use bp_runtime::InstanceId; use bp_runtime::InstanceId;
use frame_support::weights::Weight;
use futures::{FutureExt, TryFutureExt}; use futures::{FutureExt, TryFutureExt};
use jsonrpc_core::futures::Future as _; use jsonrpc_core::futures::Future as _;
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use sc_client_api::Backend as BackendT; use sc_client_api::Backend as BackendT;
use sp_api::ProvideRuntimeApi;
use sp_blockchain::{Error as BlockchainError, HeaderBackend}; use sp_blockchain::{Error as BlockchainError, HeaderBackend};
use sp_core::{storage::StorageKey, Bytes}; use sp_core::{storage::StorageKey, Bytes};
use sp_runtime::{codec::Encode, generic::BlockId, traits::Block as BlockT}; use sp_runtime::{codec::Encode, generic::BlockId, traits::Block as BlockT};
@@ -54,7 +56,8 @@ pub trait Runtime: Send + Sync + 'static {
/// Provides RPC methods for interacting with message-lane pallet. /// Provides RPC methods for interacting with message-lane pallet.
#[rpc] #[rpc]
pub trait MessageLaneApi<BlockHash> { pub trait MessageLaneApi<BlockHash> {
/// Returns proof-of-message(s) in given inclusive range. /// Returns cumulative dispatch weight of messages in given inclusive range and their storage proof.
/// The state of outbound lane is included in the proof if `include_outbound_lane_state` is true.
#[rpc(name = "messageLane_proveMessages")] #[rpc(name = "messageLane_proveMessages")]
fn prove_messages( fn prove_messages(
&self, &self,
@@ -64,7 +67,7 @@ pub trait MessageLaneApi<BlockHash> {
end: MessageNonce, end: MessageNonce,
include_outbound_lane_state: bool, include_outbound_lane_state: bool,
block: Option<BlockHash>, block: Option<BlockHash>,
) -> FutureResult<MessagesProof>; ) -> FutureResult<(Weight, MessagesProof)>;
/// Returns proof-of-message(s) delivery. /// Returns proof-of-message(s) delivery.
#[rpc(name = "messageLane_proveMessagesDelivery")] #[rpc(name = "messageLane_proveMessagesDelivery")]
@@ -77,16 +80,18 @@ pub trait MessageLaneApi<BlockHash> {
} }
/// Implements the MessageLaneApi trait for interacting with message lanes. /// Implements the MessageLaneApi trait for interacting with message lanes.
pub struct MessageLaneRpcHandler<Block, Backend, R> { pub struct MessageLaneRpcHandler<Block, Client, Backend, R> {
client: Arc<Client>,
backend: Arc<Backend>, backend: Arc<Backend>,
runtime: Arc<R>, runtime: Arc<R>,
_phantom: std::marker::PhantomData<Block>, _phantom: std::marker::PhantomData<Block>,
} }
impl<Block, Backend, R> MessageLaneRpcHandler<Block, Backend, R> { impl<Block, Client, Backend, R> MessageLaneRpcHandler<Block, Client, Backend, R> {
/// Creates new mesage lane RPC handler. /// Creates new mesage lane RPC handler.
pub fn new(backend: Arc<Backend>, runtime: Arc<R>) -> Self { pub fn new(client: Arc<Client>, backend: Arc<Backend>, runtime: Arc<R>) -> Self {
Self { Self {
client,
backend, backend,
runtime, runtime,
_phantom: Default::default(), _phantom: Default::default(),
@@ -94,9 +99,11 @@ impl<Block, Backend, R> MessageLaneRpcHandler<Block, Backend, R> {
} }
} }
impl<Block, Backend, R> MessageLaneApi<Block::Hash> for MessageLaneRpcHandler<Block, Backend, R> impl<Block, Client, Backend, R> MessageLaneApi<Block::Hash> for MessageLaneRpcHandler<Block, Client, Backend, R>
where where
Block: BlockT, Block: BlockT,
Client: ProvideRuntimeApi<Block> + Send + Sync + 'static,
Client::Api: OutboundLaneApi<Block>,
Backend: BackendT<Block> + 'static, Backend: BackendT<Block> + 'static,
R: Runtime, R: Runtime,
{ {
@@ -108,7 +115,22 @@ where
end: MessageNonce, end: MessageNonce,
include_outbound_lane_state: bool, include_outbound_lane_state: bool,
block: Option<Block::Hash>, block: Option<Block::Hash>,
) -> FutureResult<MessagesProof> { ) -> FutureResult<(Weight, MessagesProof)> {
let block = unwrap_or_best(&*self.backend, block);
let messages_dispatch_weight_result =
self.client
.runtime_api()
.messages_dispatch_weight(&BlockId::Hash(block), lane, begin, end);
let messages_dispatch_weight = match messages_dispatch_weight_result {
Ok(messages_dispatch_weight) => messages_dispatch_weight,
Err(error) => {
return Box::new(jsonrpc_core::futures::future::err(
blockchain_err(BlockchainError::Execution(Box::new(format!("{:?}", error)))).into(),
))
}
};
let runtime = self.runtime.clone(); let runtime = self.runtime.clone();
let outbound_lane_data_key = if include_outbound_lane_state { let outbound_lane_data_key = if include_outbound_lane_state {
Some(runtime.inbound_lane_data_key(&instance, &lane)) Some(runtime.inbound_lane_data_key(&instance, &lane))
@@ -118,14 +140,14 @@ where
Box::new( Box::new(
prove_keys_read( prove_keys_read(
self.backend.clone(), self.backend.clone(),
block, Some(block),
(begin..=end) (begin..=end)
.map(move |nonce| runtime.message_key(&instance, &lane, nonce)) .map(move |nonce| runtime.message_key(&instance, &lane, nonce))
.chain(outbound_lane_data_key.into_iter()), .chain(outbound_lane_data_key.into_iter()),
) )
.boxed() .boxed()
.compat() .compat()
.map(serialize_storage_proof) .map(move |proof| (messages_dispatch_weight, serialize_storage_proof(proof)))
.map_err(Into::into), .map_err(Into::into),
) )
} }
+28 -1
View File
@@ -35,7 +35,7 @@ use crate::outbound_lane::{OutboundLane, OutboundLaneStorage};
use bp_message_lane::{ use bp_message_lane::{
source_chain::{LaneMessageVerifier, MessageDeliveryAndDispatchPayment, TargetHeaderChain}, source_chain::{LaneMessageVerifier, MessageDeliveryAndDispatchPayment, TargetHeaderChain},
target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain}, target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain},
InboundLaneData, LaneId, MessageData, MessageKey, MessageNonce, OutboundLaneData, InboundLaneData, LaneId, MessageData, MessageKey, MessageNonce, MessagePayload, OutboundLaneData,
}; };
use codec::{Decode, Encode}; use codec::{Decode, Encode};
use frame_support::{ use frame_support::{
@@ -374,6 +374,33 @@ decl_module! {
} }
} }
impl<T: Trait<I>, I: Instance> Module<T, I> {
/// Get payload of given outbound message.
pub fn outbound_message_payload(lane: LaneId, nonce: MessageNonce) -> Option<MessagePayload> {
OutboundMessages::<T, I>::get(MessageKey { lane_id: lane, nonce }).map(|message_data| message_data.payload)
}
/// Get nonce of latest generated message at given outbound lane.
pub fn outbound_latest_generated_nonce(lane: LaneId) -> MessageNonce {
OutboundLanes::<I>::get(&lane).latest_generated_nonce
}
/// Get nonce of latest confirmed message at given outbound lane.
pub fn outbound_latest_received_nonce(lane: LaneId) -> MessageNonce {
OutboundLanes::<I>::get(&lane).latest_received_nonce
}
/// Get nonce of latest received message at given inbound lane.
pub fn inbound_latest_received_nonce(lane: LaneId) -> MessageNonce {
InboundLanes::<T, I>::get(&lane).latest_received_nonce
}
/// Get nonce of latest confirmed message at given inbound lane.
pub fn inbound_latest_confirmed_nonce(lane: LaneId) -> MessageNonce {
InboundLanes::<T, I>::get(&lane).latest_confirmed_nonce
}
}
/// Creates new inbound lane object, backed by runtime storage. /// Creates new inbound lane object, backed by runtime storage.
fn inbound_lane<T: Trait<I>, I: Instance>(lane_id: LaneId) -> InboundLane<RuntimeInboundLaneStorage<T, I>> { fn inbound_lane<T: Trait<I>, I: Instance>(lane_id: LaneId) -> InboundLane<RuntimeInboundLaneStorage<T, I>> {
InboundLane::new(RuntimeInboundLaneStorage { InboundLane::new(RuntimeInboundLaneStorage {
+3 -1
View File
@@ -23,7 +23,7 @@
#![allow(clippy::unnecessary_mut_passed)] #![allow(clippy::unnecessary_mut_passed)]
use codec::{Decode, Encode}; use codec::{Decode, Encode};
use frame_support::RuntimeDebug; use frame_support::{weights::Weight, RuntimeDebug};
use sp_api::decl_runtime_apis; use sp_api::decl_runtime_apis;
use sp_std::{collections::vec_deque::VecDeque, prelude::*}; use sp_std::{collections::vec_deque::VecDeque, prelude::*};
@@ -126,6 +126,8 @@ impl Default for OutboundLaneData {
decl_runtime_apis! { decl_runtime_apis! {
/// Outbound message lane API. /// Outbound message lane API.
pub trait OutboundLaneApi { pub trait OutboundLaneApi {
/// Returns dispatch weight of all messages in given inclusive range.
fn messages_dispatch_weight(lane: LaneId, begin: MessageNonce, end: MessageNonce) -> Weight;
/// Returns nonce of the latest message, received by bridged chain. /// Returns nonce of the latest message, received by bridged chain.
fn latest_received_nonce(lane: LaneId) -> MessageNonce; fn latest_received_nonce(lane: LaneId) -> MessageNonce;
/// Returns nonce of the latest message, generated by given lane. /// Returns nonce of the latest message, generated by given lane.