From 08800ba48c6f86410433185fd065ff55d523c493 Mon Sep 17 00:00:00 2001 From: fewensa <37804932+fewensa@users.noreply.github.com> Date: Thu, 16 Dec 2021 20:55:01 +0800 Subject: [PATCH] Change submit transaction spec_version and transaction_version query from chain (#1248) * The `spec_version` and `transaction_version` query from chain * fix compile * Lint * Custom spec_version and transaction_version * runtime version params struct opt * runtime version cli * cli params * Add missing types defined * fix compile * debug cli * clippy * clippy * Query spec_version and transaction_version same times * Fix vars * Wrap option * Wrap option * Try fix ci * Change follow suggestions --- bridges/primitives/polkadot-core/src/lib.rs | 7 +- .../src/chains/kusama_messages_to_polkadot.rs | 17 ++-- .../src/chains/millau_messages_to_rialto.rs | 17 ++-- .../relays/bin-substrate/src/chains/mod.rs | 30 ++++--- .../src/chains/polkadot_messages_to_kusama.rs | 17 ++-- .../src/chains/rialto_messages_to_millau.rs | 17 ++-- .../relays/bin-substrate/src/cli/bridge.rs | 30 +++++++ .../bin-substrate/src/cli/estimate_fee.rs | 9 +- .../bin-substrate/src/cli/init_bridge.rs | 50 +++++++++-- bridges/relays/bin-substrate/src/cli/mod.rs | 61 ++++++++++++- .../src/cli/register_parachain.rs | 71 ++++++++++----- .../bin-substrate/src/cli/relay_headers.rs | 32 ++++++- .../src/cli/relay_headers_and_messages.rs | 36 ++++++-- .../bin-substrate/src/cli/relay_messages.rs | 4 +- .../src/cli/resubmit_transactions.rs | 40 ++++++--- .../bin-substrate/src/cli/send_message.rs | 34 ++++--- .../bin-substrate/src/cli/swap_tokens.rs | 90 +++++++++++++------ bridges/relays/client-kusama/src/lib.rs | 28 +++--- bridges/relays/client-millau/src/lib.rs | 29 +++--- bridges/relays/client-polkadot/src/lib.rs | 28 +++--- bridges/relays/client-rialto/src/lib.rs | 29 +++--- bridges/relays/client-rococo/src/lib.rs | 28 +++--- bridges/relays/client-substrate/src/chain.rs | 25 ++++-- bridges/relays/client-substrate/src/client.rs | 29 ++++++ bridges/relays/client-substrate/src/lib.rs | 15 +++- bridges/relays/client-wococo/src/lib.rs | 28 +++--- .../src/finality_target.rs | 15 ++-- .../src/messages_source.rs | 29 ++++-- .../src/messages_target.rs | 29 ++++-- 29 files changed, 600 insertions(+), 274 deletions(-) diff --git a/bridges/primitives/polkadot-core/src/lib.rs b/bridges/primitives/polkadot-core/src/lib.rs index 0dc7c54835b9c..8be9cc17daca5 100644 --- a/bridges/primitives/polkadot-core/src/lib.rs +++ b/bridges/primitives/polkadot-core/src/lib.rs @@ -265,7 +265,8 @@ impl parity_scale_codec::Decode for SignedExtensions { impl SignedExtensions { pub fn new( - version: sp_version::RuntimeVersion, + spec_version: u32, + transaction_version: u32, era: bp_runtime::TransactionEraOf, genesis_hash: Hash, nonce: Nonce, @@ -282,8 +283,8 @@ impl SignedExtensions { tip.into(), // transaction payment / tip (compact encoding) ), additional_signed: ( - version.spec_version, - version.transaction_version, + spec_version, + transaction_version, genesis_hash, era.signed_payload(genesis_hash), (), diff --git a/bridges/relays/bin-substrate/src/chains/kusama_messages_to_polkadot.rs b/bridges/relays/bin-substrate/src/chains/kusama_messages_to_polkadot.rs index 6a8780a34aad0..82a3206b0d916 100644 --- a/bridges/relays/bin-substrate/src/chains/kusama_messages_to_polkadot.rs +++ b/bridges/relays/bin-substrate/src/chains/kusama_messages_to_polkadot.rs @@ -23,7 +23,7 @@ use sp_core::{Bytes, Pair}; use messages_relay::relay_strategy::MixStrategy; use relay_kusama_client::Kusama; use relay_polkadot_client::Polkadot; -use relay_substrate_client::{Client, TransactionSignScheme, UnsignedTransaction}; +use relay_substrate_client::{Client, SignParam, TransactionSignScheme, UnsignedTransaction}; use substrate_relay_helper::messages_lane::SubstrateMessageLane; /// Description of Kusama -> Polkadot messages bridge. @@ -69,14 +69,17 @@ pub(crate) async fn update_polkadot_to_kusama_conversion_rate( ) -> anyhow::Result<()> { let genesis_hash = *client.genesis_hash(); let signer_id = (*signer.public().as_array_ref()).into(); + let (spec_version, transaction_version) = client.simple_runtime_version().await?; client .submit_signed_extrinsic(signer_id, move |_, transaction_nonce| { Bytes( - Kusama::sign_transaction( + Kusama::sign_transaction(SignParam { + spec_version, + transaction_version, genesis_hash, - &signer, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new( + signer, + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new( relay_kusama_client::runtime::Call::BridgePolkadotMessages( relay_kusama_client::runtime::BridgePolkadotMessagesCall::update_pallet_parameter( relay_kusama_client::runtime::BridgePolkadotMessagesParameter::PolkadotToKusamaConversionRate( @@ -86,8 +89,8 @@ pub(crate) async fn update_polkadot_to_kusama_conversion_rate( ), transaction_nonce, ), - ) - .encode(), + }) + .encode(), ) }) .await diff --git a/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs b/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs index 4acc7fdd2ff8d..a496602943554 100644 --- a/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs +++ b/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs @@ -22,7 +22,7 @@ use sp_core::{Bytes, Pair}; use messages_relay::relay_strategy::MixStrategy; use relay_millau_client::Millau; use relay_rialto_client::Rialto; -use relay_substrate_client::{Client, TransactionSignScheme, UnsignedTransaction}; +use relay_substrate_client::{Client, SignParam, TransactionSignScheme, UnsignedTransaction}; use substrate_relay_helper::messages_lane::{ DirectReceiveMessagesDeliveryProofCallBuilder, DirectReceiveMessagesProofCallBuilder, SubstrateMessageLane, @@ -66,23 +66,26 @@ pub(crate) async fn update_rialto_to_millau_conversion_rate( ) -> anyhow::Result<()> { let genesis_hash = *client.genesis_hash(); let signer_id = (*signer.public().as_array_ref()).into(); + let (spec_version, transaction_version) = client.simple_runtime_version().await?; client .submit_signed_extrinsic(signer_id, move |_, transaction_nonce| { Bytes( - Millau::sign_transaction( + Millau::sign_transaction(SignParam { + spec_version, + transaction_version, genesis_hash, - &signer, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new( + signer, + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new( millau_runtime::MessagesCall::update_pallet_parameter { parameter: millau_runtime::rialto_messages::MillauToRialtoMessagesParameter::RialtoToMillauConversionRate( sp_runtime::FixedU128::from_float(updated_rate), ), } - .into(), + .into(), transaction_nonce, ), - ) + }) .encode(), ) }) diff --git a/bridges/relays/bin-substrate/src/chains/mod.rs b/bridges/relays/bin-substrate/src/chains/mod.rs index 3f2f5633a03b0..e2a7a9a2b1eb7 100644 --- a/bridges/relays/bin-substrate/src/chains/mod.rs +++ b/bridges/relays/bin-substrate/src/chains/mod.rs @@ -48,7 +48,7 @@ mod tests { use frame_support::dispatch::GetDispatchInfo; use relay_millau_client::Millau; use relay_rialto_client::Rialto; - use relay_substrate_client::{TransactionSignScheme, UnsignedTransaction}; + use relay_substrate_client::{SignParam, TransactionSignScheme, UnsignedTransaction}; use sp_core::Pair; use sp_runtime::traits::{IdentifyAccount, Verify}; @@ -204,12 +204,14 @@ mod tests { fn rialto_tx_extra_bytes_constant_is_correct() { let rialto_call = rialto_runtime::Call::System(rialto_runtime::SystemCall::remark { remark: vec![] }); - let rialto_tx = Rialto::sign_transaction( - Default::default(), - &sp_keyring::AccountKeyring::Alice.pair(), - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new(rialto_call.clone(), 0), - ); + let rialto_tx = Rialto::sign_transaction(SignParam { + spec_version: 1, + transaction_version: 1, + genesis_hash: Default::default(), + signer: sp_keyring::AccountKeyring::Alice.pair(), + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new(rialto_call.clone(), 0), + }); let extra_bytes_in_transaction = rialto_tx.encode().len() - rialto_call.encode().len(); assert!( bp_rialto::TX_EXTRA_BYTES as usize >= extra_bytes_in_transaction, @@ -223,12 +225,14 @@ mod tests { fn millau_tx_extra_bytes_constant_is_correct() { let millau_call = millau_runtime::Call::System(millau_runtime::SystemCall::remark { remark: vec![] }); - let millau_tx = Millau::sign_transaction( - Default::default(), - &sp_keyring::AccountKeyring::Alice.pair(), - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new(millau_call.clone(), 0), - ); + let millau_tx = Millau::sign_transaction(SignParam { + spec_version: 0, + transaction_version: 0, + genesis_hash: Default::default(), + signer: sp_keyring::AccountKeyring::Alice.pair(), + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new(millau_call.clone(), 0), + }); let extra_bytes_in_transaction = millau_tx.encode().len() - millau_call.encode().len(); assert!( bp_millau::TX_EXTRA_BYTES as usize >= extra_bytes_in_transaction, diff --git a/bridges/relays/bin-substrate/src/chains/polkadot_messages_to_kusama.rs b/bridges/relays/bin-substrate/src/chains/polkadot_messages_to_kusama.rs index 12ebdde15cb5b..5eeb0df3f1288 100644 --- a/bridges/relays/bin-substrate/src/chains/polkadot_messages_to_kusama.rs +++ b/bridges/relays/bin-substrate/src/chains/polkadot_messages_to_kusama.rs @@ -23,7 +23,7 @@ use frame_support::weights::Weight; use messages_relay::relay_strategy::MixStrategy; use relay_kusama_client::Kusama; use relay_polkadot_client::Polkadot; -use relay_substrate_client::{Client, TransactionSignScheme, UnsignedTransaction}; +use relay_substrate_client::{Client, SignParam, TransactionSignScheme, UnsignedTransaction}; use substrate_relay_helper::messages_lane::SubstrateMessageLane; /// Description of Polkadot -> Kusama messages bridge. @@ -69,14 +69,17 @@ pub(crate) async fn update_kusama_to_polkadot_conversion_rate( ) -> anyhow::Result<()> { let genesis_hash = *client.genesis_hash(); let signer_id = (*signer.public().as_array_ref()).into(); + let (spec_version, transaction_version) = client.simple_runtime_version().await?; client .submit_signed_extrinsic(signer_id, move |_, transaction_nonce| { Bytes( - Polkadot::sign_transaction( + Polkadot::sign_transaction(SignParam { + spec_version, + transaction_version, genesis_hash, - &signer, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new( + signer, + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new( relay_polkadot_client::runtime::Call::BridgeKusamaMessages( relay_polkadot_client::runtime::BridgeKusamaMessagesCall::update_pallet_parameter( relay_polkadot_client::runtime::BridgeKusamaMessagesParameter::KusamaToPolkadotConversionRate( @@ -85,8 +88,8 @@ pub(crate) async fn update_kusama_to_polkadot_conversion_rate( ) ), transaction_nonce, - ), - ) + ) + }) .encode(), ) }) diff --git a/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs b/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs index b6e85a7dec79f..4c7ad8e621913 100644 --- a/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs +++ b/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs @@ -22,7 +22,7 @@ use sp_core::{Bytes, Pair}; use messages_relay::relay_strategy::MixStrategy; use relay_millau_client::Millau; use relay_rialto_client::Rialto; -use relay_substrate_client::{Client, TransactionSignScheme, UnsignedTransaction}; +use relay_substrate_client::{Client, SignParam, TransactionSignScheme, UnsignedTransaction}; use substrate_relay_helper::messages_lane::{ DirectReceiveMessagesDeliveryProofCallBuilder, DirectReceiveMessagesProofCallBuilder, SubstrateMessageLane, @@ -66,14 +66,17 @@ pub(crate) async fn update_millau_to_rialto_conversion_rate( ) -> anyhow::Result<()> { let genesis_hash = *client.genesis_hash(); let signer_id = (*signer.public().as_array_ref()).into(); + let (spec_version, transaction_version) = client.simple_runtime_version().await?; client .submit_signed_extrinsic(signer_id, move |_, transaction_nonce| { Bytes( - Rialto::sign_transaction( + Rialto::sign_transaction(SignParam { + spec_version, + transaction_version, genesis_hash, - &signer, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new( + signer, + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new( rialto_runtime::MessagesCall::update_pallet_parameter { parameter: rialto_runtime::millau_messages::RialtoToMillauMessagesParameter::MillauToRialtoConversionRate( sp_runtime::FixedU128::from_float(updated_rate), @@ -81,8 +84,8 @@ pub(crate) async fn update_millau_to_rialto_conversion_rate( } .into(), transaction_nonce, - ), - ) + ) + }) .encode(), ) }) diff --git a/bridges/relays/bin-substrate/src/cli/bridge.rs b/bridges/relays/bin-substrate/src/cli/bridge.rs index 2eb836a84a753..ea16c92c9203a 100644 --- a/bridges/relays/bin-substrate/src/cli/bridge.rs +++ b/bridges/relays/bin-substrate/src/cli/bridge.rs @@ -77,6 +77,11 @@ macro_rules! select_full_bridge { #[allow(unused_imports)] use millau_runtime::millau_to_rialto_account_ownership_digest as account_ownership_digest; + #[allow(dead_code)] + const SOURCE_RUNTIME_VERSION: Option = Some(millau_runtime::VERSION); + #[allow(dead_code)] + const TARGET_RUNTIME_VERSION: Option = Some(rialto_runtime::VERSION); + $generic } FullBridge::RialtoToMillau => { @@ -100,6 +105,11 @@ macro_rules! select_full_bridge { #[allow(unused_imports)] use rialto_runtime::rialto_to_millau_account_ownership_digest as account_ownership_digest; + #[allow(dead_code)] + const SOURCE_RUNTIME_VERSION: Option = Some(rialto_runtime::VERSION); + #[allow(dead_code)] + const TARGET_RUNTIME_VERSION: Option = Some(millau_runtime::VERSION); + $generic } FullBridge::RococoToWococo => { @@ -122,6 +132,11 @@ macro_rules! select_full_bridge { #[allow(unused_imports)] use relay_rococo_client::runtime::rococo_to_wococo_account_ownership_digest as account_ownership_digest; + #[allow(dead_code)] + const SOURCE_RUNTIME_VERSION: Option = Some(bp_rococo::VERSION); + #[allow(dead_code)] + const TARGET_RUNTIME_VERSION: Option = Some(bp_wococo::VERSION); + $generic } FullBridge::WococoToRococo => { @@ -144,6 +159,11 @@ macro_rules! select_full_bridge { #[allow(unused_imports)] use relay_wococo_client::runtime::wococo_to_rococo_account_ownership_digest as account_ownership_digest; + #[allow(dead_code)] + const SOURCE_RUNTIME_VERSION: Option = Some(bp_wococo::VERSION); + #[allow(dead_code)] + const TARGET_RUNTIME_VERSION: Option = Some(bp_rococo::VERSION); + $generic } FullBridge::KusamaToPolkadot => { @@ -166,6 +186,11 @@ macro_rules! select_full_bridge { #[allow(unused_imports)] use relay_kusama_client::runtime::kusama_to_polkadot_account_ownership_digest as account_ownership_digest; + #[allow(dead_code)] + const SOURCE_RUNTIME_VERSION: Option = Some(bp_kusama::VERSION); + #[allow(dead_code)] + const TARGET_RUNTIME_VERSION: Option = Some(bp_polkadot::VERSION); + $generic } FullBridge::PolkadotToKusama => { @@ -188,6 +213,11 @@ macro_rules! select_full_bridge { #[allow(unused_imports)] use relay_polkadot_client::runtime::polkadot_to_kusama_account_ownership_digest as account_ownership_digest; + #[allow(dead_code)] + const SOURCE_RUNTIME_VERSION: Option = Some(bp_polkadot::VERSION); + #[allow(dead_code)] + const TARGET_RUNTIME_VERSION: Option = Some(bp_kusama::VERSION); + $generic } } diff --git a/bridges/relays/bin-substrate/src/cli/estimate_fee.rs b/bridges/relays/bin-substrate/src/cli/estimate_fee.rs index d063ce544cd24..18e7341fc9658 100644 --- a/bridges/relays/bin-substrate/src/cli/estimate_fee.rs +++ b/bridges/relays/bin-substrate/src/cli/estimate_fee.rs @@ -46,7 +46,7 @@ impl EstimateFee { let Self { source, bridge, lane, payload } = self; select_full_bridge!(bridge, { - let source_client = source.to_client::().await?; + let source_client = source.to_client::(SOURCE_RUNTIME_VERSION).await?; let lane = lane.into(); let payload = Source::encode_message(payload).map_err(|e| anyhow::format_err!("{:?}", e))?; @@ -86,7 +86,7 @@ pub(crate) async fn estimate_message_delivery_and_dispatch_fee { type Source = relay_millau_client::Millau; type Target = relay_rialto_client::Rialto; + const SOURCE_RUNTIME_VERSION: Option = + Some(millau_runtime::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(rialto_runtime::VERSION); fn encode_init_bridge( init_data: InitializationData<::Header>, @@ -74,6 +78,10 @@ macro_rules! select_bridge { InitBridgeName::RialtoToMillau => { type Source = relay_rialto_client::Rialto; type Target = relay_millau_client::Millau; + const SOURCE_RUNTIME_VERSION: Option = + Some(rialto_runtime::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(millau_runtime::VERSION); fn encode_init_bridge( init_data: InitializationData<::Header>, @@ -92,6 +100,10 @@ macro_rules! select_bridge { InitBridgeName::WestendToMillau => { type Source = relay_westend_client::Westend; type Target = relay_millau_client::Millau; + const SOURCE_RUNTIME_VERSION: Option = + Some(bp_westend::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(millau_runtime::VERSION); fn encode_init_bridge( init_data: InitializationData<::Header>, @@ -114,6 +126,10 @@ macro_rules! select_bridge { InitBridgeName::RococoToWococo => { type Source = relay_rococo_client::Rococo; type Target = relay_wococo_client::Wococo; + const SOURCE_RUNTIME_VERSION: Option = + Some(bp_rococo::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(bp_wococo::VERSION); fn encode_init_bridge( init_data: InitializationData<::Header>, @@ -130,6 +146,10 @@ macro_rules! select_bridge { InitBridgeName::WococoToRococo => { type Source = relay_wococo_client::Wococo; type Target = relay_rococo_client::Rococo; + const SOURCE_RUNTIME_VERSION: Option = + Some(bp_wococo::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(bp_rococo::VERSION); fn encode_init_bridge( init_data: InitializationData<::Header>, @@ -146,6 +166,10 @@ macro_rules! select_bridge { InitBridgeName::KusamaToPolkadot => { type Source = relay_kusama_client::Kusama; type Target = relay_polkadot_client::Polkadot; + const SOURCE_RUNTIME_VERSION: Option = + Some(bp_kusama::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(bp_polkadot::VERSION); fn encode_init_bridge( init_data: InitializationData<::Header>, @@ -162,6 +186,10 @@ macro_rules! select_bridge { InitBridgeName::PolkadotToKusama => { type Source = relay_polkadot_client::Polkadot; type Target = relay_kusama_client::Kusama; + const SOURCE_RUNTIME_VERSION: Option = + Some(bp_polkadot::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(bp_kusama::VERSION); fn encode_init_bridge( init_data: InitializationData<::Header>, @@ -183,25 +211,29 @@ impl InitBridge { /// Run the command. pub async fn run(self) -> anyhow::Result<()> { select_bridge!(self.bridge, { - let source_client = self.source.to_client::().await?; - let target_client = self.target.to_client::().await?; + let source_client = self.source.to_client::(SOURCE_RUNTIME_VERSION).await?; + let target_client = self.target.to_client::(TARGET_RUNTIME_VERSION).await?; let target_sign = self.target_sign.to_keypair::()?; + let (spec_version, transaction_version) = + target_client.simple_runtime_version().await?; substrate_relay_helper::headers_initialize::initialize( source_client, target_client.clone(), target_sign.public().into(), move |transaction_nonce, initialization_data| { Bytes( - Target::sign_transaction( - *target_client.genesis_hash(), - &target_sign, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new( + Target::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: *target_client.genesis_hash(), + signer: target_sign, + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new( encode_init_bridge(initialization_data), transaction_nonce, ), - ) + }) .encode(), ) }, diff --git a/bridges/relays/bin-substrate/src/cli/mod.rs b/bridges/relays/bin-substrate/src/cli/mod.rs index ae167334d8292..2a087e59b62a6 100644 --- a/bridges/relays/bin-substrate/src/cli/mod.rs +++ b/bridges/relays/bin-substrate/src/cli/mod.rs @@ -18,10 +18,13 @@ use std::convert::TryInto; -use bp_messages::LaneId; use codec::{Decode, Encode}; +use relay_substrate_client::ChainRuntimeVersion; use sp_runtime::app_crypto::Ss58Codec; use structopt::{clap::arg_enum, StructOpt}; +use strum::{EnumString, EnumVariantNames}; + +use bp_messages::LaneId; pub(crate) mod bridge; pub(crate) mod encode_call; @@ -364,6 +367,17 @@ where } } +#[doc = "Runtime version params."] +#[derive(StructOpt, Debug, PartialEq, Eq, Clone, EnumString, EnumVariantNames)] +pub enum RuntimeVersionType { + /// Auto query version from chain + Auto, + /// Custom `spec_version` and `transaction_version` + Custom, + /// Read version from bundle dependencies directly. + Bundle, +} + /// Create chain-specific set of configuration objects: connection parameters, /// signing parameters and bridge initialization parameters. #[macro_export] @@ -382,6 +396,23 @@ macro_rules! declare_chain_options { #[doc = "Use secure websocket connection."] #[structopt(long)] pub [<$chain_prefix _secure>]: bool, + #[doc = "Custom runtime version"] + #[structopt(flatten)] + pub [<$chain_prefix _runtime_version>]: [<$chain RuntimeVersionParams>], + } + + #[doc = $chain " runtime version params."] + #[derive(StructOpt, Debug, PartialEq, Eq, Clone)] + pub struct [<$chain RuntimeVersionParams>] { + #[doc = "The type of runtime version for chain " $chain] + #[structopt(long, default_value = "Bundle")] + pub [<$chain_prefix _version_mode>]: RuntimeVersionType, + #[doc = "The custom sepc_version for chain " $chain] + #[structopt(long)] + pub [<$chain_prefix _spec_version>]: Option, + #[doc = "The custom transaction_version for chain " $chain] + #[structopt(long)] + pub [<$chain_prefix _transaction_version>]: Option, } #[doc = $chain " signing params."] @@ -500,11 +531,36 @@ macro_rules! declare_chain_options { /// Convert connection params into Substrate client. pub async fn to_client( &self, + bundle_runtime_version: Option ) -> anyhow::Result> { + let runtime_version_params = &self.[<$chain_prefix _runtime_version>]; + let chain_runtime_version = match runtime_version_params.[<$chain_prefix _version_mode>] { + RuntimeVersionType::Auto => ChainRuntimeVersion::Auto, + RuntimeVersionType::Custom => { + let except_spec_version = runtime_version_params.[<$chain_prefix _spec_version>] + .ok_or(anyhow::Error::msg(format!("The {}-spec-version is required when choose custom mode", stringify!($chain_prefix))))?; + let except_transaction_version = runtime_version_params.[<$chain_prefix _transaction_version>] + .ok_or(anyhow::Error::msg(format!("The {}-transaction-version is required when choose custom mode", stringify!($chain_prefix))))?; + ChainRuntimeVersion::Custom( + except_spec_version, + except_transaction_version + ) + } + RuntimeVersionType::Bundle => { + match bundle_runtime_version { + Some(runtime_version) => ChainRuntimeVersion::Custom( + runtime_version.spec_version, + runtime_version.transaction_version + ), + None => ChainRuntimeVersion::Auto + } + } + }; Ok(relay_substrate_client::Client::new(relay_substrate_client::ConnectionParams { host: self.[<$chain_prefix _host>].clone(), port: self.[<$chain_prefix _port>], secure: self.[<$chain_prefix _secure>], + chain_runtime_version, }) .await ) @@ -521,9 +577,10 @@ declare_chain_options!(Parachain, parachain); #[cfg(test)] mod tests { - use sp_core::Pair; use std::str::FromStr; + use sp_core::Pair; + use super::*; #[test] diff --git a/bridges/relays/bin-substrate/src/cli/register_parachain.rs b/bridges/relays/bin-substrate/src/cli/register_parachain.rs index fecc431148ebd..57e0517a56601 100644 --- a/bridges/relays/bin-substrate/src/cli/register_parachain.rs +++ b/bridges/relays/bin-substrate/src/cli/register_parachain.rs @@ -29,7 +29,7 @@ use polkadot_runtime_common::{ }; use polkadot_runtime_parachains::paras::ParaLifecycle; use relay_substrate_client::{ - AccountIdOf, CallOf, Chain, Client, TransactionSignScheme, UnsignedTransaction, + AccountIdOf, CallOf, Chain, Client, SignParam, TransactionSignScheme, UnsignedTransaction, }; use rialto_runtime::SudoCall; use sp_core::{ @@ -83,6 +83,11 @@ macro_rules! select_bridge { use bp_rialto::{PARAS_PALLET_NAME, PARAS_REGISTRAR_PALLET_NAME}; + const RELAY_CHAIN_RUNTIME_VERSION: Option = + Some(rialto_runtime::VERSION); + const PARA_CHAIN_RUNTIME_VERSION: Option = + Some(rialto_parachain_runtime::VERSION); + $generic }, } @@ -93,9 +98,13 @@ impl RegisterParachain { /// Run the command. pub async fn run(self) -> anyhow::Result<()> { select_bridge!(self.parachain, { - let relay_client = self.relay_connection.to_client::().await?; + let relay_client = self + .relay_connection + .to_client::(RELAY_CHAIN_RUNTIME_VERSION) + .await?; let relay_sign = self.relay_sign.to_keypair::()?; - let para_client = self.para_connection.to_client::().await?; + let para_client = + self.para_connection.to_client::(PARA_CHAIN_RUNTIME_VERSION).await?; // hopefully we're the only actor that is registering parachain right now // => read next parachain id @@ -116,21 +125,24 @@ impl RegisterParachain { let reserve_parachain_id_call: CallOf = ParaRegistrarCall::reserve {}.into(); let reserve_parachain_signer = relay_sign.clone(); + let (spec_version, transaction_version) = relay_client.simple_runtime_version().await?; wait_until_transaction_is_finalized::( relay_client .submit_and_watch_signed_extrinsic( relay_sudo_account.clone(), move |_, transaction_nonce| { Bytes( - Relaychain::sign_transaction( - relay_genesis_hash, - &reserve_parachain_signer, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new( + Relaychain::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: relay_genesis_hash, + signer: reserve_parachain_signer, + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new( reserve_parachain_id_call, transaction_nonce, ), - ) + }) .encode(), ) }, @@ -169,15 +181,17 @@ impl RegisterParachain { relay_sudo_account.clone(), move |_, transaction_nonce| { Bytes( - Relaychain::sign_transaction( - relay_genesis_hash, - ®ister_parathread_signer, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new( + Relaychain::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: relay_genesis_hash, + signer: register_parathread_signer, + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new( register_parathread_call, transaction_nonce, ), - ) + }) .encode(), ) }, @@ -229,12 +243,14 @@ impl RegisterParachain { relay_client .submit_signed_extrinsic(relay_sudo_account.clone(), move |_, transaction_nonce| { Bytes( - Relaychain::sign_transaction( - relay_genesis_hash, - &force_lease_signer, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new(force_lease_call, transaction_nonce), - ) + Relaychain::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: relay_genesis_hash, + signer: force_lease_signer, + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new(force_lease_call, transaction_nonce), + }) .encode(), ) }) @@ -292,6 +308,9 @@ async fn wait_para_state( #[cfg(test)] mod tests { use super::*; + use crate::cli::{ + ParachainRuntimeVersionParams, RelaychainRuntimeVersionParams, RuntimeVersionType, + }; #[test] fn register_rialto_parachain() { @@ -327,6 +346,11 @@ mod tests { relaychain_host: "127.0.0.1".into(), relaychain_port: 9944, relaychain_secure: false, + relaychain_runtime_version: RelaychainRuntimeVersionParams { + relaychain_version_mode: RuntimeVersionType::Bundle, + relaychain_spec_version: None, + relaychain_transaction_version: None, + } }, relay_sign: RelaychainSigningParams { relaychain_signer: Some("//Alice".into()), @@ -339,6 +363,11 @@ mod tests { parachain_host: "127.0.0.1".into(), parachain_port: 11949, parachain_secure: false, + parachain_runtime_version: ParachainRuntimeVersionParams { + parachain_version_mode: RuntimeVersionType::Bundle, + parachain_spec_version: None, + parachain_transaction_version: None, + } }, } ); diff --git a/bridges/relays/bin-substrate/src/cli/relay_headers.rs b/bridges/relays/bin-substrate/src/cli/relay_headers.rs index 43def352a4d1d..4b17a56819c80 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_headers.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_headers.rs @@ -64,6 +64,10 @@ macro_rules! select_bridge { type Source = relay_millau_client::Millau; type Target = relay_rialto_client::Rialto; type Finality = crate::chains::millau_headers_to_rialto::MillauFinalityToRialto; + const SOURCE_RUNTIME_VERSION: Option = + Some(millau_runtime::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(rialto_runtime::VERSION); $generic }, @@ -71,6 +75,10 @@ macro_rules! select_bridge { type Source = relay_rialto_client::Rialto; type Target = relay_millau_client::Millau; type Finality = crate::chains::rialto_headers_to_millau::RialtoFinalityToMillau; + const SOURCE_RUNTIME_VERSION: Option = + Some(rialto_runtime::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(millau_runtime::VERSION); $generic }, @@ -78,6 +86,10 @@ macro_rules! select_bridge { type Source = relay_westend_client::Westend; type Target = relay_millau_client::Millau; type Finality = crate::chains::westend_headers_to_millau::WestendFinalityToMillau; + const SOURCE_RUNTIME_VERSION: Option = + Some(bp_westend::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(millau_runtime::VERSION); $generic }, @@ -85,6 +97,10 @@ macro_rules! select_bridge { type Source = relay_rococo_client::Rococo; type Target = relay_wococo_client::Wococo; type Finality = crate::chains::rococo_headers_to_wococo::RococoFinalityToWococo; + const SOURCE_RUNTIME_VERSION: Option = + Some(bp_rococo::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(bp_wococo::VERSION); $generic }, @@ -92,6 +108,10 @@ macro_rules! select_bridge { type Source = relay_wococo_client::Wococo; type Target = relay_rococo_client::Rococo; type Finality = crate::chains::wococo_headers_to_rococo::WococoFinalityToRococo; + const SOURCE_RUNTIME_VERSION: Option = + Some(bp_wococo::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(bp_rococo::VERSION); $generic }, @@ -99,6 +119,10 @@ macro_rules! select_bridge { type Source = relay_kusama_client::Kusama; type Target = relay_polkadot_client::Polkadot; type Finality = crate::chains::kusama_headers_to_polkadot::KusamaFinalityToPolkadot; + const SOURCE_RUNTIME_VERSION: Option = + Some(bp_kusama::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(bp_polkadot::VERSION); $generic }, @@ -106,6 +130,10 @@ macro_rules! select_bridge { type Source = relay_polkadot_client::Polkadot; type Target = relay_kusama_client::Kusama; type Finality = crate::chains::polkadot_headers_to_kusama::PolkadotFinalityToKusama; + const SOURCE_RUNTIME_VERSION: Option = + Some(bp_polkadot::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(bp_kusama::VERSION); $generic }, @@ -117,8 +145,8 @@ impl RelayHeaders { /// Run the command. pub async fn run(self) -> anyhow::Result<()> { select_bridge!(self.bridge, { - let source_client = self.source.to_client::().await?; - let target_client = self.target.to_client::().await?; + let source_client = self.source.to_client::(SOURCE_RUNTIME_VERSION).await?; + let target_client = self.target.to_client::(TARGET_RUNTIME_VERSION).await?; let target_transactions_mortality = self.target_sign.target_transactions_mortality; let target_sign = self.target_sign.to_keypair::()?; diff --git a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages.rs b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages.rs index 112d2f419bda3..3804513acdb7a 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages.rs @@ -29,7 +29,8 @@ use strum::VariantNames; use codec::Encode; use messages_relay::relay_strategy::MixStrategy; use relay_substrate_client::{ - AccountIdOf, CallOf, Chain, Client, TransactionSignScheme, UnsignedTransaction, + AccountIdOf, CallOf, Chain, ChainRuntimeVersion, Client, SignParam, TransactionSignScheme, + UnsignedTransaction, }; use relay_utils::metrics::MetricsParams; use sp_core::{Bytes, Pair}; @@ -39,7 +40,7 @@ use substrate_relay_helper::{ }; use crate::{ - cli::{relay_messages::RelayerMode, CliChain, HexLaneId, PrometheusParams}, + cli::{relay_messages::RelayerMode, CliChain, HexLaneId, PrometheusParams, RuntimeVersionType}, declare_chain_options, }; @@ -136,6 +137,10 @@ macro_rules! select_bridge { bp_millau::SESSION_LENGTH; const MAX_MISSING_RIGHT_HEADERS_AT_LEFT: bp_rialto::BlockNumber = bp_rialto::SESSION_LENGTH; + const LEFT_RUNTIME_VERSION: Option = + Some(millau_runtime::VERSION); + const RIGHT_RUNTIME_VERSION: Option = + Some(rialto_runtime::VERSION); use crate::chains::{ millau_messages_to_rialto::{ @@ -185,6 +190,11 @@ macro_rules! select_bridge { const MAX_MISSING_RIGHT_HEADERS_AT_LEFT: bp_wococo::BlockNumber = bp_wococo::SESSION_LENGTH; + const LEFT_RUNTIME_VERSION: Option = + Some(bp_rococo::VERSION); + const RIGHT_RUNTIME_VERSION: Option = + Some(bp_wococo::VERSION); + use crate::chains::{ rococo_messages_to_wococo::RococoMessagesToWococo as LeftToRightMessageLane, wococo_messages_to_rococo::WococoMessagesToRococo as RightToLeftMessageLane, @@ -263,6 +273,11 @@ macro_rules! select_bridge { const MAX_MISSING_RIGHT_HEADERS_AT_LEFT: bp_polkadot::BlockNumber = bp_polkadot::SESSION_LENGTH; + const LEFT_RUNTIME_VERSION: Option = + Some(bp_kusama::VERSION); + const RIGHT_RUNTIME_VERSION: Option = + Some(bp_polkadot::VERSION); + use crate::chains::{ kusama_messages_to_polkadot::{ update_polkadot_to_kusama_conversion_rate as update_right_to_left_conversion_rate, @@ -334,12 +349,12 @@ impl RelayHeadersAndMessages { select_bridge!(self, { let params: Params = self.into(); - let left_client = params.left.to_client::().await?; + let left_client = params.left.to_client::(LEFT_RUNTIME_VERSION).await?; let left_transactions_mortality = params.left_sign.transactions_mortality()?; let left_sign = params.left_sign.to_keypair::()?; let left_messages_pallet_owner = params.left_messages_pallet_owner.to_keypair::()?; - let right_client = params.right.to_client::().await?; + let right_client = params.right.to_client::(RIGHT_RUNTIME_VERSION).await?; let right_transactions_mortality = params.right_sign.transactions_mortality()?; let right_sign = params.right_sign.to_keypair::()?; let right_messages_pallet_owner = @@ -591,15 +606,18 @@ where CallOf: Send, { let genesis_hash = *client.genesis_hash(); + let (spec_version, transaction_version) = client.simple_runtime_version().await?; client .submit_signed_extrinsic(sign.public().into(), move |_, transaction_nonce| { Bytes( - C::sign_transaction( + C::sign_transaction(SignParam { + spec_version, + transaction_version, genesis_hash, - &sign, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new(call, transaction_nonce), - ) + signer: sign, + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new(call, transaction_nonce), + }) .encode(), ) }) diff --git a/bridges/relays/bin-substrate/src/cli/relay_messages.rs b/bridges/relays/bin-substrate/src/cli/relay_messages.rs index 45087fad5eb3f..521d00d50a91f 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_messages.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_messages.rs @@ -75,10 +75,10 @@ impl RelayMessages { /// Run the command. pub async fn run(self) -> anyhow::Result<()> { select_full_bridge!(self.bridge, { - let source_client = self.source.to_client::().await?; + let source_client = self.source.to_client::(SOURCE_RUNTIME_VERSION).await?; let source_sign = self.source_sign.to_keypair::()?; let source_transactions_mortality = self.source_sign.transactions_mortality()?; - let target_client = self.target.to_client::().await?; + let target_client = self.target.to_client::(TARGET_RUNTIME_VERSION).await?; let target_sign = self.target_sign.to_keypair::()?; let target_transactions_mortality = self.target_sign.transactions_mortality()?; let relayer_mode = self.relayer_mode.into(); diff --git a/bridges/relays/bin-substrate/src/cli/resubmit_transactions.rs b/bridges/relays/bin-substrate/src/cli/resubmit_transactions.rs index 64663d7e8ec02..8b021df86372d 100644 --- a/bridges/relays/bin-substrate/src/cli/resubmit_transactions.rs +++ b/bridges/relays/bin-substrate/src/cli/resubmit_transactions.rs @@ -19,7 +19,8 @@ use crate::cli::{Balance, TargetConnectionParams, TargetSigningParams}; use codec::{Decode, Encode}; use num_traits::{One, Zero}; use relay_substrate_client::{ - BlockWithJustification, Chain, Client, Error as SubstrateError, HeaderOf, TransactionSignScheme, + BlockWithJustification, Chain, Client, Error as SubstrateError, HeaderOf, SignParam, + TransactionSignScheme, }; use relay_utils::FailedClient; use sp_core::Bytes; @@ -90,18 +91,24 @@ macro_rules! select_bridge { RelayChain::Millau => { type Target = relay_millau_client::Millau; type TargetSign = relay_millau_client::Millau; + const TARGET_RUNTIME_VERSION: Option = + Some(millau_runtime::VERSION); $generic }, RelayChain::Kusama => { type Target = relay_kusama_client::Kusama; type TargetSign = relay_kusama_client::Kusama; + const TARGET_RUNTIME_VERSION: Option = + Some(bp_kusama::VERSION); $generic }, RelayChain::Polkadot => { type Target = relay_polkadot_client::Polkadot; type TargetSign = relay_polkadot_client::Polkadot; + const TARGET_RUNTIME_VERSION: Option = + Some(bp_polkadot::VERSION); $generic }, @@ -114,7 +121,7 @@ impl ResubmitTransactions { pub async fn run(self) -> anyhow::Result<()> { select_bridge!(self.chain, { let relay_loop_name = format!("ResubmitTransactions{}", Target::NAME); - let client = self.target.to_client::().await?; + let client = self.target.to_client::(TARGET_RUNTIME_VERSION).await?; let key_pair = self.target_sign.to_keypair::()?; relay_utils::relay_loop((), client) @@ -411,6 +418,7 @@ async fn update_transaction_tip>( })?; let old_tip = unsigned_tx.tip; + let (spec_version, transaction_version) = client.simple_runtime_version().await?; while current_priority < target_priority { let next_tip = unsigned_tx.tip + tip_step; if next_tip > tip_limit { @@ -430,12 +438,14 @@ async fn update_transaction_tip>( current_priority = client .validate_transaction( at_block, - S::sign_transaction( - *client.genesis_hash(), - key_pair, - relay_substrate_client::TransactionEra::immortal(), - unsigned_tx.clone(), - ), + S::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: *client.genesis_hash(), + signer: key_pair.clone(), + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: unsigned_tx.clone(), + }), ) .await?? .priority; @@ -451,12 +461,14 @@ async fn update_transaction_tip>( Ok(( old_tip != unsigned_tx.tip, - S::sign_transaction( - *client.genesis_hash(), - key_pair, - relay_substrate_client::TransactionEra::immortal(), - unsigned_tx, - ), + S::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: *client.genesis_hash(), + signer: key_pair.clone(), + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: unsigned_tx, + }), )) } diff --git a/bridges/relays/bin-substrate/src/cli/send_message.rs b/bridges/relays/bin-substrate/src/cli/send_message.rs index 5c403f6c23a95..52eab9c64ec98 100644 --- a/bridges/relays/bin-substrate/src/cli/send_message.rs +++ b/bridges/relays/bin-substrate/src/cli/send_message.rs @@ -25,7 +25,7 @@ use bp_message_dispatch::{CallOrigin, MessagePayload}; use bp_runtime::{BalanceOf, Chain as _}; use codec::Encode; use frame_support::weights::Weight; -use relay_substrate_client::{Chain, TransactionSignScheme, UnsignedTransaction}; +use relay_substrate_client::{Chain, SignParam, TransactionSignScheme, UnsignedTransaction}; use sp_core::{Bytes, Pair}; use sp_runtime::{traits::IdentifyAccount, AccountId32, MultiSignature, MultiSigner}; use std::fmt::Debug; @@ -154,7 +154,7 @@ impl SendMessage { crate::select_full_bridge!(self.bridge, { let payload = self.encode_payload()?; - let source_client = self.source.to_client::().await?; + let source_client = self.source.to_client::(SOURCE_RUNTIME_VERSION).await?; let source_sign = self.source_sign.to_keypair::()?; let lane = self.lane.clone().into(); @@ -179,25 +179,31 @@ impl SendMessage { })?; let source_genesis_hash = *source_client.genesis_hash(); + let (spec_version, transaction_version) = + source_client.simple_runtime_version().await?; let estimated_transaction_fee = source_client .estimate_extrinsic_fee(Bytes( - Source::sign_transaction( - source_genesis_hash, - &source_sign, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new(send_message_call.clone(), 0), - ) + Source::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: source_genesis_hash, + signer: source_sign.clone(), + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new(send_message_call.clone(), 0), + }) .encode(), )) .await?; source_client .submit_signed_extrinsic(source_sign.public().into(), move |_, transaction_nonce| { - let signed_source_call = Source::sign_transaction( - source_genesis_hash, - &source_sign, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new(send_message_call, transaction_nonce), - ) + let signed_source_call = Source::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: source_genesis_hash, + signer: source_sign.clone(), + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new(send_message_call, transaction_nonce), + }) .encode(); log::info!( diff --git a/bridges/relays/bin-substrate/src/cli/swap_tokens.rs b/bridges/relays/bin-substrate/src/cli/swap_tokens.rs index dbe46f4690709..18f4c1a46bc38 100644 --- a/bridges/relays/bin-substrate/src/cli/swap_tokens.rs +++ b/bridges/relays/bin-substrate/src/cli/swap_tokens.rs @@ -29,8 +29,8 @@ use strum::{EnumString, EnumVariantNames, VariantNames}; use frame_support::dispatch::GetDispatchInfo; use relay_substrate_client::{ AccountIdOf, AccountPublicOf, BalanceOf, BlockNumberOf, CallOf, Chain, ChainWithBalances, - Client, Error as SubstrateError, HashOf, SignatureOf, Subscription, TransactionSignScheme, - TransactionStatusOf, UnsignedTransaction, + Client, Error as SubstrateError, HashOf, SignParam, SignatureOf, Subscription, + TransactionSignScheme, TransactionStatusOf, UnsignedTransaction, }; use sp_core::{blake2_256, storage::StorageKey, Bytes, Pair, H256, U256}; use sp_runtime::traits::{Convert, Header as HeaderT}; @@ -98,6 +98,13 @@ macro_rules! select_bridge { SwapTokensBridge::MillauToRialto => { type Source = relay_millau_client::Millau; type Target = relay_rialto_client::Rialto; + const SOURCE_SPEC_VERSION: u32 = millau_runtime::VERSION.spec_version; + const TARGET_SPEC_VERSION: u32 = rialto_runtime::VERSION.spec_version; + + const SOURCE_RUNTIME_VERSION: Option = + Some(millau_runtime::VERSION); + const TARGET_RUNTIME_VERSION: Option = + Some(rialto_runtime::VERSION); type FromSwapToThisAccountIdConverter = bp_rialto::AccountIdConverter; @@ -114,9 +121,6 @@ macro_rules! select_bridge { const SOURCE_CHAIN_ID: bp_runtime::ChainId = bp_runtime::MILLAU_CHAIN_ID; const TARGET_CHAIN_ID: bp_runtime::ChainId = bp_runtime::RIALTO_CHAIN_ID; - const SOURCE_SPEC_VERSION: u32 = millau_runtime::VERSION.spec_version; - const TARGET_SPEC_VERSION: u32 = rialto_runtime::VERSION.spec_version; - const SOURCE_TO_TARGET_LANE_ID: bp_messages::LaneId = *b"swap"; const TARGET_TO_SOURCE_LANE_ID: bp_messages::LaneId = [0, 0, 0, 0]; @@ -130,9 +134,9 @@ impl SwapTokens { /// Run the command. pub async fn run(self) -> anyhow::Result<()> { select_bridge!(self.bridge, { - let source_client = self.source.to_client::().await?; + let source_client = self.source.to_client::(SOURCE_RUNTIME_VERSION).await?; let source_sign = self.source_sign.to_keypair::()?; - let target_client = self.target.to_client::().await?; + let target_client = self.target.to_client::(TARGET_RUNTIME_VERSION).await?; let target_sign = self.target_sign.to_keypair::()?; // names of variables in this function are matching names used by the @@ -234,18 +238,25 @@ impl SwapTokens { // start tokens swap let source_genesis_hash = *source_client.genesis_hash(); let create_swap_signer = source_sign.clone(); + let (spec_version, transaction_version) = + source_client.simple_runtime_version().await?; let swap_created_at = wait_until_transaction_is_finalized::( source_client .submit_and_watch_signed_extrinsic( accounts.source_account_at_this_chain.clone(), move |_, transaction_nonce| { Bytes( - Source::sign_transaction( - source_genesis_hash, - &create_swap_signer, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new(create_swap_call, transaction_nonce), - ) + Source::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: source_genesis_hash, + signer: create_swap_signer, + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new( + create_swap_call, + transaction_nonce, + ), + }) .encode(), ) }, @@ -369,21 +380,25 @@ impl SwapTokens { // send `claim_swap` message let target_genesis_hash = *target_client.genesis_hash(); + let (spec_version, transaction_version) = + target_client.simple_runtime_version().await?; let _ = wait_until_transaction_is_finalized::( target_client .submit_and_watch_signed_extrinsic( accounts.target_account_at_bridged_chain.clone(), move |_, transaction_nonce| { Bytes( - Target::sign_transaction( - target_genesis_hash, - &target_sign, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new( + Target::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: target_genesis_hash, + signer: target_sign, + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new( send_message_call, transaction_nonce, ), - ) + }) .encode(), ) }, @@ -409,21 +424,25 @@ impl SwapTokens { log::info!(target: "bridge", "Cancelling the swap"); let cancel_swap_call: CallOf = pallet_bridge_token_swap::Call::cancel_swap { swap: token_swap.clone() }.into(); + let (spec_version, transaction_version) = + source_client.simple_runtime_version().await?; let _ = wait_until_transaction_is_finalized::( source_client .submit_and_watch_signed_extrinsic( accounts.source_account_at_this_chain.clone(), move |_, transaction_nonce| { Bytes( - Source::sign_transaction( - source_genesis_hash, - &source_sign, - relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new( + Source::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: source_genesis_hash, + signer: source_sign, + era: relay_substrate_client::TransactionEra::immortal(), + unsigned: UnsignedTransaction::new( cancel_swap_call, transaction_nonce, ), - ) + }) .encode(), ) }, @@ -673,6 +692,7 @@ async fn read_token_swap_state( #[cfg(test)] mod tests { use super::*; + use crate::cli::{RuntimeVersionType, SourceRuntimeVersionParams, TargetRuntimeVersionParams}; #[test] fn swap_tokens_millau_to_rialto_no_lock() { @@ -706,6 +726,11 @@ mod tests { source_host: "127.0.0.1".into(), source_port: 9000, source_secure: false, + source_runtime_version: SourceRuntimeVersionParams { + source_version_mode: RuntimeVersionType::Bundle, + source_spec_version: None, + source_transaction_version: None, + } }, source_sign: SourceSigningParams { source_signer: Some("//Alice".into()), @@ -718,6 +743,11 @@ mod tests { target_host: "127.0.0.1".into(), target_port: 9001, target_secure: false, + target_runtime_version: TargetRuntimeVersionParams { + target_version_mode: RuntimeVersionType::Bundle, + target_spec_version: None, + target_transaction_version: None, + } }, target_sign: TargetSigningParams { target_signer: Some("//Bob".into()), @@ -767,6 +797,11 @@ mod tests { source_host: "127.0.0.1".into(), source_port: 9000, source_secure: false, + source_runtime_version: SourceRuntimeVersionParams { + source_version_mode: RuntimeVersionType::Bundle, + source_spec_version: None, + source_transaction_version: None, + } }, source_sign: SourceSigningParams { source_signer: Some("//Alice".into()), @@ -779,6 +814,11 @@ mod tests { target_host: "127.0.0.1".into(), target_port: 9001, target_secure: false, + target_runtime_version: TargetRuntimeVersionParams { + target_version_mode: RuntimeVersionType::Bundle, + target_spec_version: None, + target_transaction_version: None, + } }, target_sign: TargetSigningParams { target_signer: Some("//Bob".into()), diff --git a/bridges/relays/client-kusama/src/lib.rs b/bridges/relays/client-kusama/src/lib.rs index 861816bb67390..1054995d65534 100644 --- a/bridges/relays/client-kusama/src/lib.rs +++ b/bridges/relays/client-kusama/src/lib.rs @@ -20,8 +20,8 @@ use bp_messages::MessageNonce; use codec::Encode; use frame_support::weights::Weight; use relay_substrate_client::{ - Chain, ChainBase, ChainWithBalances, ChainWithMessages, TransactionEraOf, - TransactionSignScheme, UnsignedTransaction, + Chain, ChainBase, ChainWithBalances, ChainWithMessages, SignParam, TransactionSignScheme, + UnsignedTransaction, }; use sp_core::{storage::StorageKey, Pair}; use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; @@ -105,26 +105,22 @@ impl TransactionSignScheme for Kusama { type AccountKeyPair = sp_core::sr25519::Pair; type SignedTransaction = crate::runtime::UncheckedExtrinsic; - fn sign_transaction( - genesis_hash: ::Hash, - signer: &Self::AccountKeyPair, - era: TransactionEraOf, - unsigned: UnsignedTransaction, - ) -> Self::SignedTransaction { + fn sign_transaction(param: SignParam) -> Self::SignedTransaction { let raw_payload = SignedPayload::new( - unsigned.call, + param.unsigned.call.clone(), bp_kusama::SignedExtensions::new( - bp_kusama::VERSION, - era, - genesis_hash, - unsigned.nonce, - unsigned.tip, + param.spec_version, + param.transaction_version, + param.era, + param.genesis_hash, + param.unsigned.nonce, + param.unsigned.tip, ), ) .expect("SignedExtension never fails."); - let signature = raw_payload.using_encoded(|payload| signer.sign(payload)); - let signer: sp_runtime::MultiSigner = signer.public().into(); + let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload)); + let signer: sp_runtime::MultiSigner = param.signer.public().into(); let (call, extra, _) = raw_payload.deconstruct(); bp_kusama::UncheckedExtrinsic::new_signed( diff --git a/bridges/relays/client-millau/src/lib.rs b/bridges/relays/client-millau/src/lib.rs index 96a046ef5cdc2..392f3fe118c53 100644 --- a/bridges/relays/client-millau/src/lib.rs +++ b/bridges/relays/client-millau/src/lib.rs @@ -20,7 +20,7 @@ use bp_messages::MessageNonce; use codec::{Compact, Decode, Encode}; use frame_support::weights::Weight; use relay_substrate_client::{ - BalanceOf, Chain, ChainBase, ChainWithBalances, ChainWithMessages, IndexOf, TransactionEraOf, + BalanceOf, Chain, ChainBase, ChainWithBalances, ChainWithMessages, IndexOf, SignParam, TransactionSignScheme, UnsignedTransaction, }; use sp_core::{storage::StorageKey, Pair}; @@ -107,35 +107,30 @@ impl TransactionSignScheme for Millau { type AccountKeyPair = sp_core::sr25519::Pair; type SignedTransaction = millau_runtime::UncheckedExtrinsic; - fn sign_transaction( - genesis_hash: ::Hash, - signer: &Self::AccountKeyPair, - era: TransactionEraOf, - unsigned: UnsignedTransaction, - ) -> Self::SignedTransaction { + fn sign_transaction(param: SignParam) -> Self::SignedTransaction { let raw_payload = SignedPayload::from_raw( - unsigned.call, + param.unsigned.call.clone(), ( frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(era.frame_era()), - frame_system::CheckNonce::::from(unsigned.nonce), + frame_system::CheckEra::::from(param.era.frame_era()), + frame_system::CheckNonce::::from(param.unsigned.nonce), frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(unsigned.tip), + pallet_transaction_payment::ChargeTransactionPayment::::from(param.unsigned.tip), ), ( - millau_runtime::VERSION.spec_version, - millau_runtime::VERSION.transaction_version, - genesis_hash, - era.signed_payload(genesis_hash), + param.spec_version, + param.transaction_version, + param.genesis_hash, + param.era.signed_payload(param.genesis_hash), (), (), (), ), ); - let signature = raw_payload.using_encoded(|payload| signer.sign(payload)); - let signer: sp_runtime::MultiSigner = signer.public().into(); + let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload)); + let signer: sp_runtime::MultiSigner = param.signer.public().into(); let (call, extra, _) = raw_payload.deconstruct(); millau_runtime::UncheckedExtrinsic::new_signed( diff --git a/bridges/relays/client-polkadot/src/lib.rs b/bridges/relays/client-polkadot/src/lib.rs index d468206f9d5ea..bcdee223a9490 100644 --- a/bridges/relays/client-polkadot/src/lib.rs +++ b/bridges/relays/client-polkadot/src/lib.rs @@ -20,8 +20,8 @@ use bp_messages::MessageNonce; use codec::Encode; use frame_support::weights::Weight; use relay_substrate_client::{ - Chain, ChainBase, ChainWithBalances, ChainWithMessages, TransactionEraOf, - TransactionSignScheme, UnsignedTransaction, + Chain, ChainBase, ChainWithBalances, ChainWithMessages, SignParam, TransactionSignScheme, + UnsignedTransaction, }; use sp_core::{storage::StorageKey, Pair}; use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; @@ -105,26 +105,22 @@ impl TransactionSignScheme for Polkadot { type AccountKeyPair = sp_core::sr25519::Pair; type SignedTransaction = crate::runtime::UncheckedExtrinsic; - fn sign_transaction( - genesis_hash: ::Hash, - signer: &Self::AccountKeyPair, - era: TransactionEraOf, - unsigned: UnsignedTransaction, - ) -> Self::SignedTransaction { + fn sign_transaction(param: SignParam) -> Self::SignedTransaction { let raw_payload = SignedPayload::new( - unsigned.call, + param.unsigned.call.clone(), bp_polkadot::SignedExtensions::new( - bp_polkadot::VERSION, - era, - genesis_hash, - unsigned.nonce, - unsigned.tip, + param.spec_version, + param.transaction_version, + param.era, + param.genesis_hash, + param.unsigned.nonce, + param.unsigned.tip, ), ) .expect("SignedExtension never fails."); - let signature = raw_payload.using_encoded(|payload| signer.sign(payload)); - let signer: sp_runtime::MultiSigner = signer.public().into(); + let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload)); + let signer: sp_runtime::MultiSigner = param.signer.public().into(); let (call, extra, _) = raw_payload.deconstruct(); bp_polkadot::UncheckedExtrinsic::new_signed( diff --git a/bridges/relays/client-rialto/src/lib.rs b/bridges/relays/client-rialto/src/lib.rs index 80e3c2c7ae748..f11e735077e42 100644 --- a/bridges/relays/client-rialto/src/lib.rs +++ b/bridges/relays/client-rialto/src/lib.rs @@ -20,7 +20,7 @@ use bp_messages::MessageNonce; use codec::{Compact, Decode, Encode}; use frame_support::weights::Weight; use relay_substrate_client::{ - BalanceOf, Chain, ChainBase, ChainWithBalances, ChainWithMessages, IndexOf, TransactionEraOf, + BalanceOf, Chain, ChainBase, ChainWithBalances, ChainWithMessages, IndexOf, SignParam, TransactionSignScheme, UnsignedTransaction, }; use sp_core::{storage::StorageKey, Pair}; @@ -107,35 +107,30 @@ impl TransactionSignScheme for Rialto { type AccountKeyPair = sp_core::sr25519::Pair; type SignedTransaction = rialto_runtime::UncheckedExtrinsic; - fn sign_transaction( - genesis_hash: ::Hash, - signer: &Self::AccountKeyPair, - era: TransactionEraOf, - unsigned: UnsignedTransaction, - ) -> Self::SignedTransaction { + fn sign_transaction(param: SignParam) -> Self::SignedTransaction { let raw_payload = SignedPayload::from_raw( - unsigned.call, + param.unsigned.call.clone(), ( frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(era.frame_era()), - frame_system::CheckNonce::::from(unsigned.nonce), + frame_system::CheckEra::::from(param.era.frame_era()), + frame_system::CheckNonce::::from(param.unsigned.nonce), frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(unsigned.tip), + pallet_transaction_payment::ChargeTransactionPayment::::from(param.unsigned.tip), ), ( - rialto_runtime::VERSION.spec_version, - rialto_runtime::VERSION.transaction_version, - genesis_hash, - era.signed_payload(genesis_hash), + param.spec_version, + param.transaction_version, + param.genesis_hash, + param.era.signed_payload(param.genesis_hash), (), (), (), ), ); - let signature = raw_payload.using_encoded(|payload| signer.sign(payload)); - let signer: sp_runtime::MultiSigner = signer.public().into(); + let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload)); + let signer: sp_runtime::MultiSigner = param.signer.public().into(); let (call, extra, _) = raw_payload.deconstruct(); rialto_runtime::UncheckedExtrinsic::new_signed( diff --git a/bridges/relays/client-rococo/src/lib.rs b/bridges/relays/client-rococo/src/lib.rs index ee17e62dcd71f..124e3d49447ee 100644 --- a/bridges/relays/client-rococo/src/lib.rs +++ b/bridges/relays/client-rococo/src/lib.rs @@ -20,8 +20,8 @@ use bp_messages::MessageNonce; use codec::Encode; use frame_support::weights::Weight; use relay_substrate_client::{ - Chain, ChainBase, ChainWithBalances, ChainWithMessages, TransactionEraOf, - TransactionSignScheme, UnsignedTransaction, + Chain, ChainBase, ChainWithBalances, ChainWithMessages, SignParam, TransactionSignScheme, + UnsignedTransaction, }; use sp_core::{storage::StorageKey, Pair}; use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; @@ -108,26 +108,22 @@ impl TransactionSignScheme for Rococo { type AccountKeyPair = sp_core::sr25519::Pair; type SignedTransaction = crate::runtime::UncheckedExtrinsic; - fn sign_transaction( - genesis_hash: ::Hash, - signer: &Self::AccountKeyPair, - era: TransactionEraOf, - unsigned: UnsignedTransaction, - ) -> Self::SignedTransaction { + fn sign_transaction(param: SignParam) -> Self::SignedTransaction { let raw_payload = SignedPayload::new( - unsigned.call, + param.unsigned.call.clone(), bp_rococo::SignedExtensions::new( - bp_rococo::VERSION, - era, - genesis_hash, - unsigned.nonce, - unsigned.tip, + param.spec_version, + param.transaction_version, + param.era, + param.genesis_hash, + param.unsigned.nonce, + param.unsigned.tip, ), ) .expect("SignedExtension never fails."); - let signature = raw_payload.using_encoded(|payload| signer.sign(payload)); - let signer: sp_runtime::MultiSigner = signer.public().into(); + let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload)); + let signer: sp_runtime::MultiSigner = param.signer.public().into(); let (call, extra, _) = raw_payload.deconstruct(); bp_rococo::UncheckedExtrinsic::new_signed( diff --git a/bridges/relays/client-substrate/src/chain.rs b/bridges/relays/client-substrate/src/chain.rs index 6b62e699b7ef4..f447c50ccd9a9 100644 --- a/bridges/relays/client-substrate/src/chain.rs +++ b/bridges/relays/client-substrate/src/chain.rs @@ -172,12 +172,9 @@ pub trait TransactionSignScheme { type SignedTransaction: Clone + Debug + Codec + Send + 'static; /// Create transaction for given runtime call, signed by given account. - fn sign_transaction( - genesis_hash: ::Hash, - signer: &Self::AccountKeyPair, - era: TransactionEraOf, - unsigned: UnsignedTransaction, - ) -> Self::SignedTransaction; + fn sign_transaction(param: SignParam) -> Self::SignedTransaction + where + Self: Sized; /// Returns true if transaction is signed. fn is_signed(tx: &Self::SignedTransaction) -> bool; @@ -191,6 +188,22 @@ pub trait TransactionSignScheme { fn parse_transaction(tx: Self::SignedTransaction) -> Option>; } +/// Sign transaction parameters +pub struct SignParam { + /// Version of the runtime specification. + pub spec_version: u32, + /// Transaction version + pub transaction_version: u32, + /// Hash of the genesis block. + pub genesis_hash: ::Hash, + /// Signer account + pub signer: T::AccountKeyPair, + /// Transaction era used by the chain. + pub era: TransactionEraOf, + /// Transaction before it is signed. + pub unsigned: UnsignedTransaction, +} + impl BlockWithJustification for SignedBlock { fn header(&self) -> Block::Header { self.block.header().clone() diff --git a/bridges/relays/client-substrate/src/client.rs b/bridges/relays/client-substrate/src/client.rs index 443c80598c76e..74bf481d54806 100644 --- a/bridges/relays/client-substrate/src/client.rs +++ b/bridges/relays/client-substrate/src/client.rs @@ -60,6 +60,17 @@ pub struct Subscription(Mutex>>); /// Opaque GRANDPA authorities set. pub type OpaqueGrandpaAuthoritiesSet = Vec; +/// Chain runtime version in client +#[derive(Clone, Debug)] +pub enum ChainRuntimeVersion { + /// Auto query from chain. + Auto, + /// Custom runtime version, defined by user. + /// the first is `spec_version` + /// the second is `transaction_version` + Custom(u32, u32), +} + /// Substrate client type. /// /// Cloning `Client` is a cheap operation. @@ -77,6 +88,8 @@ pub struct Client { /// transactions will be rejected from the pool. This lock is here to prevent situations like /// that. submit_signed_extrinsic_lock: Arc>, + /// Saved chain runtime version + chain_runtime_version: ChainRuntimeVersion, } #[async_trait] @@ -99,6 +112,7 @@ impl Clone for Client { client: self.client.clone(), genesis_hash: self.genesis_hash, submit_signed_extrinsic_lock: self.submit_signed_extrinsic_lock.clone(), + chain_runtime_version: self.chain_runtime_version.clone(), } } } @@ -144,12 +158,14 @@ impl Client { }) .await??; + let chain_runtime_version = params.chain_runtime_version.clone(); Ok(Self { tokio, params, client, genesis_hash, submit_signed_extrinsic_lock: Arc::new(Mutex::new(())), + chain_runtime_version, }) } @@ -178,6 +194,19 @@ impl Client { } impl Client { + /// Return simple runtime version, only include `spec_version` and `transaction_version`. + pub async fn simple_runtime_version(&self) -> Result<(u32, u32)> { + let (spec_version, transaction_version) = match self.chain_runtime_version { + ChainRuntimeVersion::Auto => { + let runtime_version = self.runtime_version().await?; + (runtime_version.spec_version, runtime_version.transaction_version) + }, + ChainRuntimeVersion::Custom(spec_version, transaction_version) => + (spec_version, transaction_version), + }; + Ok((spec_version, transaction_version)) + } + /// Returns true if client is connected to at least one peer and is in synced state. pub async fn ensure_synced(&self) -> Result<()> { self.jsonrpsee_execute(|client| async move { diff --git a/bridges/relays/client-substrate/src/lib.rs b/bridges/relays/client-substrate/src/lib.rs index 56a6c981fcb18..dc005506be33c 100644 --- a/bridges/relays/client-substrate/src/lib.rs +++ b/bridges/relays/client-substrate/src/lib.rs @@ -32,10 +32,10 @@ use std::time::Duration; pub use crate::{ chain::{ AccountKeyPairOf, BlockWithJustification, CallOf, Chain, ChainWithBalances, - ChainWithMessages, TransactionSignScheme, TransactionStatusOf, UnsignedTransaction, - WeightToFeeOf, + ChainWithMessages, SignParam, TransactionSignScheme, TransactionStatusOf, + UnsignedTransaction, WeightToFeeOf, }, - client::{Client, OpaqueGrandpaAuthoritiesSet, Subscription}, + client::{ChainRuntimeVersion, Client, OpaqueGrandpaAuthoritiesSet, Subscription}, error::{Error, Result}, sync_header::SyncHeader, }; @@ -56,11 +56,18 @@ pub struct ConnectionParams { pub port: u16, /// Use secure websocket connection. pub secure: bool, + /// Defined chain runtime version + pub chain_runtime_version: ChainRuntimeVersion, } impl Default for ConnectionParams { fn default() -> Self { - ConnectionParams { host: "localhost".into(), port: 9944, secure: false } + ConnectionParams { + host: "localhost".into(), + port: 9944, + secure: false, + chain_runtime_version: ChainRuntimeVersion::Auto, + } } } diff --git a/bridges/relays/client-wococo/src/lib.rs b/bridges/relays/client-wococo/src/lib.rs index e9bdfd834a91e..97d749eb87795 100644 --- a/bridges/relays/client-wococo/src/lib.rs +++ b/bridges/relays/client-wococo/src/lib.rs @@ -20,8 +20,8 @@ use bp_messages::MessageNonce; use codec::Encode; use frame_support::weights::Weight; use relay_substrate_client::{ - Chain, ChainBase, ChainWithBalances, ChainWithMessages, TransactionEraOf, - TransactionSignScheme, UnsignedTransaction, + Chain, ChainBase, ChainWithBalances, ChainWithMessages, SignParam, TransactionSignScheme, + UnsignedTransaction, }; use sp_core::{storage::StorageKey, Pair}; use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; @@ -108,26 +108,22 @@ impl TransactionSignScheme for Wococo { type AccountKeyPair = sp_core::sr25519::Pair; type SignedTransaction = crate::runtime::UncheckedExtrinsic; - fn sign_transaction( - genesis_hash: ::Hash, - signer: &Self::AccountKeyPair, - era: TransactionEraOf, - unsigned: UnsignedTransaction, - ) -> Self::SignedTransaction { + fn sign_transaction(param: SignParam) -> Self::SignedTransaction { let raw_payload = SignedPayload::new( - unsigned.call, + param.unsigned.call.clone(), bp_wococo::SignedExtensions::new( - bp_wococo::VERSION, - era, - genesis_hash, - unsigned.nonce, - unsigned.tip, + param.spec_version, + param.transaction_version, + param.era, + param.genesis_hash, + param.unsigned.nonce, + param.unsigned.tip, ), ) .expect("SignedExtension never fails."); - let signature = raw_payload.using_encoded(|payload| signer.sign(payload)); - let signer: sp_runtime::MultiSigner = signer.public().into(); + let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload)); + let signer: sp_runtime::MultiSigner = param.signer.public().into(); let (call, extra, _) = raw_payload.deconstruct(); bp_wococo::UncheckedExtrinsic::new_signed( diff --git a/bridges/relays/lib-substrate-relay/src/finality_target.rs b/bridges/relays/lib-substrate-relay/src/finality_target.rs index 5daf6c7538a36..918c633d7420a 100644 --- a/bridges/relays/lib-substrate-relay/src/finality_target.rs +++ b/bridges/relays/lib-substrate-relay/src/finality_target.rs @@ -31,7 +31,7 @@ use codec::Encode; use finality_relay::TargetClient; use relay_substrate_client::{ AccountIdOf, AccountKeyPairOf, BlockNumberOf, Chain, Client, Error, HashOf, HeaderOf, - SyncHeader, TransactionEra, TransactionSignScheme, UnsignedTransaction, + SignParam, SyncHeader, TransactionEra, TransactionSignScheme, UnsignedTransaction, }; use relay_utils::relay_loop::Client as RelayClient; use sp_core::{Bytes, Pair}; @@ -103,17 +103,20 @@ where let transaction_params = self.transaction_params.clone(); let call = P::SubmitFinalityProofCallBuilder::build_submit_finality_proof_call(header, proof); + let (spec_version, transaction_version) = self.client.simple_runtime_version().await?; self.client .submit_signed_extrinsic( self.transaction_params.signer.public().into(), move |best_block_id, transaction_nonce| { Bytes( - P::TransactionSignScheme::sign_transaction( + P::TransactionSignScheme::sign_transaction(SignParam { + spec_version, + transaction_version, genesis_hash, - &transaction_params.signer, - TransactionEra::new(best_block_id, transaction_params.mortality), - UnsignedTransaction::new(call, transaction_nonce), - ) + signer: transaction_params.signer.clone(), + era: TransactionEra::new(best_block_id, transaction_params.mortality), + unsigned: UnsignedTransaction::new(call, transaction_nonce), + }) .encode(), ) }, diff --git a/bridges/relays/lib-substrate-relay/src/messages_source.rs b/bridges/relays/lib-substrate-relay/src/messages_source.rs index 1947f526a01f5..8519da7ae2720 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_source.rs @@ -44,8 +44,8 @@ use messages_relay::{ use num_traits::{Bounded, Zero}; use relay_substrate_client::{ AccountIdOf, AccountKeyPairOf, BalanceOf, Chain, ChainWithMessages, Client, - Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, TransactionEra, TransactionSignScheme, - UnsignedTransaction, + Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, SignParam, TransactionEra, + TransactionSignScheme, UnsignedTransaction, }; use relay_utils::{relay_loop::Client as RelayClient, HeaderId}; use sp_core::{Bytes, Pair}; @@ -230,11 +230,14 @@ where ) -> Result<(), SubstrateError> { let genesis_hash = *self.client.genesis_hash(); let transaction_params = self.transaction_params.clone(); + let (spec_version, transaction_version) = self.client.simple_runtime_version().await?; self.client .submit_signed_extrinsic( self.transaction_params.signer.public().into(), move |best_block_id, transaction_nonce| { make_messages_delivery_proof_transaction::

( + spec_version, + transaction_version, &genesis_hash, &transaction_params, best_block_id, @@ -257,8 +260,14 @@ where async fn estimate_confirmation_transaction( &self, ) -> as MessageLane>::SourceChainBalance { + let runtime_version = match self.client.runtime_version().await { + Ok(v) => v, + Err(_) => return BalanceOf::::max_value(), + }; self.client .estimate_extrinsic_fee(make_messages_delivery_proof_transaction::

( + runtime_version.spec_version, + runtime_version.transaction_version, self.client.genesis_hash(), &self.transaction_params, HeaderId(Default::default(), Default::default()), @@ -274,6 +283,8 @@ where /// Make messages delivery proof transaction from given proof. fn make_messages_delivery_proof_transaction( + spec_version: u32, + transaction_version: u32, source_genesis_hash: &HashOf, source_transaction_params: &TransactionParams>, source_best_block_id: HeaderIdOf, @@ -289,12 +300,14 @@ where proof, trace_call, ); Bytes( - P::SourceTransactionSignScheme::sign_transaction( - *source_genesis_hash, - &source_transaction_params.signer, - TransactionEra::new(source_best_block_id, source_transaction_params.mortality), - UnsignedTransaction::new(call, transaction_nonce), - ) + P::SourceTransactionSignScheme::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: *source_genesis_hash, + signer: source_transaction_params.signer.clone(), + era: TransactionEra::new(source_best_block_id, source_transaction_params.mortality), + unsigned: UnsignedTransaction::new(call, transaction_nonce), + }) .encode(), ) } diff --git a/bridges/relays/lib-substrate-relay/src/messages_target.rs b/bridges/relays/lib-substrate-relay/src/messages_target.rs index 3cbe0181d7507..f896b63d4a678 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_target.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_target.rs @@ -40,8 +40,8 @@ use messages_relay::{ use num_traits::{Bounded, Zero}; use relay_substrate_client::{ AccountIdOf, AccountKeyPairOf, BalanceOf, Chain, ChainWithMessages, Client, - Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, TransactionEra, TransactionSignScheme, - UnsignedTransaction, WeightToFeeOf, + Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, SignParam, TransactionEra, + TransactionSignScheme, UnsignedTransaction, WeightToFeeOf, }; use relay_utils::{relay_loop::Client as RelayClient, HeaderId}; use sp_core::{Bytes, Pair}; @@ -218,11 +218,14 @@ where let transaction_params = self.transaction_params.clone(); let relayer_id_at_source = self.relayer_id_at_source.clone(); let nonces_clone = nonces.clone(); + let (spec_version, transaction_version) = self.client.simple_runtime_version().await?; self.client .submit_signed_extrinsic( self.transaction_params.signer.public().into(), move |best_block_id, transaction_nonce| { make_messages_delivery_transaction::

( + spec_version, + transaction_version, &genesis_hash, &transaction_params, best_block_id, @@ -260,8 +263,11 @@ where )) })?; + let (spec_version, transaction_version) = self.client.simple_runtime_version().await?; // Prepare 'dummy' delivery transaction - we only care about its length and dispatch weight. let delivery_tx = make_messages_delivery_transaction::

( + spec_version, + transaction_version, self.client.genesis_hash(), &self.transaction_params, HeaderId(Default::default(), Default::default()), @@ -297,10 +303,13 @@ where let expected_refund_in_target_tokens = if total_prepaid_nonces != 0 { const WEIGHT_DIFFERENCE: Weight = 100; + let (spec_version, transaction_version) = self.client.simple_runtime_version().await?; let larger_dispatch_weight = total_dispatch_weight.saturating_add(WEIGHT_DIFFERENCE); let larger_delivery_tx_fee = self .client .estimate_extrinsic_fee(make_messages_delivery_transaction::

( + spec_version, + transaction_version, self.client.genesis_hash(), &self.transaction_params, HeaderId(Default::default(), Default::default()), @@ -365,6 +374,8 @@ where /// Make messages delivery transaction from given proof. #[allow(clippy::too_many_arguments)] fn make_messages_delivery_transaction( + spec_version: u32, + transaction_version: u32, target_genesis_hash: &HashOf, target_transaction_params: &TransactionParams>, target_best_block_id: HeaderIdOf, @@ -387,12 +398,14 @@ where trace_call, ); Bytes( - P::TargetTransactionSignScheme::sign_transaction( - *target_genesis_hash, - &target_transaction_params.signer, - TransactionEra::new(target_best_block_id, target_transaction_params.mortality), - UnsignedTransaction::new(call, transaction_nonce), - ) + P::TargetTransactionSignScheme::sign_transaction(SignParam { + spec_version, + transaction_version, + genesis_hash: *target_genesis_hash, + signer: target_transaction_params.signer.clone(), + era: TransactionEra::new(target_best_block_id, target_transaction_params.mortality), + unsigned: UnsignedTransaction::new(call, transaction_nonce), + }) .encode(), ) }