Substrate relay stub (#376)

* substrate-relay: initial commit

* MillauHeaderApi and RialtoHeaderApi

* post-merge fixes + TODOs + compilation
This commit is contained in:
Svyatoslav Nikolsky
2020-09-30 14:03:57 +03:00
committed by Bastian Köcher
parent f9db999a1a
commit dbb72faa86
22 changed files with 652 additions and 71 deletions
+22
View File
@@ -0,0 +1,22 @@
[package]
name = "substrate-relay"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies]
async-std = "1.6.2"
async-trait = "0.1.40"
bp-rialto = { path = "../../primitives/rialto" }
codec = { package = "parity-scale-codec", version = "1.3.4" }
futures = "0.3.5"
headers-relay = { path = "../headers-relay" }
log = "0.4.11"
messages-relay = { path = "../messages-relay" }
paste = "1.0"
relay-millau-client = { path = "../millau-client" }
relay-rialto-client = { path = "../rialto-client" }
relay-substrate-client = { path = "../substrate-client" }
sp-runtime = { version = "2.0.0", tag = 'v2.0.0', git = "https://github.com/paritytech/substrate.git" }
structopt = "0.3"
+65
View File
@@ -0,0 +1,65 @@
// 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/>.
//! Deal with CLI args of substrate-to-substrate relay.
use structopt::StructOpt;
/// Parse relay CLI args.
pub fn parse_args() -> Command {
Command::from_args()
}
/// Substrate-to-Substrate relay CLI args.
#[derive(StructOpt)]
#[structopt(about = "Substrate-to-Substrate relay")]
pub enum Command {
MillauHeadersToRialto {
#[structopt(flatten)]
millau: MillauConnectionParams,
#[structopt(flatten)]
rialto: RialtoConnectionParams,
#[structopt(flatten)]
rialto_sign: RialtoSigningParams,
},
}
macro_rules! declare_chain_options {
($chain:ident, $chain_prefix:ident) => {
paste::item! {
#[doc = $chain " connection params."]
#[derive(StructOpt)]
pub struct [<$chain ConnectionParams>] {
#[doc = "Connect to " $chain " node at given host."]
pub [<$chain_prefix _host>]: String,
#[doc = "Connect to " $chain " node at given port."]
pub [<$chain_prefix _port>]: u16,
}
#[doc = $chain " signing params."]
#[derive(StructOpt)]
pub struct [<$chain SigningParams>] {
#[doc = "The SURI of secret key to use when transactions are submitted to the " $chain " node."]
pub [<$chain_prefix _signer>]: String,
#[doc = "The password for the SURI of secret key to use when transactions are submitted to the " $chain " node."]
pub [<$chain_prefix _signer_password>]: Option<String>,
}
}
};
}
declare_chain_options!(Rialto, rialto);
declare_chain_options!(Millau, millau);
+66
View File
@@ -0,0 +1,66 @@
// 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 relay entrypoint.
#![warn(missing_docs)]
use relay_rialto_client::SigningParams as RialtoSigningParams;
use relay_substrate_client::ConnectionParams;
/// Millau node client.
pub type MillauClient = relay_substrate_client::Client<relay_millau_client::Millau>;
/// Rialto node client.
pub type RialtoClient = relay_substrate_client::Client<relay_rialto_client::Rialto>;
mod cli;
mod millau_headers_to_rialto;
fn main() {
let result = async_std::task::block_on(run_command(cli::parse_args()));
if let Err(error) = result {
log::error!(target: "bridge", "Failed to start relay: {}", error);
}
}
async fn run_command(command: cli::Command) -> Result<(), String> {
match command {
cli::Command::MillauHeadersToRialto {
millau,
rialto,
rialto_sign,
} => {
let millau_client = MillauClient::new(ConnectionParams {
host: millau.millau_host,
port: millau.millau_port,
})
.await?;
let rialto_client = RialtoClient::new(ConnectionParams {
host: rialto.rialto_host,
port: rialto.rialto_port,
})
.await?;
let rialto_sign = RialtoSigningParams::from_suri(
&rialto_sign.rialto_signer,
rialto_sign.rialto_signer_password.as_deref(),
)
.map_err(|e| format!("Failed to parse rialto-signer: {:?}", e))?;
millau_headers_to_rialto::run(millau_client, rialto_client, rialto_sign)
}
}
Ok(())
}
@@ -0,0 +1,125 @@
// 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/>.
//! Millau-to-Rialto headers sync entrypoint.
use crate::{MillauClient, RialtoClient};
use async_trait::async_trait;
use codec::Encode;
use headers_relay::{
sync::{HeadersSyncParams, TargetTransactionMode},
sync_loop::TargetClient,
sync_types::{HeadersSyncPipeline, QueuedHeader, SubmittedHeaders},
};
use relay_millau_client::{HeaderId as MillauHeaderId, Millau, SyncHeader as MillauSyncHeader};
use relay_rialto_client::SigningParams as RialtoSigningParams;
use relay_substrate_client::{headers_source::HeadersSource, BlockNumberOf, Error as SubstrateError, HashOf};
use sp_runtime::Justification;
use std::{collections::HashSet, time::Duration};
/// Millau-to-Rialto headers pipeline.
#[derive(Debug, Clone, Copy)]
struct 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()
}
}
/// Millau header in-the-queue.
type QueuedMillauHeader = QueuedHeader<MillauHeadersToRialto>;
/// Millau node as headers source.
type MillauSourceClient = HeadersSource<Millau, MillauHeadersToRialto>;
/// Rialto node as headers target.
struct RialtoTargetClient {
_client: RialtoClient,
_sign: RialtoSigningParams,
}
#[async_trait]
impl TargetClient<MillauHeadersToRialto> for RialtoTargetClient {
type Error = SubstrateError;
async fn best_header_id(&self) -> Result<MillauHeaderId, Self::Error> {
unimplemented!("https://github.com/paritytech/parity-bridges-common/issues/209")
}
async fn is_known_header(&self, _id: MillauHeaderId) -> Result<(MillauHeaderId, bool), Self::Error> {
unimplemented!("https://github.com/paritytech/parity-bridges-common/issues/209")
}
async fn submit_headers(&self, _headers: Vec<QueuedMillauHeader>) -> SubmittedHeaders<MillauHeaderId, Self::Error> {
unimplemented!("https://github.com/paritytech/parity-bridges-common/issues/209")
}
async fn incomplete_headers_ids(&self) -> Result<HashSet<MillauHeaderId>, Self::Error> {
unimplemented!("https://github.com/paritytech/parity-bridges-common/issues/209")
}
#[allow(clippy::unit_arg)]
async fn complete_header(
&self,
_id: MillauHeaderId,
_completion: Justification,
) -> Result<MillauHeaderId, Self::Error> {
unimplemented!("https://github.com/paritytech/parity-bridges-common/issues/209")
}
async fn requires_extra(&self, _header: QueuedMillauHeader) -> Result<(MillauHeaderId, bool), Self::Error> {
unimplemented!("https://github.com/paritytech/parity-bridges-common/issues/209")
}
}
/// Run Millau-to-Rialto headers sync.
pub fn run(millau_client: MillauClient, rialto_client: RialtoClient, rialto_sign: RialtoSigningParams) {
let millau_tick = Duration::from_secs(5);
let rialto_tick = Duration::from_secs(5);
let sync_params = HeadersSyncParams {
max_future_headers_to_download: 32,
max_headers_in_submitted_status: 1024,
max_headers_in_single_submit: 8,
max_headers_size_in_single_submit: 1024 * 1024,
prune_depth: 256,
target_tx_mode: TargetTransactionMode::Signed,
};
let metrics_params = None;
headers_relay::sync_loop::run(
MillauSourceClient::new(millau_client),
millau_tick,
RialtoTargetClient {
_client: rialto_client,
_sign: rialto_sign,
},
rialto_tick,
sync_params,
metrics_params,
futures::future::pending(),
);
}