mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 06:21:11 +00:00
Millau -> Rialto messages relay (#399)
* Millau messages -> Rialto relay * prepare for custom race strategy of delivery race * custom strategy for delivery race * update TODOs * add reference to issue 457 * impl reconnect * clippy * fix check in test * fmt * removed obsolete TODO * fixed another TODOs * fmt * use MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE const from primitives * Update relays/messages-relay/src/message_lane_loop.rs Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com> * added SubstrateMessagesProof typedef * fix test * removed comment * additional_proof_required -> ProofParameters * typo * multiline literal * clippy * fix typo * and_then -> await * update_source_latest_confirmed_nonce * Update relays/messages-relay/src/message_race_delivery.rs Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com> Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
This commit is contained in:
committed by
Bastian Köcher
parent
804ef55146
commit
d4fc7bebdc
@@ -16,6 +16,7 @@ rand = "0.7"
|
||||
|
||||
# Bridge dependencies
|
||||
|
||||
bp-message-lane = { path = "../../primitives/message-lane" }
|
||||
bp-runtime = { path = "../../primitives/runtime" }
|
||||
headers-relay = { path = "../headers-relay" }
|
||||
relay-utils = { path = "../utils" }
|
||||
@@ -27,6 +28,8 @@ frame-system = "2.0"
|
||||
pallet-balances = "2.0"
|
||||
sp-core = "2.0"
|
||||
sp-runtime = "2.0"
|
||||
sp-std = "2.0"
|
||||
sp-trie = "2.0"
|
||||
sp-version = "2.0"
|
||||
|
||||
#[dev-dependencies]
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
//! Substrate node client.
|
||||
|
||||
use crate::chain::{Chain, ChainWithBalances};
|
||||
use crate::error::Error;
|
||||
use crate::rpc::Substrate;
|
||||
use crate::{ConnectionParams, Result};
|
||||
use crate::rpc::{Substrate, SubstrateMessageLane};
|
||||
use crate::{ConnectionParams, Error, Result};
|
||||
|
||||
use bp_message_lane::{LaneId, MessageNonce};
|
||||
use bp_runtime::InstanceId;
|
||||
use codec::Decode;
|
||||
use frame_support::weights::Weight;
|
||||
use frame_system::AccountInfo;
|
||||
use jsonrpsee::common::DeserializeOwned;
|
||||
use jsonrpsee::raw::RawClient;
|
||||
@@ -30,7 +32,9 @@ use jsonrpsee::{client::Subscription, Client as RpcClient};
|
||||
use num_traits::Zero;
|
||||
use pallet_balances::AccountData;
|
||||
use sp_core::Bytes;
|
||||
use sp_trie::StorageProof;
|
||||
use sp_version::RuntimeVersion;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
const SUB_API_GRANDPA_AUTHORITIES: &str = "GrandpaApi_grandpa_authorities";
|
||||
|
||||
@@ -42,15 +46,26 @@ pub type OpaqueGrandpaAuthoritiesSet = Vec<u8>;
|
||||
|
||||
/// Substrate client type.
|
||||
///
|
||||
/// Cloning Client is a cheap operation.
|
||||
#[derive(Clone)]
|
||||
/// Cloning `Client` is a cheap operation.
|
||||
pub struct Client<C: Chain> {
|
||||
/// Client connection params.
|
||||
params: ConnectionParams,
|
||||
/// Substrate RPC client.
|
||||
client: RpcClient,
|
||||
/// Genesis block hash.
|
||||
genesis_hash: C::Hash,
|
||||
}
|
||||
|
||||
impl<C: Chain> Clone for Client<C> {
|
||||
fn clone(&self) -> Self {
|
||||
Client {
|
||||
params: self.params.clone(),
|
||||
client: self.client.clone(),
|
||||
genesis_hash: self.genesis_hash,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Chain> std::fmt::Debug for Client<C> {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
fmt.debug_struct("Client")
|
||||
@@ -62,15 +77,33 @@ impl<C: Chain> std::fmt::Debug for Client<C> {
|
||||
impl<C: Chain> Client<C> {
|
||||
/// Returns client that is able to call RPCs on Substrate node over websocket connection.
|
||||
pub async fn new(params: ConnectionParams) -> Result<Self> {
|
||||
let uri = format!("ws://{}:{}", params.host, params.port);
|
||||
let transport = WsTransportClient::new(&uri).await?;
|
||||
let raw_client = RawClient::new(transport);
|
||||
let client: RpcClient = raw_client.into();
|
||||
let client = Self::build_client(params.clone()).await?;
|
||||
|
||||
let number: C::BlockNumber = Zero::zero();
|
||||
let genesis_hash = Substrate::<C, _, _>::chain_get_block_hash(&client, number).await?;
|
||||
|
||||
Ok(Self { client, genesis_hash })
|
||||
Ok(Self {
|
||||
params,
|
||||
client,
|
||||
genesis_hash,
|
||||
})
|
||||
}
|
||||
|
||||
/// Reopen client connection.
|
||||
pub async fn reconnect(self) -> Result<Self> {
|
||||
Ok(Self {
|
||||
params: self.params.clone(),
|
||||
client: Self::build_client(self.params).await?,
|
||||
genesis_hash: self.genesis_hash,
|
||||
})
|
||||
}
|
||||
|
||||
/// Build client to use in connection.
|
||||
async fn build_client(params: ConnectionParams) -> Result<RpcClient> {
|
||||
let uri = format!("ws://{}:{}", params.host, params.port);
|
||||
let transport = WsTransportClient::new(&uri).await?;
|
||||
let raw_client = RawClient::new(transport);
|
||||
Ok(raw_client.into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +113,11 @@ impl<C: Chain> Client<C> {
|
||||
&self.genesis_hash
|
||||
}
|
||||
|
||||
/// Return hash of the best finalized block.
|
||||
pub async fn best_finalized_header_hash(&self) -> Result<C::Hash> {
|
||||
Ok(Substrate::<C, _, _>::chain_get_finalized_head(&self.client).await?)
|
||||
}
|
||||
|
||||
/// Returns the best Substrate header.
|
||||
pub async fn best_header(&self) -> Result<C::Header>
|
||||
where
|
||||
@@ -169,6 +207,47 @@ impl<C: Chain> Client<C> {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Returns proof-of-message(s) in given inclusive range.
|
||||
pub async fn prove_messages(
|
||||
&self,
|
||||
instance: InstanceId,
|
||||
lane: LaneId,
|
||||
range: RangeInclusive<MessageNonce>,
|
||||
include_outbound_lane_state: bool,
|
||||
at_block: C::Hash,
|
||||
) -> Result<(Weight, StorageProof)> {
|
||||
let (dispatch_weight, encoded_trie_nodes) = SubstrateMessageLane::<C, _, _>::prove_messages(
|
||||
&self.client,
|
||||
instance,
|
||||
lane,
|
||||
*range.start(),
|
||||
*range.end(),
|
||||
include_outbound_lane_state,
|
||||
Some(at_block),
|
||||
)
|
||||
.await
|
||||
.map_err(Error::Request)?;
|
||||
let decoded_trie_nodes: Vec<Vec<u8>> =
|
||||
Decode::decode(&mut &encoded_trie_nodes[..]).map_err(Error::ResponseParseFailed)?;
|
||||
Ok((dispatch_weight, StorageProof::new(decoded_trie_nodes)))
|
||||
}
|
||||
|
||||
/// Returns proof-of-message(s) delivery.
|
||||
pub async fn prove_messages_delivery(
|
||||
&self,
|
||||
instance: InstanceId,
|
||||
lane: LaneId,
|
||||
at_block: C::Hash,
|
||||
) -> Result<StorageProof> {
|
||||
let encoded_trie_nodes =
|
||||
SubstrateMessageLane::<C, _, _>::prove_messages_delivery(&self.client, instance, lane, Some(at_block))
|
||||
.await
|
||||
.map_err(Error::Request)?;
|
||||
let decoded_trie_nodes: Vec<Vec<u8>> =
|
||||
Decode::decode(&mut &encoded_trie_nodes[..]).map_err(Error::ResponseParseFailed)?;
|
||||
Ok(StorageProof::new(decoded_trie_nodes))
|
||||
}
|
||||
|
||||
/// Return new justifications stream.
|
||||
pub async fn subscribe_justifications(self) -> Result<JustificationsSubscription> {
|
||||
Ok(self
|
||||
|
||||
@@ -31,6 +31,9 @@ pub use crate::client::{Client, JustificationsSubscription, OpaqueGrandpaAuthori
|
||||
pub use crate::error::{Error, Result};
|
||||
pub use bp_runtime::{BlockNumberOf, Chain as ChainBase, HashOf, HeaderOf};
|
||||
|
||||
/// Header id used by the chain.
|
||||
pub type HeaderIdOf<C> = relay_utils::HeaderId<HashOf<C>, BlockNumberOf<C>>;
|
||||
|
||||
/// Substrate-over-websocket connection params.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ConnectionParams {
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
|
||||
use crate::chain::Chain;
|
||||
|
||||
use bp_message_lane::{LaneId, MessageNonce};
|
||||
use bp_runtime::InstanceId;
|
||||
use frame_support::weights::Weight;
|
||||
use sp_core::{
|
||||
storage::{StorageData, StorageKey},
|
||||
Bytes,
|
||||
@@ -33,6 +36,8 @@ jsonrpsee::rpc_api! {
|
||||
pub(crate) Substrate<C: Chain> {
|
||||
#[rpc(method = "chain_getHeader", positional_params)]
|
||||
fn chain_get_header(block_hash: Option<C::Hash>) -> C::Header;
|
||||
#[rpc(method = "chain_getFinalizedHead", positional_params)]
|
||||
fn chain_get_finalized_head() -> C::Hash;
|
||||
#[rpc(method = "chain_getBlock", positional_params)]
|
||||
fn chain_get_block(block_hash: Option<C::Hash>) -> C::SignedBlock;
|
||||
#[rpc(method = "chain_getBlockHash", positional_params)]
|
||||
@@ -48,4 +53,23 @@ jsonrpsee::rpc_api! {
|
||||
#[rpc(method = "state_getRuntimeVersion", positional_params)]
|
||||
fn runtime_version() -> RuntimeVersion;
|
||||
}
|
||||
|
||||
pub(crate) SubstrateMessageLane<C: Chain> {
|
||||
#[rpc(method = "messageLane_proveMessages", positional_params)]
|
||||
fn prove_messages(
|
||||
instance: InstanceId,
|
||||
lane: LaneId,
|
||||
begin: MessageNonce,
|
||||
end: MessageNonce,
|
||||
include_outbound_lane_state: bool,
|
||||
block: Option<C::Hash>,
|
||||
) -> (Weight, Bytes);
|
||||
|
||||
#[rpc(method = "messageLane_proveMessagesDelivery", positional_params)]
|
||||
fn prove_messages_delivery(
|
||||
instance: InstanceId,
|
||||
lane: LaneId,
|
||||
block: Option<C::Hash>,
|
||||
) -> Bytes;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user