diff --git a/bridges/relays/bin-substrate/src/chains/millau.rs b/bridges/relays/bin-substrate/src/chains/millau.rs index 3cba16ea32..7a86455df9 100644 --- a/bridges/relays/bin-substrate/src/chains/millau.rs +++ b/bridges/relays/bin-substrate/src/chains/millau.rs @@ -19,7 +19,9 @@ use crate::cli::{ bridge, encode_call::{self, Call, CliEncodeCall}, - encode_message, send_message, CliChain, + encode_message, + send_message::{self, DispatchFeePayment}, + CliChain, }; use bp_message_dispatch::{CallOrigin, MessagePayload}; use codec::Decode; @@ -98,7 +100,13 @@ impl CliChain for Millau { let call = Target::encode_call(&call).map_err(|e| e.to_string())?; let weight = call.get_dispatch_info().weight; - Ok(send_message::message_payload(spec_version, weight, origin, &call)) + Ok(send_message::message_payload( + spec_version, + weight, + origin, + &call, + DispatchFeePayment::AtSourceChain, + )) } } } diff --git a/bridges/relays/bin-substrate/src/chains/mod.rs b/bridges/relays/bin-substrate/src/chains/mod.rs index bd228ac7c4..9aec7d19d2 100644 --- a/bridges/relays/bin-substrate/src/chains/mod.rs +++ b/bridges/relays/bin-substrate/src/chains/mod.rs @@ -146,6 +146,7 @@ mod tests { call.get_dispatch_info().weight, bp_message_dispatch::CallOrigin::SourceRoot, &call, + send_message::DispatchFeePayment::AtSourceChain, ); assert_eq!(Millau::verify_message(&payload), Ok(())); @@ -156,6 +157,7 @@ mod tests { call.get_dispatch_info().weight, bp_message_dispatch::CallOrigin::SourceRoot, &call, + send_message::DispatchFeePayment::AtSourceChain, ); assert!(Millau::verify_message(&payload).is_err()); } @@ -183,6 +185,7 @@ mod tests { maximal_dispatch_weight, bp_message_dispatch::CallOrigin::SourceRoot, &call, + send_message::DispatchFeePayment::AtSourceChain, ); assert_eq!(Millau::verify_message(&payload), Ok(())); @@ -191,6 +194,7 @@ mod tests { maximal_dispatch_weight + 1, bp_message_dispatch::CallOrigin::SourceRoot, &call, + send_message::DispatchFeePayment::AtSourceChain, ); assert!(Millau::verify_message(&payload).is_err()); } @@ -208,6 +212,7 @@ mod tests { maximal_dispatch_weight, bp_message_dispatch::CallOrigin::SourceRoot, &call, + send_message::DispatchFeePayment::AtSourceChain, ); assert_eq!(Rialto::verify_message(&payload), Ok(())); @@ -216,6 +221,7 @@ mod tests { maximal_dispatch_weight + 1, bp_message_dispatch::CallOrigin::SourceRoot, &call, + send_message::DispatchFeePayment::AtSourceChain, ); assert!(Rialto::verify_message(&payload).is_err()); } diff --git a/bridges/relays/bin-substrate/src/chains/rialto.rs b/bridges/relays/bin-substrate/src/chains/rialto.rs index 9a6185b4fc..995ae7ae0d 100644 --- a/bridges/relays/bin-substrate/src/chains/rialto.rs +++ b/bridges/relays/bin-substrate/src/chains/rialto.rs @@ -19,7 +19,9 @@ use crate::cli::{ bridge, encode_call::{self, Call, CliEncodeCall}, - encode_message, send_message, CliChain, + encode_message, + send_message::{self, DispatchFeePayment}, + CliChain, }; use bp_message_dispatch::{CallOrigin, MessagePayload}; use codec::Decode; @@ -95,7 +97,13 @@ impl CliChain for Rialto { let call = Target::encode_call(&call).map_err(|e| e.to_string())?; let weight = call.get_dispatch_info().weight; - Ok(send_message::message_payload(spec_version, weight, origin, &call)) + Ok(send_message::message_payload( + spec_version, + weight, + origin, + &call, + DispatchFeePayment::AtSourceChain, + )) } } } diff --git a/bridges/relays/bin-substrate/src/cli/send_message.rs b/bridges/relays/bin-substrate/src/cli/send_message.rs index ab80254644..496b3707a9 100644 --- a/bridges/relays/bin-substrate/src/cli/send_message.rs +++ b/bridges/relays/bin-substrate/src/cli/send_message.rs @@ -22,7 +22,6 @@ use crate::cli::{ TargetSigningParams, }; use bp_message_dispatch::{CallOrigin, MessagePayload}; -use bp_runtime::messages::DispatchFeePayment; use codec::Encode; use frame_support::weights::Weight; use relay_substrate_client::{Chain, TransactionSignScheme}; @@ -30,7 +29,26 @@ use sp_core::{Bytes, Pair}; use sp_runtime::{traits::IdentifyAccount, AccountId32, MultiSignature, MultiSigner}; use std::fmt::Debug; use structopt::StructOpt; -use strum::VariantNames; +use strum::{EnumString, EnumVariantNames, VariantNames}; + +/// Relayer operating mode. +#[derive(Debug, EnumString, EnumVariantNames, Clone, Copy, PartialEq, Eq)] +#[strum(serialize_all = "kebab_case")] +pub enum DispatchFeePayment { + /// The dispacth fee is paid at the source chain. + AtSourceChain, + /// The dispatch fee is paid at the target chain. + AtTargetChain, +} + +impl From for bp_runtime::messages::DispatchFeePayment { + fn from(dispatch_fee_payment: DispatchFeePayment) -> Self { + match dispatch_fee_payment { + DispatchFeePayment::AtSourceChain => Self::AtSourceChain, + DispatchFeePayment::AtTargetChain => Self::AtTargetChain, + } + } +} /// Send bridge message. #[derive(StructOpt)] @@ -51,6 +69,14 @@ pub struct SendMessage { /// Hex-encoded lane id. Defaults to `00000000`. #[structopt(long, default_value = "00000000")] lane: HexLaneId, + /// Where dispatch fee is paid? + #[structopt( + long, + possible_values = DispatchFeePayment::VARIANTS, + case_insensitive = true, + default_value = "at-source-chain", + )] + dispatch_fee_payment: DispatchFeePayment, /// Dispatch weight of the message. If not passed, determined automatically. #[structopt(long)] dispatch_weight: Option>, @@ -76,6 +102,7 @@ impl SendMessage { target_signer, target_signer_password, ref mut message, + dispatch_fee_payment, dispatch_weight, origin, bridge, @@ -124,6 +151,7 @@ impl SendMessage { } }, &target_call, + *dispatch_fee_payment, ) }; Ok(payload) @@ -212,6 +240,7 @@ pub(crate) fn message_payload( weight: Weight, origin: CallOrigin, call: &impl Encode, + dispatch_fee_payment: DispatchFeePayment, ) -> MessagePayload> where SAccountId: Encode + Debug, @@ -223,7 +252,7 @@ where spec_version, weight, origin, - dispatch_fee_payment: DispatchFeePayment::AtSourceChain, + dispatch_fee_payment: dispatch_fee_payment.into(), call: HexBytes::encode(call), }; @@ -281,7 +310,7 @@ mod tests { spec_version: relay_millau_client::Millau::RUNTIME_VERSION.spec_version, weight: 1038000, origin: CallOrigin::SourceAccount(sp_keyring::AccountKeyring::Alice.to_account_id()), - dispatch_fee_payment: DispatchFeePayment::AtSourceChain, + dispatch_fee_payment: bp_runtime::messages::DispatchFeePayment::AtSourceChain, call: hex!("0401081234").to_vec(), } ); @@ -325,7 +354,7 @@ mod tests { sp_keyring::AccountKeyring::Bob.into(), signature, ), - dispatch_fee_payment: DispatchFeePayment::AtSourceChain, + dispatch_fee_payment: bp_runtime::messages::DispatchFeePayment::AtSourceChain, call: hex!("0701081234").to_vec(), } ); @@ -350,4 +379,29 @@ mod tests { assert!(send_message.is_err()); } + + #[test] + fn accepts_non_default_dispatch_fee_payment() { + // given + let mut send_message = SendMessage::from_iter(vec![ + "send-message", + "rialto-to-millau", + "--source-port", + "1234", + "--source-signer", + "//Alice", + "--dispatch-fee-payment", + "at-target-chain", + "remark", + ]); + + // when + let payload = send_message.encode_payload().unwrap(); + + // then + assert_eq!( + payload.dispatch_fee_payment, + bp_runtime::messages::DispatchFeePayment::AtTargetChain + ); + } }