diff --git a/bridges/bin/rialto-parachain/runtime/src/lib.rs b/bridges/bin/rialto-parachain/runtime/src/lib.rs index 2621b0096a7f..3614bacdc10a 100644 --- a/bridges/bin/rialto-parachain/runtime/src/lib.rs +++ b/bridges/bin/rialto-parachain/runtime/src/lib.rs @@ -28,14 +28,19 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); use crate::millau_messages::{WithMillauMessageBridge, XCM_LANE}; -use bridge_runtime_common::messages::source::{XcmBridge, XcmBridgeAdapter}; +use bridge_runtime_common::{ + generate_bridge_reject_obsolete_headers_and_messages, + messages::source::{XcmBridge, XcmBridgeAdapter}, +}; +use codec::{Decode, Encode}; use cumulus_pallet_parachain_system::AnyRelayNumber; +use scale_info::TypeInfo; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - traits::{AccountIdLookup, Block as BlockT}, - transaction_validity::{TransactionSource, TransactionValidity}, + traits::{AccountIdLookup, Block as BlockT, DispatchInfoOf, SignedExtension}, + transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, ApplyExtrinsicResult, }; @@ -93,6 +98,44 @@ use xcm_executor::{Config, XcmExecutor}; pub mod millau_messages; +// generate signed extension that rejects obsolete bridge transactions +generate_bridge_reject_obsolete_headers_and_messages! { + RuntimeCall, AccountId, + // Grandpa + BridgeMillauGrandpa, + // Messages + BridgeMillauMessages +} + +/// Dummy signed extension that does nothing. +/// +/// We're using it to have the same set of signed extensions on all parachains with bridge pallets +/// deployed (bridge hubs and rialto parachain). +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +pub struct DummyBridgeRefundMillauMessages; + +impl SignedExtension for DummyBridgeRefundMillauMessages { + const IDENTIFIER: &'static str = "DummyBridgeRefundMillauMessages"; + type AccountId = AccountId; + type Call = RuntimeCall; + type AdditionalSigned = (); + type Pre = (); + + fn additional_signed(&self) -> Result { + Ok(()) + } + + fn pre_dispatch( + self, + _who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> Result { + Ok(()) + } +} + /// The address format for describing accounts. pub type Address = MultiAddress; /// Block type as expected by this runtime. @@ -111,6 +154,8 @@ pub type SignedExtra = ( frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, + BridgeRejectObsoleteHeadersAndMessages, + DummyBridgeRefundMillauMessages, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = @@ -909,9 +954,11 @@ mod tests { frame_system::CheckNonce::from(10), frame_system::CheckWeight::new(), pallet_transaction_payment::ChargeTransactionPayment::from(10), + BridgeRejectObsoleteHeadersAndMessages, + DummyBridgeRefundMillauMessages, ); let indirect_payload = bp_rialto_parachain::SignedExtension::new( - ((), (), (), (), Era::Immortal, 10.into(), (), 10.into()), + ((), (), (), (), Era::Immortal, 10.into(), (), 10.into(), (), ()), None, ); assert_eq!(payload.encode(), indirect_payload.encode()); diff --git a/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs b/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs index cbdd36c2e4ae..5a745fdaba47 100644 --- a/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs @@ -16,12 +16,18 @@ #![cfg_attr(not(feature = "std"), no_std)] -use bp_messages::*; pub use bp_polkadot_core::{ AccountId, AccountInfoStorageMapKeyProvider, AccountPublic, Balance, BlockNumber, Hash, Hasher, Hashing, Header, Index, Nonce, Perbill, Signature, SignedBlock, UncheckedExtrinsic, EXTRA_STORAGE_PROOF_SIZE, TX_EXTRA_BYTES, }; + +use bp_messages::*; +use bp_runtime::extensions::{ + BridgeRejectObsoleteHeadersAndMessages, ChargeTransactionPayment, CheckEra, CheckGenesis, + CheckNonZeroSender, CheckNonce, CheckSpecVersion, CheckTxVersion, CheckWeight, + GenericSignedExtension, RefundBridgedParachainMessagesSchema, +}; use frame_support::{ dispatch::DispatchClass, parameter_types, @@ -94,8 +100,6 @@ pub type AccountSigner = MultiSigner; /// The address format for describing accounts. pub type Address = MultiAddress; -pub use bp_polkadot_core::BridgeSignedExtension as SignedExtension; - // Note about selecting values of two following constants: // // Normal transactions have limit of 75% of 1/2 second weight for Cumulus parachains. Let's keep @@ -125,37 +129,54 @@ pub const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 1024; /// Maximal number of unconfirmed messages at inbound lane for Cumulus-based parachains. pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 4096; -/// Module with rewarding bridge signed extension support -pub mod rewarding_bridge_signed_extension { - use super::*; - use bp_polkadot_core::PolkadotLike; - use bp_runtime::extensions::*; - - type RewardingBridgeSignedExtra = ( - CheckNonZeroSender, - CheckSpecVersion, - CheckTxVersion, - CheckGenesis, - CheckEra, - CheckNonce, - CheckWeight, - ChargeTransactionPayment, - BridgeRejectObsoleteHeadersAndMessages, - RefundBridgedParachainMessagesSchema, - ); +/// Extra signed extension data that is used by all bridge hubs. +pub type SignedExtra = ( + CheckNonZeroSender, + CheckSpecVersion, + CheckTxVersion, + CheckGenesis, + CheckEra, + CheckNonce, + CheckWeight, + ChargeTransactionPayment, + BridgeRejectObsoleteHeadersAndMessages, + RefundBridgedParachainMessagesSchema, +); + +/// Signed extension that is used by all bridge hubs. +pub type SignedExtension = GenericSignedExtension; + +/// Helper trait to define some extra methods on bridge hubs signed extension (and +/// overcome Rust limitations). +pub trait BridgeHubSignedExtension { + /// Create signed extension from its components. + fn from_params( + spec_version: u32, + transaction_version: u32, + era: bp_runtime::TransactionEra, + genesis_hash: Hash, + nonce: Index, + tip: Balance, + ) -> Self; - /// The signed extension used by Cumulus and Cumulus-like parachain with bridging and rewarding. - pub type RewardingBridgeSignedExtension = GenericSignedExtension; + /// Return transaction nonce. + fn nonce(&self) -> Index; + + /// Return transaction tip. + fn tip(&self) -> Balance; +} - pub fn from_params( +impl BridgeHubSignedExtension for SignedExtension { + /// Create signed extension from its components. + fn from_params( spec_version: u32, transaction_version: u32, - era: bp_runtime::TransactionEraOf, + era: bp_runtime::TransactionEra, genesis_hash: Hash, - nonce: Nonce, + nonce: Index, tip: Balance, - ) -> RewardingBridgeSignedExtension { - GenericSignedExtension::::new( + ) -> Self { + GenericSignedExtension::new( ( (), // non-zero sender (), // spec version @@ -166,7 +187,7 @@ pub mod rewarding_bridge_signed_extension { (), // Check weight tip.into(), // transaction payment / tip (compact encoding) (), // bridge reject obsolete headers and msgs - (), // bridge register reward to relayer for message passing + (), // bridge reward to relayer for message passing ), Some(( (), @@ -183,13 +204,13 @@ pub mod rewarding_bridge_signed_extension { ) } - /// Return signer nonce, used to craft transaction. - pub fn nonce(sign_ext: &RewardingBridgeSignedExtension) -> Nonce { - sign_ext.payload.5.into() + /// Return transaction nonce. + fn nonce(&self) -> Index { + self.payload.5 .0 } /// Return transaction tip. - pub fn tip(sign_ext: &RewardingBridgeSignedExtension) -> Balance { - sign_ext.payload.7.into() + fn tip(&self) -> Balance { + self.payload.7 .0 } } diff --git a/bridges/primitives/chain-rialto-parachain/Cargo.toml b/bridges/primitives/chain-rialto-parachain/Cargo.toml index ed7c5c079600..3335c6bcc410 100644 --- a/bridges/primitives/chain-rialto-parachain/Cargo.toml +++ b/bridges/primitives/chain-rialto-parachain/Cargo.toml @@ -10,6 +10,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" # Bridge Dependencies +bp-bridge-hub-cumulus = { path = "../chain-bridge-hub-cumulus", default-features = false } bp-messages = { path = "../messages", default-features = false } bp-polkadot-core = { path = "../polkadot-core", default-features = false } bp-runtime = { path = "../runtime", default-features = false } @@ -26,6 +27,7 @@ sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", d [features] default = ["std"] std = [ + "bp-bridge-hub-cumulus/std", "bp-messages/std", "bp-runtime/std", "frame-support/std", diff --git a/bridges/primitives/chain-rialto-parachain/src/lib.rs b/bridges/primitives/chain-rialto-parachain/src/lib.rs index e49f3d14dc5f..67b1a135f34a 100644 --- a/bridges/primitives/chain-rialto-parachain/src/lib.rs +++ b/bridges/primitives/chain-rialto-parachain/src/lib.rs @@ -133,7 +133,9 @@ impl Parachain for RialtoParachain { const PARACHAIN_ID: u32 = RIALTO_PARACHAIN_ID; } -pub use bp_polkadot_core::DefaultSignedExtension as SignedExtension; +// Technically this is incorrect, because rialto-parachain isn't a bridge hub, but we're +// trying to keep it close to the bridge hubs code (at least in this aspect). +pub use bp_bridge_hub_cumulus::SignedExtension; frame_support::parameter_types! { pub BlockLength: limits::BlockLength = diff --git a/bridges/primitives/polkadot-core/src/lib.rs b/bridges/primitives/polkadot-core/src/lib.rs index 10da6cd9b355..eae2d49a6fdb 100644 --- a/bridges/primitives/polkadot-core/src/lib.rs +++ b/bridges/primitives/polkadot-core/src/lib.rs @@ -37,7 +37,6 @@ use sp_runtime::{ use sp_std::prelude::Vec; // Re-export's to avoid extra substrate dependencies in chain-specific crates. -use bp_runtime::extensions::*; pub use frame_support::{weights::constants::ExtrinsicBaseWeight, Parameter}; pub use sp_runtime::{traits::Convert, Perbill}; @@ -252,142 +251,6 @@ impl Chain for PolkadotLike { } } -/// Some functionality associated with the default signed extension used by Polkadot and -/// Polkadot-like chains. -pub trait PolkadotSignedExtension { - fn from_params( - spec_version: u32, - transaction_version: u32, - era: bp_runtime::TransactionEraOf, - genesis_hash: Hash, - nonce: Nonce, - tip: Balance, - ) -> Self; - - fn nonce(&self) -> Nonce; - - fn tip(&self) -> Balance; -} - -type DefaultSignedExtra = ( - CheckNonZeroSender, - CheckSpecVersion, - CheckTxVersion, - CheckGenesis, - CheckEra, - CheckNonce, - CheckWeight, - ChargeTransactionPayment, -); - -/// The default signed extension used by Polkadot and Polkadot-like chains. -pub type DefaultSignedExtension = GenericSignedExtension; - -impl PolkadotSignedExtension for DefaultSignedExtension { - fn from_params( - spec_version: u32, - transaction_version: u32, - era: bp_runtime::TransactionEraOf, - genesis_hash: Hash, - nonce: Nonce, - tip: Balance, - ) -> Self { - Self::new( - ( - (), // non-zero sender - (), // spec version - (), // tx version - (), // genesis - era.frame_era(), // era - nonce.into(), // nonce (compact encoding) - (), // Check weight - tip.into(), // transaction payment / tip (compact encoding) - ), - Some(( - (), - spec_version, - transaction_version, - genesis_hash, - era.signed_payload(genesis_hash), - (), - (), - (), - )), - ) - } - - /// Return signer nonce, used to craft transaction. - fn nonce(&self) -> Nonce { - self.payload.5.into() - } - - /// Return transaction tip. - fn tip(&self) -> Balance { - self.payload.7.into() - } -} - -type BridgeSignedExtra = ( - CheckNonZeroSender, - CheckSpecVersion, - CheckTxVersion, - CheckGenesis, - CheckEra, - CheckNonce, - CheckWeight, - ChargeTransactionPayment, - BridgeRejectObsoleteHeadersAndMessages, -); - -/// The default signed extension used by Polkadot and Polkadot-like chains with bridging. -pub type BridgeSignedExtension = GenericSignedExtension; - -impl PolkadotSignedExtension for BridgeSignedExtension { - fn from_params( - spec_version: u32, - transaction_version: u32, - era: bp_runtime::TransactionEraOf, - genesis_hash: Hash, - nonce: Nonce, - tip: Balance, - ) -> Self { - Self::new( - ( - (), // non-zero sender - (), // spec version - (), // tx version - (), // genesis - era.frame_era(), // era - nonce.into(), // nonce (compact encoding) - (), // Check weight - tip.into(), // transaction payment / tip (compact encoding) - (), // bridge reject obsolete headers and msgs - ), - Some(( - (), - spec_version, - transaction_version, - genesis_hash, - era.signed_payload(genesis_hash), - (), - (), - (), - (), - )), - ) - } - - /// Return signer nonce, used to craft transaction. - fn nonce(&self) -> Nonce { - self.payload.5.into() - } - - /// Return transaction tip. - fn tip(&self) -> Balance { - self.payload.7.into() - } -} - /// Provides a storage key for account data. /// /// We need to use this approach when we don't have access to the runtime. diff --git a/bridges/primitives/runtime/src/extensions.rs b/bridges/primitives/runtime/src/extensions.rs index ea51d03741c6..96ee9d1e6ec9 100644 --- a/bridges/primitives/runtime/src/extensions.rs +++ b/bridges/primitives/runtime/src/extensions.rs @@ -16,7 +16,6 @@ //! Primitives that may be used for creating signed extensions for indirect runtimes. -use crate::{BalanceOf, HashOf}; use codec::{Compact, Decode, Encode}; use impl_trait_for_tuples::impl_for_tuples; use scale_info::{StaticTypeInfo, TypeInfo}; @@ -59,19 +58,19 @@ pub type CheckSpecVersion = GenericSignedExtensionSchema<(), u32>; pub type CheckTxVersion = GenericSignedExtensionSchema<(), u32>; /// The `SignedExtensionSchema` for `frame_system::CheckGenesis`. -pub type CheckGenesis = GenericSignedExtensionSchema<(), HashOf>; +pub type CheckGenesis = GenericSignedExtensionSchema<(), Hash>; /// The `SignedExtensionSchema` for `frame_system::CheckEra`. -pub type CheckEra = GenericSignedExtensionSchema>; +pub type CheckEra = GenericSignedExtensionSchema; /// The `SignedExtensionSchema` for `frame_system::CheckNonce`. -pub type CheckNonce = GenericSignedExtensionSchema, ()>; +pub type CheckNonce = GenericSignedExtensionSchema, ()>; /// The `SignedExtensionSchema` for `frame_system::CheckWeight`. pub type CheckWeight = GenericSignedExtensionSchema<(), ()>; /// The `SignedExtensionSchema` for `pallet_transaction_payment::ChargeTransactionPayment`. -pub type ChargeTransactionPayment = GenericSignedExtensionSchema>, ()>; +pub type ChargeTransactionPayment = GenericSignedExtensionSchema, ()>; /// The `SignedExtensionSchema` for `BridgeRejectObsoleteHeadersAndMessages`. pub type BridgeRejectObsoleteHeadersAndMessages = GenericSignedExtensionSchema<(), ()>; diff --git a/bridges/relays/client-bridge-hub-rococo/src/lib.rs b/bridges/relays/client-bridge-hub-rococo/src/lib.rs index a8238454e74e..87d461b97610 100644 --- a/bridges/relays/client-bridge-hub-rococo/src/lib.rs +++ b/bridges/relays/client-bridge-hub-rococo/src/lib.rs @@ -16,7 +16,7 @@ //! Types used to connect to the BridgeHub-Rococo-Substrate parachain. -use bp_bridge_hub_rococo::AVERAGE_BLOCK_INTERVAL; +use bp_bridge_hub_rococo::{BridgeHubSignedExtension, AVERAGE_BLOCK_INTERVAL}; use bp_messages::MessageNonce; use bp_runtime::ChainId; use codec::Encode; @@ -73,7 +73,7 @@ impl ChainWithTransactions for BridgeHubRococo { ) -> Result { let raw_payload = SignedPayload::new( unsigned.call, - runtime::rewarding_bridge_signed_extension::from_params( + runtime::SignedExtension::from_params( param.spec_version, param.transaction_version, unsigned.era, @@ -110,13 +110,7 @@ impl ChainWithTransactions for BridgeHubRococo { fn parse_transaction(tx: Self::SignedTransaction) -> Option> { let extra = &tx.signature.as_ref()?.2; - Some( - UnsignedTransaction::new( - tx.function, - runtime::rewarding_bridge_signed_extension::nonce(extra), - ) - .tip(runtime::rewarding_bridge_signed_extension::tip(extra)), - ) + Some(UnsignedTransaction::new(tx.function, extra.nonce()).tip(extra.tip())) } } diff --git a/bridges/relays/client-bridge-hub-rococo/src/runtime_wrapper.rs b/bridges/relays/client-bridge-hub-rococo/src/runtime_wrapper.rs index 711306b0127f..26e0bd9da5e2 100644 --- a/bridges/relays/client-bridge-hub-rococo/src/runtime_wrapper.rs +++ b/bridges/relays/client-bridge-hub-rococo/src/runtime_wrapper.rs @@ -19,17 +19,14 @@ use codec::{Decode, Encode}; use scale_info::TypeInfo; -pub use bp_bridge_hub_rococo::rewarding_bridge_signed_extension; +pub use bp_bridge_hub_rococo::SignedExtension; pub use bp_header_chain::BridgeGrandpaCallOf; pub use bp_parachains::BridgeParachainCall; pub use bridge_runtime_common::messages::BridgeMessagesCallOf; pub use relay_substrate_client::calls::{SystemCall, UtilityCall}; /// Unchecked BridgeHubRococo extrinsic. -pub type UncheckedExtrinsic = bp_bridge_hub_rococo::UncheckedExtrinsic< - Call, - rewarding_bridge_signed_extension::RewardingBridgeSignedExtension, ->; +pub type UncheckedExtrinsic = bp_bridge_hub_rococo::UncheckedExtrinsic; // The indirect pallet call used to sync `Wococo` GRANDPA finality to `BHRococo`. pub type BridgeWococoGrandpaCall = BridgeGrandpaCallOf; diff --git a/bridges/relays/client-bridge-hub-wococo/src/lib.rs b/bridges/relays/client-bridge-hub-wococo/src/lib.rs index 27729737310a..e9864bf98857 100644 --- a/bridges/relays/client-bridge-hub-wococo/src/lib.rs +++ b/bridges/relays/client-bridge-hub-wococo/src/lib.rs @@ -16,7 +16,7 @@ //! Types used to connect to the BridgeHub-Wococo-Substrate parachain. -use bp_bridge_hub_wococo::AVERAGE_BLOCK_INTERVAL; +use bp_bridge_hub_wococo::{BridgeHubSignedExtension, AVERAGE_BLOCK_INTERVAL}; use bp_messages::MessageNonce; use bp_runtime::ChainId; use codec::Encode; @@ -73,7 +73,7 @@ impl ChainWithTransactions for BridgeHubWococo { ) -> Result { let raw_payload = SignedPayload::new( unsigned.call, - runtime::rewarding_bridge_signed_extension::from_params( + runtime::SignedExtension::from_params( param.spec_version, param.transaction_version, unsigned.era, @@ -110,13 +110,7 @@ impl ChainWithTransactions for BridgeHubWococo { fn parse_transaction(tx: Self::SignedTransaction) -> Option> { let extra = &tx.signature.as_ref()?.2; - Some( - UnsignedTransaction::new( - tx.function, - runtime::rewarding_bridge_signed_extension::nonce(extra), - ) - .tip(runtime::rewarding_bridge_signed_extension::tip(extra)), - ) + Some(UnsignedTransaction::new(tx.function, extra.nonce()).tip(extra.tip())) } } diff --git a/bridges/relays/client-bridge-hub-wococo/src/runtime_wrapper.rs b/bridges/relays/client-bridge-hub-wococo/src/runtime_wrapper.rs index 374dd5b44ce8..b9803955922d 100644 --- a/bridges/relays/client-bridge-hub-wococo/src/runtime_wrapper.rs +++ b/bridges/relays/client-bridge-hub-wococo/src/runtime_wrapper.rs @@ -19,17 +19,14 @@ use codec::{Decode, Encode}; use scale_info::TypeInfo; -pub use bp_bridge_hub_wococo::rewarding_bridge_signed_extension; +pub use bp_bridge_hub_wococo::SignedExtension; pub use bp_header_chain::BridgeGrandpaCallOf; pub use bp_parachains::BridgeParachainCall; pub use bridge_runtime_common::messages::BridgeMessagesCallOf; pub use relay_substrate_client::calls::{SystemCall, UtilityCall}; /// Unchecked BridgeHubWococo extrinsic. -pub type UncheckedExtrinsic = bp_bridge_hub_wococo::UncheckedExtrinsic< - Call, - rewarding_bridge_signed_extension::RewardingBridgeSignedExtension, ->; +pub type UncheckedExtrinsic = bp_bridge_hub_wococo::UncheckedExtrinsic; // The indirect pallet call used to sync `Rococo` GRANDPA finality to `BHWococo`. pub type BridgeRococoGrandpaCall = BridgeGrandpaCallOf; diff --git a/bridges/relays/client-rialto-parachain/Cargo.toml b/bridges/relays/client-rialto-parachain/Cargo.toml index 807da290d249..02a9c70ce5e5 100644 --- a/bridges/relays/client-rialto-parachain/Cargo.toml +++ b/bridges/relays/client-rialto-parachain/Cargo.toml @@ -12,6 +12,7 @@ subxt = { git = "https://github.com/paritytech/subxt", branch = "master", defaul # Bridge dependencies +bp-bridge-hub-cumulus = { path = "../../primitives/chain-bridge-hub-cumulus" } bp-header-chain = { path = "../../primitives/header-chain" } bp-messages = { path = "../../primitives/messages" } bp-millau = { path = "../../primitives/chain-millau" } diff --git a/bridges/relays/client-rialto-parachain/src/lib.rs b/bridges/relays/client-rialto-parachain/src/lib.rs index 27673dc23be1..5334c59d3c19 100644 --- a/bridges/relays/client-rialto-parachain/src/lib.rs +++ b/bridges/relays/client-rialto-parachain/src/lib.rs @@ -18,8 +18,8 @@ pub mod codegen_runtime; +use bp_bridge_hub_cumulus::BridgeHubSignedExtension; use bp_messages::MessageNonce; -use bp_polkadot_core::PolkadotSignedExtension; use bp_runtime::ChainId; use codec::Encode; use relay_substrate_client::{