diff --git a/primitives/chain-rococo/src/lib.rs b/primitives/chain-rococo/src/lib.rs index b3bbc91976d..f4ee452119b 100644 --- a/primitives/chain-rococo/src/lib.rs +++ b/primitives/chain-rococo/src/lib.rs @@ -44,7 +44,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: sp_version::create_runtime_str!("rococo"), impl_name: sp_version::create_runtime_str!("parity-rococo-v1.6"), authoring_version: 0, - spec_version: 9100, + spec_version: 9130, impl_version: 0, apis: sp_version::create_apis_vec![[]], transaction_version: 0, @@ -105,6 +105,9 @@ pub const FROM_ROCOCO_LATEST_CONFIRMED_NONCE_METHOD: &str = pub const FROM_ROCOCO_UNREWARDED_RELAYERS_STATE: &str = "FromRococoInboundLaneApi_unrewarded_relayers_state"; +/// Existential deposit on Rococo. +pub const EXISTENTIAL_DEPOSIT: Balance = 1_000_000_000_000 / 100; + /// Weight of pay-dispatch-fee operation for inbound messages at Rococo chain. /// /// This value corresponds to the result of diff --git a/primitives/chain-wococo/src/lib.rs b/primitives/chain-wococo/src/lib.rs index fe2ce3a309a..14489351b82 100644 --- a/primitives/chain-wococo/src/lib.rs +++ b/primitives/chain-wococo/src/lib.rs @@ -25,7 +25,9 @@ use sp_std::prelude::*; pub use bp_polkadot_core::*; // Rococo runtime = Wococo runtime -pub use bp_rococo::{WeightToFee, PAY_INBOUND_DISPATCH_FEE_WEIGHT, SESSION_LENGTH, VERSION}; +pub use bp_rococo::{ + WeightToFee, EXISTENTIAL_DEPOSIT, PAY_INBOUND_DISPATCH_FEE_WEIGHT, SESSION_LENGTH, VERSION, +}; /// Wococo Chain pub type Wococo = PolkadotLike; diff --git a/relays/bin-substrate/src/cli/relay_headers_and_messages.rs b/relays/bin-substrate/src/cli/relay_headers_and_messages.rs index 9d76a0296fb..7755df39ed5 100644 --- a/relays/bin-substrate/src/cli/relay_headers_and_messages.rs +++ b/relays/bin-substrate/src/cli/relay_headers_and_messages.rs @@ -29,12 +29,13 @@ use strum::VariantNames; use codec::Encode; use messages_relay::relay_strategy::MixStrategy; use relay_substrate_client::{ - AccountIdOf, Chain, Client, TransactionSignScheme, UnsignedTransaction, + AccountIdOf, CallOf, Chain, Client, TransactionSignScheme, UnsignedTransaction, }; use relay_utils::metrics::MetricsParams; use sp_core::{Bytes, Pair}; use substrate_relay_helper::{ - messages_lane::MessagesRelayParams, on_demand_headers::OnDemandHeadersRelay, + finality_pipeline::SubstrateFinalitySyncPipeline, messages_lane::MessagesRelayParams, + on_demand_headers::OnDemandHeadersRelay, }; use crate::{ @@ -138,8 +139,8 @@ macro_rules! select_bridge { use crate::chains::{ millau_messages_to_rialto::{ - standalone_metrics as left_to_right_standalone_metrics, run as left_to_right_messages, + standalone_metrics as left_to_right_standalone_metrics, update_rialto_to_millau_conversion_rate as update_right_to_left_conversion_rate, }, rialto_messages_to_millau::{ @@ -187,12 +188,10 @@ macro_rules! select_bridge { use crate::chains::{ rococo_messages_to_wococo::{ - standalone_metrics as left_to_right_standalone_metrics, run as left_to_right_messages, + standalone_metrics as left_to_right_standalone_metrics, }, - wococo_messages_to_rococo::{ - run as right_to_left_messages, - }, + wococo_messages_to_rococo::run as right_to_left_messages, }; async fn update_right_to_left_conversion_rate( @@ -212,19 +211,39 @@ macro_rules! select_bridge { } async fn left_create_account( - _left_client: Client, - _left_sign: ::AccountKeyPair, - _account_id: AccountIdOf, + left_client: Client, + left_sign: ::AccountKeyPair, + account_id: AccountIdOf, ) -> anyhow::Result<()> { - Err(anyhow::format_err!("Account creation is not supported by this bridge")) + submit_signed_extrinsic( + left_client, + left_sign, + relay_rococo_client::runtime::Call::Balances( + relay_rococo_client::runtime::BalancesCall::transfer( + bp_rococo::AccountAddress::Id(account_id), + bp_rococo::EXISTENTIAL_DEPOSIT.into(), + ), + ), + ) + .await } async fn right_create_account( - _right_client: Client, - _right_sign: ::AccountKeyPair, - _account_id: AccountIdOf, + right_client: Client, + right_sign: ::AccountKeyPair, + account_id: AccountIdOf, ) -> anyhow::Result<()> { - Err(anyhow::format_err!("Account creation is not supported by this bridge")) + submit_signed_extrinsic( + right_client, + right_sign, + relay_wococo_client::runtime::Call::Balances( + relay_wococo_client::runtime::BalancesCall::transfer( + bp_wococo::AccountAddress::Id(account_id), + bp_wococo::EXISTENTIAL_DEPOSIT.into(), + ), + ), + ) + .await } $generic @@ -250,8 +269,8 @@ macro_rules! select_bridge { use crate::chains::{ kusama_messages_to_polkadot::{ - standalone_metrics as left_to_right_standalone_metrics, run as left_to_right_messages, + standalone_metrics as left_to_right_standalone_metrics, update_polkadot_to_kusama_conversion_rate as update_right_to_left_conversion_rate, }, polkadot_messages_to_kusama::{ @@ -265,29 +284,17 @@ macro_rules! select_bridge { left_sign: ::AccountKeyPair, account_id: AccountIdOf, ) -> anyhow::Result<()> { - let left_genesis_hash = *left_client.genesis_hash(); - left_client - .submit_signed_extrinsic( - left_sign.public().into(), - move |_, transaction_nonce| { - Bytes( - Left::sign_transaction(left_genesis_hash, &left_sign, relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new( - relay_kusama_client::runtime::Call::Balances( - relay_kusama_client::runtime::BalancesCall::transfer( - bp_kusama::AccountAddress::Id(account_id), - bp_kusama::EXISTENTIAL_DEPOSIT.into(), - ), - ), - transaction_nonce, - ), - ).encode() - ) - }, - ) - .await - .map(drop) - .map_err(|e| anyhow::format_err!("{}", e)) + submit_signed_extrinsic( + left_client, + left_sign, + relay_kusama_client::runtime::Call::Balances( + relay_kusama_client::runtime::BalancesCall::transfer( + bp_kusama::AccountAddress::Id(account_id), + bp_kusama::EXISTENTIAL_DEPOSIT.into(), + ), + ), + ) + .await } async fn right_create_account( @@ -295,29 +302,17 @@ macro_rules! select_bridge { right_sign: ::AccountKeyPair, account_id: AccountIdOf, ) -> anyhow::Result<()> { - let right_genesis_hash = *right_client.genesis_hash(); - right_client - .submit_signed_extrinsic( - right_sign.public().into(), - move |_, transaction_nonce| { - Bytes( - Right::sign_transaction(right_genesis_hash, &right_sign, relay_substrate_client::TransactionEra::immortal(), - UnsignedTransaction::new( - relay_polkadot_client::runtime::Call::Balances( - relay_polkadot_client::runtime::BalancesCall::transfer( - bp_polkadot::AccountAddress::Id(account_id), - bp_polkadot::EXISTENTIAL_DEPOSIT.into(), - ), - ), - transaction_nonce, - ), - ).encode() - ) - }, - ) - .await - .map(drop) - .map_err(|e| anyhow::format_err!("{}", e)) + submit_signed_extrinsic( + right_client, + right_sign, + relay_polkadot_client::runtime::Call::Balances( + relay_polkadot_client::runtime::BalancesCall::transfer( + bp_polkadot::AccountAddress::Id(account_id), + bp_polkadot::EXISTENTIAL_DEPOSIT.into(), + ), + ), + ) + .await } $generic @@ -494,11 +489,17 @@ impl RelayHeadersAndMessages { } // start on-demand header relays + let left_to_right_finality = + LeftToRightFinality::new(right_client.clone(), right_sign.clone()); + let right_to_left_finality = + RightToLeftFinality::new(left_client.clone(), left_sign.clone()); + left_to_right_finality.start_relay_guards(); + right_to_left_finality.start_relay_guards(); let left_to_right_on_demand_headers = OnDemandHeadersRelay::new( left_client.clone(), right_client.clone(), right_transactions_mortality, - LeftToRightFinality::new(right_client.clone(), right_sign.clone()), + left_to_right_finality, MAX_MISSING_LEFT_HEADERS_AT_RIGHT, params.shared.only_mandatory_headers, ); @@ -506,7 +507,7 @@ impl RelayHeadersAndMessages { right_client.clone(), left_client.clone(), left_transactions_mortality, - RightToLeftFinality::new(left_client.clone(), left_sign.clone()), + right_to_left_finality, MAX_MISSING_RIGHT_HEADERS_AT_LEFT, params.shared.only_mandatory_headers, ); @@ -561,3 +562,31 @@ impl RelayHeadersAndMessages { }) } } + +/// Sign and submit transaction with given call to the chain. +async fn submit_signed_extrinsic>( + client: Client, + sign: C::AccountKeyPair, + call: CallOf, +) -> anyhow::Result<()> +where + AccountIdOf: From<<::AccountKeyPair as Pair>::Public>, + CallOf: Send, +{ + let genesis_hash = *client.genesis_hash(); + client + .submit_signed_extrinsic(sign.public().into(), move |_, transaction_nonce| { + Bytes( + C::sign_transaction( + genesis_hash, + &sign, + relay_substrate_client::TransactionEra::immortal(), + UnsignedTransaction::new(call, transaction_nonce), + ) + .encode(), + ) + }) + .await + .map(drop) + .map_err(|e| anyhow::format_err!("{}", e)) +} diff --git a/relays/client-rococo/src/runtime.rs b/relays/client-rococo/src/runtime.rs index effe6e5c60a..df69b0a6a9c 100644 --- a/relays/client-rococo/src/runtime.rs +++ b/relays/client-rococo/src/runtime.rs @@ -17,9 +17,9 @@ //! Types that are specific to the Rococo runtime. use bp_messages::{LaneId, UnrewardedRelayersState}; -use bp_polkadot_core::PolkadotLike; +use bp_polkadot_core::{AccountAddress, Balance, PolkadotLike}; use bp_runtime::Chain; -use codec::{Decode, Encode}; +use codec::{Compact, Decode, Encode}; use frame_support::weights::Weight; use scale_info::TypeInfo; @@ -66,6 +66,9 @@ pub enum Call { /// System pallet. #[codec(index = 0)] System(SystemCall), + /// Balances pallet. + #[codec(index = 4)] + Balances(BalancesCall), /// Wococo bridge pallet. #[codec(index = 41)] BridgeGrandpaWococo(BridgeGrandpaWococoCall), @@ -81,6 +84,13 @@ pub enum SystemCall { remark(Vec), } +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +#[allow(non_camel_case_types)] +pub enum BalancesCall { + #[codec(index = 0)] + transfer(AccountAddress, Compact), +} + #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] #[allow(non_camel_case_types)] pub enum BridgeGrandpaWococoCall { diff --git a/relays/client-wococo/src/runtime.rs b/relays/client-wococo/src/runtime.rs index 91d32d1aa76..38a40abd212 100644 --- a/relays/client-wococo/src/runtime.rs +++ b/relays/client-wococo/src/runtime.rs @@ -17,9 +17,9 @@ //! Types that are specific to the Wococo runtime. use bp_messages::{LaneId, UnrewardedRelayersState}; -use bp_polkadot_core::PolkadotLike; +use bp_polkadot_core::{AccountAddress, Balance, PolkadotLike}; use bp_runtime::Chain; -use codec::{Decode, Encode}; +use codec::{Compact, Decode, Encode}; use frame_support::weights::Weight; use scale_info::TypeInfo; @@ -66,6 +66,9 @@ pub enum Call { /// System pallet. #[codec(index = 0)] System(SystemCall), + /// Balances pallet. + #[codec(index = 4)] + Balances(BalancesCall), /// Rococo bridge pallet. #[codec(index = 40)] BridgeGrandpaRococo(BridgeGrandpaRococoCall), @@ -81,6 +84,13 @@ pub enum SystemCall { remark(Vec), } +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +#[allow(non_camel_case_types)] +pub enum BalancesCall { + #[codec(index = 0)] + transfer(AccountAddress, Compact), +} + #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] #[allow(non_camel_case_types)] pub enum BridgeGrandpaRococoCall {