Skip to content

Commit

Permalink
Return cumulative dispatch weight of messages from the `messageLane_p…
Browse files Browse the repository at this point in the history
…roveMessages` (paritytech#469)

* implement OutboundLaneApi and InboundLaneApi for Millau /Rialto runtimes

* fixed typo
  • Loading branch information
svyatonik authored and bkchr committed Apr 10, 2024
1 parent 51f39c4 commit ef93575
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 12 deletions.
1 change: 1 addition & 0 deletions bridges/bin/millau/node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
finality_proof_provider.clone(),
)));
io.extend_with(MessageLaneApi::to_delegate(MessageLaneRpcHandler::new(
client.clone(),
backend.clone(),
Arc::new(MillauMessageLaneKeys),
)));
Expand Down
31 changes: 31 additions & 0 deletions bridges/bin/millau/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
pub mod rialto;
pub mod rialto_messages;

use codec::Decode;
use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
use sp_api::impl_runtime_apis;
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
Expand Down Expand Up @@ -538,4 +539,34 @@ impl_runtime_apis! {
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 change: 1 addition & 0 deletions bridges/bin/rialto/node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
DenyUnsafe::No,
)));
io.extend_with(MessageLaneApi::to_delegate(MessageLaneRpcHandler::new(
client.clone(),
backend.clone(),
Arc::new(RialtoMessageLaneKeys),
)));
Expand Down
31 changes: 31 additions & 0 deletions bridges/bin/rialto/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub mod millau;
pub mod millau_messages;
pub mod rialto_poa;

use codec::Decode;
use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
use sp_api::impl_runtime_apis;
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
Expand Down Expand Up @@ -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")]
impl frame_benchmarking::Benchmark<Block> for Runtime {
fn dispatch_benchmark(
Expand Down
2 changes: 2 additions & 0 deletions bridges/modules/message-lane/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ bp-message-lane = { path = "../../../primitives/message-lane" }

# Substrate Dependencies

frame-support = "2.0"
sc-client-api = "2.0"
sp-api = "2.0"
sp-blockchain = "2.0"
sp-core = "2.0"
sp-runtime = "2.0"
Expand Down
42 changes: 32 additions & 10 deletions bridges/modules/message-lane/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@

use crate::error::{Error, FutureResult};

use bp_message_lane::{LaneId, MessageNonce};
use bp_message_lane::{LaneId, MessageNonce, OutboundLaneApi};
use bp_runtime::InstanceId;
use frame_support::weights::Weight;
use futures::{FutureExt, TryFutureExt};
use jsonrpc_core::futures::Future as _;
use jsonrpc_derive::rpc;
use sc_client_api::Backend as BackendT;
use sp_api::ProvideRuntimeApi;
use sp_blockchain::{Error as BlockchainError, HeaderBackend};
use sp_core::{storage::StorageKey, Bytes};
use sp_runtime::{codec::Encode, generic::BlockId, traits::Block as BlockT};
Expand Down Expand Up @@ -54,7 +56,8 @@ pub trait Runtime: Send + Sync + 'static {
/// Provides RPC methods for interacting with message-lane pallet.
#[rpc]
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")]
fn prove_messages(
&self,
Expand All @@ -64,7 +67,7 @@ pub trait MessageLaneApi<BlockHash> {
end: MessageNonce,
include_outbound_lane_state: bool,
block: Option<BlockHash>,
) -> FutureResult<MessagesProof>;
) -> FutureResult<(Weight, MessagesProof)>;

/// Returns proof-of-message(s) delivery.
#[rpc(name = "messageLane_proveMessagesDelivery")]
Expand All @@ -77,26 +80,30 @@ pub trait MessageLaneApi<BlockHash> {
}

/// 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>,
runtime: Arc<R>,
_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.
pub fn new(backend: Arc<Backend>, runtime: Arc<R>) -> Self {
pub fn new(client: Arc<Client>, backend: Arc<Backend>, runtime: Arc<R>) -> Self {
Self {
client,
backend,
runtime,
_phantom: Default::default(),
}
}
}

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
Block: BlockT,
Client: ProvideRuntimeApi<Block> + Send + Sync + 'static,
Client::Api: OutboundLaneApi<Block>,
Backend: BackendT<Block> + 'static,
R: Runtime,
{
Expand All @@ -108,7 +115,22 @@ where
end: MessageNonce,
include_outbound_lane_state: bool,
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 outbound_lane_data_key = if include_outbound_lane_state {
Some(runtime.inbound_lane_data_key(&instance, &lane))
Expand All @@ -118,14 +140,14 @@ where
Box::new(
prove_keys_read(
self.backend.clone(),
block,
Some(block),
(begin..=end)
.map(move |nonce| runtime.message_key(&instance, &lane, nonce))
.chain(outbound_lane_data_key.into_iter()),
)
.boxed()
.compat()
.map(serialize_storage_proof)
.map(move |proof| (messages_dispatch_weight, serialize_storage_proof(proof)))
.map_err(Into::into),
)
}
Expand Down
29 changes: 28 additions & 1 deletion bridges/modules/message-lane/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use crate::outbound_lane::{OutboundLane, OutboundLaneStorage};
use bp_message_lane::{
source_chain::{LaneMessageVerifier, MessageDeliveryAndDispatchPayment, TargetHeaderChain},
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 frame_support::{
Expand Down Expand Up @@ -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.
fn inbound_lane<T: Trait<I>, I: Instance>(lane_id: LaneId) -> InboundLane<RuntimeInboundLaneStorage<T, I>> {
InboundLane::new(RuntimeInboundLaneStorage {
Expand Down
4 changes: 3 additions & 1 deletion bridges/primitives/message-lane/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#![allow(clippy::unnecessary_mut_passed)]

use codec::{Decode, Encode};
use frame_support::RuntimeDebug;
use frame_support::{weights::Weight, RuntimeDebug};
use sp_api::decl_runtime_apis;
use sp_std::{collections::vec_deque::VecDeque, prelude::*};

Expand Down Expand Up @@ -126,6 +126,8 @@ impl Default for OutboundLaneData {
decl_runtime_apis! {
/// Outbound message lane API.
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.
fn latest_received_nonce(lane: LaneId) -> MessageNonce;
/// Returns nonce of the latest message, generated by given lane.
Expand Down

0 comments on commit ef93575

Please sign in to comment.