SubmitMillauToRialtoMessage subcommand in substrate-relay (#460)

* substrate-relay::SubmitMillauToRialtoMessage

* typo

* Update relays/substrate/src/cli.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:
Svyatoslav Nikolsky
2020-10-28 10:04:06 +03:00
committed by Bastian Köcher
parent a6048bca59
commit b99fa90edd
7 changed files with 210 additions and 8 deletions
+1
View File
@@ -55,6 +55,7 @@ pub use frame_support::{
};
pub use pallet_balances::Call as BalancesCall;
pub use pallet_message_lane::Call as MessageLaneCall;
pub use pallet_substrate_bridge::Call as BridgeSubstrateCall;
pub use pallet_timestamp::Call as TimestampCall;
+1
View File
@@ -60,6 +60,7 @@ pub use frame_support::{
StorageValue,
};
pub use frame_system::Call as SystemCall;
pub use pallet_balances::Call as BalancesCall;
pub use pallet_bridge_currency_exchange::Call as BridgeCurrencyExchangeCall;
pub use pallet_bridge_eth_poa::Call as BridgeEthPoACall;
+2
View File
@@ -18,4 +18,6 @@ millau-runtime = { path = "../../bin/millau/runtime" }
# Substrate Dependencies
frame-system = "2.0"
pallet-transaction-payment = "2.0"
sp-core = "2.0"
sp-runtime = "2.0"
+69 -3
View File
@@ -16,10 +16,14 @@
//! Types used to connect to the Millau-Substrate chain.
use relay_substrate_client::{Chain, ChainBase};
use codec::Encode;
use headers_relay::sync_types::SourceHeader;
use sp_runtime::traits::Header as HeaderT;
use relay_substrate_client::{Chain, ChainBase, Client, TransactionSignScheme};
use sp_core::Pair;
use sp_runtime::{
generic::SignedPayload,
traits::{Header as HeaderT, IdentifyAccount},
};
/// Millau header id.
pub type HeaderId = relay_utils::HeaderId<millau_runtime::Hash, millau_runtime::BlockNumber>;
@@ -42,6 +46,68 @@ impl Chain for Millau {
type Call = millau_runtime::Call;
}
impl TransactionSignScheme for Millau {
type Chain = Millau;
type AccountKeyPair = sp_core::sr25519::Pair;
type SignedTransaction = millau_runtime::UncheckedExtrinsic;
fn sign_transaction(
client: &Client<Self>,
signer: &Self::AccountKeyPair,
signer_nonce: <Self::Chain as Chain>::Index,
call: <Self::Chain as Chain>::Call,
) -> Self::SignedTransaction {
let raw_payload = SignedPayload::from_raw(
call,
(
frame_system::CheckSpecVersion::<millau_runtime::Runtime>::new(),
frame_system::CheckTxVersion::<millau_runtime::Runtime>::new(),
frame_system::CheckGenesis::<millau_runtime::Runtime>::new(),
frame_system::CheckEra::<millau_runtime::Runtime>::from(sp_runtime::generic::Era::Immortal),
frame_system::CheckNonce::<millau_runtime::Runtime>::from(signer_nonce),
frame_system::CheckWeight::<millau_runtime::Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<millau_runtime::Runtime>::from(0),
),
(
millau_runtime::VERSION.spec_version,
millau_runtime::VERSION.transaction_version,
*client.genesis_hash(),
*client.genesis_hash(),
(),
(),
(),
),
);
let signature = raw_payload.using_encoded(|payload| signer.sign(payload));
let signer: sp_runtime::MultiSigner = signer.public().into();
let (call, extra, _) = raw_payload.deconstruct();
millau_runtime::UncheckedExtrinsic::new_signed(call, signer.into_account(), signature.into(), extra)
}
}
/// Millau signing params.
#[derive(Clone)]
pub struct SigningParams {
/// Substrate transactions signer.
pub signer: sp_core::sr25519::Pair,
}
impl SigningParams {
/// Create signing params from SURI and password.
pub fn from_suri(suri: &str, password: Option<&str>) -> Result<Self, sp_core::crypto::SecretStringError> {
Ok(SigningParams {
signer: sp_core::sr25519::Pair::from_string(suri, password)?,
})
}
}
impl std::fmt::Debug for SigningParams {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.signer.public())
}
}
/// Millau header type used in headers sync.
#[derive(Clone, Debug, PartialEq)]
pub struct SyncHeader(millau_runtime::Header);
+6
View File
@@ -10,23 +10,29 @@ async-std = "1.6.2"
async-trait = "0.1.41"
codec = { package = "parity-scale-codec", version = "1.3.4" }
futures = "0.3.7"
hex = "0.4"
log = "0.4.11"
paste = "1.0"
structopt = "0.3"
# Bridge dependencies
bp-message-lane = { path = "../../primitives/message-lane" }
bp-millau = { path = "../../primitives/millau" }
bp-rialto = { path = "../../primitives/rialto" }
headers-relay = { path = "../headers-relay" }
messages-relay = { path = "../messages-relay" }
millau-runtime = { path = "../../bin/millau/runtime" }
pallet-bridge-call-dispatch = { path = "../../modules/call-dispatch" }
pallet-substrate-bridge = { path = "../../modules/substrate" }
relay-millau-client = { path = "../millau-client" }
relay-rialto-client = { path = "../rialto-client" }
relay-substrate-client = { path = "../substrate-client" }
relay-utils = { path = "../utils" }
rialto-runtime = { path = "../../bin/rialto/runtime" }
# Substrate Dependencies
frame-support = "2.0"
sp-core = "2.0"
sp-runtime = "2.0"
+48 -1
View File
@@ -16,7 +16,8 @@
//! Deal with CLI args of substrate-to-substrate relay.
use structopt::StructOpt;
use bp_message_lane::LaneId;
use structopt::{clap::arg_enum, StructOpt};
/// Parse relay CLI args.
pub fn parse_args() -> Command {
@@ -38,6 +39,52 @@ pub enum Command {
#[structopt(flatten)]
prometheus_params: PrometheusParams,
},
/// Submit message to given Rialto -> Millau lane.
SubmitMillauToRialtoMessage {
#[structopt(flatten)]
millau: MillauConnectionParams,
#[structopt(flatten)]
millau_sign: MillauSigningParams,
#[structopt(flatten)]
rialto_sign: RialtoSigningParams,
/// Hex-encoded lane id.
#[structopt(long)]
lane: HexLaneId,
/// Message type.
#[structopt(long, possible_values = &ToRialtoMessage::variants())]
message: ToRialtoMessage,
/// Delivery and dispatch fee.
#[structopt(long)]
fee: bp_millau::Balance,
},
}
arg_enum! {
#[derive(Debug)]
/// All possible messages that may be delivered to the Rialto chain.
pub enum ToRialtoMessage {
Remark,
}
}
/// Lane id.
#[derive(Debug)]
pub struct HexLaneId(LaneId);
impl From<HexLaneId> for LaneId {
fn from(lane_id: HexLaneId) -> LaneId {
lane_id.0
}
}
impl std::str::FromStr for HexLaneId {
type Err = hex::FromHexError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut lane_id = LaneId::default();
hex::decode_to_slice(s, &mut lane_id)?;
Ok(HexLaneId(lane_id))
}
}
/// Prometheus metrics params.
+83 -4
View File
@@ -18,14 +18,19 @@
#![warn(missing_docs)]
use relay_rialto_client::SigningParams as RialtoSigningParams;
use relay_substrate_client::ConnectionParams;
use codec::Encode;
use frame_support::weights::GetDispatchInfo;
use pallet_bridge_call_dispatch::{CallOrigin, MessagePayload};
use relay_millau_client::{Millau, SigningParams as MillauSigningParams};
use relay_rialto_client::{Rialto, SigningParams as RialtoSigningParams};
use relay_substrate_client::{ConnectionParams, TransactionSignScheme};
use relay_utils::initialize::initialize_relay;
use sp_core::{Bytes, Pair};
/// Millau node client.
pub type MillauClient = relay_substrate_client::Client<relay_millau_client::Millau>;
pub type MillauClient = relay_substrate_client::Client<Millau>;
/// Rialto node client.
pub type RialtoClient = relay_substrate_client::Client<relay_rialto_client::Rialto>;
pub type RialtoClient = relay_substrate_client::Client<Rialto>;
mod cli;
mod headers_maintain;
@@ -66,6 +71,80 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
.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;
}
cli::Command::SubmitMillauToRialtoMessage {
millau,
millau_sign,
rialto_sign,
lane,
message,
fee,
} => {
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))?;
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))?;
let rialto_call = match message {
cli::ToRialtoMessage::Remark => rialto_runtime::Call::System(rialto_runtime::SystemCall::remark(
format!(
"Unix time: {}",
std::time::SystemTime::now()
.duration_since(std::time::SystemTime::UNIX_EPOCH)
.unwrap_or_default()
.as_secs(),
)
.as_bytes()
.to_vec(),
)),
};
let rialto_call_weight = rialto_call.get_dispatch_info().weight;
let millau_sender_public = millau_sign.signer.public();
let rialto_origin_public = rialto_sign.signer.public();
let mut rialto_origin_signature_message = Vec::new();
rialto_call.encode_to(&mut rialto_origin_signature_message);
millau_sender_public.encode_to(&mut rialto_origin_signature_message);
let rialto_origin_signature = rialto_sign.signer.sign(&rialto_origin_signature_message);
let millau_call =
millau_runtime::Call::BridgeRialtoMessageLane(millau_runtime::MessageLaneCall::send_message(
lane.into(),
MessagePayload {
spec_version: millau_runtime::VERSION.spec_version,
weight: rialto_call_weight,
origin: CallOrigin::RealAccount(
millau_sender_public.into(),
rialto_origin_public.into(),
rialto_origin_signature.into(),
),
call: rialto_call.encode(),
},
fee,
));
let signed_millau_call = Millau::sign_transaction(
&millau_client,
&millau_sign.signer,
millau_client.next_account_index(millau_sender_public.into()).await?,
millau_call,
);
millau_client
.submit_extrinsic(Bytes(signed_millau_call.encode()))
.await?;
}
}
Ok(())