mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 05:11:02 +00:00
Chain specific message lane apis (#503)
* replace generic message lane APIs with chain-specific * moved SubstrateHeadersSyncPipeline to headers_pipeline.rs * substrate-specific message lane trait * Update relays/substrate/src/messages_lane.rs Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com> Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
This commit is contained in:
committed by
Bastian Köcher
parent
d2ab81340a
commit
53791a1d4a
@@ -540,8 +540,7 @@ impl_runtime_apis! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: runtime should support several chains (https://github.com/paritytech/parity-bridges-common/issues/457)
|
impl bp_rialto::ToRialtoOutboundLaneApi<Block> for Runtime {
|
||||||
impl bp_message_lane::OutboundLaneApi<Block> for Runtime {
|
|
||||||
fn messages_dispatch_weight(
|
fn messages_dispatch_weight(
|
||||||
lane: bp_message_lane::LaneId,
|
lane: bp_message_lane::LaneId,
|
||||||
begin: bp_message_lane::MessageNonce,
|
begin: bp_message_lane::MessageNonce,
|
||||||
@@ -566,8 +565,7 @@ impl_runtime_apis! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: runtime should support several chains (https://github.com/paritytech/parity-bridges-common/issues/457)
|
impl bp_rialto::FromRialtoInboundLaneApi<Block> for Runtime {
|
||||||
impl bp_message_lane::InboundLaneApi<Block> for Runtime {
|
|
||||||
fn latest_received_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
|
fn latest_received_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
|
||||||
BridgeRialtoMessageLane::inbound_latest_received_nonce(lane)
|
BridgeRialtoMessageLane::inbound_latest_received_nonce(lane)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -704,8 +704,7 @@ impl_runtime_apis! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: runtime should support several chains (https://github.com/paritytech/parity-bridges-common/issues/457)
|
impl bp_millau::ToMillauOutboundLaneApi<Block> for Runtime {
|
||||||
impl bp_message_lane::OutboundLaneApi<Block> for Runtime {
|
|
||||||
fn messages_dispatch_weight(
|
fn messages_dispatch_weight(
|
||||||
lane: bp_message_lane::LaneId,
|
lane: bp_message_lane::LaneId,
|
||||||
begin: bp_message_lane::MessageNonce,
|
begin: bp_message_lane::MessageNonce,
|
||||||
@@ -730,8 +729,7 @@ impl_runtime_apis! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: runtime should support several chains (https://github.com/paritytech/parity-bridges-common/issues/457)
|
impl bp_millau::FromMillauInboundLaneApi<Block> for Runtime {
|
||||||
impl bp_message_lane::InboundLaneApi<Block> for Runtime {
|
|
||||||
fn latest_received_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
|
fn latest_received_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
|
||||||
BridgeMillauMessageLane::inbound_latest_received_nonce(lane)
|
BridgeMillauMessageLane::inbound_latest_received_nonce(lane)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ codec = { package = "parity-scale-codec", version = "1.3.1", default-features =
|
|||||||
# Substrate Dependencies
|
# Substrate Dependencies
|
||||||
|
|
||||||
frame-support = { version = "2.0", default-features = false }
|
frame-support = { version = "2.0", default-features = false }
|
||||||
sp-api = { version = "2.0", default-features = false }
|
|
||||||
sp-std = { version = "2.0", default-features = false }
|
sp-std = { version = "2.0", default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
@@ -20,6 +19,5 @@ default = ["std"]
|
|||||||
std = [
|
std = [
|
||||||
"codec/std",
|
"codec/std",
|
||||||
"frame-support/std",
|
"frame-support/std",
|
||||||
"sp-api/std",
|
|
||||||
"sp-std/std"
|
"sp-std/std"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use frame_support::RuntimeDebug;
|
use frame_support::RuntimeDebug;
|
||||||
use sp_api::decl_runtime_apis;
|
|
||||||
use sp_std::{collections::vec_deque::VecDeque, prelude::*};
|
use sp_std::{collections::vec_deque::VecDeque, prelude::*};
|
||||||
|
|
||||||
pub mod source_chain;
|
pub mod source_chain;
|
||||||
@@ -125,30 +124,3 @@ impl Default for OutboundLaneData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
decl_runtime_apis! {
|
|
||||||
/// Outbound message lane API.
|
|
||||||
pub trait OutboundLaneApi {
|
|
||||||
/// Returns dispatch weight of all messages in given inclusive range.
|
|
||||||
///
|
|
||||||
/// If some (or all) messages are missing from the storage, they'll also will
|
|
||||||
/// be missing from the resulting vector. The vector is ordered by the nonce.
|
|
||||||
fn messages_dispatch_weight(
|
|
||||||
lane: LaneId,
|
|
||||||
begin: MessageNonce,
|
|
||||||
end: MessageNonce,
|
|
||||||
) -> Vec<(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.
|
|
||||||
fn latest_generated_nonce(lane: LaneId) -> MessageNonce;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inbound message lane API.
|
|
||||||
pub trait InboundLaneApi {
|
|
||||||
/// Returns nonce of the latest message, received by given lane.
|
|
||||||
fn latest_received_nonce(lane: LaneId) -> MessageNonce;
|
|
||||||
/// Nonce of latest message that has been confirmed to the bridged chain.
|
|
||||||
fn latest_confirmed_nonce(lane: LaneId) -> MessageNonce;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
mod millau_hash;
|
mod millau_hash;
|
||||||
|
|
||||||
use bp_message_lane::MessageNonce;
|
use bp_message_lane::{LaneId, MessageNonce};
|
||||||
use bp_runtime::Chain;
|
use bp_runtime::Chain;
|
||||||
use frame_support::{weights::Weight, RuntimeDebug};
|
use frame_support::{weights::Weight, RuntimeDebug};
|
||||||
use sp_core::Hasher as HasherT;
|
use sp_core::Hasher as HasherT;
|
||||||
@@ -111,6 +111,18 @@ pub const IS_KNOWN_MILLAU_BLOCK_METHOD: &str = "MillauHeaderApi_is_known_block";
|
|||||||
/// Name of the `MillauHeaderApi::incomplete_headers` runtime method.
|
/// Name of the `MillauHeaderApi::incomplete_headers` runtime method.
|
||||||
pub const INCOMPLETE_MILLAU_HEADERS_METHOD: &str = "MillauHeaderApi_incomplete_headers";
|
pub const INCOMPLETE_MILLAU_HEADERS_METHOD: &str = "MillauHeaderApi_incomplete_headers";
|
||||||
|
|
||||||
|
/// Name of the `ToMillauOutboundLaneApi::messages_dispatch_weight` runtime method.
|
||||||
|
pub const TO_MILLAU_MESSAGES_DISPATCH_WEIGHT_METHOD: &str = "ToMillauOutboundLaneApi_messages_dispatch_weight";
|
||||||
|
/// Name of the `ToMillauOutboundLaneApi::latest_received_nonce` runtime method.
|
||||||
|
pub const TO_MILLAU_LATEST_RECEIVED_NONCE_METHOD: &str = "ToMillauOutboundLaneApi_latest_received_nonce";
|
||||||
|
/// Name of the `ToMillauOutboundLaneApi::latest_generated_nonce` runtime method.
|
||||||
|
pub const TO_MILLAU_LATEST_GENERATED_NONCE_METHOD: &str = "ToMillauOutboundLaneApi_latest_generated_nonce";
|
||||||
|
|
||||||
|
/// Name of the `FromMillauInboundLaneApi::latest_received_nonce` runtime method.
|
||||||
|
pub const FROM_MILLAU_LATEST_RECEIVED_NONCE_METHOD: &str = "FromMillauInboundLaneApi_latest_received_nonce";
|
||||||
|
/// Name of the `FromMillauInboundLaneApi::latest_onfirmed_nonce` runtime method.
|
||||||
|
pub const FROM_MILLAU_LATEST_CONFIRMED_NONCE_METHOD: &str = "FromMillauInboundLaneApi_latest_confirmed_nonce";
|
||||||
|
|
||||||
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
|
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
|
||||||
pub type Signature = MultiSignature;
|
pub type Signature = MultiSignature;
|
||||||
|
|
||||||
@@ -149,4 +161,35 @@ sp_api::decl_runtime_apis! {
|
|||||||
/// Returns true if the header is considered finalized by the runtime.
|
/// Returns true if the header is considered finalized by the runtime.
|
||||||
fn is_finalized_block(hash: Hash) -> bool;
|
fn is_finalized_block(hash: Hash) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Outbound message lane API for messages that are sent to Millau chain.
|
||||||
|
///
|
||||||
|
/// This API is implemented by runtimes that are sending messages to Millau chain, not the
|
||||||
|
/// Millau runtime itself.
|
||||||
|
pub trait ToMillauOutboundLaneApi {
|
||||||
|
/// Returns dispatch weight of all messages in given inclusive range.
|
||||||
|
///
|
||||||
|
/// If some (or all) messages are missing from the storage, they'll also will
|
||||||
|
/// be missing from the resulting vector. The vector is ordered by the nonce.
|
||||||
|
fn messages_dispatch_weight(
|
||||||
|
lane: LaneId,
|
||||||
|
begin: MessageNonce,
|
||||||
|
end: MessageNonce,
|
||||||
|
) -> Vec<(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.
|
||||||
|
fn latest_generated_nonce(lane: LaneId) -> MessageNonce;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inbound message lane API for messages sent by Millau chain.
|
||||||
|
///
|
||||||
|
/// This API is implemented by runtimes that are receiving messages from Millau chain, not the
|
||||||
|
/// Millau runtime itself.
|
||||||
|
pub trait FromMillauInboundLaneApi {
|
||||||
|
/// Returns nonce of the latest message, received by given lane.
|
||||||
|
fn latest_received_nonce(lane: LaneId) -> MessageNonce;
|
||||||
|
/// Nonce of latest message that has been confirmed to the bridged chain.
|
||||||
|
fn latest_confirmed_nonce(lane: LaneId) -> MessageNonce;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
// Runtime-generated DecodeLimit::decode_all_With_depth_limit
|
// Runtime-generated DecodeLimit::decode_all_With_depth_limit
|
||||||
#![allow(clippy::unnecessary_mut_passed)]
|
#![allow(clippy::unnecessary_mut_passed)]
|
||||||
|
|
||||||
use bp_message_lane::MessageNonce;
|
use bp_message_lane::{LaneId, MessageNonce};
|
||||||
use bp_runtime::Chain;
|
use bp_runtime::Chain;
|
||||||
use frame_support::{weights::Weight, RuntimeDebug};
|
use frame_support::{weights::Weight, RuntimeDebug};
|
||||||
use sp_core::Hasher as HasherT;
|
use sp_core::Hasher as HasherT;
|
||||||
@@ -73,6 +73,18 @@ pub const IS_KNOWN_RIALTO_BLOCK_METHOD: &str = "RialtoHeaderApi_is_known_block";
|
|||||||
/// Name of the `RialtoHeaderApi::incomplete_headers` runtime method.
|
/// Name of the `RialtoHeaderApi::incomplete_headers` runtime method.
|
||||||
pub const INCOMPLETE_RIALTO_HEADERS_METHOD: &str = "RialtoHeaderApi_incomplete_headers";
|
pub const INCOMPLETE_RIALTO_HEADERS_METHOD: &str = "RialtoHeaderApi_incomplete_headers";
|
||||||
|
|
||||||
|
/// Name of the `ToRialtoOutboundLaneApi::messages_dispatch_weight` runtime method.
|
||||||
|
pub const TO_RIALTO_MESSAGES_DISPATCH_WEIGHT_METHOD: &str = "ToRialtoOutboundLaneApi_messages_dispatch_weight";
|
||||||
|
/// Name of the `ToRialtoOutboundLaneApi::latest_generated_nonce` runtime method.
|
||||||
|
pub const TO_RIALTO_LATEST_GENERATED_NONCE_METHOD: &str = "ToRialtoOutboundLaneApi_latest_generated_nonce";
|
||||||
|
/// Name of the `ToRialtoOutboundLaneApi::latest_received_nonce` runtime method.
|
||||||
|
pub const TO_RIALTO_LATEST_RECEIVED_NONCE_METHOD: &str = "ToRialtoOutboundLaneApi_latest_received_nonce";
|
||||||
|
|
||||||
|
/// Name of the `FromRialtoInboundLaneApi::latest_received_nonce` runtime method.
|
||||||
|
pub const FROM_RIALTO_LATEST_RECEIVED_NONCE_METHOD: &str = "FromRialtoInboundLaneApi_latest_received_nonce";
|
||||||
|
/// Name of the `FromRialtoInboundLaneApi::latest_onfirmed_nonce` runtime method.
|
||||||
|
pub const FROM_RIALTO_LATEST_CONFIRMED_NONCE_METHOD: &str = "FromRialtoInboundLaneApi_latest_confirmed_nonce";
|
||||||
|
|
||||||
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
|
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
|
||||||
pub type Signature = MultiSignature;
|
pub type Signature = MultiSignature;
|
||||||
|
|
||||||
@@ -111,4 +123,35 @@ sp_api::decl_runtime_apis! {
|
|||||||
/// Returns true if the header is considered finalized by the runtime.
|
/// Returns true if the header is considered finalized by the runtime.
|
||||||
fn is_finalized_block(hash: Hash) -> bool;
|
fn is_finalized_block(hash: Hash) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Outbound message lane API for messages that are sent to Rialto chain.
|
||||||
|
///
|
||||||
|
/// This API is implemented by runtimes that are sending messages to Rialto chain, not the
|
||||||
|
/// Rialto runtime itself.
|
||||||
|
pub trait ToRialtoOutboundLaneApi {
|
||||||
|
/// Returns dispatch weight of all messages in given inclusive range.
|
||||||
|
///
|
||||||
|
/// If some (or all) messages are missing from the storage, they'll also will
|
||||||
|
/// be missing from the resulting vector. The vector is ordered by the nonce.
|
||||||
|
fn messages_dispatch_weight(
|
||||||
|
lane: LaneId,
|
||||||
|
begin: MessageNonce,
|
||||||
|
end: MessageNonce,
|
||||||
|
) -> Vec<(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.
|
||||||
|
fn latest_generated_nonce(lane: LaneId) -> MessageNonce;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inbound message lane API for messages sent by Rialto chain.
|
||||||
|
///
|
||||||
|
/// This API is implemented by runtimes that are receiving messages from Rialto chain, not the
|
||||||
|
/// Rialto runtime itself.
|
||||||
|
pub trait FromRialtoInboundLaneApi {
|
||||||
|
/// Returns nonce of the latest message, received by given lane.
|
||||||
|
fn latest_received_nonce(lane: LaneId) -> MessageNonce;
|
||||||
|
/// Nonce of latest message that has been confirmed to the bridged chain.
|
||||||
|
fn latest_confirmed_nonce(lane: LaneId) -> MessageNonce;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
//! best finalized header on the target chain, we submit this justification to the target
|
//! best finalized header on the target chain, we submit this justification to the target
|
||||||
//! node.
|
//! node.
|
||||||
|
|
||||||
use crate::headers_target::SubstrateHeadersSyncPipeline;
|
use crate::headers_pipeline::SubstrateHeadersSyncPipeline;
|
||||||
|
|
||||||
use async_std::sync::{Arc, Mutex};
|
use async_std::sync::{Arc, Mutex};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|||||||
@@ -16,21 +16,50 @@
|
|||||||
|
|
||||||
//! Substrate-to-Substrate headers sync entrypoint.
|
//! Substrate-to-Substrate headers sync entrypoint.
|
||||||
|
|
||||||
use crate::{
|
use crate::{headers_maintain::SubstrateHeadersToSubstrateMaintain, headers_target::SubstrateHeadersTarget};
|
||||||
headers_maintain::SubstrateHeadersToSubstrateMaintain,
|
|
||||||
headers_target::{SubstrateHeadersSyncPipeline, SubstrateHeadersTarget},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use headers_relay::{
|
use headers_relay::{
|
||||||
sync::{HeadersSyncParams, TargetTransactionMode},
|
sync::{HeadersSyncParams, TargetTransactionMode},
|
||||||
sync_types::{HeadersSyncPipeline, QueuedHeader, SourceHeader},
|
sync_types::{HeaderIdOf, HeadersSyncPipeline, QueuedHeader, SourceHeader},
|
||||||
|
};
|
||||||
|
use relay_substrate_client::{
|
||||||
|
headers_source::HeadersSource, BlockNumberOf, Chain, Client, Error as SubstrateError, HashOf,
|
||||||
};
|
};
|
||||||
use relay_substrate_client::{headers_source::HeadersSource, BlockNumberOf, Chain, Client, HashOf};
|
|
||||||
use relay_utils::BlockNumberBase;
|
use relay_utils::BlockNumberBase;
|
||||||
use sp_runtime::Justification;
|
use sp_runtime::Justification;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
/// Headers sync pipeline for Substrate <-> Substrate relays.
|
||||||
|
#[async_trait]
|
||||||
|
pub trait SubstrateHeadersSyncPipeline: HeadersSyncPipeline {
|
||||||
|
/// Name of the `best_block` runtime method.
|
||||||
|
const BEST_BLOCK_METHOD: &'static str;
|
||||||
|
/// Name of the `finalized_block` runtime method.
|
||||||
|
const FINALIZED_BLOCK_METHOD: &'static str;
|
||||||
|
/// Name of the `is_known_block` runtime method.
|
||||||
|
const IS_KNOWN_BLOCK_METHOD: &'static str;
|
||||||
|
/// Name of the `incomplete_headers` runtime method.
|
||||||
|
const INCOMPLETE_HEADERS_METHOD: &'static str;
|
||||||
|
|
||||||
|
/// Signed transaction type.
|
||||||
|
type SignedTransaction: Send + Sync + Encode;
|
||||||
|
|
||||||
|
/// Make submit header transaction.
|
||||||
|
async fn make_submit_header_transaction(
|
||||||
|
&self,
|
||||||
|
header: QueuedHeader<Self>,
|
||||||
|
) -> Result<Self::SignedTransaction, SubstrateError>;
|
||||||
|
|
||||||
|
/// Make completion transaction for the header.
|
||||||
|
async fn make_complete_header_transaction(
|
||||||
|
&self,
|
||||||
|
id: HeaderIdOf<Self>,
|
||||||
|
completion: Justification,
|
||||||
|
) -> Result<Self::SignedTransaction, SubstrateError>;
|
||||||
|
}
|
||||||
|
|
||||||
/// Substrate-to-Substrate headers pipeline.
|
/// Substrate-to-Substrate headers pipeline.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SubstrateHeadersToSubstrate<SourceChain, SourceSyncHeader, TargetChain: Chain, TargetSign> {
|
pub struct SubstrateHeadersToSubstrate<SourceChain, SourceSyncHeader, TargetChain: Chain, TargetSign> {
|
||||||
|
|||||||
@@ -18,12 +18,14 @@
|
|||||||
//! runtime that implements `<BridgedChainName>HeaderApi` to allow bridging with
|
//! runtime that implements `<BridgedChainName>HeaderApi` to allow bridging with
|
||||||
//! <BridgedName> chain.
|
//! <BridgedName> chain.
|
||||||
|
|
||||||
|
use crate::headers_pipeline::SubstrateHeadersSyncPipeline;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use futures::TryFutureExt;
|
use futures::TryFutureExt;
|
||||||
use headers_relay::{
|
use headers_relay::{
|
||||||
sync_loop::TargetClient,
|
sync_loop::TargetClient,
|
||||||
sync_types::{HeaderIdOf, HeadersSyncPipeline, QueuedHeader, SubmittedHeaders},
|
sync_types::{HeaderIdOf, QueuedHeader, SubmittedHeaders},
|
||||||
};
|
};
|
||||||
use relay_substrate_client::{Chain, Client, Error as SubstrateError};
|
use relay_substrate_client::{Chain, Client, Error as SubstrateError};
|
||||||
use relay_utils::HeaderId;
|
use relay_utils::HeaderId;
|
||||||
@@ -31,35 +33,6 @@ use sp_core::Bytes;
|
|||||||
use sp_runtime::Justification;
|
use sp_runtime::Justification;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
/// Headers sync pipeline for Substrate <-> Substrate relays.
|
|
||||||
#[async_trait]
|
|
||||||
pub trait SubstrateHeadersSyncPipeline: HeadersSyncPipeline {
|
|
||||||
/// Name of the `best_block` runtime method.
|
|
||||||
const BEST_BLOCK_METHOD: &'static str;
|
|
||||||
/// Name of the `finalized_block` runtime method.
|
|
||||||
const FINALIZED_BLOCK_METHOD: &'static str;
|
|
||||||
/// Name of the `is_known_block` runtime method.
|
|
||||||
const IS_KNOWN_BLOCK_METHOD: &'static str;
|
|
||||||
/// Name of the `incomplete_headers` runtime method.
|
|
||||||
const INCOMPLETE_HEADERS_METHOD: &'static str;
|
|
||||||
|
|
||||||
/// Signed transaction type.
|
|
||||||
type SignedTransaction: Send + Sync + Encode;
|
|
||||||
|
|
||||||
/// Make submit header transaction.
|
|
||||||
async fn make_submit_header_transaction(
|
|
||||||
&self,
|
|
||||||
header: QueuedHeader<Self>,
|
|
||||||
) -> Result<Self::SignedTransaction, SubstrateError>;
|
|
||||||
|
|
||||||
/// Make completion transaction for the header.
|
|
||||||
async fn make_complete_header_transaction(
|
|
||||||
&self,
|
|
||||||
id: HeaderIdOf<Self>,
|
|
||||||
completion: Justification,
|
|
||||||
) -> Result<Self::SignedTransaction, SubstrateError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Substrate client as Substrate headers target.
|
/// Substrate client as Substrate headers target.
|
||||||
pub struct SubstrateHeadersTarget<C: Chain, P> {
|
pub struct SubstrateHeadersTarget<C: Chain, P> {
|
||||||
client: Client<C>,
|
client: Client<C>,
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ mod headers_initialize;
|
|||||||
mod headers_maintain;
|
mod headers_maintain;
|
||||||
mod headers_pipeline;
|
mod headers_pipeline;
|
||||||
mod headers_target;
|
mod headers_target;
|
||||||
|
mod messages_lane;
|
||||||
mod messages_source;
|
mod messages_source;
|
||||||
mod messages_target;
|
mod messages_target;
|
||||||
mod millau_headers_to_rialto;
|
mod millau_headers_to_rialto;
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
// Copyright 2019-2020 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity Bridges Common.
|
||||||
|
|
||||||
|
// Parity Bridges Common is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity Bridges Common is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use bp_message_lane::MessageNonce;
|
||||||
|
use codec::Encode;
|
||||||
|
use messages_relay::message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf};
|
||||||
|
use relay_substrate_client::Error as SubstrateError;
|
||||||
|
use std::ops::RangeInclusive;
|
||||||
|
|
||||||
|
/// Message sync pipeline for Substrate <-> Substrate relays.
|
||||||
|
#[async_trait]
|
||||||
|
pub trait SubstrateMessageLane: MessageLane {
|
||||||
|
/// Name of the runtime method that returns dispatch weight of outbound messages at the source chain.
|
||||||
|
const OUTBOUND_LANE_MESSAGES_DISPATCH_WEIGHT_METHOD: &'static str;
|
||||||
|
/// Name of the runtime method that returns latest generated nonce at the source chain.
|
||||||
|
const OUTBOUND_LANE_LATEST_GENERATED_NONCE_METHOD: &'static str;
|
||||||
|
/// Name of the runtime method that returns latest received (confirmed) nonce at the the source chain.
|
||||||
|
const OUTBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str;
|
||||||
|
|
||||||
|
/// Name of the runtime method that returns latest received nonce at the source chain.
|
||||||
|
const INBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str;
|
||||||
|
/// Name of the runtime method that returns latest confirmed (reward-paid) nonce at the source chain.
|
||||||
|
const INBOUND_LANE_LATEST_CONFIRMED_NONCE_METHOD: &'static str;
|
||||||
|
|
||||||
|
/// Name of the runtime method that returns id of best finalized source header at target chain.
|
||||||
|
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str;
|
||||||
|
/// Name of the runtime method that returns id of best finalized target header at source chain.
|
||||||
|
const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str;
|
||||||
|
|
||||||
|
/// Signed transaction type of the source chain.
|
||||||
|
type SourceSignedTransaction: Send + Sync + Encode;
|
||||||
|
/// Signed transaction type of the target chain.
|
||||||
|
type TargetSignedTransaction: Send + Sync + Encode;
|
||||||
|
|
||||||
|
/// Make messages delivery transaction.
|
||||||
|
async fn make_messages_delivery_transaction(
|
||||||
|
&self,
|
||||||
|
generated_at_header: SourceHeaderIdOf<Self>,
|
||||||
|
nonces: RangeInclusive<MessageNonce>,
|
||||||
|
proof: Self::MessagesProof,
|
||||||
|
) -> Result<Self::TargetSignedTransaction, SubstrateError>;
|
||||||
|
|
||||||
|
/// Make messages receiving proof transaction.
|
||||||
|
async fn make_messages_receiving_proof_transaction(
|
||||||
|
&self,
|
||||||
|
generated_at_header: TargetHeaderIdOf<Self>,
|
||||||
|
proof: Self::MessagesReceivingProof,
|
||||||
|
) -> Result<Self::SourceSignedTransaction, SubstrateError>;
|
||||||
|
}
|
||||||
@@ -18,13 +18,15 @@
|
|||||||
//! runtime that implements `<BridgedChainName>HeaderApi` to allow bridging with
|
//! runtime that implements `<BridgedChainName>HeaderApi` to allow bridging with
|
||||||
//! <BridgedName> chain.
|
//! <BridgedName> chain.
|
||||||
|
|
||||||
|
use crate::messages_lane::SubstrateMessageLane;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bp_message_lane::{LaneId, MessageNonce};
|
use bp_message_lane::{LaneId, MessageNonce};
|
||||||
use bp_runtime::InstanceId;
|
use bp_runtime::InstanceId;
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use frame_support::weights::Weight;
|
use frame_support::weights::Weight;
|
||||||
use messages_relay::{
|
use messages_relay::{
|
||||||
message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf},
|
message_lane::{SourceHeaderIdOf, TargetHeaderIdOf},
|
||||||
message_lane_loop::{ClientState, MessageProofParameters, MessageWeightsMap, SourceClient, SourceClientState},
|
message_lane_loop::{ClientState, MessageProofParameters, MessageWeightsMap, SourceClient, SourceClientState},
|
||||||
};
|
};
|
||||||
use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf, HeaderIdOf};
|
use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf, HeaderIdOf};
|
||||||
@@ -32,7 +34,7 @@ use relay_utils::{BlockNumberBase, HeaderId};
|
|||||||
use sp_core::Bytes;
|
use sp_core::Bytes;
|
||||||
use sp_runtime::{traits::Header as HeaderT, DeserializeOwned};
|
use sp_runtime::{traits::Header as HeaderT, DeserializeOwned};
|
||||||
use sp_trie::StorageProof;
|
use sp_trie::StorageProof;
|
||||||
use std::{marker::PhantomData, ops::RangeInclusive};
|
use std::ops::RangeInclusive;
|
||||||
|
|
||||||
/// Intermediate message proof returned by the source Substrate node. Includes everything
|
/// Intermediate message proof returned by the source Substrate node. Includes everything
|
||||||
/// required to submit to the target node: cumulative dispatch weight of bundled messages and
|
/// required to submit to the target node: cumulative dispatch weight of bundled messages and
|
||||||
@@ -40,68 +42,50 @@ use std::{marker::PhantomData, ops::RangeInclusive};
|
|||||||
pub type SubstrateMessagesProof<C> = (Weight, (HashOf<C>, StorageProof, LaneId, MessageNonce, MessageNonce));
|
pub type SubstrateMessagesProof<C> = (Weight, (HashOf<C>, StorageProof, LaneId, MessageNonce, MessageNonce));
|
||||||
|
|
||||||
/// Substrate client as Substrate messages source.
|
/// Substrate client as Substrate messages source.
|
||||||
pub struct SubstrateMessagesSource<C: Chain, P, M> {
|
pub struct SubstrateMessagesSource<C: Chain, P> {
|
||||||
client: Client<C>,
|
client: Client<C>,
|
||||||
tx_maker: M,
|
lane: P,
|
||||||
lane: LaneId,
|
lane_id: LaneId,
|
||||||
instance: InstanceId,
|
instance: InstanceId,
|
||||||
_marker: PhantomData<P>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Substrate transactions maker.
|
impl<C: Chain, P> SubstrateMessagesSource<C, P> {
|
||||||
#[async_trait]
|
|
||||||
pub trait SubstrateTransactionMaker<C: Chain, P: MessageLane>: Clone + Send + Sync {
|
|
||||||
/// Signed transaction type.
|
|
||||||
type SignedTransaction: Send + Sync + Encode;
|
|
||||||
|
|
||||||
/// Make messages receiving proof transaction.
|
|
||||||
async fn make_messages_receiving_proof_transaction(
|
|
||||||
&self,
|
|
||||||
generated_at_block: TargetHeaderIdOf<P>,
|
|
||||||
proof: P::MessagesReceivingProof,
|
|
||||||
) -> Result<Self::SignedTransaction, SubstrateError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: Chain, P, M> SubstrateMessagesSource<C, P, M> {
|
|
||||||
/// Create new Substrate headers source.
|
/// Create new Substrate headers source.
|
||||||
pub fn new(client: Client<C>, tx_maker: M, lane: LaneId, instance: InstanceId) -> Self {
|
pub fn new(client: Client<C>, lane: P, lane_id: LaneId, instance: InstanceId) -> Self {
|
||||||
SubstrateMessagesSource {
|
SubstrateMessagesSource {
|
||||||
client,
|
client,
|
||||||
tx_maker,
|
|
||||||
lane,
|
lane,
|
||||||
|
lane_id,
|
||||||
instance,
|
instance,
|
||||||
_marker: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Chain, P, M: Clone> Clone for SubstrateMessagesSource<C, P, M> {
|
impl<C: Chain, P: SubstrateMessageLane> Clone for SubstrateMessagesSource<C, P> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
client: self.client.clone(),
|
client: self.client.clone(),
|
||||||
tx_maker: self.tx_maker.clone(),
|
lane: self.lane.clone(),
|
||||||
lane: self.lane,
|
lane_id: self.lane_id,
|
||||||
instance: self.instance,
|
instance: self.instance,
|
||||||
_marker: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<C, P, M> SourceClient<P> for SubstrateMessagesSource<C, P, M>
|
impl<C, P> SourceClient<P> for SubstrateMessagesSource<C, P>
|
||||||
where
|
where
|
||||||
C: Chain,
|
C: Chain,
|
||||||
C::Header: DeserializeOwned,
|
C::Header: DeserializeOwned,
|
||||||
C::Index: DeserializeOwned,
|
C::Index: DeserializeOwned,
|
||||||
C::BlockNumber: BlockNumberBase,
|
C::BlockNumber: BlockNumberBase,
|
||||||
P: MessageLane<
|
P: SubstrateMessageLane<
|
||||||
MessagesProof = SubstrateMessagesProof<C>,
|
MessagesProof = SubstrateMessagesProof<C>,
|
||||||
SourceHeaderNumber = <C::Header as HeaderT>::Number,
|
SourceHeaderNumber = <C::Header as HeaderT>::Number,
|
||||||
SourceHeaderHash = <C::Header as HeaderT>::Hash,
|
SourceHeaderHash = <C::Header as HeaderT>::Hash,
|
||||||
>,
|
>,
|
||||||
P::TargetHeaderNumber: Decode,
|
P::TargetHeaderNumber: Decode,
|
||||||
P::TargetHeaderHash: Decode,
|
P::TargetHeaderHash: Decode,
|
||||||
M: SubstrateTransactionMaker<C, P>,
|
|
||||||
{
|
{
|
||||||
type Error = SubstrateError;
|
type Error = SubstrateError;
|
||||||
|
|
||||||
@@ -112,7 +96,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn state(&self) -> Result<SourceClientState<P>, Self::Error> {
|
async fn state(&self) -> Result<SourceClientState<P>, Self::Error> {
|
||||||
read_client_state::<_, P::TargetHeaderHash, P::TargetHeaderNumber>(&self.client, P::TARGET_NAME).await
|
read_client_state::<_, P::TargetHeaderHash, P::TargetHeaderNumber>(
|
||||||
|
&self.client,
|
||||||
|
P::BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn latest_generated_nonce(
|
async fn latest_generated_nonce(
|
||||||
@@ -122,9 +110,8 @@ where
|
|||||||
let encoded_response = self
|
let encoded_response = self
|
||||||
.client
|
.client
|
||||||
.state_call(
|
.state_call(
|
||||||
// TODO: https://github.com/paritytech/parity-bridges-common/issues/457
|
P::OUTBOUND_LANE_LATEST_GENERATED_NONCE_METHOD.into(),
|
||||||
"OutboundLaneApi_latest_generated_nonce".into(),
|
Bytes(self.lane_id.encode()),
|
||||||
Bytes(self.lane.encode()),
|
|
||||||
Some(id.1),
|
Some(id.1),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -140,9 +127,8 @@ where
|
|||||||
let encoded_response = self
|
let encoded_response = self
|
||||||
.client
|
.client
|
||||||
.state_call(
|
.state_call(
|
||||||
// TODO: https://github.com/paritytech/parity-bridges-common/issues/457
|
P::OUTBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD.into(),
|
||||||
"OutboundLaneApi_latest_received_nonce".into(),
|
Bytes(self.lane_id.encode()),
|
||||||
Bytes(self.lane.encode()),
|
|
||||||
Some(id.1),
|
Some(id.1),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -159,9 +145,8 @@ where
|
|||||||
let encoded_response = self
|
let encoded_response = self
|
||||||
.client
|
.client
|
||||||
.state_call(
|
.state_call(
|
||||||
// TODO: https://github.com/paritytech/parity-bridges-common/issues/457
|
P::OUTBOUND_LANE_MESSAGES_DISPATCH_WEIGHT_METHOD.into(),
|
||||||
"OutboundLaneApi_messages_dispatch_weight".into(),
|
Bytes((self.lane_id, nonces.start(), nonces.end()).encode()),
|
||||||
Bytes((self.lane, nonces.start(), nonces.end()).encode()),
|
|
||||||
Some(id.1),
|
Some(id.1),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -194,13 +179,13 @@ where
|
|||||||
.client
|
.client
|
||||||
.prove_messages(
|
.prove_messages(
|
||||||
self.instance,
|
self.instance,
|
||||||
self.lane,
|
self.lane_id,
|
||||||
nonces.clone(),
|
nonces.clone(),
|
||||||
proof_parameters.outbound_state_proof_required,
|
proof_parameters.outbound_state_proof_required,
|
||||||
id.1,
|
id.1,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let proof = (id.1, proof, self.lane, *nonces.start(), *nonces.end());
|
let proof = (id.1, proof, self.lane_id, *nonces.start(), *nonces.end());
|
||||||
Ok((id, nonces, (proof_parameters.dispatch_weight, proof)))
|
Ok((id, nonces, (proof_parameters.dispatch_weight, proof)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,7 +195,7 @@ where
|
|||||||
proof: P::MessagesReceivingProof,
|
proof: P::MessagesReceivingProof,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
let tx = self
|
let tx = self
|
||||||
.tx_maker
|
.lane
|
||||||
.make_messages_receiving_proof_transaction(generated_at_block, proof)
|
.make_messages_receiving_proof_transaction(generated_at_block, proof)
|
||||||
.await?;
|
.await?;
|
||||||
self.client.submit_extrinsic(Bytes(tx.encode())).await?;
|
self.client.submit_extrinsic(Bytes(tx.encode())).await?;
|
||||||
@@ -220,7 +205,7 @@ where
|
|||||||
|
|
||||||
pub async fn read_client_state<SelfChain, BridgedHeaderHash, BridgedHeaderNumber>(
|
pub async fn read_client_state<SelfChain, BridgedHeaderHash, BridgedHeaderNumber>(
|
||||||
self_client: &Client<SelfChain>,
|
self_client: &Client<SelfChain>,
|
||||||
bridged_chain_name: &str,
|
best_finalized_header_id_method_name: &str,
|
||||||
) -> Result<ClientState<HeaderIdOf<SelfChain>, HeaderId<BridgedHeaderHash, BridgedHeaderNumber>>, SubstrateError>
|
) -> Result<ClientState<HeaderIdOf<SelfChain>, HeaderId<BridgedHeaderHash, BridgedHeaderNumber>>, SubstrateError>
|
||||||
where
|
where
|
||||||
SelfChain: Chain,
|
SelfChain: Chain,
|
||||||
@@ -240,10 +225,9 @@ where
|
|||||||
let self_best_id = HeaderId(*self_best_header.number(), self_best_hash);
|
let self_best_id = HeaderId(*self_best_header.number(), self_best_hash);
|
||||||
|
|
||||||
// now let's read id of best finalized peer header at our best finalized block
|
// now let's read id of best finalized peer header at our best finalized block
|
||||||
let best_finalized_peer_on_self_method = format!("{}HeaderApi_finalized_block", bridged_chain_name);
|
|
||||||
let encoded_best_finalized_peer_on_self = self_client
|
let encoded_best_finalized_peer_on_self = self_client
|
||||||
.state_call(
|
.state_call(
|
||||||
best_finalized_peer_on_self_method,
|
best_finalized_header_id_method_name.into(),
|
||||||
Bytes(Vec::new()),
|
Bytes(Vec::new()),
|
||||||
Some(self_best_hash),
|
Some(self_best_hash),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
//! runtime that implements `<BridgedChainName>HeaderApi` to allow bridging with
|
//! runtime that implements `<BridgedChainName>HeaderApi` to allow bridging with
|
||||||
//! <BridgedName> chain.
|
//! <BridgedName> chain.
|
||||||
|
|
||||||
|
use crate::messages_lane::SubstrateMessageLane;
|
||||||
use crate::messages_source::read_client_state;
|
use crate::messages_source::read_client_state;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
@@ -25,7 +26,7 @@ use bp_message_lane::{LaneId, MessageNonce};
|
|||||||
use bp_runtime::InstanceId;
|
use bp_runtime::InstanceId;
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use messages_relay::{
|
use messages_relay::{
|
||||||
message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf},
|
message_lane::{SourceHeaderIdOf, TargetHeaderIdOf},
|
||||||
message_lane_loop::{TargetClient, TargetClientState},
|
message_lane_loop::{TargetClient, TargetClientState},
|
||||||
};
|
};
|
||||||
use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf};
|
use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf};
|
||||||
@@ -33,72 +34,53 @@ use relay_utils::BlockNumberBase;
|
|||||||
use sp_core::Bytes;
|
use sp_core::Bytes;
|
||||||
use sp_runtime::{traits::Header as HeaderT, DeserializeOwned};
|
use sp_runtime::{traits::Header as HeaderT, DeserializeOwned};
|
||||||
use sp_trie::StorageProof;
|
use sp_trie::StorageProof;
|
||||||
use std::{marker::PhantomData, ops::RangeInclusive};
|
use std::ops::RangeInclusive;
|
||||||
|
|
||||||
/// Substrate client as Substrate messages target.
|
/// Substrate client as Substrate messages target.
|
||||||
pub struct SubstrateMessagesTarget<C: Chain, P, M> {
|
pub struct SubstrateMessagesTarget<C: Chain, P> {
|
||||||
client: Client<C>,
|
client: Client<C>,
|
||||||
tx_maker: M,
|
lane: P,
|
||||||
lane: LaneId,
|
lane_id: LaneId,
|
||||||
instance: InstanceId,
|
instance: InstanceId,
|
||||||
_marker: PhantomData<P>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Substrate transactions maker.
|
impl<C: Chain, P> SubstrateMessagesTarget<C, P> {
|
||||||
#[async_trait]
|
|
||||||
pub trait SubstrateTransactionMaker<C: Chain, P: MessageLane>: Clone + Send + Sync {
|
|
||||||
/// Signed transaction type.
|
|
||||||
type SignedTransaction: Send + Sync + Encode;
|
|
||||||
|
|
||||||
/// Make messages delivery transaction.
|
|
||||||
async fn make_messages_delivery_transaction(
|
|
||||||
&self,
|
|
||||||
generated_at_header: SourceHeaderIdOf<P>,
|
|
||||||
nonces: RangeInclusive<MessageNonce>,
|
|
||||||
proof: P::MessagesProof,
|
|
||||||
) -> Result<Self::SignedTransaction, SubstrateError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: Chain, P, M> SubstrateMessagesTarget<C, P, M> {
|
|
||||||
/// Create new Substrate headers target.
|
/// Create new Substrate headers target.
|
||||||
pub fn new(client: Client<C>, tx_maker: M, lane: LaneId, instance: InstanceId) -> Self {
|
pub fn new(client: Client<C>, lane: P, lane_id: LaneId, instance: InstanceId) -> Self {
|
||||||
SubstrateMessagesTarget {
|
SubstrateMessagesTarget {
|
||||||
client,
|
client,
|
||||||
tx_maker,
|
|
||||||
lane,
|
lane,
|
||||||
|
lane_id,
|
||||||
instance,
|
instance,
|
||||||
_marker: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Chain, P, M: Clone> Clone for SubstrateMessagesTarget<C, P, M> {
|
impl<C: Chain, P: SubstrateMessageLane> Clone for SubstrateMessagesTarget<C, P> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
client: self.client.clone(),
|
client: self.client.clone(),
|
||||||
tx_maker: self.tx_maker.clone(),
|
lane: self.lane.clone(),
|
||||||
lane: self.lane,
|
lane_id: self.lane_id,
|
||||||
instance: self.instance,
|
instance: self.instance,
|
||||||
_marker: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<C, P, M> TargetClient<P> for SubstrateMessagesTarget<C, P, M>
|
impl<C, P> TargetClient<P> for SubstrateMessagesTarget<C, P>
|
||||||
where
|
where
|
||||||
C: Chain,
|
C: Chain,
|
||||||
C::Header: DeserializeOwned,
|
C::Header: DeserializeOwned,
|
||||||
C::Index: DeserializeOwned,
|
C::Index: DeserializeOwned,
|
||||||
<C::Header as HeaderT>::Number: BlockNumberBase,
|
<C::Header as HeaderT>::Number: BlockNumberBase,
|
||||||
P: MessageLane<
|
P: SubstrateMessageLane<
|
||||||
MessagesReceivingProof = (HashOf<C>, StorageProof, LaneId),
|
MessagesReceivingProof = (HashOf<C>, StorageProof, LaneId),
|
||||||
TargetHeaderNumber = <C::Header as HeaderT>::Number,
|
TargetHeaderNumber = <C::Header as HeaderT>::Number,
|
||||||
TargetHeaderHash = <C::Header as HeaderT>::Hash,
|
TargetHeaderHash = <C::Header as HeaderT>::Hash,
|
||||||
>,
|
>,
|
||||||
P::SourceHeaderNumber: Decode,
|
P::SourceHeaderNumber: Decode,
|
||||||
P::SourceHeaderHash: Decode,
|
P::SourceHeaderHash: Decode,
|
||||||
M: SubstrateTransactionMaker<C, P>,
|
|
||||||
{
|
{
|
||||||
type Error = SubstrateError;
|
type Error = SubstrateError;
|
||||||
|
|
||||||
@@ -109,7 +91,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn state(&self) -> Result<TargetClientState<P>, Self::Error> {
|
async fn state(&self) -> Result<TargetClientState<P>, Self::Error> {
|
||||||
read_client_state::<_, P::SourceHeaderHash, P::SourceHeaderNumber>(&self.client, P::SOURCE_NAME).await
|
read_client_state::<_, P::SourceHeaderHash, P::SourceHeaderNumber>(
|
||||||
|
&self.client,
|
||||||
|
P::BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn latest_received_nonce(
|
async fn latest_received_nonce(
|
||||||
@@ -119,9 +105,8 @@ where
|
|||||||
let encoded_response = self
|
let encoded_response = self
|
||||||
.client
|
.client
|
||||||
.state_call(
|
.state_call(
|
||||||
// TODO: https://github.com/paritytech/parity-bridges-common/issues/457
|
P::INBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD.into(),
|
||||||
"InboundLaneApi_latest_received_nonce".into(),
|
Bytes(self.lane_id.encode()),
|
||||||
Bytes(self.lane.encode()),
|
|
||||||
Some(id.1),
|
Some(id.1),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -137,9 +122,8 @@ where
|
|||||||
let encoded_response = self
|
let encoded_response = self
|
||||||
.client
|
.client
|
||||||
.state_call(
|
.state_call(
|
||||||
// TODO: https://github.com/paritytech/parity-bridges-common/issues/457
|
P::INBOUND_LANE_LATEST_CONFIRMED_NONCE_METHOD.into(),
|
||||||
"OutboundLaneApi_latest_received_nonce".into(),
|
Bytes(self.lane_id.encode()),
|
||||||
Bytes(self.lane.encode()),
|
|
||||||
Some(id.1),
|
Some(id.1),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -154,9 +138,9 @@ where
|
|||||||
) -> Result<(TargetHeaderIdOf<P>, P::MessagesReceivingProof), Self::Error> {
|
) -> Result<(TargetHeaderIdOf<P>, P::MessagesReceivingProof), Self::Error> {
|
||||||
let proof = self
|
let proof = self
|
||||||
.client
|
.client
|
||||||
.prove_messages_delivery(self.instance, self.lane, id.1)
|
.prove_messages_delivery(self.instance, self.lane_id, id.1)
|
||||||
.await?;
|
.await?;
|
||||||
let proof = (id.1, proof, self.lane);
|
let proof = (id.1, proof, self.lane_id);
|
||||||
Ok((id, proof))
|
Ok((id, proof))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +151,7 @@ where
|
|||||||
proof: P::MessagesProof,
|
proof: P::MessagesProof,
|
||||||
) -> Result<RangeInclusive<MessageNonce>, Self::Error> {
|
) -> Result<RangeInclusive<MessageNonce>, Self::Error> {
|
||||||
let tx = self
|
let tx = self
|
||||||
.tx_maker
|
.lane
|
||||||
.make_messages_delivery_transaction(generated_at_header, nonces.clone(), proof)
|
.make_messages_delivery_transaction(generated_at_header, nonces.clone(), proof)
|
||||||
.await?;
|
.await?;
|
||||||
self.client.submit_extrinsic(Bytes(tx.encode())).await?;
|
self.client.submit_extrinsic(Bytes(tx.encode())).await?;
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
//! Millau-to-Rialto headers sync entrypoint.
|
//! Millau-to-Rialto headers sync entrypoint.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
headers_pipeline::SubstrateHeadersToSubstrate, headers_target::SubstrateHeadersSyncPipeline, MillauClient,
|
headers_pipeline::{SubstrateHeadersSyncPipeline, SubstrateHeadersToSubstrate},
|
||||||
RialtoClient,
|
MillauClient, RialtoClient,
|
||||||
};
|
};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|||||||
@@ -16,8 +16,9 @@
|
|||||||
|
|
||||||
//! Millau-to-Rialto messages sync entrypoint.
|
//! Millau-to-Rialto messages sync entrypoint.
|
||||||
|
|
||||||
use crate::messages_source::{SubstrateMessagesSource, SubstrateTransactionMaker as SubstrateSourceTransactionMaker};
|
use crate::messages_lane::SubstrateMessageLane;
|
||||||
use crate::messages_target::{SubstrateMessagesTarget, SubstrateTransactionMaker as SubstrateTargetTransactionMaker};
|
use crate::messages_source::SubstrateMessagesSource;
|
||||||
|
use crate::messages_target::SubstrateMessagesTarget;
|
||||||
use crate::{MillauClient, RialtoClient};
|
use crate::{MillauClient, RialtoClient};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
@@ -45,8 +46,14 @@ type FromMillauMessagesProof = (
|
|||||||
type FromRialtoMessagesReceivingProof = (HashOf<Rialto>, StorageProof, LaneId);
|
type FromRialtoMessagesReceivingProof = (HashOf<Rialto>, StorageProof, LaneId);
|
||||||
|
|
||||||
/// Millau-to-Rialto messages pipeline.
|
/// Millau-to-Rialto messages pipeline.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone)]
|
||||||
struct MillauMessagesToRialto;
|
struct MillauMessagesToRialto {
|
||||||
|
millau_client: MillauClient,
|
||||||
|
millau_sign: MillauSigningParams,
|
||||||
|
rialto_client: RialtoClient,
|
||||||
|
rialto_sign: RialtoSigningParams,
|
||||||
|
relayer_id: bp_millau::AccountId,
|
||||||
|
}
|
||||||
|
|
||||||
impl MessageLane for MillauMessagesToRialto {
|
impl MessageLane for MillauMessagesToRialto {
|
||||||
const SOURCE_NAME: &'static str = "Millau";
|
const SOURCE_NAME: &'static str = "Millau";
|
||||||
@@ -62,72 +69,66 @@ impl MessageLane for MillauMessagesToRialto {
|
|||||||
type TargetHeaderHash = HashOf<Rialto>;
|
type TargetHeaderHash = HashOf<Rialto>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Millau node as messages source.
|
|
||||||
type MillauSourceClient = SubstrateMessagesSource<Millau, MillauMessagesToRialto, MillauTransactionMaker>;
|
|
||||||
|
|
||||||
/// Millau transaction maker.
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct MillauTransactionMaker {
|
|
||||||
client: MillauClient,
|
|
||||||
sign: MillauSigningParams,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl SubstrateSourceTransactionMaker<Millau, MillauMessagesToRialto> for MillauTransactionMaker {
|
impl SubstrateMessageLane for MillauMessagesToRialto {
|
||||||
type SignedTransaction = <Millau as TransactionSignScheme>::SignedTransaction;
|
const OUTBOUND_LANE_MESSAGES_DISPATCH_WEIGHT_METHOD: &'static str =
|
||||||
|
bp_rialto::TO_RIALTO_MESSAGES_DISPATCH_WEIGHT_METHOD;
|
||||||
|
const OUTBOUND_LANE_LATEST_GENERATED_NONCE_METHOD: &'static str =
|
||||||
|
bp_rialto::TO_RIALTO_LATEST_GENERATED_NONCE_METHOD;
|
||||||
|
const OUTBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str = bp_rialto::TO_RIALTO_LATEST_RECEIVED_NONCE_METHOD;
|
||||||
|
|
||||||
|
const INBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str = bp_millau::FROM_MILLAU_LATEST_RECEIVED_NONCE_METHOD;
|
||||||
|
const INBOUND_LANE_LATEST_CONFIRMED_NONCE_METHOD: &'static str =
|
||||||
|
bp_millau::FROM_MILLAU_LATEST_CONFIRMED_NONCE_METHOD;
|
||||||
|
|
||||||
|
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_millau::FINALIZED_MILLAU_BLOCK_METHOD;
|
||||||
|
const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str = bp_rialto::FINALIZED_RIALTO_BLOCK_METHOD;
|
||||||
|
|
||||||
|
type SourceSignedTransaction = <Millau as TransactionSignScheme>::SignedTransaction;
|
||||||
|
type TargetSignedTransaction = <Rialto as TransactionSignScheme>::SignedTransaction;
|
||||||
|
|
||||||
async fn make_messages_receiving_proof_transaction(
|
async fn make_messages_receiving_proof_transaction(
|
||||||
&self,
|
&self,
|
||||||
_generated_at_block: RialtoHeaderId,
|
_generated_at_block: RialtoHeaderId,
|
||||||
proof: FromRialtoMessagesReceivingProof,
|
proof: FromRialtoMessagesReceivingProof,
|
||||||
) -> Result<Self::SignedTransaction, SubstrateError> {
|
) -> Result<Self::SourceSignedTransaction, SubstrateError> {
|
||||||
let account_id = self.sign.signer.public().as_array_ref().clone().into();
|
let account_id = self.millau_sign.signer.public().as_array_ref().clone().into();
|
||||||
let nonce = self.client.next_account_index(account_id).await?;
|
let nonce = self.millau_client.next_account_index(account_id).await?;
|
||||||
let call = millau_runtime::MessageLaneCall::receive_messages_delivery_proof(proof).into();
|
let call = millau_runtime::MessageLaneCall::receive_messages_delivery_proof(proof).into();
|
||||||
let transaction = Millau::sign_transaction(&self.client, &self.sign.signer, nonce, call);
|
let transaction = Millau::sign_transaction(&self.millau_client, &self.millau_sign.signer, nonce, call);
|
||||||
Ok(transaction)
|
Ok(transaction)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Rialto node as messages target.
|
|
||||||
type RialtoTargetClient = SubstrateMessagesTarget<Rialto, MillauMessagesToRialto, RialtoTransactionMaker>;
|
|
||||||
|
|
||||||
/// Rialto transaction maker.
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct RialtoTransactionMaker {
|
|
||||||
client: RialtoClient,
|
|
||||||
relayer_id: bp_millau::AccountId,
|
|
||||||
sign: RialtoSigningParams,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl SubstrateTargetTransactionMaker<Rialto, MillauMessagesToRialto> for RialtoTransactionMaker {
|
|
||||||
type SignedTransaction = <Rialto as TransactionSignScheme>::SignedTransaction;
|
|
||||||
|
|
||||||
async fn make_messages_delivery_transaction(
|
async fn make_messages_delivery_transaction(
|
||||||
&self,
|
&self,
|
||||||
_generated_at_header: MillauHeaderId,
|
_generated_at_header: MillauHeaderId,
|
||||||
_nonces: RangeInclusive<MessageNonce>,
|
_nonces: RangeInclusive<MessageNonce>,
|
||||||
proof: FromMillauMessagesProof,
|
proof: FromMillauMessagesProof,
|
||||||
) -> Result<Self::SignedTransaction, SubstrateError> {
|
) -> Result<Self::TargetSignedTransaction, SubstrateError> {
|
||||||
let (dispatch_weight, proof) = proof;
|
let (dispatch_weight, proof) = proof;
|
||||||
let account_id = self.sign.signer.public().as_array_ref().clone().into();
|
let account_id = self.rialto_sign.signer.public().as_array_ref().clone().into();
|
||||||
let nonce = self.client.next_account_index(account_id).await?;
|
let nonce = self.rialto_client.next_account_index(account_id).await?;
|
||||||
let call =
|
let call =
|
||||||
rialto_runtime::MessageLaneCall::receive_messages_proof(self.relayer_id.clone(), proof, dispatch_weight)
|
rialto_runtime::MessageLaneCall::receive_messages_proof(self.relayer_id.clone(), proof, dispatch_weight)
|
||||||
.into();
|
.into();
|
||||||
let transaction = Rialto::sign_transaction(&self.client, &self.sign.signer, nonce, call);
|
let transaction = Rialto::sign_transaction(&self.rialto_client, &self.rialto_sign.signer, nonce, call);
|
||||||
Ok(transaction)
|
Ok(transaction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Millau node as messages source.
|
||||||
|
type MillauSourceClient = SubstrateMessagesSource<Millau, MillauMessagesToRialto>;
|
||||||
|
|
||||||
|
/// Rialto node as messages target.
|
||||||
|
type RialtoTargetClient = SubstrateMessagesTarget<Rialto, MillauMessagesToRialto>;
|
||||||
|
|
||||||
/// Run Millau-to-Rialto messages sync.
|
/// Run Millau-to-Rialto messages sync.
|
||||||
pub fn run(
|
pub fn run(
|
||||||
millau_client: MillauClient,
|
millau_client: MillauClient,
|
||||||
millau_sign: MillauSigningParams,
|
millau_sign: MillauSigningParams,
|
||||||
rialto_client: RialtoClient,
|
rialto_client: RialtoClient,
|
||||||
rialto_sign: RialtoSigningParams,
|
rialto_sign: RialtoSigningParams,
|
||||||
lane: LaneId,
|
lane_id: LaneId,
|
||||||
metrics_params: Option<MetricsParams>,
|
metrics_params: Option<MetricsParams>,
|
||||||
) {
|
) {
|
||||||
let millau_tick = Duration::from_secs(5);
|
let millau_tick = Duration::from_secs(5);
|
||||||
@@ -136,9 +137,17 @@ pub fn run(
|
|||||||
let stall_timeout = Duration::from_secs(5 * 60);
|
let stall_timeout = Duration::from_secs(5 * 60);
|
||||||
let relayer_id = millau_sign.signer.public().as_array_ref().clone().into();
|
let relayer_id = millau_sign.signer.public().as_array_ref().clone().into();
|
||||||
|
|
||||||
|
let lane = MillauMessagesToRialto {
|
||||||
|
millau_client: millau_client.clone(),
|
||||||
|
millau_sign,
|
||||||
|
rialto_client: rialto_client.clone(),
|
||||||
|
rialto_sign,
|
||||||
|
relayer_id,
|
||||||
|
};
|
||||||
|
|
||||||
messages_relay::message_lane_loop::run(
|
messages_relay::message_lane_loop::run(
|
||||||
messages_relay::message_lane_loop::Params {
|
messages_relay::message_lane_loop::Params {
|
||||||
lane,
|
lane: lane_id,
|
||||||
source_tick: millau_tick,
|
source_tick: millau_tick,
|
||||||
target_tick: rialto_tick,
|
target_tick: rialto_tick,
|
||||||
reconnect_delay,
|
reconnect_delay,
|
||||||
@@ -150,25 +159,8 @@ pub fn run(
|
|||||||
max_messages_weight_in_single_batch: bp_rialto::MAXIMUM_EXTRINSIC_WEIGHT,
|
max_messages_weight_in_single_batch: bp_rialto::MAXIMUM_EXTRINSIC_WEIGHT,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
MillauSourceClient::new(
|
MillauSourceClient::new(millau_client, lane.clone(), lane_id, RIALTO_BRIDGE_INSTANCE),
|
||||||
millau_client.clone(),
|
RialtoTargetClient::new(rialto_client, lane, lane_id, MILLAU_BRIDGE_INSTANCE),
|
||||||
MillauTransactionMaker {
|
|
||||||
client: millau_client,
|
|
||||||
sign: millau_sign,
|
|
||||||
},
|
|
||||||
lane,
|
|
||||||
RIALTO_BRIDGE_INSTANCE,
|
|
||||||
),
|
|
||||||
RialtoTargetClient::new(
|
|
||||||
rialto_client.clone(),
|
|
||||||
RialtoTransactionMaker {
|
|
||||||
client: rialto_client,
|
|
||||||
relayer_id,
|
|
||||||
sign: rialto_sign,
|
|
||||||
},
|
|
||||||
lane,
|
|
||||||
MILLAU_BRIDGE_INSTANCE,
|
|
||||||
),
|
|
||||||
metrics_params,
|
metrics_params,
|
||||||
futures::future::pending(),
|
futures::future::pending(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
//! Rialto-to-Millau headers sync entrypoint.
|
//! Rialto-to-Millau headers sync entrypoint.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
headers_pipeline::SubstrateHeadersToSubstrate, headers_target::SubstrateHeadersSyncPipeline, MillauClient,
|
headers_pipeline::{SubstrateHeadersSyncPipeline, SubstrateHeadersToSubstrate},
|
||||||
RialtoClient,
|
MillauClient, RialtoClient,
|
||||||
};
|
};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|||||||
Reference in New Issue
Block a user