mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 04:01:02 +00:00
Rialto -> Millau headers relay (#477)
* Rialto -> Millau headers relay * removed more constraints * removed file from other PR * Update primitives/rialto/src/lib.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
b027c81266
commit
3e45356aad
@@ -57,7 +57,7 @@ pub use frame_support::{
|
|||||||
|
|
||||||
pub use pallet_balances::Call as BalancesCall;
|
pub use pallet_balances::Call as BalancesCall;
|
||||||
pub use pallet_message_lane::Call as MessageLaneCall;
|
pub use pallet_message_lane::Call as MessageLaneCall;
|
||||||
pub use pallet_substrate_bridge::Call as BridgeSubstrateCall;
|
pub use pallet_substrate_bridge::Call as BridgeRialtoCall;
|
||||||
pub use pallet_timestamp::Call as TimestampCall;
|
pub use pallet_timestamp::Call as TimestampCall;
|
||||||
|
|
||||||
#[cfg(any(feature = "std", test))]
|
#[cfg(any(feature = "std", test))]
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ use sp_runtime::{
|
|||||||
};
|
};
|
||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
|
|
||||||
/// Maximal weight of single Millau block.
|
/// Maximal weight of single Rialto block.
|
||||||
pub const MAXIMUM_BLOCK_WEIGHT: Weight = 2_000_000_000_000;
|
pub const MAXIMUM_BLOCK_WEIGHT: Weight = 2_000_000_000_000;
|
||||||
/// Portion of block reserved for regular transactions.
|
/// Portion of block reserved for regular transactions.
|
||||||
pub const AVAILABLE_BLOCK_RATIO: u32 = 75;
|
pub const AVAILABLE_BLOCK_RATIO: u32 = 75;
|
||||||
/// Maximal weight of single Millau extrinsic (65% of maximum block weight = 75% for regular
|
/// Maximal weight of single Rialto extrinsic (65% of maximum block weight = 75% for regular
|
||||||
/// transactions minus 10% for initialization).
|
/// transactions minus 10% for initialization).
|
||||||
pub const MAXIMUM_EXTRINSIC_WEIGHT: Weight = MAXIMUM_BLOCK_WEIGHT / 100 * (AVAILABLE_BLOCK_RATIO as Weight - 10);
|
pub const MAXIMUM_EXTRINSIC_WEIGHT: Weight = MAXIMUM_BLOCK_WEIGHT / 100 * (AVAILABLE_BLOCK_RATIO as Weight - 10);
|
||||||
|
|
||||||
@@ -60,6 +60,15 @@ impl Chain for Rialto {
|
|||||||
type Header = Header;
|
type Header = Header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Name of the `RialtoHeaderApi::best_blocks` runtime method.
|
||||||
|
pub const BEST_RIALTO_BLOCKS_METHOD: &str = "RialtoHeaderApi_best_blocks";
|
||||||
|
/// Name of the `RialtoHeaderApi::finalized_block` runtime method.
|
||||||
|
pub const FINALIZED_RIALTO_BLOCK_METHOD: &str = "RialtoHeaderApi_finalized_block";
|
||||||
|
/// Name of the `RialtoHeaderApi::is_known_block` runtime method.
|
||||||
|
pub const IS_KNOWN_RIALTO_BLOCK_METHOD: &str = "RialtoHeaderApi_is_known_block";
|
||||||
|
/// Name of the `RialtoHeaderApi::incomplete_headers` runtime method.
|
||||||
|
pub const INCOMPLETE_RIALTO_HEADERS_METHOD: &str = "RialtoHeaderApi_incomplete_headers";
|
||||||
|
|
||||||
/// 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;
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ pub trait Chain: Send + Sync + 'static {
|
|||||||
/// A type that fulfills the abstract idea of what a Substrate header is.
|
/// A type that fulfills the abstract idea of what a Substrate header is.
|
||||||
// See here for more info:
|
// See here for more info:
|
||||||
// https://crates.parity.io/sp_runtime/traits/trait.Header.html
|
// https://crates.parity.io/sp_runtime/traits/trait.Header.html
|
||||||
type Header: Parameter + HeaderT<Number = Self::BlockNumber, Hash = Self::Hash>;
|
type Header: Parameter + HeaderT<Number = Self::BlockNumber, Hash = Self::Hash> + MaybeSerializeDeserialize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Block number used by the chain.
|
/// Block number used by the chain.
|
||||||
|
|||||||
@@ -36,15 +36,15 @@ use relay_ethereum_client::{
|
|||||||
Client as EthereumClient, ConnectionParams as EthereumConnectionParams,
|
Client as EthereumClient, ConnectionParams as EthereumConnectionParams,
|
||||||
};
|
};
|
||||||
use relay_rialto_client::{Rialto, SigningParams as RialtoSigningParams};
|
use relay_rialto_client::{Rialto, SigningParams as RialtoSigningParams};
|
||||||
use relay_substrate_client::{Client as SubstrateClient, ConnectionParams as SubstrateConnectionParams};
|
use relay_substrate_client::{
|
||||||
|
Chain as SubstrateChain, Client as SubstrateClient, ConnectionParams as SubstrateConnectionParams,
|
||||||
|
};
|
||||||
use relay_utils::{metrics::MetricsParams, HeaderId};
|
use relay_utils::{metrics::MetricsParams, HeaderId};
|
||||||
use rialto_runtime::exchange::EthereumTransactionInclusionProof;
|
use rialto_runtime::exchange::EthereumTransactionInclusionProof;
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
|
|
||||||
/// Interval at which we ask Ethereum node for updates.
|
/// Interval at which we ask Ethereum node for updates.
|
||||||
const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_secs(10);
|
const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_secs(10);
|
||||||
/// Interval at which we ask Substrate node for updates.
|
|
||||||
const SUBSTRATE_TICK_INTERVAL: Duration = Duration::from_secs(5);
|
|
||||||
|
|
||||||
/// Exchange relay mode.
|
/// Exchange relay mode.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -210,7 +210,7 @@ impl TargetClient<EthereumToSubstrateExchange> for SubstrateTransactionsTarget {
|
|||||||
type Error = RpcError;
|
type Error = RpcError;
|
||||||
|
|
||||||
async fn tick(&self) {
|
async fn tick(&self) {
|
||||||
async_std::task::sleep(SUBSTRATE_TICK_INTERVAL).await;
|
async_std::task::sleep(Rialto::AVERAGE_BLOCK_INTERVAL).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn is_header_known(&self, id: &EthereumHeaderId) -> Result<bool, Self::Error> {
|
async fn is_header_known(&self, id: &EthereumHeaderId) -> Result<bool, Self::Error> {
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ use relay_ethereum_client::{
|
|||||||
Client as EthereumClient, ConnectionParams as EthereumConnectionParams,
|
Client as EthereumClient, ConnectionParams as EthereumConnectionParams,
|
||||||
};
|
};
|
||||||
use relay_rialto_client::{Rialto, SigningParams as RialtoSigningParams};
|
use relay_rialto_client::{Rialto, SigningParams as RialtoSigningParams};
|
||||||
use relay_substrate_client::{Client as SubstrateClient, ConnectionParams as SubstrateConnectionParams};
|
use relay_substrate_client::{
|
||||||
|
Chain as SubstrateChain, Client as SubstrateClient, ConnectionParams as SubstrateConnectionParams,
|
||||||
|
};
|
||||||
use relay_utils::metrics::MetricsParams;
|
use relay_utils::metrics::MetricsParams;
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
@@ -45,8 +47,6 @@ pub mod consts {
|
|||||||
|
|
||||||
/// Interval at which we check new Ethereum headers when we are synced/almost synced.
|
/// Interval at which we check new Ethereum headers when we are synced/almost synced.
|
||||||
pub const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_secs(10);
|
pub const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_secs(10);
|
||||||
/// Interval at which we check new Substrate blocks.
|
|
||||||
pub const SUBSTRATE_TICK_INTERVAL: Duration = Duration::from_secs(5);
|
|
||||||
/// Max number of headers in single submit transaction.
|
/// Max number of headers in single submit transaction.
|
||||||
pub const MAX_HEADERS_IN_SINGLE_SUBMIT: usize = 32;
|
pub const MAX_HEADERS_IN_SINGLE_SUBMIT: usize = 32;
|
||||||
/// Max total size of headers in single submit transaction. This only affects signed
|
/// Max total size of headers in single submit transaction. This only affects signed
|
||||||
@@ -253,7 +253,7 @@ pub fn run(params: EthereumSyncParams) -> Result<(), RpcError> {
|
|||||||
source,
|
source,
|
||||||
consts::ETHEREUM_TICK_INTERVAL,
|
consts::ETHEREUM_TICK_INTERVAL,
|
||||||
target,
|
target,
|
||||||
consts::SUBSTRATE_TICK_INTERVAL,
|
Rialto::AVERAGE_BLOCK_INTERVAL,
|
||||||
(),
|
(),
|
||||||
sync_params,
|
sync_params,
|
||||||
metrics_params,
|
metrics_params,
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ use relay_ethereum_client::{
|
|||||||
};
|
};
|
||||||
use relay_rialto_client::{HeaderId as RialtoHeaderId, Rialto, SyncHeader as RialtoSyncHeader};
|
use relay_rialto_client::{HeaderId as RialtoHeaderId, Rialto, SyncHeader as RialtoSyncHeader};
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
headers_source::HeadersSource, Client as SubstrateClient, ConnectionParams as SubstrateConnectionParams,
|
headers_source::HeadersSource, Chain as SubstrateChain, Client as SubstrateClient,
|
||||||
|
ConnectionParams as SubstrateConnectionParams,
|
||||||
};
|
};
|
||||||
use relay_utils::metrics::MetricsParams;
|
use relay_utils::metrics::MetricsParams;
|
||||||
use sp_runtime::Justification;
|
use sp_runtime::Justification;
|
||||||
@@ -43,8 +44,6 @@ use std::{collections::HashSet, time::Duration};
|
|||||||
pub mod consts {
|
pub mod consts {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// Interval at which we check new Substrate headers when we are synced/almost synced.
|
|
||||||
pub const SUBSTRATE_TICK_INTERVAL: Duration = Duration::from_secs(10);
|
|
||||||
/// Interval at which we check new Ethereum blocks.
|
/// Interval at which we check new Ethereum blocks.
|
||||||
pub const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_secs(5);
|
pub const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_secs(5);
|
||||||
/// Max Ethereum headers we want to have in all 'before-submitted' states.
|
/// Max Ethereum headers we want to have in all 'before-submitted' states.
|
||||||
@@ -174,7 +173,7 @@ pub fn run(params: SubstrateSyncParams) -> Result<(), RpcError> {
|
|||||||
|
|
||||||
headers_relay::sync_loop::run(
|
headers_relay::sync_loop::run(
|
||||||
source,
|
source,
|
||||||
consts::SUBSTRATE_TICK_INTERVAL,
|
Rialto::AVERAGE_BLOCK_INTERVAL,
|
||||||
target,
|
target,
|
||||||
consts::ETHEREUM_TICK_INTERVAL,
|
consts::ETHEREUM_TICK_INTERVAL,
|
||||||
(),
|
(),
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ pub trait HeadersSyncPipeline: Clone + Send + Sync {
|
|||||||
+ num_traits::One
|
+ num_traits::One
|
||||||
+ Into<u64>;
|
+ Into<u64>;
|
||||||
/// Type of header that we're syncing.
|
/// Type of header that we're syncing.
|
||||||
type Header: Clone + std::fmt::Debug + PartialEq + SourceHeader<Self::Hash, Self::Number> + Send + Sync;
|
type Header: SourceHeader<Self::Hash, Self::Number>;
|
||||||
/// Type of extra data for the header that we're receiving from the source node:
|
/// Type of extra data for the header that we're receiving from the source node:
|
||||||
/// 1) extra data is required for some headers;
|
/// 1) extra data is required for some headers;
|
||||||
/// 2) target node may answer if it'll require extra data before header is submitted;
|
/// 2) target node may answer if it'll require extra data before header is submitted;
|
||||||
@@ -94,7 +94,7 @@ pub trait HeadersSyncPipeline: Clone + Send + Sync {
|
|||||||
pub type HeaderIdOf<P> = HeaderId<<P as HeadersSyncPipeline>::Hash, <P as HeadersSyncPipeline>::Number>;
|
pub type HeaderIdOf<P> = HeaderId<<P as HeadersSyncPipeline>::Hash, <P as HeadersSyncPipeline>::Number>;
|
||||||
|
|
||||||
/// Header that we're receiving from source node.
|
/// Header that we're receiving from source node.
|
||||||
pub trait SourceHeader<Hash, Number> {
|
pub trait SourceHeader<Hash, Number>: Clone + std::fmt::Debug + PartialEq + Send + Sync {
|
||||||
/// Returns ID of header.
|
/// Returns ID of header.
|
||||||
fn id(&self) -> HeaderId<Hash, Number>;
|
fn id(&self) -> HeaderId<Hash, Number>;
|
||||||
/// Returns ID of parent header.
|
/// Returns ID of parent header.
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ use sp_runtime::{
|
|||||||
};
|
};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
pub use millau_runtime::BridgeRialtoCall;
|
||||||
|
|
||||||
/// Millau header id.
|
/// Millau header id.
|
||||||
pub type HeaderId = relay_utils::HeaderId<millau_runtime::Hash, millau_runtime::BlockNumber>;
|
pub type HeaderId = relay_utils::HeaderId<millau_runtime::Hash, millau_runtime::BlockNumber>;
|
||||||
|
|
||||||
|
|||||||
@@ -151,6 +151,12 @@ impl From<rialto_runtime::Header> for SyncHeader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<SyncHeader> for rialto_runtime::Header {
|
||||||
|
fn from(header: SyncHeader) -> Self {
|
||||||
|
header.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SourceHeader<rialto_runtime::Hash, rialto_runtime::BlockNumber> for SyncHeader {
|
impl SourceHeader<rialto_runtime::Hash, rialto_runtime::BlockNumber> for SyncHeader {
|
||||||
fn id(&self) -> HeaderId {
|
fn id(&self) -> HeaderId {
|
||||||
relay_utils::HeaderId(*self.number(), self.hash())
|
relay_utils::HeaderId(*self.number(), self.hash())
|
||||||
|
|||||||
@@ -34,14 +34,23 @@ pub trait Chain: ChainBase {
|
|||||||
const NAME: &'static str;
|
const NAME: &'static str;
|
||||||
/// Average block interval.
|
/// Average block interval.
|
||||||
///
|
///
|
||||||
/// How often blocks are produced on that chain. It's suggested to set this value to match the block time of the chain.
|
/// How often blocks are produced on that chain. It's suggested to set this value
|
||||||
|
/// to match the block time of the chain.
|
||||||
const AVERAGE_BLOCK_INTERVAL: Duration;
|
const AVERAGE_BLOCK_INTERVAL: Duration;
|
||||||
|
|
||||||
/// The user account identifier type for the runtime.
|
/// The user account identifier type for the runtime.
|
||||||
type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + Default;
|
type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + Default;
|
||||||
/// Account index (aka nonce) type. This stores the number of previous transactions associated
|
/// Account index (aka nonce) type. This stores the number of previous transactions associated
|
||||||
/// with a sender account.
|
/// with a sender account.
|
||||||
type Index: Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + AtLeast32Bit + Copy;
|
type Index: Parameter
|
||||||
|
+ Member
|
||||||
|
+ MaybeSerialize
|
||||||
|
+ Debug
|
||||||
|
+ Default
|
||||||
|
+ MaybeDisplay
|
||||||
|
+ DeserializeOwned
|
||||||
|
+ AtLeast32Bit
|
||||||
|
+ Copy;
|
||||||
/// Block type.
|
/// Block type.
|
||||||
type SignedBlock: Member + Serialize + DeserializeOwned + BlockWithJustification;
|
type SignedBlock: Member + Serialize + DeserializeOwned + BlockWithJustification;
|
||||||
/// The aggregated `Call` type.
|
/// The aggregated `Call` type.
|
||||||
|
|||||||
@@ -138,10 +138,7 @@ impl<C: Chain> Client<C> {
|
|||||||
/// Get the nonce of the given Substrate account.
|
/// Get the nonce of the given Substrate account.
|
||||||
///
|
///
|
||||||
/// Note: It's the caller's responsibility to make sure `account` is a valid ss58 address.
|
/// Note: It's the caller's responsibility to make sure `account` is a valid ss58 address.
|
||||||
pub async fn next_account_index(&self, account: C::AccountId) -> Result<C::Index>
|
pub async fn next_account_index(&self, account: C::AccountId) -> Result<C::Index> {
|
||||||
where
|
|
||||||
C::Index: DeserializeOwned,
|
|
||||||
{
|
|
||||||
Ok(Substrate::<C, _, _>::system_account_next_index(&self.client, account).await?)
|
Ok(Substrate::<C, _, _>::system_account_next_index(&self.client, account).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ use headers_relay::{
|
|||||||
sync_loop::SourceClient,
|
sync_loop::SourceClient,
|
||||||
sync_types::{HeaderIdOf, HeadersSyncPipeline, QueuedHeader, SourceHeader},
|
sync_types::{HeaderIdOf, HeadersSyncPipeline, QueuedHeader, SourceHeader},
|
||||||
};
|
};
|
||||||
use jsonrpsee::common::DeserializeOwned;
|
|
||||||
use num_traits::Saturating;
|
use num_traits::Saturating;
|
||||||
use sp_runtime::{traits::Header as HeaderT, Justification};
|
use sp_runtime::{traits::Header as HeaderT, Justification};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
@@ -51,8 +50,7 @@ impl<C, P> SourceClient<P> for HeadersSource<C, P>
|
|||||||
where
|
where
|
||||||
C: Chain,
|
C: Chain,
|
||||||
C::BlockNumber: Into<u64> + Saturating,
|
C::BlockNumber: Into<u64> + Saturating,
|
||||||
C::Header: DeserializeOwned + Into<P::Header>,
|
C::Header: Into<P::Header>,
|
||||||
C::Index: DeserializeOwned,
|
|
||||||
P: HeadersSyncPipeline<Extra = (), Completion = Justification, Hash = C::Hash, Number = C::BlockNumber>,
|
P: HeadersSyncPipeline<Extra = (), Completion = Justification, Hash = C::Hash, Number = C::BlockNumber>,
|
||||||
P::Header: SourceHeader<C::Hash, C::BlockNumber>,
|
P::Header: SourceHeader<C::Hash, C::BlockNumber>,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ codec = { package = "parity-scale-codec", version = "1.3.4" }
|
|||||||
futures = "0.3.7"
|
futures = "0.3.7"
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
log = "0.4.11"
|
log = "0.4.11"
|
||||||
|
num-traits = "0.2"
|
||||||
paste = "1.0"
|
paste = "1.0"
|
||||||
structopt = "0.3"
|
structopt = "0.3"
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,17 @@ pub enum Command {
|
|||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
prometheus_params: PrometheusParams,
|
prometheus_params: PrometheusParams,
|
||||||
},
|
},
|
||||||
|
/// Relay Rialto headers to Millau.
|
||||||
|
RialtoHeadersToMillau {
|
||||||
|
#[structopt(flatten)]
|
||||||
|
rialto: RialtoConnectionParams,
|
||||||
|
#[structopt(flatten)]
|
||||||
|
millau: MillauConnectionParams,
|
||||||
|
#[structopt(flatten)]
|
||||||
|
millau_sign: MillauSigningParams,
|
||||||
|
#[structopt(flatten)]
|
||||||
|
prometheus_params: PrometheusParams,
|
||||||
|
},
|
||||||
/// Submit message to given Rialto -> Millau lane.
|
/// Submit message to given Rialto -> Millau lane.
|
||||||
SubmitMillauToRialtoMessage {
|
SubmitMillauToRialtoMessage {
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ use headers_relay::{
|
|||||||
use relay_substrate_client::{Chain, Client, Error as SubstrateError, JustificationsSubscription};
|
use relay_substrate_client::{Chain, Client, Error as SubstrateError, JustificationsSubscription};
|
||||||
use relay_utils::HeaderId;
|
use relay_utils::HeaderId;
|
||||||
use sp_core::Bytes;
|
use sp_core::Bytes;
|
||||||
use sp_runtime::{traits::Header as HeaderT, DeserializeOwned, Justification};
|
use sp_runtime::{traits::Header as HeaderT, Justification};
|
||||||
use std::{collections::VecDeque, task::Poll};
|
use std::{collections::VecDeque, task::Poll};
|
||||||
|
|
||||||
/// Substrate-to-Substrate headers synchronization maintain procedure.
|
/// Substrate-to-Substrate headers synchronization maintain procedure.
|
||||||
@@ -80,8 +80,6 @@ impl<P: SubstrateHeadersSyncPipeline, C: Chain> SubstrateHeadersToSubstrateMaint
|
|||||||
impl<P, C> SyncMaintain<P> for SubstrateHeadersToSubstrateMaintain<P, C>
|
impl<P, C> SyncMaintain<P> for SubstrateHeadersToSubstrateMaintain<P, C>
|
||||||
where
|
where
|
||||||
C: Chain,
|
C: Chain,
|
||||||
C::Header: DeserializeOwned,
|
|
||||||
C::Index: DeserializeOwned,
|
|
||||||
P::Number: Decode + From<C::BlockNumber>,
|
P::Number: Decode + From<C::BlockNumber>,
|
||||||
P::Hash: Decode + From<C::Hash>,
|
P::Hash: Decode + From<C::Hash>,
|
||||||
P: SubstrateHeadersSyncPipeline<Completion = Justification, Extra = ()>,
|
P: SubstrateHeadersSyncPipeline<Completion = Justification, Extra = ()>,
|
||||||
@@ -271,8 +269,6 @@ where
|
|||||||
P::Number: Decode + From<C::BlockNumber>,
|
P::Number: Decode + From<C::BlockNumber>,
|
||||||
P::Hash: Decode + From<C::Hash>,
|
P::Hash: Decode + From<C::Hash>,
|
||||||
C: Chain,
|
C: Chain,
|
||||||
C::Header: DeserializeOwned,
|
|
||||||
C::Index: DeserializeOwned,
|
|
||||||
{
|
{
|
||||||
let call = P::FINALIZED_BLOCK_METHOD.into();
|
let call = P::FINALIZED_BLOCK_METHOD.into();
|
||||||
let data = Bytes(Vec::new());
|
let data = Bytes(Vec::new());
|
||||||
@@ -288,7 +284,8 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::millau_headers_to_rialto::{sync_params, MillauHeadersToRialto};
|
use crate::headers_pipeline::sync_params;
|
||||||
|
use crate::millau_headers_to_rialto::MillauHeadersToRialto;
|
||||||
|
|
||||||
fn parent_hash(index: u8) -> bp_millau::Hash {
|
fn parent_hash(index: u8) -> bp_millau::Hash {
|
||||||
if index == 1 {
|
if index == 1 {
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
|
//! Substrate-to-Substrate headers sync entrypoint.
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
headers_maintain::SubstrateHeadersToSubstrateMaintain,
|
||||||
|
headers_target::{SubstrateHeadersSyncPipeline, SubstrateHeadersTarget},
|
||||||
|
};
|
||||||
|
|
||||||
|
use codec::Encode;
|
||||||
|
use headers_relay::{
|
||||||
|
sync::{HeadersSyncParams, TargetTransactionMode},
|
||||||
|
sync_types::{HeadersSyncPipeline, QueuedHeader, SourceHeader},
|
||||||
|
};
|
||||||
|
use num_traits::Saturating;
|
||||||
|
use relay_substrate_client::{headers_source::HeadersSource, BlockNumberOf, Chain, Client, HashOf};
|
||||||
|
use sp_runtime::Justification;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
/// Substrate-to-Substrate headers pipeline.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct SubstrateHeadersToSubstrate<SourceChain, SourceSyncHeader, TargetChain: Chain, TargetSign> {
|
||||||
|
/// Client for the target chain.
|
||||||
|
pub(crate) target_client: Client<TargetChain>,
|
||||||
|
/// Data required to sign target chain transactions.
|
||||||
|
pub(crate) target_sign: TargetSign,
|
||||||
|
/// Unused generic arguments dump.
|
||||||
|
_marker: PhantomData<(SourceChain, SourceSyncHeader)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<SourceChain, SourceSyncHeader, TargetChain: Chain, TargetSign>
|
||||||
|
SubstrateHeadersToSubstrate<SourceChain, SourceSyncHeader, TargetChain, TargetSign>
|
||||||
|
{
|
||||||
|
/// Create new Substrate-to-Substrate headers pipeline.
|
||||||
|
pub fn new(target_client: Client<TargetChain>, target_sign: TargetSign) -> Self {
|
||||||
|
SubstrateHeadersToSubstrate {
|
||||||
|
target_client,
|
||||||
|
target_sign,
|
||||||
|
_marker: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<SourceChain, SourceSyncHeader, TargetChain, TargetSign> HeadersSyncPipeline
|
||||||
|
for SubstrateHeadersToSubstrate<SourceChain, SourceSyncHeader, TargetChain, TargetSign>
|
||||||
|
where
|
||||||
|
SourceChain: Clone + Chain,
|
||||||
|
BlockNumberOf<SourceChain>: Saturating + Into<u64>,
|
||||||
|
SourceSyncHeader:
|
||||||
|
SourceHeader<HashOf<SourceChain>, BlockNumberOf<SourceChain>> + std::ops::Deref<Target = SourceChain::Header>,
|
||||||
|
TargetChain: Clone + Chain,
|
||||||
|
TargetSign: Clone + Send + Sync,
|
||||||
|
{
|
||||||
|
const SOURCE_NAME: &'static str = SourceChain::NAME;
|
||||||
|
const TARGET_NAME: &'static str = TargetChain::NAME;
|
||||||
|
|
||||||
|
type Hash = HashOf<SourceChain>;
|
||||||
|
type Number = BlockNumberOf<SourceChain>;
|
||||||
|
type Header = SourceSyncHeader;
|
||||||
|
type Extra = ();
|
||||||
|
type Completion = Justification;
|
||||||
|
|
||||||
|
fn estimate_size(source: &QueuedHeader<Self>) -> usize {
|
||||||
|
source.header().encode().len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return sync parameters for Substrate-to-Substrate headers sync.
|
||||||
|
pub fn sync_params() -> HeadersSyncParams {
|
||||||
|
HeadersSyncParams {
|
||||||
|
max_future_headers_to_download: 32,
|
||||||
|
max_headers_in_submitted_status: 8,
|
||||||
|
max_headers_in_single_submit: 1,
|
||||||
|
max_headers_size_in_single_submit: 1024 * 1024,
|
||||||
|
prune_depth: 256,
|
||||||
|
target_tx_mode: TargetTransactionMode::Signed,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run Substrate-to-Substrate headers sync.
|
||||||
|
pub async fn run<SourceChain, TargetChain, P>(
|
||||||
|
pipeline: P,
|
||||||
|
source_client: Client<SourceChain>,
|
||||||
|
target_client: Client<TargetChain>,
|
||||||
|
metrics_params: Option<relay_utils::metrics::MetricsParams>,
|
||||||
|
) where
|
||||||
|
P: SubstrateHeadersSyncPipeline<
|
||||||
|
Hash = HashOf<SourceChain>,
|
||||||
|
Number = BlockNumberOf<SourceChain>,
|
||||||
|
Completion = Justification,
|
||||||
|
Extra = (),
|
||||||
|
>,
|
||||||
|
P::Header: SourceHeader<HashOf<SourceChain>, BlockNumberOf<SourceChain>>,
|
||||||
|
SourceChain: Clone + Chain,
|
||||||
|
SourceChain::Header: Into<P::Header>,
|
||||||
|
BlockNumberOf<SourceChain>: Into<u64> + Saturating,
|
||||||
|
TargetChain: Clone + Chain,
|
||||||
|
{
|
||||||
|
let source_justifications = match source_client.clone().subscribe_justifications().await {
|
||||||
|
Ok(source_justifications) => source_justifications,
|
||||||
|
Err(error) => {
|
||||||
|
log::warn!(
|
||||||
|
target: "bridge",
|
||||||
|
"Failed to subscribe to {} justifications: {:?}",
|
||||||
|
SourceChain::NAME,
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let sync_maintain =
|
||||||
|
SubstrateHeadersToSubstrateMaintain::new(pipeline.clone(), source_client.clone(), source_justifications);
|
||||||
|
|
||||||
|
headers_relay::sync_loop::run(
|
||||||
|
HeadersSource::new(source_client),
|
||||||
|
SourceChain::AVERAGE_BLOCK_INTERVAL,
|
||||||
|
SubstrateHeadersTarget::new(target_client, pipeline),
|
||||||
|
TargetChain::AVERAGE_BLOCK_INTERVAL,
|
||||||
|
sync_maintain,
|
||||||
|
sync_params(),
|
||||||
|
metrics_params,
|
||||||
|
futures::future::pending(),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ use headers_relay::{
|
|||||||
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;
|
||||||
use sp_core::Bytes;
|
use sp_core::Bytes;
|
||||||
use sp_runtime::{DeserializeOwned, Justification};
|
use sp_runtime::Justification;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
/// Headers sync pipeline for Substrate <-> Substrate relays.
|
/// Headers sync pipeline for Substrate <-> Substrate relays.
|
||||||
@@ -77,8 +77,6 @@ impl<C: Chain, P> SubstrateHeadersTarget<C, P> {
|
|||||||
impl<C, P> TargetClient<P> for SubstrateHeadersTarget<C, P>
|
impl<C, P> TargetClient<P> for SubstrateHeadersTarget<C, P>
|
||||||
where
|
where
|
||||||
C: Chain,
|
C: Chain,
|
||||||
C::Header: DeserializeOwned,
|
|
||||||
C::Index: DeserializeOwned,
|
|
||||||
P::Number: Decode,
|
P::Number: Decode,
|
||||||
P::Hash: Decode + Encode,
|
P::Hash: Decode + Encode,
|
||||||
P: SubstrateHeadersSyncPipeline<Completion = Justification, Extra = ()>,
|
P: SubstrateHeadersSyncPipeline<Completion = Justification, Extra = ()>,
|
||||||
|
|||||||
@@ -34,8 +34,10 @@ pub type RialtoClient = relay_substrate_client::Client<Rialto>;
|
|||||||
|
|
||||||
mod cli;
|
mod cli;
|
||||||
mod headers_maintain;
|
mod headers_maintain;
|
||||||
|
mod headers_pipeline;
|
||||||
mod headers_target;
|
mod headers_target;
|
||||||
mod millau_headers_to_rialto;
|
mod millau_headers_to_rialto;
|
||||||
|
mod rialto_headers_to_millau;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
initialize_relay();
|
initialize_relay();
|
||||||
@@ -71,6 +73,29 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
|
|||||||
.map_err(|e| format!("Failed to parse rialto-signer: {:?}", e))?;
|
.map_err(|e| format!("Failed to parse rialto-signer: {:?}", e))?;
|
||||||
millau_headers_to_rialto::run(millau_client, rialto_client, rialto_sign, prometheus_params.into()).await;
|
millau_headers_to_rialto::run(millau_client, rialto_client, rialto_sign, prometheus_params.into()).await;
|
||||||
}
|
}
|
||||||
|
cli::Command::RialtoHeadersToMillau {
|
||||||
|
rialto,
|
||||||
|
millau,
|
||||||
|
millau_sign,
|
||||||
|
prometheus_params,
|
||||||
|
} => {
|
||||||
|
let rialto_client = RialtoClient::new(ConnectionParams {
|
||||||
|
host: rialto.rialto_host,
|
||||||
|
port: rialto.rialto_port,
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
let millau_client = MillauClient::new(ConnectionParams {
|
||||||
|
host: millau.millau_host,
|
||||||
|
port: millau.millau_port,
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
let millau_sign = MillauSigningParams::from_suri(
|
||||||
|
&millau_sign.millau_signer,
|
||||||
|
millau_sign.millau_signer_password.as_deref(),
|
||||||
|
)
|
||||||
|
.map_err(|e| format!("Failed to parse millau-signer: {:?}", e))?;
|
||||||
|
rialto_headers_to_millau::run(rialto_client, millau_client, millau_sign, prometheus_params.into()).await;
|
||||||
|
}
|
||||||
cli::Command::SubmitMillauToRialtoMessage {
|
cli::Command::SubmitMillauToRialtoMessage {
|
||||||
millau,
|
millau,
|
||||||
millau_sign,
|
millau_sign,
|
||||||
|
|||||||
@@ -17,9 +17,8 @@
|
|||||||
//! Millau-to-Rialto headers sync entrypoint.
|
//! Millau-to-Rialto headers sync entrypoint.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
headers_maintain::SubstrateHeadersToSubstrateMaintain,
|
headers_pipeline::SubstrateHeadersToSubstrate, headers_target::SubstrateHeadersSyncPipeline, MillauClient,
|
||||||
headers_target::{SubstrateHeadersSyncPipeline, SubstrateHeadersTarget},
|
RialtoClient,
|
||||||
MillauClient, RialtoClient,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
@@ -27,41 +26,18 @@ use bp_millau::{
|
|||||||
BEST_MILLAU_BLOCKS_METHOD, FINALIZED_MILLAU_BLOCK_METHOD, INCOMPLETE_MILLAU_HEADERS_METHOD,
|
BEST_MILLAU_BLOCKS_METHOD, FINALIZED_MILLAU_BLOCK_METHOD, INCOMPLETE_MILLAU_HEADERS_METHOD,
|
||||||
IS_KNOWN_MILLAU_BLOCK_METHOD,
|
IS_KNOWN_MILLAU_BLOCK_METHOD,
|
||||||
};
|
};
|
||||||
use codec::Encode;
|
use headers_relay::sync_types::QueuedHeader;
|
||||||
use headers_relay::{
|
|
||||||
sync::{HeadersSyncParams, TargetTransactionMode},
|
|
||||||
sync_types::{HeadersSyncPipeline, QueuedHeader},
|
|
||||||
};
|
|
||||||
use relay_millau_client::{HeaderId as MillauHeaderId, Millau, SyncHeader as MillauSyncHeader};
|
use relay_millau_client::{HeaderId as MillauHeaderId, Millau, SyncHeader as MillauSyncHeader};
|
||||||
use relay_rialto_client::{BridgeMillauCall, Rialto, SigningParams as RialtoSigningParams};
|
use relay_rialto_client::{BridgeMillauCall, Rialto, SigningParams as RialtoSigningParams};
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{Error as SubstrateError, TransactionSignScheme};
|
||||||
headers_source::HeadersSource, BlockNumberOf, Error as SubstrateError, HashOf, TransactionSignScheme,
|
|
||||||
};
|
|
||||||
use sp_core::Pair;
|
use sp_core::Pair;
|
||||||
use sp_runtime::Justification;
|
use sp_runtime::Justification;
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
/// Millau-to-Rialto headers pipeline.
|
/// Millau-to-Rialto headers sync pipeline.
|
||||||
#[derive(Debug, Clone)]
|
pub(crate) type MillauHeadersToRialto =
|
||||||
pub struct MillauHeadersToRialto {
|
SubstrateHeadersToSubstrate<Millau, MillauSyncHeader, Rialto, RialtoSigningParams>;
|
||||||
client: RialtoClient,
|
/// Millau header in-the-queue.
|
||||||
sign: RialtoSigningParams,
|
type QueuedMillauHeader = QueuedHeader<MillauHeadersToRialto>;
|
||||||
}
|
|
||||||
|
|
||||||
impl HeadersSyncPipeline for MillauHeadersToRialto {
|
|
||||||
const SOURCE_NAME: &'static str = "Millau";
|
|
||||||
const TARGET_NAME: &'static str = "Rialto";
|
|
||||||
|
|
||||||
type Hash = HashOf<Millau>;
|
|
||||||
type Number = BlockNumberOf<Millau>;
|
|
||||||
type Header = MillauSyncHeader;
|
|
||||||
type Extra = ();
|
|
||||||
type Completion = Justification;
|
|
||||||
|
|
||||||
fn estimate_size(source: &QueuedHeader<Self>) -> usize {
|
|
||||||
source.header().encode().len()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl SubstrateHeadersSyncPipeline for MillauHeadersToRialto {
|
impl SubstrateHeadersSyncPipeline for MillauHeadersToRialto {
|
||||||
@@ -76,10 +52,10 @@ impl SubstrateHeadersSyncPipeline for MillauHeadersToRialto {
|
|||||||
&self,
|
&self,
|
||||||
header: QueuedMillauHeader,
|
header: QueuedMillauHeader,
|
||||||
) -> Result<Self::SignedTransaction, SubstrateError> {
|
) -> Result<Self::SignedTransaction, SubstrateError> {
|
||||||
let account_id = self.sign.signer.public().as_array_ref().clone().into();
|
let account_id = self.target_sign.signer.public().as_array_ref().clone().into();
|
||||||
let nonce = self.client.next_account_index(account_id).await?;
|
let nonce = self.target_client.next_account_index(account_id).await?;
|
||||||
let call = BridgeMillauCall::import_signed_header(header.header().clone().into()).into();
|
let call = BridgeMillauCall::import_signed_header(header.header().clone().into()).into();
|
||||||
let transaction = Rialto::sign_transaction(&self.client, &self.sign.signer, nonce, call);
|
let transaction = Rialto::sign_transaction(&self.target_client, &self.target_sign.signer, nonce, call);
|
||||||
Ok(transaction)
|
Ok(transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,35 +64,14 @@ impl SubstrateHeadersSyncPipeline for MillauHeadersToRialto {
|
|||||||
id: MillauHeaderId,
|
id: MillauHeaderId,
|
||||||
completion: Justification,
|
completion: Justification,
|
||||||
) -> Result<Self::SignedTransaction, SubstrateError> {
|
) -> Result<Self::SignedTransaction, SubstrateError> {
|
||||||
let account_id = self.sign.signer.public().as_array_ref().clone().into();
|
let account_id = self.target_sign.signer.public().as_array_ref().clone().into();
|
||||||
let nonce = self.client.next_account_index(account_id).await?;
|
let nonce = self.target_client.next_account_index(account_id).await?;
|
||||||
let call = BridgeMillauCall::finalize_header(id.1, completion).into();
|
let call = BridgeMillauCall::finalize_header(id.1, completion).into();
|
||||||
let transaction = Rialto::sign_transaction(&self.client, &self.sign.signer, nonce, call);
|
let transaction = Rialto::sign_transaction(&self.target_client, &self.target_sign.signer, nonce, call);
|
||||||
Ok(transaction)
|
Ok(transaction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Millau header in-the-queue.
|
|
||||||
type QueuedMillauHeader = QueuedHeader<MillauHeadersToRialto>;
|
|
||||||
|
|
||||||
/// Millau node as headers source.
|
|
||||||
type MillauSourceClient = HeadersSource<Millau, MillauHeadersToRialto>;
|
|
||||||
|
|
||||||
/// Rialto node as headers target.
|
|
||||||
type RialtoTargetClient = SubstrateHeadersTarget<Rialto, MillauHeadersToRialto>;
|
|
||||||
|
|
||||||
/// Return sync parameters for Millau-to-Rialto headers sync.
|
|
||||||
pub fn sync_params() -> HeadersSyncParams {
|
|
||||||
HeadersSyncParams {
|
|
||||||
max_future_headers_to_download: 32,
|
|
||||||
max_headers_in_submitted_status: 8,
|
|
||||||
max_headers_in_single_submit: 1,
|
|
||||||
max_headers_size_in_single_submit: 1024 * 1024,
|
|
||||||
prune_depth: 256,
|
|
||||||
target_tx_mode: TargetTransactionMode::Signed,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run Millau-to-Rialto headers sync.
|
/// Run Millau-to-Rialto headers sync.
|
||||||
pub async fn run(
|
pub async fn run(
|
||||||
millau_client: MillauClient,
|
millau_client: MillauClient,
|
||||||
@@ -124,37 +79,11 @@ pub async fn run(
|
|||||||
rialto_sign: RialtoSigningParams,
|
rialto_sign: RialtoSigningParams,
|
||||||
metrics_params: Option<relay_utils::metrics::MetricsParams>,
|
metrics_params: Option<relay_utils::metrics::MetricsParams>,
|
||||||
) {
|
) {
|
||||||
let millau_tick = Duration::from_secs(5);
|
crate::headers_pipeline::run(
|
||||||
let rialto_tick = Duration::from_secs(5);
|
MillauHeadersToRialto::new(rialto_client.clone(), rialto_sign),
|
||||||
|
millau_client,
|
||||||
let millau_justifications = match millau_client.clone().subscribe_justifications().await {
|
rialto_client,
|
||||||
Ok(millau_justifications) => millau_justifications,
|
|
||||||
Err(error) => {
|
|
||||||
log::warn!(
|
|
||||||
target: "bridge",
|
|
||||||
"Failed to subscribe to Millau justifications: {:?}",
|
|
||||||
error,
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let pipeline = MillauHeadersToRialto {
|
|
||||||
client: rialto_client.clone(),
|
|
||||||
sign: rialto_sign,
|
|
||||||
};
|
|
||||||
let sync_maintain =
|
|
||||||
SubstrateHeadersToSubstrateMaintain::new(pipeline.clone(), rialto_client.clone(), millau_justifications);
|
|
||||||
|
|
||||||
headers_relay::sync_loop::run(
|
|
||||||
MillauSourceClient::new(millau_client),
|
|
||||||
millau_tick,
|
|
||||||
RialtoTargetClient::new(rialto_client, pipeline),
|
|
||||||
rialto_tick,
|
|
||||||
sync_maintain,
|
|
||||||
sync_params(),
|
|
||||||
metrics_params,
|
metrics_params,
|
||||||
futures::future::pending(),
|
)
|
||||||
);
|
.await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
|
//! Rialto-to-Millau headers sync entrypoint.
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
headers_pipeline::SubstrateHeadersToSubstrate, headers_target::SubstrateHeadersSyncPipeline, MillauClient,
|
||||||
|
RialtoClient,
|
||||||
|
};
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use bp_rialto::{
|
||||||
|
BEST_RIALTO_BLOCKS_METHOD, FINALIZED_RIALTO_BLOCK_METHOD, INCOMPLETE_RIALTO_HEADERS_METHOD,
|
||||||
|
IS_KNOWN_RIALTO_BLOCK_METHOD,
|
||||||
|
};
|
||||||
|
use headers_relay::sync_types::QueuedHeader;
|
||||||
|
use relay_millau_client::{BridgeRialtoCall, Millau, SigningParams as MillauSigningParams};
|
||||||
|
use relay_rialto_client::{HeaderId as RialtoHeaderId, Rialto, SyncHeader as RialtoSyncHeader};
|
||||||
|
use relay_substrate_client::{Error as SubstrateError, TransactionSignScheme};
|
||||||
|
use sp_core::Pair;
|
||||||
|
use sp_runtime::Justification;
|
||||||
|
|
||||||
|
/// Rialto-to-Millau headers sync pipeline.
|
||||||
|
type RialtoHeadersToMillau = SubstrateHeadersToSubstrate<Rialto, RialtoSyncHeader, Millau, MillauSigningParams>;
|
||||||
|
/// Rialto header in-the-queue.
|
||||||
|
type QueuedRialtoHeader = QueuedHeader<RialtoHeadersToMillau>;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl SubstrateHeadersSyncPipeline for RialtoHeadersToMillau {
|
||||||
|
const BEST_BLOCK_METHOD: &'static str = BEST_RIALTO_BLOCKS_METHOD;
|
||||||
|
const FINALIZED_BLOCK_METHOD: &'static str = FINALIZED_RIALTO_BLOCK_METHOD;
|
||||||
|
const IS_KNOWN_BLOCK_METHOD: &'static str = IS_KNOWN_RIALTO_BLOCK_METHOD;
|
||||||
|
const INCOMPLETE_HEADERS_METHOD: &'static str = INCOMPLETE_RIALTO_HEADERS_METHOD;
|
||||||
|
|
||||||
|
type SignedTransaction = <Millau as TransactionSignScheme>::SignedTransaction;
|
||||||
|
|
||||||
|
async fn make_submit_header_transaction(
|
||||||
|
&self,
|
||||||
|
header: QueuedRialtoHeader,
|
||||||
|
) -> Result<Self::SignedTransaction, SubstrateError> {
|
||||||
|
let account_id = self.target_sign.signer.public().as_array_ref().clone().into();
|
||||||
|
let nonce = self.target_client.next_account_index(account_id).await?;
|
||||||
|
let call = BridgeRialtoCall::import_signed_header(header.header().clone().into()).into();
|
||||||
|
let transaction = Millau::sign_transaction(&self.target_client, &self.target_sign.signer, nonce, call);
|
||||||
|
Ok(transaction)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn make_complete_header_transaction(
|
||||||
|
&self,
|
||||||
|
id: RialtoHeaderId,
|
||||||
|
completion: Justification,
|
||||||
|
) -> Result<Self::SignedTransaction, SubstrateError> {
|
||||||
|
let account_id = self.target_sign.signer.public().as_array_ref().clone().into();
|
||||||
|
let nonce = self.target_client.next_account_index(account_id).await?;
|
||||||
|
let call = BridgeRialtoCall::finalize_header(id.1, completion).into();
|
||||||
|
let transaction = Millau::sign_transaction(&self.target_client, &self.target_sign.signer, nonce, call);
|
||||||
|
Ok(transaction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run Rialto-to-Millau headers sync.
|
||||||
|
pub async fn run(
|
||||||
|
rialto_client: RialtoClient,
|
||||||
|
millau_client: MillauClient,
|
||||||
|
millau_sign: MillauSigningParams,
|
||||||
|
metrics_params: Option<relay_utils::metrics::MetricsParams>,
|
||||||
|
) {
|
||||||
|
crate::headers_pipeline::run(
|
||||||
|
RialtoHeadersToMillau::new(millau_client.clone(), millau_sign),
|
||||||
|
rialto_client,
|
||||||
|
millau_client,
|
||||||
|
metrics_params,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user