// Copyright 2019-2021 Parity Technologies (UK) Ltd. // This file is part of Parity Bridges Common. // Parity Bridges Common is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Parity Bridges Common is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . //! The Millau runtime. This can be compiled with `#[no_std]`, ready for Wasm. #![cfg_attr(not(feature = "std"), no_std)] // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit = "256"] // Runtime-generated enums #![allow(clippy::large_enum_variant)] // From construct_runtime macro #![allow(clippy::from_over_into)] // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); pub mod rialto_messages; pub mod rialto_parachain_messages; pub mod xcm_config; use bp_parachains::SingleParaStoredHeaderDataBuilder; use bp_runtime::HeaderId; use pallet_grandpa::{ fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList, }; use pallet_transaction_payment::{FeeDetails, Multiplier, RuntimeDispatchInfo}; use sp_api::impl_runtime_apis; use sp_beefy::{crypto::AuthorityId as BeefyId, mmr::MmrLeafVersion, ValidatorSet}; use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{Block as BlockT, IdentityLookup, Keccak256, NumberFor, OpaqueKeys}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, FixedPointNumber, Perquintill, }; use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; // to be able to use Millau runtime in `bridge-runtime-common` tests pub use bridge_runtime_common; // A few exports that help ease life for downstream crates. pub use frame_support::{ construct_runtime, dispatch::DispatchClass, parameter_types, traits::{ConstU32, ConstU8, Currency, ExistenceRequirement, Imbalance, KeyOwnerProofSystem}, weights::{ constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, IdentityFee, RuntimeDbWeight, Weight, }, RuntimeDebug, StorageValue, }; pub use frame_system::Call as SystemCall; pub use pallet_balances::Call as BalancesCall; pub use pallet_bridge_grandpa::Call as BridgeGrandpaCall; pub use pallet_bridge_messages::Call as MessagesCall; pub use pallet_bridge_parachains::Call as BridgeParachainsCall; pub use pallet_sudo::Call as SudoCall; pub use pallet_timestamp::Call as TimestampCall; pub use pallet_xcm::Call as XcmCall; use bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; pub use sp_runtime::{Perbill, Permill}; /// An index to a block. pub type BlockNumber = bp_millau::BlockNumber; /// Alias to 512-bit hash when used in the context of a transaction signature on the chain. pub type Signature = bp_millau::Signature; /// Some way of identifying an account on the chain. We intentionally make it equivalent /// to the public key of our transaction signing scheme. pub type AccountId = bp_millau::AccountId; /// The type for looking up accounts. We don't expect more than 4 billion of them, but you /// never know... pub type AccountIndex = u32; /// Balance of an account. pub type Balance = bp_millau::Balance; /// Index of a transaction in the chain. pub type Index = bp_millau::Index; /// A hash of some data used by the chain. pub type Hash = bp_millau::Hash; /// Hashing algorithm used by the chain. pub type Hashing = bp_millau::Hasher; /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know /// the specifics of the runtime. They can then be made to be agnostic over specific formats /// of data like extrinsics, allowing for them to continue syncing the network through upgrades /// to even the core data structures. pub mod opaque { use super::*; pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; /// Opaque block header type. pub type Header = generic::Header; /// Opaque block type. pub type Block = generic::Block; /// Opaque block identifier type. pub type BlockId = generic::BlockId; } impl_opaque_keys! { pub struct SessionKeys { pub aura: Aura, pub beefy: Beefy, pub grandpa: Grandpa, } } /// This runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("millau-runtime"), impl_name: create_runtime_str!("millau-runtime"), authoring_version: 1, spec_version: 1, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, state_version: 0, }; /// The version information used to identify this runtime when compiled natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } parameter_types! { pub const BlockHashCount: BlockNumber = 250; pub const Version: RuntimeVersion = VERSION; pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { read: 60_000_000, // ~0.06 ms = ~60 µs write: 200_000_000, // ~0.2 ms = 200 µs }; pub const SS58Prefix: u8 = 60; } impl frame_system::Config for Runtime { /// The basic call filter to use in dispatchable. type BaseCallFilter = frame_support::traits::Everything; /// The identifier used to distinguish between accounts. type AccountId = AccountId; /// The aggregated dispatch type that is available for extrinsics. type RuntimeCall = RuntimeCall; /// The lookup mechanism to get account ID from whatever is passed in dispatchers. type Lookup = IdentityLookup; /// The index type for storing how many extrinsics an account has signed. type Index = Index; /// The index type for blocks. type BlockNumber = BlockNumber; /// The type for hashing blocks and tries. type Hash = Hash; /// The hashing algorithm used. type Hashing = Hashing; /// The header type. type Header = generic::Header; /// The ubiquitous event type. type RuntimeEvent = RuntimeEvent; /// The ubiquitous origin type. type RuntimeOrigin = RuntimeOrigin; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount = BlockHashCount; /// Version of the runtime. type Version = Version; /// Provides information about the pallet setup in the runtime. type PalletInfo = PalletInfo; /// What to do if a new account is created. type OnNewAccount = (); /// What to do if an account is fully reaped from the system. type OnKilledAccount = (); /// The data to be stored in an account. type AccountData = pallet_balances::AccountData; // TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78) /// Weight information for the extrinsics of this pallet. type SystemWeightInfo = (); /// Block and extrinsics weights: base values and limits. type BlockWeights = bp_millau::BlockWeights; /// The maximum length of a block (in bytes). type BlockLength = bp_millau::BlockLength; /// The weight of database operations that the runtime can invoke. type DbWeight = DbWeight; /// The designated SS58 prefix of this chain. type SS58Prefix = SS58Prefix; /// The set code logic, just the default since we're not a parachain. type OnSetCode = (); type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_randomness_collective_flip::Config for Runtime {} impl pallet_aura::Config for Runtime { type AuthorityId = AuraId; type MaxAuthorities = ConstU32<10>; type DisabledValidators = (); } impl pallet_beefy::Config for Runtime { type BeefyId = BeefyId; type MaxAuthorities = ConstU32<10>; type OnNewValidatorSet = MmrLeaf; } impl pallet_grandpa::Config for Runtime { type RuntimeEvent = RuntimeEvent; type KeyOwnerProofSystem = (); type KeyOwnerProof = >::Proof; type KeyOwnerIdentification = >::IdentificationTuple; type HandleEquivocation = (); // TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78) type WeightInfo = (); type MaxAuthorities = ConstU32<10>; } /// MMR helper types. mod mmr { use super::Runtime; pub use pallet_mmr::primitives::*; use sp_runtime::traits::Keccak256; pub type Leaf = <::LeafData as LeafDataProvider>::LeafData; pub type Hash = ::Output; pub type Hashing = ::Hashing; } impl pallet_mmr::Config for Runtime { const INDEXING_PREFIX: &'static [u8] = b"mmr"; type Hashing = Keccak256; type Hash = mmr::Hash; type OnNewRoot = pallet_beefy_mmr::DepositBeefyDigest; type WeightInfo = (); type LeafData = pallet_beefy_mmr::Pallet; } parameter_types! { /// Version of the produced MMR leaf. /// /// The version consists of two parts; /// - `major` (3 bits) /// - `minor` (5 bits) /// /// `major` should be updated only if decoding the previous MMR Leaf format from the payload /// is not possible (i.e. backward incompatible change). /// `minor` should be updated if fields are added to the previous MMR Leaf, which given SCALE /// encoding does not prevent old leafs from being decoded. /// /// Hence we expect `major` to be changed really rarely (think never). /// See [`MmrLeafVersion`] type documentation for more details. pub LeafVersion: MmrLeafVersion = MmrLeafVersion::new(0, 0); } pub struct BeefyDummyDataProvider; impl sp_beefy::mmr::BeefyDataProvider<()> for BeefyDummyDataProvider { fn extra_data() {} } impl pallet_beefy_mmr::Config for Runtime { type LeafVersion = LeafVersion; type BeefyAuthorityToMerkleLeaf = pallet_beefy_mmr::BeefyEcdsaToEthereum; type LeafExtra = (); type BeefyDataProvider = BeefyDummyDataProvider; } parameter_types! { pub const MinimumPeriod: u64 = bp_millau::SLOT_DURATION / 2; } impl pallet_timestamp::Config for Runtime { /// A timestamp: milliseconds since the UNIX epoch. type Moment = u64; type OnTimestampSet = Aura; type MinimumPeriod = MinimumPeriod; // TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78) type WeightInfo = (); } parameter_types! { pub const ExistentialDeposit: bp_millau::Balance = 500; } impl pallet_balances::Config for Runtime { /// The type for recording an account's balance. type Balance = Balance; /// The ubiquitous event type. type RuntimeEvent = RuntimeEvent; type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; // TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78) type WeightInfo = (); // For weight estimation, we assume that the most locks on an individual account will be 50. // This number may need to be adjusted in the future if this assumption no longer holds true. type MaxLocks = ConstU32<50>; type MaxReserves = ConstU32<50>; type ReserveIdentifier = [u8; 8]; } parameter_types! { pub const TransactionBaseFee: Balance = 0; pub const TransactionByteFee: Balance = 1; // values for following parameters are copied from polkadot repo, but it is fine // not to sync them - we're not going to make Rialto a full copy of one of Polkadot-like chains pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25); pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(3, 100_000); pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000u128); pub MaximumMultiplier: Multiplier = sp_runtime::traits::Bounded::max_value(); } impl pallet_transaction_payment::Config for Runtime { type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; type OperationalFeeMultiplier = ConstU8<5>; type WeightToFee = bp_millau::WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = pallet_transaction_payment::TargetedFeeAdjustment< Runtime, TargetBlockFullness, AdjustmentVariable, MinimumMultiplier, MaximumMultiplier, >; type RuntimeEvent = RuntimeEvent; } impl pallet_sudo::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; } parameter_types! { /// Authorities are changing every 5 minutes. pub const Period: BlockNumber = bp_millau::SESSION_LENGTH; pub const Offset: BlockNumber = 0; } impl pallet_session::Config for Runtime { type RuntimeEvent = RuntimeEvent; type ValidatorId = ::AccountId; type ValidatorIdOf = (); type ShouldEndSession = pallet_session::PeriodicSessions; type NextSessionRotation = pallet_session::PeriodicSessions; type SessionManager = pallet_shift_session_manager::Pallet; type SessionHandler = ::KeyTypeIdProviders; type Keys = SessionKeys; // TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78) type WeightInfo = (); } impl pallet_bridge_relayers::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Reward = Balance; type PaymentProcedure = bp_relayers::PayLaneRewardFromAccount, AccountId>; type WeightInfo = (); } #[cfg(feature = "runtime-benchmarks")] parameter_types! { /// Number of headers to keep in benchmarks. /// /// In benchmarks we always populate with full number of `HeadersToKeep` to make sure that /// pruning is taken into account. /// /// Note: This is lower than regular value, to speed up benchmarking setup. pub const HeadersToKeep: u32 = 1024; /// Maximal number of authorities at Rialto. /// /// In benchmarks we're using sets of up to `1024` authorities to prepare for possible /// upgrades in the future and see if performance degrades when number of authorities /// grow. pub const MaxAuthoritiesAtRialto: u32 = pallet_bridge_grandpa::benchmarking::MAX_VALIDATOR_SET_SIZE; } #[cfg(not(feature = "runtime-benchmarks"))] parameter_types! { /// Number of headers to keep. /// /// Assuming the worst case of every header being finalized, we will keep headers at least for a /// week. pub const HeadersToKeep: u32 = 7 * bp_rialto::DAYS; /// Maximal number of authorities at Rialto. pub const MaxAuthoritiesAtRialto: u32 = bp_rialto::MAX_AUTHORITIES_COUNT; } parameter_types! { /// Maximal number of authorities at Westend. pub const MaxAuthoritiesAtWestend: u32 = bp_westend::MAX_AUTHORITIES_COUNT; } pub type RialtoGrandpaInstance = (); impl pallet_bridge_grandpa::Config for Runtime { type BridgedChain = bp_rialto::Rialto; // This is a pretty unscientific cap. // // Note that once this is hit the pallet will essentially throttle incoming requests down to one // call per block. type MaxRequests = ConstU32<50>; type HeadersToKeep = HeadersToKeep; type MaxBridgedAuthorities = MaxAuthoritiesAtRialto; type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight; } pub type WestendGrandpaInstance = pallet_bridge_grandpa::Instance1; impl pallet_bridge_grandpa::Config for Runtime { type BridgedChain = bp_westend::Westend; type MaxRequests = ConstU32<50>; type HeadersToKeep = HeadersToKeep; type MaxBridgedAuthorities = MaxAuthoritiesAtWestend; type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight; } impl pallet_shift_session_manager::Config for Runtime {} parameter_types! { pub const MaxMessagesToPruneAtOnce: bp_messages::MessageNonce = 8; pub const MaxUnrewardedRelayerEntriesAtInboundLane: bp_messages::MessageNonce = bp_rialto::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_rialto::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; pub const RootAccountForPayments: Option = None; pub const RialtoChainId: bp_runtime::ChainId = bp_runtime::RIALTO_CHAIN_ID; pub const RialtoParachainChainId: bp_runtime::ChainId = bp_runtime::RIALTO_PARACHAIN_CHAIN_ID; pub RialtoActiveOutboundLanes: &'static [bp_messages::LaneId] = &[rialto_messages::XCM_LANE]; pub RialtoParachainActiveOutboundLanes: &'static [bp_messages::LaneId] = &[rialto_parachain_messages::XCM_LANE]; } /// Instance of the messages pallet used to relay messages to/from Rialto chain. pub type WithRialtoMessagesInstance = (); impl pallet_bridge_messages::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_bridge_messages::weights::BridgeWeight; type ActiveOutboundLanes = RialtoActiveOutboundLanes; type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; type MaximalOutboundPayloadSize = crate::rialto_messages::ToRialtoMaximalOutboundPayloadSize; type OutboundPayload = crate::rialto_messages::ToRialtoMessagePayload; type InboundPayload = crate::rialto_messages::FromRialtoMessagePayload; type InboundRelayer = bp_rialto::AccountId; type DeliveryPayments = (); type TargetHeaderChain = crate::rialto_messages::RialtoAsTargetHeaderChain; type LaneMessageVerifier = crate::rialto_messages::ToRialtoMessageVerifier; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, frame_support::traits::ConstU64<100_000>, frame_support::traits::ConstU64<10_000>, >; type SourceHeaderChain = crate::rialto_messages::RialtoAsSourceHeaderChain; type MessageDispatch = crate::rialto_messages::FromRialtoMessageDispatch; type BridgedChainId = RialtoChainId; } /// Instance of the messages pallet used to relay messages to/from RialtoParachain chain. pub type WithRialtoParachainMessagesInstance = pallet_bridge_messages::Instance1; impl pallet_bridge_messages::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_bridge_messages::weights::BridgeWeight; type ActiveOutboundLanes = RialtoParachainActiveOutboundLanes; type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; type MaximalOutboundPayloadSize = crate::rialto_parachain_messages::ToRialtoParachainMaximalOutboundPayloadSize; type OutboundPayload = crate::rialto_parachain_messages::ToRialtoParachainMessagePayload; type InboundPayload = crate::rialto_parachain_messages::FromRialtoParachainMessagePayload; type InboundRelayer = bp_rialto_parachain::AccountId; type DeliveryPayments = (); type TargetHeaderChain = crate::rialto_parachain_messages::RialtoParachainAsTargetHeaderChain; type LaneMessageVerifier = crate::rialto_parachain_messages::ToRialtoParachainMessageVerifier; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, frame_support::traits::ConstU64<100_000>, frame_support::traits::ConstU64<10_000>, >; type SourceHeaderChain = crate::rialto_parachain_messages::RialtoParachainAsSourceHeaderChain; type MessageDispatch = crate::rialto_parachain_messages::FromRialtoParachainMessageDispatch; type BridgedChainId = RialtoParachainChainId; } parameter_types! { pub const RialtoParachainMessagesLane: bp_messages::LaneId = rialto_parachain_messages::XCM_LANE; pub const RialtoParachainId: u32 = bp_rialto_parachain::RIALTO_PARACHAIN_ID; pub const RialtoParasPalletName: &'static str = bp_rialto::PARAS_PALLET_NAME; pub const WestendParasPalletName: &'static str = bp_westend::PARAS_PALLET_NAME; pub const MaxRialtoParaHeadDataSize: u32 = bp_rialto::MAX_NESTED_PARACHAIN_HEAD_DATA_SIZE; pub const MaxWestendParaHeadDataSize: u32 = bp_westend::MAX_NESTED_PARACHAIN_HEAD_DATA_SIZE; } /// Instance of the with-Rialto parachains pallet. pub type WithRialtoParachainsInstance = (); impl pallet_bridge_parachains::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_bridge_parachains::weights::BridgeWeight; type BridgesGrandpaPalletInstance = RialtoGrandpaInstance; type ParasPalletName = RialtoParasPalletName; type ParaStoredHeaderDataBuilder = SingleParaStoredHeaderDataBuilder; type HeadsToKeep = HeadersToKeep; type MaxParaHeadDataSize = MaxRialtoParaHeadDataSize; } /// Instance of the with-Westend parachains pallet. pub type WithWestendParachainsInstance = pallet_bridge_parachains::Instance1; impl pallet_bridge_parachains::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_bridge_parachains::weights::BridgeWeight; type BridgesGrandpaPalletInstance = WestendGrandpaInstance; type ParasPalletName = WestendParasPalletName; type ParaStoredHeaderDataBuilder = SingleParaStoredHeaderDataBuilder; type HeadsToKeep = HeadersToKeep; type MaxParaHeadDataSize = MaxWestendParaHeadDataSize; } impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; type WeightInfo = (); } construct_runtime!( pub enum Runtime where Block = Block, NodeBlock = opaque::Block, UncheckedExtrinsic = UncheckedExtrinsic { System: frame_system::{Pallet, Call, Config, Storage, Event}, Sudo: pallet_sudo::{Pallet, Call, Config, Storage, Event}, Utility: pallet_utility, // Must be before session. Aura: pallet_aura::{Pallet, Config}, Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, // Consensus support. Session: pallet_session::{Pallet, Call, Storage, Event, Config}, Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event}, ShiftSessionManager: pallet_shift_session_manager::{Pallet}, RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage}, // BEEFY Bridges support. Beefy: pallet_beefy::{Pallet, Storage, Config}, Mmr: pallet_mmr::{Pallet, Storage}, MmrLeaf: pallet_beefy_mmr::{Pallet, Storage}, // Rialto bridge modules. BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event}, BridgeRialtoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage}, BridgeRialtoMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event, Config}, // Westend bridge modules. BridgeWestendGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Config, Storage}, BridgeWestendParachains: pallet_bridge_parachains::::{Pallet, Call, Storage, Event}, // RialtoParachain bridge modules. BridgeRialtoParachains: pallet_bridge_parachains::{Pallet, Call, Storage, Event}, BridgeRialtoParachainMessages: pallet_bridge_messages::::{Pallet, Call, Storage, Event, Config}, // Pallet for sending XCM. XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 99, } ); generate_bridge_reject_obsolete_headers_and_messages! { RuntimeCall, AccountId, // Grandpa BridgeRialtoGrandpa, BridgeWestendGrandpa, // Parachains BridgeRialtoParachains, //Messages BridgeRialtoMessages, BridgeRialtoParachainMessages } /// Signed extension that refunds relayers that are delivering messages from the Rialto parachain. pub type BridgeRefundRialtoParachainRelayers = bridge_runtime_common::refund_relayer_extension::RefundRelayerForMessagesFromParachain< Runtime, RialtoGrandpaInstance, WithRialtoParachainsInstance, WithRialtoParachainMessagesInstance, BridgeRejectObsoleteHeadersAndMessages, RialtoParachainId, RialtoParachainMessagesLane, Runtime, >; /// The address format for describing accounts. pub type Address = AccountId; /// Block header type as expected by this runtime. pub type Header = generic::Header; /// Block type as expected by this runtime. pub type Block = generic::Block; /// A Block signed with a Justification pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; /// The SignedExtension to the basic transaction logic. pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, frame_system::CheckGenesis, frame_system::CheckEra, frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, BridgeRejectObsoleteHeadersAndMessages, BridgeRefundRialtoParachainRelayers, ); /// The payload being signed in transactions. pub type SignedPayload = generic::SignedPayload; /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = generic::CheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, Block, frame_system::ChainContext, Runtime, AllPalletsWithSystem, >; impl_runtime_apis! { impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION } fn execute_block(block: Block) { Executive::execute_block(block); } fn initialize_block(header: &::Header) { Executive::initialize_block(header) } } impl sp_api::Metadata for Runtime { fn metadata() -> OpaqueMetadata { OpaqueMetadata::new(Runtime::metadata().into()) } } impl sp_block_builder::BlockBuilder for Runtime { fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { Executive::apply_extrinsic(extrinsic) } fn finalize_block() -> ::Header { Executive::finalize_block() } fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { data.create_extrinsics() } fn check_inherents( block: Block, data: sp_inherents::InherentData, ) -> sp_inherents::CheckInherentsResult { data.check_extrinsics(&block) } } impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { fn account_nonce(account: AccountId) -> Index { System::account_nonce(account) } } impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { fn validate_transaction( source: TransactionSource, tx: ::Extrinsic, block_hash: ::Hash, ) -> TransactionValidity { Executive::validate_transaction(source, tx, block_hash) } } impl sp_offchain::OffchainWorkerApi for Runtime { fn offchain_worker(header: &::Header) { Executive::offchain_worker(header) } } impl sp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> sp_consensus_aura::SlotDuration { sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) } fn authorities() -> Vec { Aura::authorities().to_vec() } } impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< Block, Balance, > for Runtime { fn query_info(uxt: ::Extrinsic, len: u32) -> RuntimeDispatchInfo { TransactionPayment::query_info(uxt, len) } fn query_fee_details(uxt: ::Extrinsic, len: u32) -> FeeDetails { TransactionPayment::query_fee_details(uxt, len) } } impl sp_session::SessionKeys for Runtime { fn generate_session_keys(seed: Option>) -> Vec { SessionKeys::generate(seed) } fn decode_session_keys( encoded: Vec, ) -> Option, sp_core::crypto::KeyTypeId)>> { SessionKeys::decode_into_raw_public_keys(&encoded) } } impl sp_beefy::BeefyApi for Runtime { fn validator_set() -> Option> { Beefy::validator_set() } } impl pallet_mmr::primitives::MmrApi< Block, mmr::Hash, BlockNumber, > for Runtime { fn mmr_root() -> Result { Ok(Mmr::mmr_root()) } fn mmr_leaf_count() -> Result { Ok(Mmr::mmr_leaves()) } fn generate_proof( block_numbers: Vec, best_known_block_number: Option, ) -> Result<(Vec, mmr::Proof), mmr::Error> { Mmr::generate_proof(block_numbers, best_known_block_number).map( |(leaves, proof)| { ( leaves .into_iter() .map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf)) .collect(), proof, ) }, ) } fn verify_proof(leaves: Vec, proof: mmr::Proof) -> Result<(), mmr::Error> { let leaves = leaves.into_iter().map(|leaf| leaf.into_opaque_leaf() .try_decode() .ok_or(mmr::Error::Verify)).collect::, mmr::Error>>()?; Mmr::verify_leaves(leaves, proof) } fn verify_proof_stateless( root: mmr::Hash, leaves: Vec, proof: mmr::Proof ) -> Result<(), mmr::Error> { let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect(); pallet_mmr::verify_leaves_proof::(root, nodes, proof) } } impl fg_primitives::GrandpaApi for Runtime { fn current_set_id() -> fg_primitives::SetId { Grandpa::current_set_id() } fn grandpa_authorities() -> GrandpaAuthorityList { Grandpa::grandpa_authorities() } fn submit_report_equivocation_unsigned_extrinsic( equivocation_proof: fg_primitives::EquivocationProof< ::Hash, NumberFor, >, key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof, ) -> Option<()> { let key_owner_proof = key_owner_proof.decode()?; Grandpa::submit_unsigned_equivocation_report( equivocation_proof, key_owner_proof, ) } fn generate_key_ownership_proof( _set_id: fg_primitives::SetId, _authority_id: GrandpaId, ) -> Option { // NOTE: this is the only implementation possible since we've // defined our key owner proof type as a bottom type (i.e. a type // with no values). None } } impl bp_rialto::RialtoFinalityApi for Runtime { fn best_finalized() -> Option> { BridgeRialtoGrandpa::best_finalized() } } impl bp_westend::WestendFinalityApi for Runtime { fn best_finalized() -> Option> { BridgeWestendGrandpa::best_finalized() } } impl bp_westend::WestmintFinalityApi for Runtime { fn best_finalized() -> Option> { pallet_bridge_parachains::Pallet::< Runtime, WithWestendParachainsInstance, >::best_parachain_head_id::().unwrap_or(None) } } impl bp_rialto_parachain::RialtoParachainFinalityApi for Runtime { fn best_finalized() -> Option> { pallet_bridge_parachains::Pallet::< Runtime, WithRialtoParachainsInstance, >::best_parachain_head_id::().unwrap_or(None) } } impl bp_rialto::ToRialtoOutboundLaneApi for Runtime { fn message_details( lane: bp_messages::LaneId, begin: bp_messages::MessageNonce, end: bp_messages::MessageNonce, ) -> Vec { bridge_runtime_common::messages_api::outbound_message_details::< Runtime, WithRialtoMessagesInstance, >(lane, begin, end) } } impl bp_rialto::FromRialtoInboundLaneApi for Runtime { fn message_details( lane: bp_messages::LaneId, messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, ) -> Vec { bridge_runtime_common::messages_api::inbound_message_details::< Runtime, WithRialtoMessagesInstance, >(lane, messages) } } impl bp_rialto_parachain::ToRialtoParachainOutboundLaneApi for Runtime { fn message_details( lane: bp_messages::LaneId, begin: bp_messages::MessageNonce, end: bp_messages::MessageNonce, ) -> Vec { bridge_runtime_common::messages_api::outbound_message_details::< Runtime, WithRialtoParachainMessagesInstance, >(lane, begin, end) } } impl bp_rialto_parachain::FromRialtoParachainInboundLaneApi for Runtime { fn message_details( lane: bp_messages::LaneId, messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, ) -> Vec { bridge_runtime_common::messages_api::inbound_message_details::< Runtime, WithRialtoParachainMessagesInstance, >(lane, messages) } } #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { fn benchmark_metadata(extra: bool) -> ( Vec, Vec, ) { use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use pallet_bridge_messages::benchmarking::Pallet as MessagesBench; use pallet_bridge_parachains::benchmarking::Pallet as ParachainsBench; use pallet_bridge_relayers::benchmarking::Pallet as RelayersBench; let mut list = Vec::::new(); list_benchmark!(list, extra, pallet_bridge_messages, MessagesBench::); list_benchmark!(list, extra, pallet_bridge_grandpa, BridgeRialtoGrandpa); list_benchmark!(list, extra, pallet_bridge_parachains, ParachainsBench::); list_benchmark!(list, extra, pallet_bridge_relayers, RelayersBench::); let storage_info = AllPalletsWithSystem::storage_info(); return (list, storage_info) } fn dispatch_benchmark( config: frame_benchmarking::BenchmarkConfig, ) -> Result, sp_runtime::RuntimeString> { use frame_benchmarking::{Benchmarking, BenchmarkBatch, TrackedStorageKey, add_benchmark}; let whitelist: Vec = vec![ // Block Number hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(), // Execution Phase hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(), // Event Count hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(), // System Events hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(), // Caller 0 Account hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da946c154ffd9992e395af90b5b13cc6f295c77033fce8a9045824a6690bbf99c6db269502f0a8d1d2a008542d5690a0749").to_vec().into(), ]; let mut batches = Vec::::new(); let params = (&config, &whitelist); use bridge_runtime_common::messages_benchmarking::{prepare_message_delivery_proof, prepare_message_proof}; use pallet_bridge_messages::benchmarking::{ Pallet as MessagesBench, Config as MessagesConfig, MessageDeliveryProofParams, MessageProofParams, }; use pallet_bridge_parachains::benchmarking::{ Pallet as ParachainsBench, Config as ParachainsConfig, }; use pallet_bridge_relayers::benchmarking::{ Pallet as RelayersBench, Config as RelayersConfig, }; use rialto_messages::WithRialtoMessageBridge; impl MessagesConfig for Runtime { fn prepare_message_proof( params: MessageProofParams, ) -> (rialto_messages::FromRialtoMessagesProof, Weight) { prepare_message_proof::( params, ) } fn prepare_message_delivery_proof( params: MessageDeliveryProofParams, ) -> rialto_messages::ToRialtoMessagesDeliveryProof { prepare_message_delivery_proof::( params, ) } fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool { pallet_bridge_relayers::Pallet::::relayer_reward(relayer, &Self::bench_lane_id()).is_some() } } impl ParachainsConfig for Runtime { fn parachains() -> Vec { use bp_runtime::Parachain; vec![bp_polkadot_core::parachains::ParaId(bp_rialto_parachain::RialtoParachain::PARACHAIN_ID)] } fn prepare_parachain_heads_proof( parachains: &[bp_polkadot_core::parachains::ParaId], parachain_head_size: u32, proof_size: bp_runtime::StorageProofSize, ) -> ( pallet_bridge_parachains::RelayBlockNumber, pallet_bridge_parachains::RelayBlockHash, bp_polkadot_core::parachains::ParaHeadsProof, Vec<(bp_polkadot_core::parachains::ParaId, bp_polkadot_core::parachains::ParaHash)>, ) { bridge_runtime_common::parachains_benchmarking::prepare_parachain_heads_proof::( parachains, parachain_head_size, proof_size, ) } } impl RelayersConfig for Runtime { fn prepare_environment( lane: bp_messages::LaneId, reward: Balance, ) { use frame_support::traits::fungible::Mutate; let lane_rewards_account = bp_relayers::PayLaneRewardFromAccount::< Balances, AccountId >::lane_rewards_account(lane); Balances::mint_into(&lane_rewards_account, reward).unwrap(); } } add_benchmark!( params, batches, pallet_bridge_messages, MessagesBench:: ); add_benchmark!(params, batches, pallet_bridge_grandpa, BridgeRialtoGrandpa); add_benchmark!( params, batches, pallet_bridge_parachains, ParachainsBench:: ); add_benchmark!(params, batches, pallet_bridge_relayers, RelayersBench::); Ok(batches) } } } #[cfg(test)] mod tests { use super::*; #[test] fn call_size() { const BRIDGES_PALLETS_MAX_CALL_SIZE: usize = 200; assert!( core::mem::size_of::>() <= BRIDGES_PALLETS_MAX_CALL_SIZE ); assert!( core::mem::size_of::>() <= BRIDGES_PALLETS_MAX_CALL_SIZE ); const MAX_CALL_SIZE: usize = 230; // value from polkadot-runtime tests assert!(core::mem::size_of::() <= MAX_CALL_SIZE); } }