diff --git a/bridges/bin/millau/runtime/src/lib.rs b/bridges/bin/millau/runtime/src/lib.rs index 09f17cf6cf534..095250a55861a 100644 --- a/bridges/bin/millau/runtime/src/lib.rs +++ b/bridges/bin/millau/runtime/src/lib.rs @@ -32,18 +32,8 @@ pub mod rialto_messages; pub mod rialto_parachain_messages; pub mod xcm_config; -use crate::{ - rialto_messages::{ToRialtoMessagePayload, WithRialtoMessageBridge}, - rialto_parachain_messages::{ - ToRialtoParachainMessagePayload, WithRialtoParachainMessageBridge, - }, -}; - use beefy_primitives::{crypto::AuthorityId as BeefyId, mmr::MmrLeafVersion, ValidatorSet}; use bp_runtime::{HeaderId, HeaderIdProvider}; -use bridge_runtime_common::messages::{ - source::estimate_message_dispatch_and_delivery_fee, MessageBridge, -}; use codec::Decode; use pallet_grandpa::{ fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList, @@ -57,7 +47,7 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{Block as BlockT, IdentityLookup, Keccak256, NumberFor, OpaqueKeys}, transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, FixedPointNumber, FixedU128, Perquintill, + ApplyExtrinsicResult, FixedPointNumber, Perquintill, }; use sp_std::prelude::*; #[cfg(feature = "std")] @@ -476,9 +466,6 @@ parameter_types! { bp_rialto::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_rialto::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; - // `IdentityFee` is used by Millau => we may use weight directly - pub const GetDeliveryConfirmationTransactionFee: Balance = - bp_millau::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT.ref_time() as _; 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; @@ -490,17 +477,14 @@ pub type WithRialtoMessagesInstance = (); impl pallet_bridge_messages::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_bridge_messages::weights::BridgeWeight; - type Parameter = rialto_messages::MillauToRialtoMessagesParameter; type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce; type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; type MaximalOutboundPayloadSize = crate::rialto_messages::ToRialtoMaximalOutboundPayloadSize; type OutboundPayload = crate::rialto_messages::ToRialtoMessagePayload; - type OutboundMessageFee = Balance; type InboundPayload = crate::rialto_messages::FromRialtoMessagePayload; - type InboundMessageFee = bp_rialto::Balance; type InboundRelayer = bp_rialto::AccountId; type TargetHeaderChain = crate::rialto_messages::Rialto; @@ -509,7 +493,6 @@ impl pallet_bridge_messages::Config for Runtime { pallet_bridge_relayers::MessageDeliveryAndDispatchPaymentAdapter< Runtime, WithRialtoMessagesInstance, - GetDeliveryConfirmationTransactionFee, >; type OnMessageAccepted = (); type OnDeliveryConfirmed = (); @@ -525,7 +508,6 @@ 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 Parameter = rialto_parachain_messages::MillauToRialtoParachainMessagesParameter; type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce; type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; @@ -533,10 +515,8 @@ impl pallet_bridge_messages::Config for Run type MaximalOutboundPayloadSize = crate::rialto_parachain_messages::ToRialtoParachainMaximalOutboundPayloadSize; type OutboundPayload = crate::rialto_parachain_messages::ToRialtoParachainMessagePayload; - type OutboundMessageFee = Balance; type InboundPayload = crate::rialto_parachain_messages::FromRialtoParachainMessagePayload; - type InboundMessageFee = bp_rialto_parachain::Balance; type InboundRelayer = bp_rialto_parachain::AccountId; type TargetHeaderChain = crate::rialto_parachain_messages::RialtoParachain; @@ -545,7 +525,6 @@ impl pallet_bridge_messages::Config for Run pallet_bridge_relayers::MessageDeliveryAndDispatchPaymentAdapter< Runtime, WithRialtoParachainMessagesInstance, - GetDeliveryConfirmationTransactionFee, >; type OnMessageAccepted = (); type OnDeliveryConfirmed = (); @@ -941,24 +920,12 @@ impl_runtime_apis! { } } - impl bp_rialto::ToRialtoOutboundLaneApi for Runtime { - fn estimate_message_delivery_and_dispatch_fee( - _lane_id: bp_messages::LaneId, - payload: ToRialtoMessagePayload, - rialto_to_this_conversion_rate: Option, - ) -> Option { - estimate_message_dispatch_and_delivery_fee::( - &payload, - WithRialtoMessageBridge::RELAYER_FEE_PERCENT, - rialto_to_this_conversion_rate, - ).ok() - } - + impl bp_rialto::ToRialtoOutboundLaneApi for Runtime { fn message_details( lane: bp_messages::LaneId, begin: bp_messages::MessageNonce, end: bp_messages::MessageNonce, - ) -> Vec> { + ) -> Vec { bridge_runtime_common::messages_api::outbound_message_details::< Runtime, WithRialtoMessagesInstance, @@ -966,10 +933,10 @@ impl_runtime_apis! { } } - impl bp_rialto::FromRialtoInboundLaneApi for Runtime { + impl bp_rialto::FromRialtoInboundLaneApi for Runtime { fn message_details( lane: bp_messages::LaneId, - messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, + messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, ) -> Vec { bridge_runtime_common::messages_api::inbound_message_details::< Runtime, @@ -978,24 +945,12 @@ impl_runtime_apis! { } } - impl bp_rialto_parachain::ToRialtoParachainOutboundLaneApi for Runtime { - fn estimate_message_delivery_and_dispatch_fee( - _lane_id: bp_messages::LaneId, - payload: ToRialtoParachainMessagePayload, - rialto_parachain_to_this_conversion_rate: Option, - ) -> Option { - estimate_message_dispatch_and_delivery_fee::( - &payload, - WithRialtoParachainMessageBridge::RELAYER_FEE_PERCENT, - rialto_parachain_to_this_conversion_rate, - ).ok() - } - + impl bp_rialto_parachain::ToRialtoParachainOutboundLaneApi for Runtime { fn message_details( lane: bp_messages::LaneId, begin: bp_messages::MessageNonce, end: bp_messages::MessageNonce, - ) -> Vec> { + ) -> Vec { bridge_runtime_common::messages_api::outbound_message_details::< Runtime, WithRialtoParachainMessagesInstance, @@ -1003,10 +958,10 @@ impl_runtime_apis! { } } - impl bp_rialto_parachain::FromRialtoParachainInboundLaneApi for Runtime { + impl bp_rialto_parachain::FromRialtoParachainInboundLaneApi for Runtime { fn message_details( lane: bp_messages::LaneId, - messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, + messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, ) -> Vec { bridge_runtime_common::messages_api::inbound_message_details::< Runtime, @@ -1060,13 +1015,11 @@ impl_runtime_apis! { let mut batches = Vec::::new(); let params = (&config, &whitelist); - use bridge_runtime_common::messages_benchmarking::{prepare_message_delivery_proof, prepare_message_proof, prepare_outbound_message}; - use bridge_runtime_common::messages; + 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, - MessageParams, MessageProofParams, }; use pallet_bridge_parachains::benchmarking::{ @@ -1076,18 +1029,10 @@ impl_runtime_apis! { use rialto_messages::WithRialtoMessageBridge; impl MessagesConfig for Runtime { - fn maximal_message_size() -> u32 { - messages::source::maximal_message_size::() - } - fn bridged_relayer_id() -> Self::InboundRelayer { [0u8; 32].into() } - fn account_balance(account: &Self::AccountId) -> Self::OutboundMessageFee { - pallet_balances::Pallet::::free_balance(account) - } - fn endow_account(account: &Self::AccountId) { pallet_balances::Pallet::::make_free_balance_be( account, @@ -1095,12 +1040,6 @@ impl_runtime_apis! { ); } - fn prepare_outbound_message( - params: MessageParams, - ) -> (rialto_messages::ToRialtoMessagePayload, Balance) { - (prepare_outbound_message::(params), Self::message_fee()) - } - fn prepare_message_proof( params: MessageProofParams, ) -> (rialto_messages::FromRialtoMessagesProof, Weight) { diff --git a/bridges/bin/millau/runtime/src/rialto_messages.rs b/bridges/bin/millau/runtime/src/rialto_messages.rs index c6bc308a8e819..c0868298a3276 100644 --- a/bridges/bin/millau/runtime/src/rialto_messages.rs +++ b/bridges/bin/millau/runtime/src/rialto_messages.rs @@ -21,35 +21,20 @@ use crate::{OriginCaller, RialtoGrandpaInstance, Runtime, RuntimeCall, RuntimeOr use bp_messages::{ source_chain::TargetHeaderChain, target_chain::{ProvedMessages, SourceHeaderChain}, - InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessagesParameter, + InboundLaneData, LaneId, Message, MessageNonce, }; use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_CHAIN_ID}; -use bridge_runtime_common::messages::{ - self, BasicConfirmationTransactionEstimation, MessageBridge, MessageTransaction, -}; -use codec::{Decode, Encode}; -use frame_support::{dispatch::DispatchClass, parameter_types, weights::Weight, RuntimeDebug}; -use scale_info::TypeInfo; -use sp_runtime::{traits::Saturating, FixedPointNumber, FixedU128}; -use sp_std::convert::TryFrom; +use bridge_runtime_common::messages::{self, MessageBridge}; +use frame_support::{parameter_types, weights::Weight, RuntimeDebug}; /// Default lane that is used to send messages to Rialto. pub const DEFAULT_XCM_LANE_TO_RIALTO: LaneId = [0, 0, 0, 0]; -/// Initial value of `RialtoToMillauConversionRate` parameter. -pub const INITIAL_RIALTO_TO_MILLAU_CONVERSION_RATE: FixedU128 = - FixedU128::from_inner(FixedU128::DIV); -/// Initial value of `RialtoFeeMultiplier` parameter. -pub const INITIAL_RIALTO_FEE_MULTIPLIER: FixedU128 = FixedU128::from_inner(FixedU128::DIV); /// Weight of 2 XCM instructions is for simple `Trap(42)` program, coming through bridge /// (it is prepended with `UniversalOrigin` instruction). It is used just for simplest manual /// tests, confirming that we don't break encoding somewhere between. pub const BASE_XCM_WEIGHT_TWICE: u64 = 2 * crate::xcm_config::BASE_XCM_WEIGHT; parameter_types! { - /// Rialto to Millau conversion rate. Initially we treat both tokens as equal. - pub storage RialtoToMillauConversionRate: FixedU128 = INITIAL_RIALTO_TO_MILLAU_CONVERSION_RATE; - /// Fee multiplier value at Rialto chain. - pub storage RialtoFeeMultiplier: FixedU128 = INITIAL_RIALTO_FEE_MULTIPLIER; /// Weight credit for our test messages. /// /// 2 XCM instructions is for simple `Trap(42)` program, coming through bridge @@ -91,7 +76,6 @@ pub type ToRialtoMaximalOutboundPayloadSize = pub struct WithRialtoMessageBridge; impl MessageBridge for WithRialtoMessageBridge { - const RELAYER_FEE_PERCENT: u32 = 10; const THIS_CHAIN_ID: ChainId = MILLAU_CHAIN_ID; const BRIDGED_CHAIN_ID: ChainId = RIALTO_CHAIN_ID; const BRIDGED_MESSAGES_PALLET_NAME: &'static str = bp_millau::WITH_MILLAU_MESSAGES_PALLET_NAME; @@ -100,16 +84,6 @@ impl MessageBridge for WithRialtoMessageBridge { type BridgedChain = Rialto; type BridgedHeaderChain = pallet_bridge_grandpa::GrandpaChainHeaders; - - fn bridged_balance_to_this_balance( - bridged_balance: bp_rialto::Balance, - bridged_to_this_conversion_rate_override: Option, - ) -> bp_millau::Balance { - let conversion_rate = bridged_to_this_conversion_rate_override - .unwrap_or_else(RialtoToMillauConversionRate::get); - bp_millau::Balance::try_from(conversion_rate.saturating_mul_int(bridged_balance)) - .unwrap_or(bp_millau::Balance::MAX) - } } /// Millau chain from message lane point of view. @@ -123,12 +97,6 @@ impl messages::UnderlyingChainProvider for Millau { impl messages::ThisChainWithMessages for Millau { type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; - type ConfirmationTransactionEstimation = BasicConfirmationTransactionEstimation< - bp_millau::AccountId, - { bp_millau::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT.ref_time() }, - { bp_rialto::EXTRA_STORAGE_PROOF_SIZE }, - { bp_millau::TX_EXTRA_BYTES }, - >; fn is_message_accepted(send_origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool { let here_location = @@ -153,21 +121,6 @@ impl messages::ThisChainWithMessages for Millau { fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { MessageNonce::MAX } - - fn transaction_payment(transaction: MessageTransaction) -> bp_millau::Balance { - // `transaction` may represent transaction from the future, when multiplier value will - // be larger, so let's use slightly increased value - let multiplier = FixedU128::saturating_from_rational(110, 100) - .saturating_mul(pallet_transaction_payment::Pallet::::next_fee_multiplier()); - // in our testnets, both per-byte fee and weight-to-fee are 1:1 - messages::transaction_payment( - bp_millau::BlockWeights::get().get(DispatchClass::Normal).base_extrinsic, - 1, - multiplier, - |weight| weight.ref_time() as _, - transaction, - ) - } } /// Rialto chain from message lane point of view. @@ -182,45 +135,6 @@ impl messages::BridgedChainWithMessages for Rialto { fn verify_dispatch_weight(_message_payload: &[u8]) -> bool { true } - - fn estimate_delivery_transaction( - message_payload: &[u8], - include_pay_dispatch_fee_cost: bool, - message_dispatch_weight: Weight, - ) -> MessageTransaction { - let message_payload_len = u32::try_from(message_payload.len()).unwrap_or(u32::MAX); - let extra_bytes_in_payload = message_payload_len - .saturating_sub(pallet_bridge_messages::EXPECTED_DEFAULT_MESSAGE_LENGTH); - - MessageTransaction { - dispatch_weight: bp_rialto::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT - .saturating_mul(extra_bytes_in_payload as u64) - .saturating_add(bp_rialto::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT) - .saturating_sub(if include_pay_dispatch_fee_cost { - Weight::from_ref_time(0) - } else { - bp_rialto::PAY_INBOUND_DISPATCH_FEE_WEIGHT - }) - .saturating_add(message_dispatch_weight), - size: message_payload_len - .saturating_add(bp_millau::EXTRA_STORAGE_PROOF_SIZE) - .saturating_add(bp_rialto::TX_EXTRA_BYTES), - } - } - - fn transaction_payment(transaction: MessageTransaction) -> bp_rialto::Balance { - // we don't have a direct access to the value of multiplier at Rialto chain - // => it is a messages module parameter - let multiplier = RialtoFeeMultiplier::get(); - // in our testnets, both per-byte fee and weight-to-fee are 1:1 - messages::transaction_payment( - bp_rialto::BlockWeights::get().get(DispatchClass::Normal).base_extrinsic, - 1, - multiplier, - |weight| weight.ref_time() as _, - transaction, - ) - } } impl TargetHeaderChain for Rialto { @@ -242,7 +156,7 @@ impl TargetHeaderChain for Rialto } } -impl SourceHeaderChain for Rialto { +impl SourceHeaderChain for Rialto { type Error = &'static str; // The proof is: // - hash of the header this proof has been created with; @@ -254,28 +168,12 @@ impl SourceHeaderChain for Rialto { fn verify_messages_proof( proof: Self::MessagesProof, messages_count: u32, - ) -> Result>, Self::Error> { + ) -> Result, Self::Error> { messages::target::verify_messages_proof::(proof, messages_count) .map_err(Into::into) } } -/// Millau -> Rialto message lane pallet parameters. -#[derive(RuntimeDebug, Clone, Encode, Decode, PartialEq, Eq, TypeInfo)] -pub enum MillauToRialtoMessagesParameter { - /// The conversion formula we use is: `MillauTokens = RialtoTokens * conversion_rate`. - RialtoToMillauConversionRate(FixedU128), -} - -impl MessagesParameter for MillauToRialtoMessagesParameter { - fn save(&self) { - match *self { - MillauToRialtoMessagesParameter::RialtoToMillauConversionRate(ref conversion_rate) => - RialtoToMillauConversionRate::set(conversion_rate), - } - } -} - #[cfg(test)] mod tests { use super::*; @@ -295,13 +193,7 @@ mod tests { fn ensure_millau_message_lane_weights_are_correct() { type Weights = pallet_bridge_messages::weights::BridgeWeight; - pallet_bridge_messages::ensure_weights_are_correct::( - bp_millau::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT, - bp_millau::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT, - bp_millau::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT, - bp_millau::PAY_INBOUND_DISPATCH_FEE_WEIGHT, - DbWeight::get(), - ); + pallet_bridge_messages::ensure_weights_are_correct::(); let max_incoming_message_proof_size = bp_rialto::EXTRA_STORAGE_PROOF_SIZE.saturating_add( messages::target::maximal_incoming_message_size(bp_millau::Millau::max_extrinsic_size()), @@ -366,13 +258,5 @@ mod tests { bp_rialto::WITH_RIALTO_MESSAGES_PALLET_NAME, }, }); - - assert_eq!( - RialtoToMillauConversionRate::key().to_vec(), - bp_runtime::storage_parameter_key( - bp_millau::RIALTO_TO_MILLAU_CONVERSION_RATE_PARAMETER_NAME - ) - .0, - ); } } diff --git a/bridges/bin/millau/runtime/src/rialto_parachain_messages.rs b/bridges/bin/millau/runtime/src/rialto_parachain_messages.rs index da4ca9d83cb2e..8655edd59f491 100644 --- a/bridges/bin/millau/runtime/src/rialto_parachain_messages.rs +++ b/bridges/bin/millau/runtime/src/rialto_parachain_messages.rs @@ -21,17 +21,11 @@ use crate::{Runtime, RuntimeCall, RuntimeOrigin, WithRialtoParachainsInstance}; use bp_messages::{ source_chain::TargetHeaderChain, target_chain::{ProvedMessages, SourceHeaderChain}, - InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessagesParameter, + InboundLaneData, LaneId, Message, MessageNonce, }; use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_PARACHAIN_CHAIN_ID}; -use bridge_runtime_common::messages::{ - self, BasicConfirmationTransactionEstimation, MessageBridge, MessageTransaction, -}; -use codec::{Decode, Encode}; -use frame_support::{dispatch::DispatchClass, parameter_types, weights::Weight, RuntimeDebug}; -use scale_info::TypeInfo; -use sp_runtime::{traits::Saturating, FixedPointNumber, FixedU128}; -use sp_std::convert::TryFrom; +use bridge_runtime_common::messages::{self, MessageBridge}; +use frame_support::{parameter_types, weights::Weight, RuntimeDebug}; /// Default lane that is used to send messages to Rialto parachain. pub const DEFAULT_XCM_LANE_TO_RIALTO_PARACHAIN: LaneId = [0, 0, 0, 0]; @@ -40,18 +34,7 @@ pub const DEFAULT_XCM_LANE_TO_RIALTO_PARACHAIN: LaneId = [0, 0, 0, 0]; /// tests, confirming that we don't break encoding somewhere between. pub const BASE_XCM_WEIGHT_TWICE: u64 = 2 * crate::xcm_config::BASE_XCM_WEIGHT; -/// Initial value of `RialtoParachainToMillauConversionRate` parameter. -pub const INITIAL_RIALTO_PARACHAIN_TO_MILLAU_CONVERSION_RATE: FixedU128 = - FixedU128::from_inner(FixedU128::DIV); -/// Initial value of `RialtoParachainFeeMultiplier` parameter. -pub const INITIAL_RIALTO_PARACHAIN_FEE_MULTIPLIER: FixedU128 = - FixedU128::from_inner(FixedU128::DIV); - parameter_types! { - /// RialtoParachain to Millau conversion rate. Initially we treat both tokens as equal. - pub storage RialtoParachainToMillauConversionRate: FixedU128 = INITIAL_RIALTO_PARACHAIN_TO_MILLAU_CONVERSION_RATE; - /// Fee multiplier value at RialtoParachain chain. - pub storage RialtoParachainFeeMultiplier: FixedU128 = INITIAL_RIALTO_PARACHAIN_FEE_MULTIPLIER; /// Weight credit for our test messages. /// /// 2 XCM instructions is for simple `Trap(42)` program, coming through bridge @@ -95,7 +78,6 @@ pub type ToRialtoParachainMaximalOutboundPayloadSize = pub struct WithRialtoParachainMessageBridge; impl MessageBridge for WithRialtoParachainMessageBridge { - const RELAYER_FEE_PERCENT: u32 = 10; const THIS_CHAIN_ID: ChainId = MILLAU_CHAIN_ID; const BRIDGED_CHAIN_ID: ChainId = RIALTO_PARACHAIN_CHAIN_ID; const BRIDGED_MESSAGES_PALLET_NAME: &'static str = bp_millau::WITH_MILLAU_MESSAGES_PALLET_NAME; @@ -107,16 +89,6 @@ impl MessageBridge for WithRialtoParachainMessageBridge { WithRialtoParachainsInstance, bp_rialto_parachain::RialtoParachain, >; - - fn bridged_balance_to_this_balance( - bridged_balance: bp_rialto_parachain::Balance, - bridged_to_this_conversion_rate_override: Option, - ) -> bp_millau::Balance { - let conversion_rate = bridged_to_this_conversion_rate_override - .unwrap_or_else(RialtoParachainToMillauConversionRate::get); - bp_millau::Balance::try_from(conversion_rate.saturating_mul_int(bridged_balance)) - .unwrap_or(bp_millau::Balance::MAX) - } } /// Millau chain from message lane point of view. @@ -130,12 +102,6 @@ impl messages::UnderlyingChainProvider for Millau { impl messages::ThisChainWithMessages for Millau { type RuntimeCall = RuntimeCall; type RuntimeOrigin = RuntimeOrigin; - type ConfirmationTransactionEstimation = BasicConfirmationTransactionEstimation< - bp_rialto_parachain::AccountId, - { bp_millau::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT.ref_time() }, - { bp_rialto_parachain::EXTRA_STORAGE_PROOF_SIZE }, - { bp_millau::TX_EXTRA_BYTES }, - >; fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool { *lane == DEFAULT_XCM_LANE_TO_RIALTO_PARACHAIN || *lane == [0, 0, 0, 1] @@ -144,21 +110,6 @@ impl messages::ThisChainWithMessages for Millau { fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { MessageNonce::MAX } - - fn transaction_payment(transaction: MessageTransaction) -> bp_millau::Balance { - // `transaction` may represent transaction from the future, when multiplier value will - // be larger, so let's use slightly increased value - let multiplier = FixedU128::saturating_from_rational(110, 100) - .saturating_mul(pallet_transaction_payment::Pallet::::next_fee_multiplier()); - // in our testnets, both per-byte fee and weight-to-fee are 1:1 - messages::transaction_payment( - bp_millau::BlockWeights::get().get(DispatchClass::Normal).base_extrinsic, - 1, - multiplier, - |weight| weight.ref_time() as _, - transaction, - ) - } } /// RialtoParachain chain from message lane point of view. @@ -173,49 +124,6 @@ impl messages::BridgedChainWithMessages for RialtoParachain { fn verify_dispatch_weight(_message_payload: &[u8]) -> bool { true } - - fn estimate_delivery_transaction( - message_payload: &[u8], - include_pay_dispatch_fee_cost: bool, - message_dispatch_weight: Weight, - ) -> MessageTransaction { - let message_payload_len = u32::try_from(message_payload.len()).unwrap_or(u32::MAX); - let extra_bytes_in_payload = message_payload_len - .saturating_sub(pallet_bridge_messages::EXPECTED_DEFAULT_MESSAGE_LENGTH); - - MessageTransaction { - dispatch_weight: bp_rialto_parachain::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT - .saturating_mul(extra_bytes_in_payload as _) - .saturating_add(bp_rialto_parachain::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT) - .saturating_sub(if include_pay_dispatch_fee_cost { - Weight::from_ref_time(0) - } else { - bp_rialto_parachain::PAY_INBOUND_DISPATCH_FEE_WEIGHT - }) - .saturating_add(message_dispatch_weight), - size: message_payload_len - .saturating_add(bp_millau::EXTRA_STORAGE_PROOF_SIZE) - .saturating_add(bp_rialto_parachain::TX_EXTRA_BYTES), - } - } - - fn transaction_payment( - transaction: MessageTransaction, - ) -> bp_rialto_parachain::Balance { - // we don't have a direct access to the value of multiplier at RialtoParachain chain - // => it is a messages module parameter - let multiplier = RialtoParachainFeeMultiplier::get(); - // in our testnets, both per-byte fee and weight-to-fee are 1:1 - messages::transaction_payment( - bp_rialto_parachain::BlockWeights::get() - .get(DispatchClass::Normal) - .base_extrinsic, - 1, - multiplier, - |weight| weight.ref_time() as _, - transaction, - ) - } } impl TargetHeaderChain for RialtoParachain { @@ -237,7 +145,7 @@ impl TargetHeaderChain fo } } -impl SourceHeaderChain for RialtoParachain { +impl SourceHeaderChain for RialtoParachain { type Error = &'static str; // The proof is: // - hash of the header this proof has been created with; @@ -249,7 +157,7 @@ impl SourceHeaderChain for RialtoParachain { fn verify_messages_proof( proof: Self::MessagesProof, messages_count: u32, - ) -> Result>, Self::Error> { + ) -> Result, Self::Error> { messages::target::verify_messages_proof::( proof, messages_count, @@ -257,20 +165,3 @@ impl SourceHeaderChain for RialtoParachain { .map_err(Into::into) } } - -/// Millau -> RialtoParachain message lane pallet parameters. -#[derive(RuntimeDebug, Clone, Encode, Decode, PartialEq, Eq, TypeInfo)] -pub enum MillauToRialtoParachainMessagesParameter { - /// The conversion formula we use is: `MillauTokens = RialtoParachainTokens * conversion_rate`. - RialtoParachainToMillauConversionRate(FixedU128), -} - -impl MessagesParameter for MillauToRialtoParachainMessagesParameter { - fn save(&self) { - match *self { - MillauToRialtoParachainMessagesParameter::RialtoParachainToMillauConversionRate( - ref conversion_rate, - ) => RialtoParachainToMillauConversionRate::set(conversion_rate), - } - } -} diff --git a/bridges/bin/millau/runtime/src/xcm_config.rs b/bridges/bin/millau/runtime/src/xcm_config.rs index 9a5851c8d0552..32b14f27a3b80 100644 --- a/bridges/bin/millau/runtime/src/xcm_config.rs +++ b/bridges/bin/millau/runtime/src/xcm_config.rs @@ -271,7 +271,7 @@ mod tests { fn xcm_messages_are_sent_using_bridge_router() { new_test_ext().execute_with(|| { let xcm: Xcm<()> = vec![Instruction::Trap(42)].into(); - let expected_fee = MultiAssets::from((Here, 4_259_858_152_u64)); + let expected_fee = MultiAssets::from((Here, 1_000_000_u128)); let expected_hash = ([0u8, 0u8, 0u8, 0u8], 1u64).using_encoded(sp_io::hashing::blake2_256); @@ -305,7 +305,7 @@ mod tests { let mut incoming_message = DispatchMessage { key: MessageKey { lane_id: [0, 0, 0, 0], nonce: 1 }, - data: DispatchMessageData { payload: Ok((location, xcm).into()), fee: 0 }, + data: DispatchMessageData { payload: Ok((location, xcm).into()) }, }; let dispatch_weight = MessageDispatcher::dispatch_weight(&mut incoming_message); diff --git a/bridges/bin/rialto-parachain/runtime/src/lib.rs b/bridges/bin/rialto-parachain/runtime/src/lib.rs index c427bfac59a84..c5b9e50d067c0 100644 --- a/bridges/bin/rialto-parachain/runtime/src/lib.rs +++ b/bridges/bin/rialto-parachain/runtime/src/lib.rs @@ -26,14 +26,9 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use crate::millau_messages::{ - ToMillauMessagePayload, WithMillauMessageBridge, DEFAULT_XCM_LANE_TO_MILLAU, -}; +use crate::millau_messages::{WithMillauMessageBridge, DEFAULT_XCM_LANE_TO_MILLAU}; -use bridge_runtime_common::messages::{ - source::{estimate_message_dispatch_and_delivery_fee, XcmBridge, XcmBridgeAdapter}, - MessageBridge, -}; +use bridge_runtime_common::messages::source::{XcmBridge, XcmBridgeAdapter}; use cumulus_pallet_parachain_system::AnyRelayNumber; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; @@ -41,7 +36,7 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{AccountIdLookup, Block as BlockT}, transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, FixedU128, + ApplyExtrinsicResult, }; use sp_std::prelude::*; @@ -557,9 +552,6 @@ parameter_types! { bp_millau::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_millau::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; - // `IdentityFee` is used by Rialto => we may use weight directly - pub const GetDeliveryConfirmationTransactionFee: Balance = - bp_rialto_parachain::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT.ref_time() as _; pub const RootAccountForPayments: Option = None; pub const BridgedChainId: bp_runtime::ChainId = bp_runtime::MILLAU_CHAIN_ID; } @@ -570,17 +562,14 @@ pub type WithMillauMessagesInstance = (); impl pallet_bridge_messages::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_bridge_messages::weights::BridgeWeight; - type Parameter = millau_messages::RialtoParachainToMillauMessagesParameter; type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce; type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; type MaximalOutboundPayloadSize = crate::millau_messages::ToMillauMaximalOutboundPayloadSize; type OutboundPayload = crate::millau_messages::ToMillauMessagePayload; - type OutboundMessageFee = Balance; type InboundPayload = crate::millau_messages::FromMillauMessagePayload; - type InboundMessageFee = bp_millau::Balance; type InboundRelayer = bp_millau::AccountId; type TargetHeaderChain = crate::millau_messages::Millau; @@ -589,7 +578,6 @@ impl pallet_bridge_messages::Config for Runtime { pallet_bridge_relayers::MessageDeliveryAndDispatchPaymentAdapter< Runtime, WithMillauMessagesInstance, - GetDeliveryConfirmationTransactionFee, >; type OnMessageAccepted = (); type OnDeliveryConfirmed = (); @@ -748,24 +736,12 @@ impl_runtime_apis! { } } - impl bp_millau::ToMillauOutboundLaneApi for Runtime { - fn estimate_message_delivery_and_dispatch_fee( - _lane_id: bp_messages::LaneId, - payload: ToMillauMessagePayload, - millau_to_this_conversion_rate: Option, - ) -> Option { - estimate_message_dispatch_and_delivery_fee::( - &payload, - WithMillauMessageBridge::RELAYER_FEE_PERCENT, - millau_to_this_conversion_rate, - ).ok() - } - + impl bp_millau::ToMillauOutboundLaneApi for Runtime { fn message_details( lane: bp_messages::LaneId, begin: bp_messages::MessageNonce, end: bp_messages::MessageNonce, - ) -> Vec> { + ) -> Vec { bridge_runtime_common::messages_api::outbound_message_details::< Runtime, WithMillauMessagesInstance, @@ -773,10 +749,10 @@ impl_runtime_apis! { } } - impl bp_millau::FromMillauInboundLaneApi for Runtime { + impl bp_millau::FromMillauInboundLaneApi for Runtime { fn message_details( lane: bp_messages::LaneId, - messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, + messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, ) -> Vec { bridge_runtime_common::messages_api::inbound_message_details::< Runtime, @@ -882,7 +858,7 @@ mod tests { let xcm: Xcm<()> = vec![Instruction::Trap(42)].into(); let send_result = send_xcm::(dest.into(), xcm); - let expected_fee = MultiAssets::from((Here, Fungibility::Fungible(4_259_858_152_u128))); + let expected_fee = MultiAssets::from((Here, Fungibility::Fungible(1_000_000_u128))); let expected_hash = ([0u8, 0u8, 0u8, 0u8], 1u64).using_encoded(sp_io::hashing::blake2_256); assert_eq!(send_result, Ok((expected_hash, expected_fee)),); @@ -906,7 +882,7 @@ mod tests { let mut incoming_message = DispatchMessage { key: MessageKey { lane_id: [0, 0, 0, 0], nonce: 1 }, - data: DispatchMessageData { payload: Ok((location, xcm).into()), fee: 0 }, + data: DispatchMessageData { payload: Ok((location, xcm).into()) }, }; let dispatch_weight = MessageDispatcher::dispatch_weight(&mut incoming_message); diff --git a/bridges/bin/rialto-parachain/runtime/src/millau_messages.rs b/bridges/bin/rialto-parachain/runtime/src/millau_messages.rs index 60bc038339620..ceabcd57b6663 100644 --- a/bridges/bin/rialto-parachain/runtime/src/millau_messages.rs +++ b/bridges/bin/rialto-parachain/runtime/src/millau_messages.rs @@ -24,35 +24,20 @@ use crate::{MillauGrandpaInstance, OriginCaller, Runtime, RuntimeCall, RuntimeOr use bp_messages::{ source_chain::TargetHeaderChain, target_chain::{ProvedMessages, SourceHeaderChain}, - InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessagesParameter, + InboundLaneData, LaneId, Message, MessageNonce, }; use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_PARACHAIN_CHAIN_ID}; -use bridge_runtime_common::messages::{ - self, BasicConfirmationTransactionEstimation, MessageBridge, MessageTransaction, -}; -use codec::{Decode, Encode}; -use frame_support::{dispatch::DispatchClass, parameter_types, weights::Weight, RuntimeDebug}; -use scale_info::TypeInfo; -use sp_runtime::{traits::Saturating, FixedPointNumber, FixedU128}; -use sp_std::convert::TryFrom; +use bridge_runtime_common::messages::{self, MessageBridge}; +use frame_support::{parameter_types, weights::Weight, RuntimeDebug}; /// Default lane that is used to send messages to Millau. pub const DEFAULT_XCM_LANE_TO_MILLAU: LaneId = [0, 0, 0, 0]; -/// Initial value of `MillauToRialtoParachainConversionRate` parameter. -pub const INITIAL_MILLAU_TO_RIALTO_PARACHAIN_CONVERSION_RATE: FixedU128 = - FixedU128::from_inner(FixedU128::DIV); -/// Initial value of `MillauFeeMultiplier` parameter. -pub const INITIAL_MILLAU_FEE_MULTIPLIER: FixedU128 = FixedU128::from_inner(FixedU128::DIV); /// Weight of 2 XCM instructions is for simple `Trap(42)` program, coming through bridge /// (it is prepended with `UniversalOrigin` instruction). It is used just for simplest manual /// tests, confirming that we don't break encoding somewhere between. pub const BASE_XCM_WEIGHT_TWICE: u64 = 2 * crate::BASE_XCM_WEIGHT; parameter_types! { - /// Millau to RialtoParachain conversion rate. Initially we treat both tokens as equal. - pub storage MillauToRialtoParachainConversionRate: FixedU128 = INITIAL_MILLAU_TO_RIALTO_PARACHAIN_CONVERSION_RATE; - /// Fee multiplier value at Millau chain. - pub storage MillauFeeMultiplier: FixedU128 = INITIAL_MILLAU_FEE_MULTIPLIER; /// Weight credit for our test messages. /// /// 2 XCM instructions is for simple `Trap(42)` program, coming through bridge @@ -94,7 +79,6 @@ pub type ToMillauMaximalOutboundPayloadSize = pub struct WithMillauMessageBridge; impl MessageBridge for WithMillauMessageBridge { - const RELAYER_FEE_PERCENT: u32 = 10; const THIS_CHAIN_ID: ChainId = RIALTO_PARACHAIN_CHAIN_ID; const BRIDGED_CHAIN_ID: ChainId = MILLAU_CHAIN_ID; const BRIDGED_MESSAGES_PALLET_NAME: &'static str = @@ -104,16 +88,6 @@ impl MessageBridge for WithMillauMessageBridge { type BridgedChain = Millau; type BridgedHeaderChain = pallet_bridge_grandpa::GrandpaChainHeaders; - - fn bridged_balance_to_this_balance( - bridged_balance: bp_millau::Balance, - bridged_to_this_conversion_rate_override: Option, - ) -> bp_rialto_parachain::Balance { - let conversion_rate = bridged_to_this_conversion_rate_override - .unwrap_or_else(MillauToRialtoParachainConversionRate::get); - bp_rialto_parachain::Balance::try_from(conversion_rate.saturating_mul_int(bridged_balance)) - .unwrap_or(bp_rialto_parachain::Balance::MAX) - } } /// RialtoParachain chain from message lane point of view. @@ -127,12 +101,6 @@ impl messages::UnderlyingChainProvider for RialtoParachain { impl messages::ThisChainWithMessages for RialtoParachain { type RuntimeCall = RuntimeCall; type RuntimeOrigin = RuntimeOrigin; - type ConfirmationTransactionEstimation = BasicConfirmationTransactionEstimation< - bp_rialto_parachain::AccountId, - { bp_rialto_parachain::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT.ref_time() }, - { bp_millau::EXTRA_STORAGE_PROOF_SIZE }, - { bp_rialto_parachain::TX_EXTRA_BYTES }, - >; fn is_message_accepted(send_origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool { let here_location = xcm::v3::MultiLocation::from(crate::UniversalLocation::get()); @@ -156,25 +124,6 @@ impl messages::ThisChainWithMessages for RialtoParachain { fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { MessageNonce::MAX } - - fn transaction_payment( - transaction: MessageTransaction, - ) -> bp_rialto_parachain::Balance { - // `transaction` may represent transaction from the future, when multiplier value will - // be larger, so let's use slightly increased value - let multiplier = FixedU128::saturating_from_rational(110, 100) - .saturating_mul(pallet_transaction_payment::Pallet::::next_fee_multiplier()); - // in our testnets, both per-byte fee and weight-to-fee are 1:1 - messages::transaction_payment( - bp_rialto_parachain::BlockWeights::get() - .get(DispatchClass::Normal) - .base_extrinsic, - 1, - multiplier, - |weight| weight.ref_time() as _, - transaction, - ) - } } /// Millau chain from message lane point of view. @@ -189,45 +138,6 @@ impl messages::BridgedChainWithMessages for Millau { fn verify_dispatch_weight(_message_payload: &[u8]) -> bool { true } - - fn estimate_delivery_transaction( - message_payload: &[u8], - include_pay_dispatch_fee_cost: bool, - message_dispatch_weight: Weight, - ) -> MessageTransaction { - let message_payload_len = u32::try_from(message_payload.len()).unwrap_or(u32::MAX); - let extra_bytes_in_payload = message_payload_len - .saturating_sub(pallet_bridge_messages::EXPECTED_DEFAULT_MESSAGE_LENGTH); - - MessageTransaction { - dispatch_weight: bp_millau::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT - .saturating_mul(extra_bytes_in_payload as u64) - .saturating_add(bp_millau::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT) - .saturating_sub(if include_pay_dispatch_fee_cost { - Weight::from_ref_time(0) - } else { - bp_millau::PAY_INBOUND_DISPATCH_FEE_WEIGHT - }) - .saturating_add(message_dispatch_weight), - size: message_payload_len - .saturating_add(bp_rialto_parachain::EXTRA_STORAGE_PROOF_SIZE) - .saturating_add(bp_millau::TX_EXTRA_BYTES), - } - } - - fn transaction_payment(transaction: MessageTransaction) -> bp_millau::Balance { - // we don't have a direct access to the value of multiplier at Millau chain - // => it is a messages module parameter - let multiplier = MillauFeeMultiplier::get(); - // in our testnets, both per-byte fee and weight-to-fee are 1:1 - messages::transaction_payment( - bp_millau::BlockWeights::get().get(DispatchClass::Normal).base_extrinsic, - 1, - multiplier, - |weight| weight.ref_time() as _, - transaction, - ) - } } impl TargetHeaderChain for Millau { @@ -249,7 +159,7 @@ impl TargetHeaderChain f } } -impl SourceHeaderChain for Millau { +impl SourceHeaderChain for Millau { type Error = &'static str; // The proof is: // - hash of the header this proof has been created with; @@ -261,25 +171,8 @@ impl SourceHeaderChain for Millau { fn verify_messages_proof( proof: Self::MessagesProof, messages_count: u32, - ) -> Result>, Self::Error> { + ) -> Result, Self::Error> { messages::target::verify_messages_proof::(proof, messages_count) .map_err(Into::into) } } - -/// RialtoParachain -> Millau message lane pallet parameters. -#[derive(RuntimeDebug, Clone, Encode, Decode, PartialEq, Eq, TypeInfo)] -pub enum RialtoParachainToMillauMessagesParameter { - /// The conversion formula we use is: `RialtoParachainTokens = MillauTokens * conversion_rate`. - MillauToRialtoParachainConversionRate(FixedU128), -} - -impl MessagesParameter for RialtoParachainToMillauMessagesParameter { - fn save(&self) { - match *self { - RialtoParachainToMillauMessagesParameter::MillauToRialtoParachainConversionRate( - ref conversion_rate, - ) => MillauToRialtoParachainConversionRate::set(conversion_rate), - } - } -} diff --git a/bridges/bin/rialto/runtime/src/lib.rs b/bridges/bin/rialto/runtime/src/lib.rs index 53b0f821f3e48..3ce0b650dc5f1 100644 --- a/bridges/bin/rialto/runtime/src/lib.rs +++ b/bridges/bin/rialto/runtime/src/lib.rs @@ -32,13 +32,8 @@ pub mod millau_messages; pub mod parachains; pub mod xcm_config; -use crate::millau_messages::{ToMillauMessagePayload, WithMillauMessageBridge}; - use beefy_primitives::{crypto::AuthorityId as BeefyId, mmr::MmrLeafVersion, ValidatorSet}; use bp_runtime::{HeaderId, HeaderIdProvider}; -use bridge_runtime_common::messages::{ - source::estimate_message_dispatch_and_delivery_fee, MessageBridge, -}; use pallet_grandpa::{ fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList, }; @@ -54,7 +49,7 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{AccountIdLookup, Block as BlockT, Keccak256, NumberFor, OpaqueKeys}, transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, FixedPointNumber, FixedU128, Perquintill, + ApplyExtrinsicResult, FixedPointNumber, Perquintill, }; use sp_std::{collections::btree_map::BTreeMap, prelude::*}; #[cfg(feature = "std")] @@ -445,9 +440,6 @@ parameter_types! { bp_millau::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_millau::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; - // `IdentityFee` is used by Rialto => we may use weight directly - pub const GetDeliveryConfirmationTransactionFee: Balance = - bp_rialto::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT.ref_time() as _; pub const RootAccountForPayments: Option = None; pub const BridgedChainId: bp_runtime::ChainId = bp_runtime::MILLAU_CHAIN_ID; } @@ -458,17 +450,14 @@ pub type WithMillauMessagesInstance = (); impl pallet_bridge_messages::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_bridge_messages::weights::BridgeWeight; - type Parameter = millau_messages::RialtoToMillauMessagesParameter; type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce; type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; type MaximalOutboundPayloadSize = crate::millau_messages::ToMillauMaximalOutboundPayloadSize; type OutboundPayload = crate::millau_messages::ToMillauMessagePayload; - type OutboundMessageFee = Balance; type InboundPayload = crate::millau_messages::FromMillauMessagePayload; - type InboundMessageFee = bp_millau::Balance; type InboundRelayer = bp_millau::AccountId; type TargetHeaderChain = crate::millau_messages::Millau; @@ -477,7 +466,6 @@ impl pallet_bridge_messages::Config for Runtime { pallet_bridge_relayers::MessageDeliveryAndDispatchPaymentAdapter< Runtime, WithMillauMessagesInstance, - GetDeliveryConfirmationTransactionFee, >; type OnMessageAccepted = (); type OnDeliveryConfirmed = (); @@ -958,24 +946,12 @@ impl_runtime_apis! { } } - impl bp_millau::ToMillauOutboundLaneApi for Runtime { - fn estimate_message_delivery_and_dispatch_fee( - _lane_id: bp_messages::LaneId, - payload: ToMillauMessagePayload, - millau_to_this_conversion_rate: Option, - ) -> Option { - estimate_message_dispatch_and_delivery_fee::( - &payload, - WithMillauMessageBridge::RELAYER_FEE_PERCENT, - millau_to_this_conversion_rate, - ).ok() - } - + impl bp_millau::ToMillauOutboundLaneApi for Runtime { fn message_details( lane: bp_messages::LaneId, begin: bp_messages::MessageNonce, end: bp_messages::MessageNonce, - ) -> Vec> { + ) -> Vec { bridge_runtime_common::messages_api::outbound_message_details::< Runtime, WithMillauMessagesInstance, @@ -983,10 +959,10 @@ impl_runtime_apis! { } } - impl bp_millau::FromMillauInboundLaneApi for Runtime { + impl bp_millau::FromMillauInboundLaneApi for Runtime { fn message_details( lane: bp_messages::LaneId, - messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, + messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, ) -> Vec { bridge_runtime_common::messages_api::inbound_message_details::< Runtime, diff --git a/bridges/bin/rialto/runtime/src/millau_messages.rs b/bridges/bin/rialto/runtime/src/millau_messages.rs index cf8812eaf9a69..9eb6c82f3678d 100644 --- a/bridges/bin/rialto/runtime/src/millau_messages.rs +++ b/bridges/bin/rialto/runtime/src/millau_messages.rs @@ -21,33 +21,18 @@ use crate::{MillauGrandpaInstance, OriginCaller, Runtime, RuntimeCall, RuntimeOr use bp_messages::{ source_chain::TargetHeaderChain, target_chain::{ProvedMessages, SourceHeaderChain}, - InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessagesParameter, + InboundLaneData, LaneId, Message, MessageNonce, }; use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_CHAIN_ID}; -use bridge_runtime_common::messages::{ - self, BasicConfirmationTransactionEstimation, MessageBridge, MessageTransaction, -}; -use codec::{Decode, Encode}; -use frame_support::{dispatch::DispatchClass, parameter_types, weights::Weight, RuntimeDebug}; -use scale_info::TypeInfo; -use sp_runtime::{traits::Saturating, FixedPointNumber, FixedU128}; -use sp_std::convert::TryFrom; - -/// Initial value of `MillauToRialtoConversionRate` parameter. -pub const INITIAL_MILLAU_TO_RIALTO_CONVERSION_RATE: FixedU128 = - FixedU128::from_inner(FixedU128::DIV); -/// Initial value of `MillauFeeMultiplier` parameter. -pub const INITIAL_MILLAU_FEE_MULTIPLIER: FixedU128 = FixedU128::from_inner(FixedU128::DIV); +use bridge_runtime_common::messages::{self, MessageBridge}; +use frame_support::{parameter_types, weights::Weight, RuntimeDebug}; + /// Weight of 2 XCM instructions is for simple `Trap(42)` program, coming through bridge /// (it is prepended with `UniversalOrigin` instruction). It is used just for simplest manual /// tests, confirming that we don't break encoding somewhere between. pub const BASE_XCM_WEIGHT_TWICE: u64 = 2 * crate::xcm_config::BASE_XCM_WEIGHT; parameter_types! { - /// Millau to Rialto conversion rate. Initially we treat both tokens as equal. - pub storage MillauToRialtoConversionRate: FixedU128 = INITIAL_MILLAU_TO_RIALTO_CONVERSION_RATE; - /// Fee multiplier value at Millau chain. - pub storage MillauFeeMultiplier: FixedU128 = INITIAL_MILLAU_FEE_MULTIPLIER; /// Weight credit for our test messages. /// /// 2 XCM instructions is for simple `Trap(42)` program, coming through bridge @@ -89,7 +74,6 @@ pub type ToMillauMaximalOutboundPayloadSize = pub struct WithMillauMessageBridge; impl MessageBridge for WithMillauMessageBridge { - const RELAYER_FEE_PERCENT: u32 = 10; const THIS_CHAIN_ID: ChainId = RIALTO_CHAIN_ID; const BRIDGED_CHAIN_ID: ChainId = MILLAU_CHAIN_ID; const BRIDGED_MESSAGES_PALLET_NAME: &'static str = bp_rialto::WITH_RIALTO_MESSAGES_PALLET_NAME; @@ -98,16 +82,6 @@ impl MessageBridge for WithMillauMessageBridge { type BridgedChain = Millau; type BridgedHeaderChain = pallet_bridge_grandpa::GrandpaChainHeaders; - - fn bridged_balance_to_this_balance( - bridged_balance: bp_millau::Balance, - bridged_to_this_conversion_rate_override: Option, - ) -> bp_rialto::Balance { - let conversion_rate = bridged_to_this_conversion_rate_override - .unwrap_or_else(MillauToRialtoConversionRate::get); - bp_rialto::Balance::try_from(conversion_rate.saturating_mul_int(bridged_balance)) - .unwrap_or(bp_rialto::Balance::MAX) - } } /// Rialto chain from message lane point of view. @@ -121,12 +95,6 @@ impl messages::UnderlyingChainProvider for Rialto { impl messages::ThisChainWithMessages for Rialto { type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; - type ConfirmationTransactionEstimation = BasicConfirmationTransactionEstimation< - bp_rialto::AccountId, - { bp_rialto::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT.ref_time() }, - { bp_millau::EXTRA_STORAGE_PROOF_SIZE }, - { bp_rialto::TX_EXTRA_BYTES }, - >; fn is_message_accepted(send_origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool { let here_location = @@ -151,21 +119,6 @@ impl messages::ThisChainWithMessages for Rialto { fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { MessageNonce::MAX } - - fn transaction_payment(transaction: MessageTransaction) -> bp_rialto::Balance { - // `transaction` may represent transaction from the future, when multiplier value will - // be larger, so let's use slightly increased value - let multiplier = FixedU128::saturating_from_rational(110, 100) - .saturating_mul(pallet_transaction_payment::Pallet::::next_fee_multiplier()); - // in our testnets, both per-byte fee and weight-to-fee are 1:1 - messages::transaction_payment( - bp_rialto::BlockWeights::get().get(DispatchClass::Normal).base_extrinsic, - 1, - multiplier, - |weight| weight.ref_time() as _, - transaction, - ) - } } /// Millau chain from message lane point of view. @@ -180,45 +133,6 @@ impl messages::BridgedChainWithMessages for Millau { fn verify_dispatch_weight(_message_payload: &[u8]) -> bool { true } - - fn estimate_delivery_transaction( - message_payload: &[u8], - include_pay_dispatch_fee_cost: bool, - message_dispatch_weight: Weight, - ) -> MessageTransaction { - let message_payload_len = u32::try_from(message_payload.len()).unwrap_or(u32::MAX); - let extra_bytes_in_payload = message_payload_len - .saturating_sub(pallet_bridge_messages::EXPECTED_DEFAULT_MESSAGE_LENGTH); - - MessageTransaction { - dispatch_weight: bp_millau::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT - .saturating_mul(extra_bytes_in_payload as u64) - .saturating_add(bp_millau::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT) - .saturating_sub(if include_pay_dispatch_fee_cost { - Weight::from_ref_time(0) - } else { - bp_millau::PAY_INBOUND_DISPATCH_FEE_WEIGHT - }) - .saturating_add(message_dispatch_weight), - size: message_payload_len - .saturating_add(bp_rialto::EXTRA_STORAGE_PROOF_SIZE) - .saturating_add(bp_millau::TX_EXTRA_BYTES), - } - } - - fn transaction_payment(transaction: MessageTransaction) -> bp_millau::Balance { - // we don't have a direct access to the value of multiplier at Millau chain - // => it is a messages module parameter - let multiplier = MillauFeeMultiplier::get(); - // in our testnets, both per-byte fee and weight-to-fee are 1:1 - messages::transaction_payment( - bp_millau::BlockWeights::get().get(DispatchClass::Normal).base_extrinsic, - 1, - multiplier, - |weight| weight.ref_time() as _, - transaction, - ) - } } impl TargetHeaderChain for Millau { @@ -240,7 +154,7 @@ impl TargetHeaderChain for Millau } } -impl SourceHeaderChain for Millau { +impl SourceHeaderChain for Millau { type Error = &'static str; // The proof is: // - hash of the header this proof has been created with; @@ -252,28 +166,12 @@ impl SourceHeaderChain for Millau { fn verify_messages_proof( proof: Self::MessagesProof, messages_count: u32, - ) -> Result>, Self::Error> { + ) -> Result, Self::Error> { messages::target::verify_messages_proof::(proof, messages_count) .map_err(Into::into) } } -/// Rialto -> Millau message lane pallet parameters. -#[derive(RuntimeDebug, Clone, Encode, Decode, PartialEq, Eq, TypeInfo)] -pub enum RialtoToMillauMessagesParameter { - /// The conversion formula we use is: `RialtoTokens = MillauTokens * conversion_rate`. - MillauToRialtoConversionRate(FixedU128), -} - -impl MessagesParameter for RialtoToMillauMessagesParameter { - fn save(&self) { - match *self { - RialtoToMillauMessagesParameter::MillauToRialtoConversionRate(ref conversion_rate) => - MillauToRialtoConversionRate::set(conversion_rate), - } - } -} - #[cfg(test)] mod tests { use super::*; @@ -291,13 +189,7 @@ mod tests { fn ensure_rialto_message_lane_weights_are_correct() { type Weights = pallet_bridge_messages::weights::BridgeWeight; - pallet_bridge_messages::ensure_weights_are_correct::( - bp_rialto::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT, - bp_rialto::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT, - bp_rialto::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT, - bp_rialto::PAY_INBOUND_DISPATCH_FEE_WEIGHT, - DbWeight::get(), - ); + pallet_bridge_messages::ensure_weights_are_correct::(); let max_incoming_message_proof_size = bp_millau::EXTRA_STORAGE_PROOF_SIZE.saturating_add( messages::target::maximal_incoming_message_size(bp_rialto::Rialto::max_extrinsic_size()), @@ -362,13 +254,5 @@ mod tests { bp_millau::WITH_MILLAU_MESSAGES_PALLET_NAME, }, }); - - assert_eq!( - MillauToRialtoConversionRate::key().to_vec(), - bp_runtime::storage_parameter_key( - bp_rialto::MILLAU_TO_RIALTO_CONVERSION_RATE_PARAMETER_NAME - ) - .0, - ); } } diff --git a/bridges/bin/rialto/runtime/src/xcm_config.rs b/bridges/bin/rialto/runtime/src/xcm_config.rs index 780ce710ba9f6..b874ec8ce8534 100644 --- a/bridges/bin/rialto/runtime/src/xcm_config.rs +++ b/bridges/bin/rialto/runtime/src/xcm_config.rs @@ -238,7 +238,7 @@ mod tests { let xcm: Xcm<()> = vec![Instruction::Trap(42)].into(); let send_result = send_xcm::(dest.into(), xcm); - let expected_fee = MultiAssets::from((Here, 4_259_858_152_u128)); + let expected_fee = MultiAssets::from((Here, 1_000_000_u128)); let expected_hash = ([0u8, 0u8, 0u8, 0u8], 1u64).using_encoded(sp_io::hashing::blake2_256); assert_eq!(send_result, Ok((expected_hash, expected_fee)),); @@ -262,7 +262,7 @@ mod tests { let mut incoming_message = DispatchMessage { key: MessageKey { lane_id: [0, 0, 0, 0], nonce: 1 }, - data: DispatchMessageData { payload: Ok((location, xcm).into()), fee: 0 }, + data: DispatchMessageData { payload: Ok((location, xcm).into()) }, }; let dispatch_weight = MessageDispatcher::dispatch_weight(&mut incoming_message); diff --git a/bridges/bin/runtime-common/src/integrity.rs b/bridges/bin/runtime-common/src/integrity.rs index 3b64d1e8afea5..a9a2c06470c97 100644 --- a/bridges/bin/runtime-common/src/integrity.rs +++ b/bridges/bin/runtime-common/src/integrity.rs @@ -88,10 +88,8 @@ macro_rules! assert_bridge_messages_pallet_types( use static_assertions::assert_type_eq_all; assert_type_eq_all!(<$r as MessagesConfig<$i>>::OutboundPayload, FromThisChainMessagePayload); - assert_type_eq_all!(<$r as MessagesConfig<$i>>::OutboundMessageFee, BalanceOf>); assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundPayload, FromBridgedChainMessagePayload>>); - assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundMessageFee, BalanceOf>); assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundRelayer, AccountIdOf>); assert_type_eq_all!(<$r as MessagesConfig<$i>>::TargetHeaderChain, BridgedChain<$bridge>); diff --git a/bridges/bin/runtime-common/src/messages.rs b/bridges/bin/runtime-common/src/messages.rs index 320b91539b945..3bbf6df4f559a 100644 --- a/bridges/bin/runtime-common/src/messages.rs +++ b/bridges/bin/runtime-common/src/messages.rs @@ -24,26 +24,19 @@ use bp_header_chain::{HeaderChain, HeaderChainError}; use bp_messages::{ source_chain::LaneMessageVerifier, target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages}, - InboundLaneData, LaneId, Message, MessageData, MessageKey, MessageNonce, OutboundLaneData, + InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, }; use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, Size, StorageProofChecker}; -use codec::{Decode, DecodeLimit, Encode, MaxEncodedLen}; +use codec::{Decode, DecodeLimit, Encode}; use frame_support::{traits::Get, weights::Weight, RuntimeDebug}; use hash_db::Hasher; use scale_info::TypeInfo; -use sp_runtime::{ - traits::{AtLeast32BitUnsigned, CheckedAdd, CheckedDiv, CheckedMul}, - FixedPointNumber, FixedPointOperand, FixedU128, -}; use sp_std::{convert::TryFrom, fmt::Debug, marker::PhantomData, vec::Vec}; use sp_trie::StorageProof; use xcm::latest::prelude::*; /// Bidirectional message bridge. pub trait MessageBridge { - /// Relayer interest (in percents). - const RELAYER_FEE_PERCENT: u32; - /// Identifier of this chain. const THIS_CHAIN_ID: ChainId; /// Identifier of the Bridged chain. @@ -59,60 +52,6 @@ pub trait MessageBridge { type BridgedChain: BridgedChainWithMessages; /// Bridged header chain. type BridgedHeaderChain: HeaderChain>; - - /// Convert Bridged chain balance into This chain balance. - fn bridged_balance_to_this_balance( - bridged_balance: BalanceOf>, - bridged_to_this_conversion_rate_override: Option, - ) -> BalanceOf>; -} - -/// Message related transaction parameters estimation. -#[derive(RuntimeDebug)] -pub struct MessageTransaction { - /// The estimated dispatch weight of the transaction. - pub dispatch_weight: Weight, - /// The estimated size of the encoded transaction. - pub size: u32, -} - -/// Helper trait for estimating the size and weight of a single message delivery confirmation -/// transaction. -pub trait ConfirmationTransactionEstimation { - // Estimate size and weight of single message delivery confirmation transaction. - fn estimate_delivery_confirmation_transaction() -> MessageTransaction; -} - -/// Default implementation for `ConfirmationTransactionEstimation`. -pub struct BasicConfirmationTransactionEstimation< - AccountId: MaxEncodedLen, - const MAX_CONFIRMATION_TX_WEIGHT: u64, - const EXTRA_STORAGE_PROOF_SIZE: u32, - const TX_EXTRA_BYTES: u32, ->(PhantomData); - -impl< - AccountId: MaxEncodedLen, - const MAX_CONFIRMATION_TX_WEIGHT: u64, - const EXTRA_STORAGE_PROOF_SIZE: u32, - const TX_EXTRA_BYTES: u32, - > ConfirmationTransactionEstimation - for BasicConfirmationTransactionEstimation< - AccountId, - MAX_CONFIRMATION_TX_WEIGHT, - EXTRA_STORAGE_PROOF_SIZE, - TX_EXTRA_BYTES, - > -{ - fn estimate_delivery_confirmation_transaction() -> MessageTransaction { - let inbound_data_size = InboundLaneData::::encoded_size_hint_u32(1, 1); - MessageTransaction { - dispatch_weight: Weight::from_ref_time(MAX_CONFIRMATION_TX_WEIGHT), - size: inbound_data_size - .saturating_add(EXTRA_STORAGE_PROOF_SIZE) - .saturating_add(TX_EXTRA_BYTES), - } - } } /// A trait that provides the type of the underlying chain. @@ -127,9 +66,6 @@ pub trait ThisChainWithMessages: UnderlyingChainProvider { type RuntimeOrigin; /// Call type on the chain. type RuntimeCall: Encode + Decode; - /// Helper for estimating the size and weight of a single message delivery confirmation - /// transaction at this chain. - type ConfirmationTransactionEstimation: ConfirmationTransactionEstimation; /// Do we accept message sent by given origin to given lane? fn is_message_accepted(origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool; @@ -138,14 +74,6 @@ pub trait ThisChainWithMessages: UnderlyingChainProvider { /// /// Any messages over this limit, will be rejected. fn maximal_pending_messages_at_outbound_lane() -> MessageNonce; - - /// Estimate size and weight of single message delivery confirmation transaction at This chain. - fn estimate_delivery_confirmation_transaction() -> MessageTransaction { - Self::ConfirmationTransactionEstimation::estimate_delivery_confirmation_transaction() - } - - /// Returns minimal transaction fee that must be paid for given transaction at This chain. - fn transaction_payment(transaction: MessageTransaction) -> BalanceOf; } /// Bridged chain that has `pallet-bridge-messages` module. @@ -153,17 +81,6 @@ pub trait BridgedChainWithMessages: UnderlyingChainProvider { /// Returns `true` if message dispatch weight is withing expected limits. `false` means /// that the message is too heavy to be sent over the bridge and shall be rejected. fn verify_dispatch_weight(message_payload: &[u8]) -> bool; - - /// Estimate size and weight of single message delivery transaction at the Bridged chain. - fn estimate_delivery_transaction( - message_payload: &[u8], - include_pay_dispatch_fee_cost: bool, - message_dispatch_weight: Weight, - ) -> MessageTransaction; - - /// Returns minimal transaction fee that must be paid for given transaction at the Bridged - /// chain. - fn transaction_payment(transaction: MessageTransaction) -> BalanceOf; } /// This chain in context of message bridge. @@ -188,33 +105,6 @@ pub type CallOf = ::RuntimeCall; /// Raw storage proof type (just raw trie nodes). pub type RawStorageProof = Vec>; -/// Compute fee of transaction at runtime where regular transaction payment pallet is being used. -/// -/// The value of `multiplier` parameter is the expected value of -/// `pallet_transaction_payment::NextFeeMultiplier` at the moment when transaction is submitted. If -/// you're charging this payment in advance (and that's what happens with delivery and confirmation -/// transaction in this crate), then there's a chance that the actual fee will be larger than what -/// is paid in advance. So the value must be chosen carefully. -pub fn transaction_payment( - base_extrinsic_weight: Weight, - per_byte_fee: Balance, - multiplier: FixedU128, - weight_to_fee: impl Fn(Weight) -> Balance, - transaction: MessageTransaction, -) -> Balance { - // base fee is charged for every tx - let base_fee = weight_to_fee(base_extrinsic_weight); - - // non-adjustable per-byte fee - let len_fee = per_byte_fee.saturating_mul(Balance::from(transaction.size)); - - // the adjustable part of the fee - let unadjusted_weight_fee = weight_to_fee(transaction.dispatch_weight); - let adjusted_weight_fee = multiplier.saturating_mul_int(unadjusted_weight_fee); - - base_fee.saturating_add(len_fee).saturating_add(adjusted_weight_fee) -} - /// Sub-module that is declaring types required for processing This -> Bridged chain messages. pub mod source { use super::*; @@ -286,15 +176,9 @@ pub mod source { pub const TOO_MANY_PENDING_MESSAGES: &str = "Too many pending messages at the lane."; /// The error message returned from LaneMessageVerifier when call origin is mismatch. pub const BAD_ORIGIN: &str = "Unable to match the source origin to expected target origin."; - /// The error message returned from LaneMessageVerifier when the message fee is too low. - pub const TOO_LOW_FEE: &str = "Provided fee is below minimal threshold required by the lane."; - impl - LaneMessageVerifier< - OriginOf>, - FromThisChainMessagePayload, - BalanceOf>, - > for FromThisChainMessageVerifier + impl LaneMessageVerifier>, FromThisChainMessagePayload> + for FromThisChainMessageVerifier where B: MessageBridge, // matches requirements from the `frame_system::Config::Origin` @@ -306,10 +190,9 @@ pub mod source { fn verify_message( submitter: &OriginOf>, - delivery_and_dispatch_fee: &BalanceOf>, lane: &LaneId, lane_outbound_data: &OutboundLaneData, - payload: &FromThisChainMessagePayload, + _payload: &FromThisChainMessagePayload, ) -> Result<(), Self::Error> { // reject message if lane is blocked if !ThisChain::::is_message_accepted(submitter, lane) { @@ -325,17 +208,6 @@ pub mod source { return Err(TOO_MANY_PENDING_MESSAGES) } - let minimal_fee_in_this_tokens = estimate_message_dispatch_and_delivery_fee::( - payload, - B::RELAYER_FEE_PERCENT, - None, - )?; - - // compare with actual fee paid - if *delivery_and_dispatch_fee < minimal_fee_in_this_tokens { - return Err(TOO_LOW_FEE) - } - Ok(()) } } @@ -376,52 +248,6 @@ pub mod source { Ok(()) } - /// Estimate delivery and dispatch fee that must be paid for delivering a message to the Bridged - /// chain. - /// - /// The fee is paid in This chain Balance, but we use Bridged chain balance to avoid additional - /// conversions. Returns `None` if overflow has happened. - pub fn estimate_message_dispatch_and_delivery_fee( - payload: &FromThisChainMessagePayload, - relayer_fee_percent: u32, - bridged_to_this_conversion_rate: Option, - ) -> Result>, &'static str> { - // the fee (in Bridged tokens) of all transactions that are made on the Bridged chain - // - // if we're going to pay dispatch fee at the target chain, then we don't include weight - // of the message dispatch in the delivery transaction cost - let delivery_transaction = BridgedChain::::estimate_delivery_transaction( - &payload.encode(), - true, - Weight::zero(), - ); - let delivery_transaction_fee = BridgedChain::::transaction_payment(delivery_transaction); - - // the fee (in This tokens) of all transactions that are made on This chain - let confirmation_transaction = ThisChain::::estimate_delivery_confirmation_transaction(); - let confirmation_transaction_fee = - ThisChain::::transaction_payment(confirmation_transaction); - - // minimal fee (in This tokens) is a sum of all required fees - let minimal_fee = B::bridged_balance_to_this_balance( - delivery_transaction_fee, - bridged_to_this_conversion_rate, - ) - .checked_add(&confirmation_transaction_fee); - - // before returning, add extra fee that is paid to the relayer (relayer interest) - minimal_fee - .and_then(|fee| - // having message with fee that is near the `Balance::MAX_VALUE` of the chain is - // unlikely and should be treated as an error - // => let's do multiplication first - fee - .checked_mul(&relayer_fee_percent.into()) - .and_then(|interest| interest.checked_div(&100u32.into())) - .and_then(|interest| fee.checked_add(&interest))) - .ok_or("Overflow when computing minimal required message delivery and dispatch fee") - } - /// Verify proof of This -> Bridged chain messages delivery. /// /// This function is used when Bridged chain is directly using GRANDPA finality. For Bridged @@ -462,7 +288,6 @@ pub mod source { /// Runtime message sender adapter. type MessageSender: bp_messages::source_chain::MessagesBridge< OriginOf>, - BalanceOf>, FromThisChainMessagePayload, >; @@ -484,7 +309,7 @@ pub mod source { BalanceOf>: Into, OriginOf>: From, { - type Ticket = (BalanceOf>, FromThisChainMessagePayload); + type Ticket = FromThisChainMessagePayload; fn validate( dest: &mut Option, @@ -499,39 +324,22 @@ pub mod source { let route = T::build_destination(); let msg = (route, msg.take().ok_or(SendError::MissingArgument)?).encode(); - let fee = estimate_message_dispatch_and_delivery_fee::( - &msg, - T::MessageBridge::RELAYER_FEE_PERCENT, - None, - ); - let fee = match fee { - Ok(fee) => fee, - Err(e) => { - log::trace!( - target: "runtime::bridge", - "Failed to comupte fee for XCM message to {:?}: {:?}", - T::MessageBridge::BRIDGED_CHAIN_ID, - e, - ); - *dest = Some(d); - return Err(SendError::Transport(e)) - }, - }; - let fee_assets = MultiAssets::from((Here, fee)); + // let's just take fixed (out of thin air) fee per message in our test bridges + // (this code won't be used in production anyway) + let fee_assets = MultiAssets::from((Here, 1_000_000_u128)); - Ok(((fee, msg), fee_assets)) + Ok((msg, fee_assets)) } fn deliver(ticket: Self::Ticket) -> Result { use bp_messages::source_chain::MessagesBridge; let lane = T::xcm_lane(); - let (fee, msg) = ticket; + let msg = ticket; let result = T::MessageSender::send_message( pallet_xcm::Origin::from(MultiLocation::from(T::universal_location())).into(), lane, msg, - fee, ); result .map(|artifacts| { @@ -633,7 +441,7 @@ pub mod target { } impl - MessageDispatch>, BalanceOf>> + MessageDispatch>> for FromBridgedChainMessageDispatch where XcmExecutor: xcm::v3::ExecuteXcm>>, @@ -643,7 +451,7 @@ pub mod target { type DispatchPayload = FromBridgedChainMessagePayload>>; fn dispatch_weight( - message: &mut DispatchMessage>>, + message: &mut DispatchMessage, ) -> frame_support::weights::Weight { match message.data.payload { Ok(ref mut payload) => { @@ -673,7 +481,7 @@ pub mod target { fn dispatch( _relayer_account: &AccountIdOf>, - message: DispatchMessage>>, + message: DispatchMessage, ) -> MessageDispatchResult { let message_id = (message.key.lane_id, message.key.nonce); let do_dispatch = move || -> sp_std::result::Result { @@ -738,7 +546,7 @@ pub mod target { pub fn verify_messages_proof( proof: FromBridgedChainMessagesProof>>, messages_count: u32, - ) -> Result>>>, MessageProofError> { + ) -> Result, MessageProofError> { let FromBridgedChainMessagesProof { bridged_header_hash, storage_proof, @@ -779,11 +587,9 @@ pub mod target { let raw_message_data = parser .read_raw_message(&message_key) .ok_or(MessageProofError::MissingRequiredMessage)?; - let message_data = MessageData::>>::decode( - &mut &raw_message_data[..], - ) - .map_err(|_| MessageProofError::FailedToDecodeMessage)?; - messages.push(Message { key: message_key, data: message_data }); + let payload = MessagePayload::decode(&mut &raw_message_data[..]) + .map_err(|_| MessageProofError::FailedToDecodeMessage)?; + messages.push(Message { key: message_key, payload }); } // Now let's check if proof contains outbound lane state proof. It is optional, so @@ -885,11 +691,6 @@ mod tests { use sp_runtime::traits::{BlakeTwo256, Header as _}; use std::cell::RefCell; - const DELIVERY_TRANSACTION_WEIGHT: Weight = Weight::from_ref_time(100); - const DELIVERY_CONFIRMATION_TRANSACTION_WEIGHT: u64 = 100; - const THIS_CHAIN_WEIGHT_TO_BALANCE_RATE: u32 = 2; - const BRIDGED_CHAIN_WEIGHT_TO_BALANCE_RATE: u32 = 4; - const BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE: u32 = 6; const BRIDGED_CHAIN_MIN_EXTRINSIC_WEIGHT: usize = 5; const BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT: usize = 2048; const BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE: u32 = 1024; @@ -900,7 +701,6 @@ mod tests { struct OnThisChainBridge; impl MessageBridge for OnThisChainBridge { - const RELAYER_FEE_PERCENT: u32 = 10; const THIS_CHAIN_ID: ChainId = *b"this"; const BRIDGED_CHAIN_ID: ChainId = *b"brdg"; const BRIDGED_MESSAGES_PALLET_NAME: &'static str = ""; @@ -908,16 +708,6 @@ mod tests { type ThisChain = ThisChain; type BridgedChain = BridgedChain; type BridgedHeaderChain = BridgedHeaderChain; - - fn bridged_balance_to_this_balance( - bridged_balance: BridgedChainBalance, - bridged_to_this_conversion_rate_override: Option, - ) -> ThisChainBalance { - let conversion_rate = bridged_to_this_conversion_rate_override - .map(|r| r.to_float() as u32) - .unwrap_or(BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE); - bridged_balance as ThisChainBalance * conversion_rate as ThisChainBalance - } } /// Bridge that is deployed on BridgedChain and allows sending/receiving messages to/from @@ -926,7 +716,6 @@ mod tests { struct OnBridgedChainBridge; impl MessageBridge for OnBridgedChainBridge { - const RELAYER_FEE_PERCENT: u32 = 20; const THIS_CHAIN_ID: ChainId = *b"brdg"; const BRIDGED_CHAIN_ID: ChainId = *b"this"; const BRIDGED_MESSAGES_PALLET_NAME: &'static str = ""; @@ -934,13 +723,6 @@ mod tests { type ThisChain = BridgedChain; type BridgedChain = ThisChain; type BridgedHeaderChain = ThisHeaderChain; - - fn bridged_balance_to_this_balance( - _this_balance: ThisChainBalance, - _bridged_to_this_conversion_rate_override: Option, - ) -> BridgedChainBalance { - unreachable!() - } } #[derive(Clone, Debug)] @@ -989,6 +771,7 @@ mod tests { fn max_extrinsic_size() -> u32 { BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE } + fn max_extrinsic_weight() -> Weight { Weight::zero() } @@ -1003,12 +786,6 @@ mod tests { impl ThisChainWithMessages for ThisChain { type RuntimeOrigin = ThisChainOrigin; type RuntimeCall = ThisChainCall; - type ConfirmationTransactionEstimation = BasicConfirmationTransactionEstimation< - ThisChainAccountId, - { DELIVERY_CONFIRMATION_TRANSACTION_WEIGHT }, - 0, - 0, - >; fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool { lane == TEST_LANE_ID @@ -1017,31 +794,12 @@ mod tests { fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { MAXIMAL_PENDING_MESSAGES_AT_TEST_LANE } - - fn transaction_payment(transaction: MessageTransaction) -> BalanceOf { - transaction - .dispatch_weight - .saturating_mul(THIS_CHAIN_WEIGHT_TO_BALANCE_RATE as u64) - .ref_time() as _ - } } impl BridgedChainWithMessages for ThisChain { fn verify_dispatch_weight(_message_payload: &[u8]) -> bool { unreachable!() } - - fn estimate_delivery_transaction( - _message_payload: &[u8], - _include_pay_dispatch_fee_cost: bool, - _message_dispatch_weight: Weight, - ) -> MessageTransaction { - unreachable!() - } - - fn transaction_payment(_transaction: MessageTransaction) -> BalanceOf { - unreachable!() - } } struct BridgedUnderlyingChain; @@ -1078,8 +836,6 @@ mod tests { impl ThisChainWithMessages for BridgedChain { type RuntimeOrigin = BridgedChainOrigin; type RuntimeCall = BridgedChainCall; - type ConfirmationTransactionEstimation = - BasicConfirmationTransactionEstimation; fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, _lane: &LaneId) -> bool { unreachable!() @@ -1088,10 +844,6 @@ mod tests { fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { unreachable!() } - - fn transaction_payment(_transaction: MessageTransaction) -> BalanceOf { - unreachable!() - } } impl BridgedChainWithMessages for BridgedChain { @@ -1099,24 +851,6 @@ mod tests { message_payload.len() >= BRIDGED_CHAIN_MIN_EXTRINSIC_WEIGHT && message_payload.len() <= BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT } - - fn estimate_delivery_transaction( - _message_payload: &[u8], - _include_pay_dispatch_fee_cost: bool, - message_dispatch_weight: Weight, - ) -> MessageTransaction { - MessageTransaction { - dispatch_weight: DELIVERY_TRANSACTION_WEIGHT + message_dispatch_weight, - size: 0, - } - } - - fn transaction_payment(transaction: MessageTransaction) -> BalanceOf { - transaction - .dispatch_weight - .saturating_mul(BRIDGED_CHAIN_WEIGHT_TO_BALANCE_RATE as u64) - .ref_time() as _ - } } thread_local! { @@ -1152,50 +886,11 @@ mod tests { vec![42] } - #[test] - fn message_fee_is_checked_by_verifier() { - const EXPECTED_MINIMAL_FEE: u32 = 2860; - - // payload of the This -> Bridged chain message - let payload = regular_outbound_message_payload(); - - // let's check if estimation matching hardcoded value - assert_eq!( - source::estimate_message_dispatch_and_delivery_fee::( - &payload, - OnThisChainBridge::RELAYER_FEE_PERCENT, - None, - ), - Ok(EXPECTED_MINIMAL_FEE), - ); - - // and now check that the verifier checks the fee - assert_eq!( - source::FromThisChainMessageVerifier::::verify_message( - &ThisChainOrigin(Ok(frame_system::RawOrigin::Root)), - &1, - TEST_LANE_ID, - &test_lane_outbound_data(), - &payload, - ), - Err(source::TOO_LOW_FEE) - ); - assert!(source::FromThisChainMessageVerifier::::verify_message( - &ThisChainOrigin(Ok(frame_system::RawOrigin::Root)), - &1_000_000, - TEST_LANE_ID, - &test_lane_outbound_data(), - &payload, - ) - .is_ok(),); - } - #[test] fn message_is_rejected_when_sent_using_disabled_lane() { assert_eq!( source::FromThisChainMessageVerifier::::verify_message( &ThisChainOrigin(Ok(frame_system::RawOrigin::Root)), - &1_000_000, b"dsbl", &test_lane_outbound_data(), ®ular_outbound_message_payload(), @@ -1209,7 +904,6 @@ mod tests { assert_eq!( source::FromThisChainMessageVerifier::::verify_message( &ThisChainOrigin(Ok(frame_system::RawOrigin::Root)), - &1_000_000, TEST_LANE_ID, &OutboundLaneData { latest_received_nonce: 100, @@ -1267,7 +961,7 @@ mod tests { fn using_messages_proof( nonces_end: MessageNonce, outbound_lane_data: Option, - encode_message: impl Fn(MessageNonce, &MessageData) -> Option>, + encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, test: impl Fn(target::FromBridgedChainMessagesProof) -> R, ) -> R { @@ -1366,10 +1060,9 @@ mod tests { |n, m| { let mut m = m.encode(); if n == 5 { - m = MessageData { fee: 0, payload: vec![0u8; 42] }.encode(); - m.truncate(2); + m = vec![42] } - Some(m.encode()) + Some(m) }, encode_lane_data, |proof| target::verify_messages_proof::(proof, 10), @@ -1464,7 +1157,7 @@ mod tests { }), messages: vec![Message { key: MessageKey { lane_id: *TEST_LANE_ID, nonce: 1 }, - data: MessageData { payload: vec![42], fee: 0 }, + payload: vec![42], }], }, )] @@ -1483,53 +1176,4 @@ mod tests { Err(target::MessageProofError::MessagesCountMismatch), ); } - - #[test] - fn transaction_payment_works_with_zero_multiplier() { - use sp_runtime::traits::Zero; - - assert_eq!( - transaction_payment( - Weight::from_ref_time(100), - 10, - FixedU128::zero(), - |weight| weight.ref_time(), - MessageTransaction { size: 50, dispatch_weight: Weight::from_ref_time(777) }, - ), - 100 + 50 * 10, - ); - } - - #[test] - fn transaction_payment_works_with_non_zero_multiplier() { - use sp_runtime::traits::One; - - assert_eq!( - transaction_payment::( - Weight::from_ref_time(100), - 10, - FixedU128::one(), - |weight| weight.ref_time(), - MessageTransaction { size: 50, dispatch_weight: Weight::from_ref_time(777) }, - ), - 100 + 50 * 10 + 777, - ); - } - - #[test] - fn conversion_rate_override_works() { - let payload = regular_outbound_message_payload(); - let regular_fee = source::estimate_message_dispatch_and_delivery_fee::( - &payload, - OnThisChainBridge::RELAYER_FEE_PERCENT, - None, - ); - let overrided_fee = source::estimate_message_dispatch_and_delivery_fee::( - &payload, - OnThisChainBridge::RELAYER_FEE_PERCENT, - Some(FixedU128::from_float((BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE * 2) as f64)), - ); - - assert!(regular_fee < overrided_fee); - } } diff --git a/bridges/bin/runtime-common/src/messages_api.rs b/bridges/bin/runtime-common/src/messages_api.rs index 28090daee5ae0..199e062fe9826 100644 --- a/bridges/bin/runtime-common/src/messages_api.rs +++ b/bridges/bin/runtime-common/src/messages_api.rs @@ -26,7 +26,7 @@ pub fn outbound_message_details( lane: LaneId, begin: MessageNonce, end: MessageNonce, -) -> Vec> +) -> Vec where Runtime: pallet_bridge_messages::Config, MessagesPalletInstance: 'static, @@ -40,10 +40,7 @@ where // dispatch message weight is always zero at the source chain, since we're paying for // dispatch at the target chain dispatch_weight: frame_support::weights::Weight::zero(), - size: message_data.payload.len() as _, - delivery_and_dispatch_fee: message_data.fee, - // we're delivering XCM messages here, so fee is always paid at the target chain - dispatch_fee_payment: bp_runtime::messages::DispatchFeePayment::AtTargetChain, + size: message_data.len() as _, }) }) .collect() @@ -52,7 +49,7 @@ where /// Implementation of the `To*InboundLaneApi::message_details`. pub fn inbound_message_details( lane: LaneId, - messages: Vec<(MessagePayload, OutboundMessageDetails)>, + messages: Vec<(MessagePayload, OutboundMessageDetails)>, ) -> Vec where Runtime: pallet_bridge_messages::Config, diff --git a/bridges/bin/runtime-common/src/messages_benchmarking.rs b/bridges/bin/runtime-common/src/messages_benchmarking.rs index 24df69dc90a5e..919c03583b882 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -21,8 +21,7 @@ use crate::{ messages::{ - source::{FromBridgedChainMessagesDeliveryProof, FromThisChainMessagePayload}, - target::FromBridgedChainMessagesProof, + source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, AccountIdOf, BalanceOf, BridgedChain, CallOf, HashOf, MessageBridge, ThisChain, }, messages_generation::{ @@ -34,25 +33,12 @@ use bp_messages::storage_keys; use bp_runtime::{record_all_trie_keys, StorageProofSize}; use codec::Encode; use frame_support::{dispatch::GetDispatchInfo, weights::Weight}; -use pallet_bridge_messages::benchmarking::{ - MessageDeliveryProofParams, MessageParams, MessageProofParams, -}; +use pallet_bridge_messages::benchmarking::{MessageDeliveryProofParams, MessageProofParams}; use sp_core::Hasher; use sp_runtime::traits::{Header, MaybeSerializeDeserialize, Zero}; use sp_std::{fmt::Debug, prelude::*}; use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, Recorder, TrieMut}; -/// Prepare outbound message for the `send_message` call. -pub fn prepare_outbound_message( - params: MessageParams>>, -) -> FromThisChainMessagePayload -where - B: MessageBridge, - BalanceOf>: From, -{ - vec![0; params.size as usize] -} - /// Prepare proof of messages for the `receive_messages_proof` call. /// /// In addition to returning valid messages proof, environment is prepared to verify this message diff --git a/bridges/bin/runtime-common/src/messages_extension.rs b/bridges/bin/runtime-common/src/messages_extension.rs index c5fb897b92681..28606d58dadfa 100644 --- a/bridges/bin/runtime-common/src/messages_extension.rs +++ b/bridges/bin/runtime-common/src/messages_extension.rs @@ -31,7 +31,6 @@ use sp_runtime::transaction_validity::TransactionValidity; impl< BridgedHeaderHash, SourceHeaderChain: bp_messages::target_chain::SourceHeaderChain< - >::InboundMessageFee, MessagesProof = FromBridgedChainMessagesProof, >, TargetHeaderChain: bp_messages::source_chain::TargetHeaderChain< diff --git a/bridges/bin/runtime-common/src/messages_generation.rs b/bridges/bin/runtime-common/src/messages_generation.rs index 822b635cc9b63..560033d122a84 100644 --- a/bridges/bin/runtime-common/src/messages_generation.rs +++ b/bridges/bin/runtime-common/src/messages_generation.rs @@ -18,23 +18,19 @@ #![cfg(any(feature = "runtime-benchmarks", test))] -use crate::messages::{BalanceOf, BridgedChain, HashOf, HasherOf, MessageBridge, RawStorageProof}; +use crate::messages::{BridgedChain, HashOf, HasherOf, MessageBridge, RawStorageProof}; use bp_messages::{ - storage_keys, LaneId, MessageData, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, + storage_keys, LaneId, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, }; use bp_runtime::{record_all_trie_keys, StorageProofSize}; use codec::Encode; use sp_core::Hasher; -use sp_runtime::traits::Zero; use sp_std::{ops::RangeInclusive, prelude::*}; use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, Recorder, TrieMut}; /// Simple and correct message data encode function. -pub(crate) fn encode_all_messages( - _: MessageNonce, - m: &MessageData, -) -> Option> { +pub(crate) fn encode_all_messages(_: MessageNonce, m: &MessagePayload) -> Option> { Some(m.encode()) } @@ -52,7 +48,7 @@ pub(crate) fn prepare_messages_storage_proof( outbound_lane_data: Option, size: StorageProofSize, message_payload: MessagePayload, - encode_message: impl Fn(MessageNonce, &MessageData>>) -> Option>, + encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, ) -> (HashOf>, RawStorageProof) where @@ -71,12 +67,8 @@ where // insert messages for nonce in message_nonces { let message_key = MessageKey { lane_id: lane, nonce }; - let message_data = MessageData { - fee: BalanceOf::>::zero(), - payload: message_payload.clone(), - }; - let message_data = match encode_message(nonce, &message_data) { - Some(message_data) => message_data, + let message_payload = match encode_message(nonce, &message_payload) { + Some(message_payload) => message_payload, None => continue, }; let storage_key = storage_keys::message_key( @@ -85,7 +77,7 @@ where message_key.nonce, ) .0; - trie.insert(&storage_key, &message_data) + trie.insert(&storage_key, &message_payload) .map_err(|_| "TrieMut::insert has failed") .expect("TrieMut::insert should not fail in benchmarks"); storage_keys.push(storage_key); diff --git a/bridges/modules/grandpa/src/weights.rs b/bridges/modules/grandpa/src/weights.rs index bb9d5270b54fa..6997713face51 100644 --- a/bridges/modules/grandpa/src/weights.rs +++ b/bridges/modules/grandpa/src/weights.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for `pallet_bridge_grandpa` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-10-04, STEPS: 50, REPEAT: 20 +//! DATE: 2022-11-17, STEPS: 50, REPEAT: 20 //! LOW RANGE: [], HIGH RANGE: [] //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled //! CHAIN: Some("dev"), DB CACHE: 1024 @@ -59,9 +59,9 @@ pub trait WeightInfo { pub struct BridgeWeight(PhantomData); impl WeightInfo for BridgeWeight { fn submit_finality_proof(p: u32, v: u32) -> Weight { - Weight::from_ref_time(105_417_000 as u64) - .saturating_add(Weight::from_ref_time(40_923_000 as u64).saturating_mul(p as u64)) - .saturating_add(Weight::from_ref_time(1_691_000 as u64).saturating_mul(v as u64)) + Weight::from_ref_time(198_274_668 as u64) + .saturating_add(Weight::from_ref_time(39_830_948 as u64).saturating_mul(p as u64)) + .saturating_add(Weight::from_ref_time(1_535_681 as u64).saturating_mul(v as u64)) .saturating_add(T::DbWeight::get().reads(7 as u64)) .saturating_add(T::DbWeight::get().writes(6 as u64)) } @@ -70,9 +70,9 @@ impl WeightInfo for BridgeWeight { // For backwards compatibility and tests impl WeightInfo for () { fn submit_finality_proof(p: u32, v: u32) -> Weight { - Weight::from_ref_time(105_417_000 as u64) - .saturating_add(Weight::from_ref_time(40_923_000 as u64).saturating_mul(p as u64)) - .saturating_add(Weight::from_ref_time(1_691_000 as u64).saturating_mul(v as u64)) + Weight::from_ref_time(198_274_668 as u64) + .saturating_add(Weight::from_ref_time(39_830_948 as u64).saturating_mul(p as u64)) + .saturating_add(Weight::from_ref_time(1_535_681 as u64).saturating_mul(v as u64)) .saturating_add(RocksDbWeight::get().reads(7 as u64)) .saturating_add(RocksDbWeight::get().writes(6 as u64)) } diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index e7650f17214db..254ba6cbace30 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -18,35 +18,25 @@ use crate::{ inbound_lane::InboundLaneStorage, inbound_lane_storage, outbound_lane, - outbound_lane::ReceivalConfirmationResult, weights_ext::EXPECTED_DEFAULT_MESSAGE_LENGTH, Call, - OutboundLanes, OutboundMessages, + weights_ext::EXPECTED_DEFAULT_MESSAGE_LENGTH, Call, OutboundLanes, }; use bp_messages::{ source_chain::TargetHeaderChain, target_chain::SourceHeaderChain, DeliveredMessages, - InboundLaneData, LaneId, MessageData, MessageKey, MessageNonce, OutboundLaneData, - UnrewardedRelayer, UnrewardedRelayersState, + InboundLaneData, LaneId, MessageNonce, OutboundLaneData, UnrewardedRelayer, + UnrewardedRelayersState, }; -use bp_runtime::{messages::DispatchFeePayment, StorageProofSize}; +use bp_runtime::StorageProofSize; use frame_benchmarking::{account, benchmarks_instance_pallet}; -use frame_support::{traits::Get, weights::Weight}; +use frame_support::weights::Weight; use frame_system::RawOrigin; -use sp_std::{collections::vec_deque::VecDeque, convert::TryInto, ops::RangeInclusive, prelude::*}; +use sp_std::{ops::RangeInclusive, prelude::*}; const SEED: u32 = 0; /// Pallet we're benchmarking here. pub struct Pallet, I: 'static>(crate::Pallet); -/// Benchmark-specific message parameters. -#[derive(Debug)] -pub struct MessageParams { - /// Size of the message payload. - pub size: u32, - /// Message sender account. - pub sender_account: ThisAccountId, -} - /// Benchmark-specific message proof parameters. #[derive(Debug)] pub struct MessageProofParams { @@ -58,8 +48,6 @@ pub struct MessageProofParams { pub outbound_lane_data: Option, /// Proof size requirements. pub size: StorageProofSize, - /// Where the fee for dispatching message is paid? - pub dispatch_fee_payment: DispatchFeePayment, } /// Benchmark-specific message delivery proof parameters. @@ -79,29 +67,14 @@ pub trait Config: crate::Config { fn bench_lane_id() -> LaneId { Default::default() } - /// Get maximal size of the message payload. - fn maximal_message_size() -> u32; /// Return id of relayer account at the bridged chain. fn bridged_relayer_id() -> Self::InboundRelayer; - /// Return balance of given account. - fn account_balance(account: &Self::AccountId) -> Self::OutboundMessageFee; /// Create given account and give it enough balance for test purposes. fn endow_account(account: &Self::AccountId); - /// Fee paid by submitter for single message delivery. - fn message_fee() -> Self::OutboundMessageFee { - 100_000_000_000_000.into() - } - /// Prepare message to send over lane. - fn prepare_outbound_message( - params: MessageParams, - ) -> (Self::OutboundPayload, Self::OutboundMessageFee); /// Prepare messages proof to receive by the module. fn prepare_message_proof( params: MessageProofParams, - ) -> ( - >::MessagesProof, - Weight, - ); + ) -> (::MessagesProof, Weight); /// Prepare messages delivery proof to receive by the module. fn prepare_message_delivery_proof( params: MessageDeliveryProofParams, @@ -115,156 +88,6 @@ benchmarks_instance_pallet! { // Benchmarks that are used directly by the runtime. // - // Benchmark `send_message` extrinsic with the worst possible conditions: - // * outbound lane already has state, so it needs to be read and decoded; - // * relayers fund account does not exists (in practice it needs to exist in production environment); - // * maximal number of messages is being pruned during the call; - // * message size is minimal for the target chain. - // - // Result of this benchmark is used as a base weight for `send_message` call. Then the 'message weight' - // (estimated using `send_half_maximal_message_worst_case` and `send_maximal_message_worst_case`) is - // added. - send_minimal_message_worst_case { - let lane_id = T::bench_lane_id(); - let sender = account("sender", 0, SEED); - T::endow_account(&sender); - - // 'send' messages that are to be pruned when our message is sent - for _nonce in 1..=T::MaxMessagesToPruneAtOnce::get() { - send_regular_message::(); - } - confirm_message_delivery::(T::MaxMessagesToPruneAtOnce::get()); - - let (payload, fee) = T::prepare_outbound_message(MessageParams { - size: 0, - sender_account: sender.clone(), - }); - }: send_message(RawOrigin::Signed(sender), lane_id, payload, fee) - verify { - assert_eq!( - crate::OutboundLanes::::get(&T::bench_lane_id()).latest_generated_nonce, - T::MaxMessagesToPruneAtOnce::get() + 1, - ); - } - - // Benchmark `send_message` extrinsic with the worst possible conditions: - // * outbound lane already has state, so it needs to be read and decoded; - // * relayers fund account does not exists (in practice it needs to exist in production environment); - // * maximal number of messages is being pruned during the call; - // * message size is 1KB. - // - // With single KB of message size, the weight of the call is increased (roughly) by - // `(send_16_kb_message_worst_case - send_1_kb_message_worst_case) / 15`. - send_1_kb_message_worst_case { - let lane_id = T::bench_lane_id(); - let sender = account("sender", 0, SEED); - T::endow_account(&sender); - - // 'send' messages that are to be pruned when our message is sent - for _nonce in 1..=T::MaxMessagesToPruneAtOnce::get() { - send_regular_message::(); - } - confirm_message_delivery::(T::MaxMessagesToPruneAtOnce::get()); - - let size = 1024; - assert!( - T::maximal_message_size() > size, - "This benchmark can only be used with runtime that accepts 1KB messages", - ); - - let (payload, fee) = T::prepare_outbound_message(MessageParams { - size, - sender_account: sender.clone(), - }); - }: send_message(RawOrigin::Signed(sender), lane_id, payload, fee) - verify { - assert_eq!( - crate::OutboundLanes::::get(&T::bench_lane_id()).latest_generated_nonce, - T::MaxMessagesToPruneAtOnce::get() + 1, - ); - } - - // Benchmark `send_message` extrinsic with the worst possible conditions: - // * outbound lane already has state, so it needs to be read and decoded; - // * relayers fund account does not exists (in practice it needs to exist in production environment); - // * maximal number of messages is being pruned during the call; - // * message size is 16KB. - // - // With single KB of message size, the weight of the call is increased (roughly) by - // `(send_16_kb_message_worst_case - send_1_kb_message_worst_case) / 15`. - send_16_kb_message_worst_case { - let lane_id = T::bench_lane_id(); - let sender = account("sender", 0, SEED); - T::endow_account(&sender); - - // 'send' messages that are to be pruned when our message is sent - for _nonce in 1..=T::MaxMessagesToPruneAtOnce::get() { - send_regular_message::(); - } - confirm_message_delivery::(T::MaxMessagesToPruneAtOnce::get()); - - let size = 16 * 1024; - assert!( - T::maximal_message_size() > size, - "This benchmark can only be used with runtime that accepts 16KB messages", - ); - - let (payload, fee) = T::prepare_outbound_message(MessageParams { - size, - sender_account: sender.clone(), - }); - }: send_message(RawOrigin::Signed(sender), lane_id, payload, fee) - verify { - assert_eq!( - crate::OutboundLanes::::get(&T::bench_lane_id()).latest_generated_nonce, - T::MaxMessagesToPruneAtOnce::get() + 1, - ); - } - - // Benchmark `increase_message_fee` with following conditions: - // * message has maximal message; - // * submitter account is killed because its balance is less than ED after payment. - // - // Result of this benchmark is directly used by weight formula of the call. - maximal_increase_message_fee { - let sender = account("sender", 42, SEED); - T::endow_account(&sender); - - let additional_fee = T::account_balance(&sender); - let lane_id = T::bench_lane_id(); - let nonce = 1; - - send_regular_message_with_payload::(vec![42u8; T::maximal_message_size() as _]); - }: increase_message_fee(RawOrigin::Signed(sender.clone()), lane_id, nonce, additional_fee) - verify { - assert_eq!( - OutboundMessages::::get(MessageKey { lane_id, nonce }).unwrap().fee, - T::message_fee() + additional_fee, - ); - } - - // Benchmark `increase_message_fee` with following conditions: - // * message size varies from minimal to maximal; - // * submitter account is killed because its balance is less than ED after payment. - increase_message_fee { - let i in 0..T::maximal_message_size().try_into().unwrap_or_default(); - - let sender = account("sender", 42, SEED); - T::endow_account(&sender); - - let additional_fee = T::account_balance(&sender); - let lane_id = T::bench_lane_id(); - let nonce = 1; - - send_regular_message_with_payload::(vec![42u8; i as _]); - }: increase_message_fee(RawOrigin::Signed(sender.clone()), lane_id, nonce, additional_fee) - verify { - assert_eq!( - OutboundMessages::::get(MessageKey { lane_id, nonce }).unwrap().fee, - T::message_fee() + additional_fee, - ); - } - // Benchmark `receive_messages_proof` extrinsic with single minimal-weight message and following conditions: // * proof does not include outbound lane state proof; // * inbound lane already has state, so it needs to be read and decoded; @@ -286,7 +109,6 @@ benchmarks_instance_pallet! { message_nonces: 21..=21, outbound_lane_data: None, size: StorageProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH), - dispatch_fee_payment: DispatchFeePayment::AtTargetChain, }); }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight) verify { @@ -321,7 +143,6 @@ benchmarks_instance_pallet! { message_nonces: 21..=22, outbound_lane_data: None, size: StorageProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH), - dispatch_fee_payment: DispatchFeePayment::AtTargetChain, }); }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 2, dispatch_weight) verify { @@ -360,7 +181,6 @@ benchmarks_instance_pallet! { latest_generated_nonce: 21, }), size: StorageProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH), - dispatch_fee_payment: DispatchFeePayment::AtTargetChain, }); }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight) verify { @@ -392,7 +212,6 @@ benchmarks_instance_pallet! { message_nonces: 21..=21, outbound_lane_data: None, size: StorageProofSize::HasExtraNodes(1024), - dispatch_fee_payment: DispatchFeePayment::AtTargetChain, }); }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight) verify { @@ -427,7 +246,6 @@ benchmarks_instance_pallet! { message_nonces: 21..=21, outbound_lane_data: None, size: StorageProofSize::HasExtraNodes(16 * 1024), - dispatch_fee_payment: DispatchFeePayment::AtTargetChain, }); }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight) verify { @@ -461,7 +279,6 @@ benchmarks_instance_pallet! { message_nonces: 21..=21, outbound_lane_data: None, size: StorageProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH), - dispatch_fee_payment: DispatchFeePayment::AtSourceChain, }); }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight) verify { @@ -479,7 +296,6 @@ benchmarks_instance_pallet! { // This is base benchmark for all other confirmations delivery benchmarks. receive_delivery_proof_for_single_message { let relayer_id: T::AccountId = account("relayer", 0, SEED); - let relayer_balance = T::account_balance(&relayer_id); // send message that we're going to confirm send_regular_message::(); @@ -515,7 +331,6 @@ benchmarks_instance_pallet! { // - weight(receive_delivery_proof_for_single_message)`. receive_delivery_proof_for_two_messages_by_single_relayer { let relayer_id: T::AccountId = account("relayer", 0, SEED); - let relayer_balance = T::account_balance(&relayer_id); // send message that we're going to confirm send_regular_message::(); @@ -554,9 +369,7 @@ benchmarks_instance_pallet! { // - weight(receive_delivery_proof_for_two_messages_by_single_relayer)`. receive_delivery_proof_for_two_messages_by_two_relayers { let relayer1_id: T::AccountId = account("relayer1", 1, SEED); - let relayer1_balance = T::account_balance(&relayer1_id); let relayer2_id: T::AccountId = account("relayer2", 2, SEED); - let relayer2_balance = T::account_balance(&relayer2_id); // send message that we're going to confirm send_regular_message::(); @@ -593,28 +406,7 @@ benchmarks_instance_pallet! { fn send_regular_message, I: 'static>() { let mut outbound_lane = outbound_lane::(T::bench_lane_id()); - outbound_lane.send_message(MessageData { payload: vec![], fee: T::message_fee() }); -} - -fn send_regular_message_with_payload, I: 'static>(payload: Vec) { - let mut outbound_lane = outbound_lane::(T::bench_lane_id()); - outbound_lane.send_message(MessageData { payload, fee: T::message_fee() }); -} - -fn confirm_message_delivery, I: 'static>(nonce: MessageNonce) { - let mut outbound_lane = outbound_lane::(T::bench_lane_id()); - let latest_received_nonce = outbound_lane.data().latest_received_nonce; - let mut relayers = VecDeque::with_capacity((nonce - latest_received_nonce) as usize); - for nonce in latest_received_nonce + 1..=nonce { - relayers.push_back(UnrewardedRelayer { - relayer: (), - messages: DeliveredMessages::new(nonce, true), - }); - } - assert!(matches!( - outbound_lane.confirm_delivery(nonce - latest_received_nonce, nonce, &relayers), - ReceivalConfirmationResult::ConfirmedMessages(_), - )); + outbound_lane.send_message(vec![]); } fn receive_messages, I: 'static>(nonce: MessageNonce) { diff --git a/bridges/modules/messages/src/inbound_lane.rs b/bridges/modules/messages/src/inbound_lane.rs index bee1df06c5a71..ba4483e608c3c 100644 --- a/bridges/modules/messages/src/inbound_lane.rs +++ b/bridges/modules/messages/src/inbound_lane.rs @@ -31,8 +31,6 @@ use sp_std::prelude::PartialEq; /// Inbound lane storage. pub trait InboundLaneStorage { - /// Delivery and dispatch fee type on source chain. - type MessageFee; /// Id of relayer on source chain. type Relayer: Clone + PartialEq; @@ -183,12 +181,12 @@ impl InboundLane { } /// Receive new message. - pub fn receive_message, AccountId>( + pub fn receive_message, AccountId>( &mut self, relayer_at_bridged_chain: &S::Relayer, relayer_at_this_chain: &AccountId, nonce: MessageNonce, - message_data: DispatchMessageData, + message_data: DispatchMessageData, ) -> ReceivalResult { let mut data = self.storage.data(); let is_correct_message = nonce == data.last_delivered_nonce() + 1; @@ -242,9 +240,9 @@ mod tests { use crate::{ inbound_lane, mock::{ - dispatch_result, message_data, run_test, unrewarded_relayer, TestMessageDispatch, - TestRuntime, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_RELAYER_A, TEST_RELAYER_B, - TEST_RELAYER_C, + dispatch_result, inbound_message_data, run_test, unrewarded_relayer, + TestMessageDispatch, TestRuntime, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_RELAYER_A, + TEST_RELAYER_B, TEST_RELAYER_C, }, RuntimeInboundLaneStorage, }; @@ -258,7 +256,7 @@ mod tests { &TEST_RELAYER_A, &TEST_RELAYER_A, nonce, - message_data(REGULAR_PAYLOAD).into() + inbound_message_data(REGULAR_PAYLOAD) ), ReceivalResult::Dispatched(dispatch_result(0)) ); @@ -386,7 +384,7 @@ mod tests { &TEST_RELAYER_A, &TEST_RELAYER_A, 10, - message_data(REGULAR_PAYLOAD).into() + inbound_message_data(REGULAR_PAYLOAD) ), ReceivalResult::InvalidNonce ); @@ -406,7 +404,7 @@ mod tests { &(TEST_RELAYER_A + current_nonce), &(TEST_RELAYER_A + current_nonce), current_nonce, - message_data(REGULAR_PAYLOAD).into() + inbound_message_data(REGULAR_PAYLOAD) ), ReceivalResult::Dispatched(dispatch_result(0)) ); @@ -417,7 +415,7 @@ mod tests { &(TEST_RELAYER_A + max_nonce + 1), &(TEST_RELAYER_A + max_nonce + 1), max_nonce + 1, - message_data(REGULAR_PAYLOAD).into() + inbound_message_data(REGULAR_PAYLOAD) ), ReceivalResult::TooManyUnrewardedRelayers, ); @@ -427,7 +425,7 @@ mod tests { &(TEST_RELAYER_A + max_nonce), &(TEST_RELAYER_A + max_nonce), max_nonce + 1, - message_data(REGULAR_PAYLOAD).into() + inbound_message_data(REGULAR_PAYLOAD) ), ReceivalResult::TooManyUnrewardedRelayers, ); @@ -445,7 +443,7 @@ mod tests { &TEST_RELAYER_A, &TEST_RELAYER_A, current_nonce, - message_data(REGULAR_PAYLOAD).into() + inbound_message_data(REGULAR_PAYLOAD) ), ReceivalResult::Dispatched(dispatch_result(0)) ); @@ -456,7 +454,7 @@ mod tests { &TEST_RELAYER_B, &TEST_RELAYER_B, max_nonce + 1, - message_data(REGULAR_PAYLOAD).into() + inbound_message_data(REGULAR_PAYLOAD) ), ReceivalResult::TooManyUnconfirmedMessages, ); @@ -466,7 +464,7 @@ mod tests { &TEST_RELAYER_A, &TEST_RELAYER_A, max_nonce + 1, - message_data(REGULAR_PAYLOAD).into() + inbound_message_data(REGULAR_PAYLOAD) ), ReceivalResult::TooManyUnconfirmedMessages, ); @@ -482,7 +480,7 @@ mod tests { &TEST_RELAYER_A, &TEST_RELAYER_A, 1, - message_data(REGULAR_PAYLOAD).into() + inbound_message_data(REGULAR_PAYLOAD) ), ReceivalResult::Dispatched(dispatch_result(0)) ); @@ -491,7 +489,7 @@ mod tests { &TEST_RELAYER_B, &TEST_RELAYER_B, 2, - message_data(REGULAR_PAYLOAD).into() + inbound_message_data(REGULAR_PAYLOAD) ), ReceivalResult::Dispatched(dispatch_result(0)) ); @@ -500,7 +498,7 @@ mod tests { &TEST_RELAYER_A, &TEST_RELAYER_A, 3, - message_data(REGULAR_PAYLOAD).into() + inbound_message_data(REGULAR_PAYLOAD) ), ReceivalResult::Dispatched(dispatch_result(0)) ); @@ -524,7 +522,7 @@ mod tests { &TEST_RELAYER_A, &TEST_RELAYER_A, 1, - message_data(REGULAR_PAYLOAD).into() + inbound_message_data(REGULAR_PAYLOAD) ), ReceivalResult::Dispatched(dispatch_result(0)) ); @@ -533,7 +531,7 @@ mod tests { &TEST_RELAYER_B, &TEST_RELAYER_B, 1, - message_data(REGULAR_PAYLOAD).into() + inbound_message_data(REGULAR_PAYLOAD) ), ReceivalResult::InvalidNonce, ); @@ -560,7 +558,7 @@ mod tests { &TEST_RELAYER_A, &TEST_RELAYER_A, 1, - message_data(payload).into() + inbound_message_data(payload) ), ReceivalResult::Dispatched(dispatch_result(1)) ); diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index 66f568e698c9e..d6a5ffe453c0b 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -38,7 +38,7 @@ #![allow(clippy::unused_unit)] pub use inbound_lane::StoredInboundLaneData; -pub use outbound_lane::StoredMessageData; +pub use outbound_lane::StoredMessagePayload; pub use weights::WeightInfo; pub use weights_ext::{ ensure_able_to_receive_confirmation, ensure_able_to_receive_message, @@ -59,17 +59,16 @@ use bp_messages::{ DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain, }, total_unrewarded_messages, DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId, - MessageData, MessageKey, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData, - OutboundMessageDetails, Parameter as MessagesParameter, UnrewardedRelayer, - UnrewardedRelayersState, + MessageKey, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData, + OutboundMessageDetails, UnrewardedRelayer, UnrewardedRelayersState, }; use bp_runtime::{BasicOperatingMode, ChainId, OwnedBridgeModule, Size}; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{dispatch::PostDispatchInfo, ensure, fail, traits::Get}; -use num_traits::{SaturatingAdd, Zero}; +use num_traits::Zero; use sp_std::{ - cell::RefCell, cmp::PartialOrd, collections::vec_deque::VecDeque, marker::PhantomData, - ops::RangeInclusive, prelude::*, + cell::RefCell, collections::vec_deque::VecDeque, marker::PhantomData, ops::RangeInclusive, + prelude::*, }; mod inbound_lane; @@ -108,11 +107,6 @@ pub mod pallet { /// Gets the chain id value from the instance. #[pallet::constant] type BridgedChainId: Get; - /// Pallet parameter that is opaque to the pallet itself, but may be used by the runtime - /// for integrating the pallet. - /// - /// All pallet parameters may only be updated either by the root, or by the pallet owner. - type Parameter: MessagesParameter; /// Maximal number of messages that may be pruned during maintenance. Maintenance occurs /// whenever new message is sent. The reason is that if you want to use lane, you should @@ -142,25 +136,14 @@ pub mod pallet { /// these messages are from different lanes. type MaxUnconfirmedMessagesAtInboundLane: Get; - /// Maximal size of the outbound payload. + /// Maximal encoded size of the outbound payload. #[pallet::constant] type MaximalOutboundPayloadSize: Get; /// Payload type of outbound messages. This payload is dispatched on the bridged chain. type OutboundPayload: Parameter + Size; - /// Message fee type of outbound messages. This fee is paid on this chain. - type OutboundMessageFee: Default - + From - + PartialOrd - + Parameter - + SaturatingAdd - + Zero - + Copy - + MaxEncodedLen; /// Payload type of inbound messages. This payload is dispatched on this chain. type InboundPayload: Decode; - /// Message fee type of inbound messages. This fee is paid on the bridged chain. - type InboundMessageFee: Decode + Zero; /// Identifier of relayer that deliver messages to this chain. Relayer reward is paid on the /// bridged chain. type InboundRelayer: Parameter + MaxEncodedLen; @@ -170,16 +153,11 @@ pub mod pallet { /// Target header chain. type TargetHeaderChain: TargetHeaderChain; /// Message payload verifier. - type LaneMessageVerifier: LaneMessageVerifier< - Self::RuntimeOrigin, - Self::OutboundPayload, - Self::OutboundMessageFee, - >; + type LaneMessageVerifier: LaneMessageVerifier; /// Message delivery payment. type MessageDeliveryAndDispatchPayment: MessageDeliveryAndDispatchPayment< Self::RuntimeOrigin, Self::AccountId, - Self::OutboundMessageFee, >; /// Handler for accepted messages. type OnMessageAccepted: OnMessageAccepted; @@ -189,19 +167,17 @@ pub mod pallet { // Types that are used by inbound_lane (on target chain). /// Source header chain, as it is represented on target chain. - type SourceHeaderChain: SourceHeaderChain; + type SourceHeaderChain: SourceHeaderChain; /// Message dispatch. type MessageDispatch: MessageDispatch< Self::AccountId, - Self::InboundMessageFee, DispatchPayload = Self::InboundPayload, >; } /// Shortcut to messages proof type for Config. - type MessagesProofOf = <>::SourceHeaderChain as SourceHeaderChain< - >::InboundMessageFee, - >>::MessagesProof; + type MessagesProofOf = + <>::SourceHeaderChain as SourceHeaderChain>::MessagesProof; /// Shortcut to messages delivery proof type for Config. type MessagesDeliveryProofOf = <>::TargetHeaderChain as TargetHeaderChain< @@ -241,101 +217,6 @@ pub mod pallet { >::set_operating_mode(origin, operating_mode) } - /// Update pallet parameter. - /// - /// May only be called either by root, or by `PalletOwner`. - /// - /// The weight is: single read for permissions check + 2 writes for parameter value and - /// event. - #[pallet::weight((T::DbWeight::get().reads_writes(1, 2), DispatchClass::Operational))] - pub fn update_pallet_parameter( - origin: OriginFor, - parameter: T::Parameter, - ) -> DispatchResult { - Self::ensure_owner_or_root(origin)?; - parameter.save(); - Self::deposit_event(Event::ParameterUpdated { parameter }); - Ok(()) - } - - /// Send message over lane. - #[pallet::weight(T::WeightInfo::send_message_weight(payload, T::DbWeight::get()))] - pub fn send_message( - origin: OriginFor, - lane_id: LaneId, - payload: T::OutboundPayload, - delivery_and_dispatch_fee: T::OutboundMessageFee, - ) -> DispatchResultWithPostInfo { - crate::send_message::(origin, lane_id, payload, delivery_and_dispatch_fee).map( - |sent_message| PostDispatchInfo { - actual_weight: Some(sent_message.weight), - pays_fee: Pays::Yes, - }, - ) - } - - /// Pay additional fee for the message. - #[pallet::weight(T::WeightInfo::maximal_increase_message_fee())] - pub fn increase_message_fee( - origin: OriginFor, - lane_id: LaneId, - nonce: MessageNonce, - additional_fee: T::OutboundMessageFee, - ) -> DispatchResultWithPostInfo { - Self::ensure_not_halted().map_err(Error::::BridgeModule)?; - // if someone tries to pay for already-delivered message, we're rejecting this intention - // (otherwise this additional fee will be locked forever in relayers fund) - // - // if someone tries to pay for not-yet-sent message, we're rejecting this intention, or - // we're risking to have mess in the storage - let lane = outbound_lane::(lane_id); - ensure!( - nonce > lane.data().latest_received_nonce, - Error::::MessageIsAlreadyDelivered - ); - ensure!( - nonce <= lane.data().latest_generated_nonce, - Error::::MessageIsNotYetSent - ); - - // withdraw additional fee from submitter - T::MessageDeliveryAndDispatchPayment::pay_delivery_and_dispatch_fee( - &origin, - &additional_fee, - ) - .map_err(|err| { - log::trace!( - target: LOG_TARGET, - "Submitter can't pay additional fee {:?} for the message {:?}/{:?}: {:?}", - additional_fee, - lane_id, - nonce, - err, - ); - - Error::::FailedToWithdrawMessageFee - })?; - - // and finally update fee in the storage - let message_key = MessageKey { lane_id, nonce }; - let message_size = OutboundMessages::::mutate(message_key, |message_data| { - // saturating_add is fine here - overflow here means that someone controls all - // chain funds, which shouldn't ever happen + `pay_delivery_and_dispatch_fee` - // above will fail before we reach here - let message_data = message_data.as_mut().expect( - "the message is sent and not yet delivered; so it is in the storage; qed", - ); - message_data.fee = message_data.fee.saturating_add(&additional_fee); - message_data.payload.len() - }); - - // compute actual dispatch weight that depends on the stored message size - let actual_weight = T::WeightInfo::maximal_increase_message_fee() - .min(T::WeightInfo::increase_message_fee(message_size as _)); - - Ok(PostDispatchInfo { actual_weight: Some(actual_weight), pays_fee: Pays::Yes }) - } - /// Receive messages proof from bridged chain. /// /// The weight of the call assumes that the transaction always brings outbound lane @@ -378,7 +259,6 @@ pub mod pallet { // verify messages proof && convert proof into messages let messages = verify_and_decode_messages_proof::< T::SourceHeaderChain, - T::InboundMessageFee, T::InboundPayload, >(proof, messages_count) .map_err(|err| { @@ -636,8 +516,6 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event, I: 'static = ()> { - /// Pallet parameter has been updated. - ParameterUpdated { parameter: T::Parameter }, /// Message has been accepted and is waiting to be delivered. MessageAccepted { lane_id: LaneId, nonce: MessageNonce }, /// Messages in the inclusive range have been delivered to the bridged chain. @@ -709,7 +587,7 @@ pub mod pallet { /// All queued outbound messages. #[pallet::storage] pub type OutboundMessages, I: 'static = ()> = - StorageMap<_, Blake2_128Concat, MessageKey, StoredMessageData>; + StorageMap<_, Blake2_128Concat, MessageKey, StoredMessagePayload>; #[pallet::genesis_config] pub struct GenesisConfig, I: 'static = ()> { @@ -744,10 +622,7 @@ pub mod pallet { impl, I: 'static> Pallet { /// Get stored data of the outbound message with given nonce. - pub fn outbound_message_data( - lane: LaneId, - nonce: MessageNonce, - ) -> Option> { + pub fn outbound_message_data(lane: LaneId, nonce: MessageNonce) -> Option { OutboundMessages::::get(MessageKey { lane_id: lane, nonce }).map(Into::into) } @@ -755,12 +630,11 @@ pub mod pallet { pub fn inbound_message_data( lane: LaneId, payload: MessagePayload, - outbound_details: OutboundMessageDetails, + outbound_details: OutboundMessageDetails, ) -> InboundMessageDetails { let mut dispatch_message = DispatchMessage { key: MessageKey { lane_id: lane, nonce: outbound_details.nonce }, - data: MessageData { payload, fee: outbound_details.delivery_and_dispatch_fee } - .into(), + data: payload.into(), }; InboundMessageDetails { dispatch_weight: T::MessageDispatch::dispatch_weight(&mut dispatch_message), @@ -769,12 +643,8 @@ pub mod pallet { } } -impl - bp_messages::source_chain::MessagesBridge< - T::RuntimeOrigin, - T::OutboundMessageFee, - T::OutboundPayload, - > for Pallet +impl bp_messages::source_chain::MessagesBridge + for Pallet where T: Config, I: 'static, @@ -785,9 +655,8 @@ where sender: T::RuntimeOrigin, lane: LaneId, message: T::OutboundPayload, - delivery_and_dispatch_fee: T::OutboundMessageFee, ) -> Result { - crate::send_message::(sender, lane, message, delivery_and_dispatch_fee) + crate::send_message::(sender, lane, message) } } @@ -796,21 +665,14 @@ fn send_message, I: 'static>( submitter: T::RuntimeOrigin, lane_id: LaneId, payload: T::OutboundPayload, - delivery_and_dispatch_fee: T::OutboundMessageFee, ) -> sp_std::result::Result< SendMessageArtifacts, sp_runtime::DispatchErrorWithPostInfo, > { ensure_normal_operating_mode::()?; - // the most lightweigh check is the message size check - ensure!( - payload.size() <= T::MaximalOutboundPayloadSize::get(), - Error::::MessageIsTooLarge, - ); - // initially, actual (post-dispatch) weight is equal to pre-dispatch weight - let mut actual_weight = T::WeightInfo::send_message_weight(&payload, T::DbWeight::get()); + let mut actual_weight = frame_support::weights::Weight::zero(); // TODO (https://github.com/paritytech/parity-bridges-common/issues/1647): remove this // let's first check if message can be delivered to target chain T::TargetHeaderChain::verify_message(&payload).map_err(|err| { @@ -826,46 +688,28 @@ fn send_message, I: 'static>( // now let's enforce any additional lane rules let mut lane = outbound_lane::(lane_id); - T::LaneMessageVerifier::verify_message( - &submitter, - &delivery_and_dispatch_fee, - &lane_id, - &lane.data(), - &payload, - ) - .map_err(|err| { - log::trace!( - target: LOG_TARGET, - "Message to lane {:?} is rejected by lane verifier: {:?}", - lane_id, - err, - ); - - Error::::MessageRejectedByLaneVerifier - })?; - - // let's withdraw delivery and dispatch fee from submitter - T::MessageDeliveryAndDispatchPayment::pay_delivery_and_dispatch_fee( - &submitter, - &delivery_and_dispatch_fee, - ) - .map_err(|err| { - log::trace!( - target: LOG_TARGET, - "Message to lane {:?} is rejected because submitter is unable to pay fee {:?}: {:?}", - lane_id, - delivery_and_dispatch_fee, - err, - ); + T::LaneMessageVerifier::verify_message(&submitter, &lane_id, &lane.data(), &payload).map_err( + |err| { + log::trace!( + target: LOG_TARGET, + "Message to lane {:?} is rejected by lane verifier: {:?}", + lane_id, + err, + ); - Error::::FailedToWithdrawMessageFee - })?; + Error::::MessageRejectedByLaneVerifier + }, + )?; // finally, save message in outbound storage and emit event let encoded_payload = payload.encode(); let encoded_payload_len = encoded_payload.len(); - let nonce = - lane.send_message(MessageData { payload: encoded_payload, fee: delivery_and_dispatch_fee }); + ensure!( + encoded_payload_len <= T::MaximalOutboundPayloadSize::get() as usize, + Error::::MessageIsTooLarge + ); + let nonce = lane.send_message(encoded_payload); + // Guaranteed to be called outside only when the message is accepted. // We assume that the maximum weight call back used is `single_message_callback_overhead`, so do // not perform complex db operation in callback. If you want to, put these magic logic in @@ -920,32 +764,26 @@ fn send_message, I: 'static>( Ok(SendMessageArtifacts { nonce, weight: actual_weight }) } -/// Calculate the relayers rewards +/// Calculate the number of messages that the relayers have delivered. pub fn calc_relayers_rewards( - lane_id: LaneId, messages_relayers: VecDeque>, received_range: &RangeInclusive, -) -> RelayersRewards +) -> RelayersRewards where T: frame_system::Config + crate::Config, I: 'static, { // remember to reward relayers that have delivered messages // this loop is bounded by `T::MaxUnrewardedRelayerEntriesAtInboundLane` on the bridged chain - let mut relayers_rewards: RelayersRewards<_, T::OutboundMessageFee> = RelayersRewards::new(); + let mut relayers_rewards = RelayersRewards::new(); for entry in messages_relayers { let nonce_begin = sp_std::cmp::max(entry.messages.begin, *received_range.start()); let nonce_end = sp_std::cmp::min(entry.messages.end, *received_range.end()); // loop won't proceed if current entry is ahead of received range (begin > end). // this loop is bound by `T::MaxUnconfirmedMessagesAtInboundLane` on the bridged chain - let mut relayer_reward = relayers_rewards.entry(entry.relayer).or_default(); - for nonce in nonce_begin..=nonce_end { - let key = MessageKey { lane_id, nonce }; - let message_data = OutboundMessages::::get(key) - .expect("message was just confirmed; we never prune unconfirmed messages; qed"); - relayer_reward.reward = relayer_reward.reward.saturating_add(&message_data.fee); - relayer_reward.messages += 1; + if nonce_end >= nonce_begin { + *relayers_rewards.entry(entry.relayer).or_default() += nonce_end - nonce_begin + 1; } } relayers_rewards @@ -995,7 +833,6 @@ struct RuntimeInboundLaneStorage, I: 'static = ()> { } impl, I: 'static> InboundLaneStorage for RuntimeInboundLaneStorage { - type MessageFee = T::InboundMessageFee; type Relayer = T::InboundRelayer; fn id(&self) -> LaneId { @@ -1041,8 +878,6 @@ struct RuntimeOutboundLaneStorage { } impl, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorage { - type MessageFee = T::OutboundMessageFee; - fn id(&self) -> LaneId { self.lane_id } @@ -1056,17 +891,20 @@ impl, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorag } #[cfg(test)] - fn message(&self, nonce: &MessageNonce) -> Option> { + fn message(&self, nonce: &MessageNonce) -> Option { OutboundMessages::::get(MessageKey { lane_id: self.lane_id, nonce: *nonce }) .map(Into::into) } - fn save_message( - &mut self, - nonce: MessageNonce, - mesage_data: MessageData, - ) { - OutboundMessages::::insert(MessageKey { lane_id: self.lane_id, nonce }, mesage_data); + fn save_message(&mut self, nonce: MessageNonce, message_payload: MessagePayload) { + OutboundMessages::::insert( + MessageKey { lane_id: self.lane_id, nonce }, + StoredMessagePayload::::try_from(message_payload).expect( + "save_message is called after all checks in send_message; \ + send_message checks message size; \ + qed", + ), + ); } fn remove_message(&mut self, nonce: &MessageNonce) { @@ -1075,10 +913,10 @@ impl, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorag } /// Verify messages proof and return proved messages with decoded payload. -fn verify_and_decode_messages_proof, Fee, DispatchPayload: Decode>( +fn verify_and_decode_messages_proof( proof: Chain::MessagesProof, messages_count: u32, -) -> Result>, Chain::Error> { +) -> Result>, Chain::Error> { // `receive_messages_proof` weight formula and `MaxUnconfirmedMessagesAtInboundLane` check // guarantees that the `message_count` is sane and Vec may be allocated. // (tx with too many messages will either be rejected from the pool, or will fail earlier) @@ -1102,12 +940,12 @@ fn verify_and_decode_messages_proof, Fee, Dispatch mod tests { use super::*; use crate::mock::{ - message, message_payload, run_test, unrewarded_relayer, Balance, RuntimeEvent as TestEvent, + message, message_payload, run_test, unrewarded_relayer, RuntimeEvent as TestEvent, RuntimeOrigin, TestMessageDeliveryAndDispatchPayment, TestMessagesDeliveryProof, - TestMessagesParameter, TestMessagesProof, TestOnDeliveryConfirmed1, - TestOnDeliveryConfirmed2, TestOnMessageAccepted, TestRuntime, TokenConversionRate, - MAX_OUTBOUND_PAYLOAD_SIZE, PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID, - TEST_RELAYER_A, TEST_RELAYER_B, + TestMessagesProof, TestOnDeliveryConfirmed1, TestOnDeliveryConfirmed2, + TestOnMessageAccepted, TestRuntime, MAX_OUTBOUND_PAYLOAD_SIZE, + PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_RELAYER_A, + TEST_RELAYER_B, }; use bp_messages::{UnrewardedRelayer, UnrewardedRelayersState}; use bp_test_utils::generate_owned_bridge_module_tests; @@ -1146,15 +984,13 @@ mod tests { let message_nonce = outbound_lane::(TEST_LANE_ID).data().latest_generated_nonce + 1; - let weight = Pallet::::send_message( + let weight = send_message::( RuntimeOrigin::signed(1), TEST_LANE_ID, REGULAR_PAYLOAD, - REGULAR_PAYLOAD.declared_weight.ref_time(), ) .expect("send_message has failed") - .actual_weight - .expect("send_message always returns Some"); + .weight; // check event with assigned nonce assert_eq!( @@ -1169,12 +1005,6 @@ mod tests { }], ); - // check that fee has been withdrawn from submitter - assert!(TestMessageDeliveryAndDispatchPayment::is_fee_paid( - 1, - REGULAR_PAYLOAD.declared_weight.ref_time() - )); - weight } @@ -1217,102 +1047,6 @@ mod tests { ); } - #[test] - fn pallet_parameter_may_be_updated_by_root() { - run_test(|| { - get_ready_for_events(); - - let parameter = TestMessagesParameter::TokenConversionRate(10.into()); - assert_ok!(Pallet::::update_pallet_parameter( - RuntimeOrigin::root(), - parameter.clone(), - )); - - assert_eq!(TokenConversionRate::get(), 10.into()); - assert_eq!( - System::::events(), - vec![EventRecord { - phase: Phase::Initialization, - event: TestEvent::Messages(Event::ParameterUpdated { parameter }), - topics: vec![], - }], - ); - }); - } - - #[test] - fn pallet_parameter_may_be_updated_by_owner() { - run_test(|| { - PalletOwner::::put(2); - get_ready_for_events(); - - let parameter = TestMessagesParameter::TokenConversionRate(10.into()); - assert_ok!(Pallet::::update_pallet_parameter( - RuntimeOrigin::signed(2), - parameter.clone(), - )); - - assert_eq!(TokenConversionRate::get(), 10.into()); - assert_eq!( - System::::events(), - vec![EventRecord { - phase: Phase::Initialization, - event: TestEvent::Messages(Event::ParameterUpdated { parameter }), - topics: vec![], - }], - ); - }); - } - - #[test] - fn pallet_parameter_cant_be_updated_by_arbitrary_submitter() { - run_test(|| { - assert_noop!( - Pallet::::update_pallet_parameter( - RuntimeOrigin::signed(2), - TestMessagesParameter::TokenConversionRate(10.into()), - ), - DispatchError::BadOrigin, - ); - - PalletOwner::::put(2); - - assert_noop!( - Pallet::::update_pallet_parameter( - RuntimeOrigin::signed(1), - TestMessagesParameter::TokenConversionRate(10.into()), - ), - DispatchError::BadOrigin, - ); - }); - } - - #[test] - fn fixed_u128_works_as_i_think() { - // this test is here just to be sure that conversion rate may be represented with FixedU128 - run_test(|| { - use sp_runtime::{FixedPointNumber, FixedU128}; - - // 1:1 conversion that we use by default for testnets - let rialto_token = 1u64; - let rialto_token_in_millau_tokens = - TokenConversionRate::get().saturating_mul_int(rialto_token); - assert_eq!(rialto_token_in_millau_tokens, 1); - - // let's say conversion rate is 1:1.7 - let conversion_rate = FixedU128::saturating_from_rational(170, 100); - let rialto_tokens = 100u64; - let rialto_tokens_in_millau_tokens = conversion_rate.saturating_mul_int(rialto_tokens); - assert_eq!(rialto_tokens_in_millau_tokens, 170); - - // let's say conversion rate is 1:0.25 - let conversion_rate = FixedU128::saturating_from_rational(25, 100); - let rialto_tokens = 100u64; - let rialto_tokens_in_millau_tokens = conversion_rate.saturating_mul_int(rialto_tokens); - assert_eq!(rialto_tokens_in_millau_tokens, 25); - }); - } - #[test] fn pallet_rejects_transactions_if_halted() { run_test(|| { @@ -1324,25 +1058,14 @@ mod tests { )); assert_noop!( - Pallet::::send_message( + send_message::( RuntimeOrigin::signed(1), TEST_LANE_ID, REGULAR_PAYLOAD, - REGULAR_PAYLOAD.declared_weight.ref_time(), ), Error::::NotOperatingNormally, ); - assert_noop!( - Pallet::::increase_message_fee( - RuntimeOrigin::signed(1), - TEST_LANE_ID, - 1, - 1, - ), - Error::::BridgeModule(bp_runtime::OwnedBridgeModuleError::Halted), - ); - assert_noop!( Pallet::::receive_messages_proof( RuntimeOrigin::signed(1), @@ -1389,22 +1112,14 @@ mod tests { ); assert_noop!( - Pallet::::send_message( + send_message::( RuntimeOrigin::signed(1), TEST_LANE_ID, REGULAR_PAYLOAD, - REGULAR_PAYLOAD.declared_weight.ref_time(), ), Error::::NotOperatingNormally, ); - assert_ok!(Pallet::::increase_message_fee( - RuntimeOrigin::signed(1), - TEST_LANE_ID, - 1, - 1, - )); - assert_ok!(Pallet::::receive_messages_proof( RuntimeOrigin::signed(1), TEST_RELAYER_A, @@ -1451,25 +1166,23 @@ mod tests { .extra .extend_from_slice(&[0u8; MAX_OUTBOUND_PAYLOAD_SIZE as usize]); assert_noop!( - Pallet::::send_message( + send_message::( RuntimeOrigin::signed(1), TEST_LANE_ID, message_payload.clone(), - Balance::MAX, ), Error::::MessageIsTooLarge, ); // let's check that we're able to send `MAX_OUTBOUND_PAYLOAD_SIZE` messages - while message_payload.size() > MAX_OUTBOUND_PAYLOAD_SIZE { + while message_payload.encoded_size() as u32 > MAX_OUTBOUND_PAYLOAD_SIZE { message_payload.extra.pop(); } - assert_eq!(message_payload.size(), MAX_OUTBOUND_PAYLOAD_SIZE); - assert_ok!(Pallet::::send_message( + assert_eq!(message_payload.encoded_size() as u32, MAX_OUTBOUND_PAYLOAD_SIZE); + assert_ok!(send_message::( RuntimeOrigin::signed(1), TEST_LANE_ID, message_payload, - Balance::MAX, ),); }) } @@ -1479,11 +1192,10 @@ mod tests { run_test(|| { // messages with this payload are rejected by target chain verifier assert_noop!( - Pallet::::send_message( + send_message::( RuntimeOrigin::signed(1), TEST_LANE_ID, PAYLOAD_REJECTED_BY_TARGET_CHAIN, - PAYLOAD_REJECTED_BY_TARGET_CHAIN.declared_weight.ref_time(), ), Error::::MessageRejectedByChainVerifier, ); @@ -1494,34 +1206,15 @@ mod tests { fn lane_verifier_rejects_invalid_message_in_send_message() { run_test(|| { // messages with zero fee are rejected by lane verifier + let mut message = REGULAR_PAYLOAD; + message.reject_by_lane_verifier = true; assert_noop!( - Pallet::::send_message( - RuntimeOrigin::signed(1), - TEST_LANE_ID, - REGULAR_PAYLOAD, - 0 - ), + send_message::(RuntimeOrigin::signed(1), TEST_LANE_ID, message,), Error::::MessageRejectedByLaneVerifier, ); }); } - #[test] - fn message_send_fails_if_submitter_cant_pay_message_fee() { - run_test(|| { - TestMessageDeliveryAndDispatchPayment::reject_payments(); - assert_noop!( - Pallet::::send_message( - RuntimeOrigin::signed(1), - TEST_LANE_ID, - REGULAR_PAYLOAD, - REGULAR_PAYLOAD.declared_weight.ref_time(), - ), - Error::::FailedToWithdrawMessageFee, - ); - }); - } - #[test] fn receive_messages_proof_works() { run_test(|| { @@ -1665,17 +1358,15 @@ mod tests { #[test] fn receive_messages_delivery_proof_rewards_relayers() { run_test(|| { - assert_ok!(Pallet::::send_message( + assert_ok!(send_message::( RuntimeOrigin::signed(1), TEST_LANE_ID, REGULAR_PAYLOAD, - 1000, )); - assert_ok!(Pallet::::send_message( + assert_ok!(send_message::( RuntimeOrigin::signed(1), TEST_LANE_ID, REGULAR_PAYLOAD, - 2000, )); // this reports delivery of message 1 => reward is paid to TEST_RELAYER_A @@ -1697,8 +1388,8 @@ mod tests { ..Default::default() }, )); - assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_A, 1000)); - assert!(!TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_B, 2000)); + assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_A, 1)); + assert!(!TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_B, 1)); // this reports delivery of both message 1 and message 2 => reward is paid only to // TEST_RELAYER_B @@ -1723,8 +1414,8 @@ mod tests { ..Default::default() }, )); - assert!(!TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_A, 1000)); - assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_B, 2000)); + assert!(!TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_A, 1)); + assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_B, 1)); }); } @@ -1829,7 +1520,7 @@ mod tests { fn receive_messages_accepts_single_message_with_invalid_payload() { run_test(|| { let mut invalid_message = message(1, REGULAR_PAYLOAD); - invalid_message.data.payload = Vec::new(); + invalid_message.payload = Vec::new(); assert_ok!(Pallet::::receive_messages_proof( RuntimeOrigin::signed(1), @@ -1848,7 +1539,7 @@ mod tests { fn receive_messages_accepts_batch_with_message_with_invalid_payload() { run_test(|| { let mut invalid_message = message(2, REGULAR_PAYLOAD); - invalid_message.data.payload = Vec::new(); + invalid_message.payload = Vec::new(); assert_ok!(Pallet::::receive_messages_proof( RuntimeOrigin::signed(1), @@ -1884,73 +1575,6 @@ mod tests { }); } - #[test] - fn increase_message_fee_fails_if_message_is_already_delivered() { - run_test(|| { - send_regular_message(); - receive_messages_delivery_proof(); - - assert_noop!( - Pallet::::increase_message_fee( - RuntimeOrigin::signed(1), - TEST_LANE_ID, - 1, - 100, - ), - Error::::MessageIsAlreadyDelivered, - ); - }); - } - - #[test] - fn increase_message_fee_fails_if_message_is_not_yet_sent() { - run_test(|| { - assert_noop!( - Pallet::::increase_message_fee( - RuntimeOrigin::signed(1), - TEST_LANE_ID, - 1, - 100, - ), - Error::::MessageIsNotYetSent, - ); - }); - } - - #[test] - fn increase_message_fee_fails_if_submitter_cant_pay_additional_fee() { - run_test(|| { - send_regular_message(); - - TestMessageDeliveryAndDispatchPayment::reject_payments(); - - assert_noop!( - Pallet::::increase_message_fee( - RuntimeOrigin::signed(1), - TEST_LANE_ID, - 1, - 100, - ), - Error::::FailedToWithdrawMessageFee, - ); - }); - } - - #[test] - fn increase_message_fee_succeeds() { - run_test(|| { - send_regular_message(); - - assert_ok!(Pallet::::increase_message_fee( - RuntimeOrigin::signed(1), - TEST_LANE_ID, - 1, - 100, - ),); - assert!(TestMessageDeliveryAndDispatchPayment::is_fee_paid(1, 100)); - }); - } - #[test] fn weight_refund_from_receive_messages_proof_works() { run_test(|| { @@ -2187,101 +1811,6 @@ mod tests { }); } - #[test] - fn increase_message_fee_weight_depends_on_message_size() { - run_test(|| { - let mut small_payload = message_payload(0, 100); - let mut large_payload = message_payload(1, 100); - small_payload.extra = vec![1; MAX_OUTBOUND_PAYLOAD_SIZE as usize / 10]; - large_payload.extra = vec![2; MAX_OUTBOUND_PAYLOAD_SIZE as usize / 5]; - - assert_ok!(Pallet::::send_message( - RuntimeOrigin::signed(1), - TEST_LANE_ID, - small_payload, - 100, - )); - assert_ok!(Pallet::::send_message( - RuntimeOrigin::signed(1), - TEST_LANE_ID, - large_payload, - 100, - )); - - let small_weight = Pallet::::increase_message_fee( - RuntimeOrigin::signed(1), - TEST_LANE_ID, - 1, - 1, - ) - .expect("increase_message_fee has failed") - .actual_weight - .expect("increase_message_fee always returns Some"); - - let large_weight = Pallet::::increase_message_fee( - RuntimeOrigin::signed(1), - TEST_LANE_ID, - 2, - 1, - ) - .expect("increase_message_fee has failed") - .actual_weight - .expect("increase_message_fee always returns Some"); - - assert!( - large_weight.ref_time() > small_weight.ref_time(), - "Actual post-dispatch weigth for larger message {} must be larger than {} for small message", - large_weight, - small_weight, - ); - }); - } - - #[test] - fn weight_is_refunded_for_messages_that_are_not_pruned() { - run_test(|| { - // send first MAX messages - no messages are pruned - let max_messages_to_prune = crate::mock::MaxMessagesToPruneAtOnce::get(); - let when_zero_messages_are_pruned = send_regular_message(); - let mut delivered_messages = DeliveredMessages::new(1, true); - for _ in 1..max_messages_to_prune { - assert_eq!(send_regular_message(), when_zero_messages_are_pruned); - delivered_messages.note_dispatched_message(true); - } - - // confirm delivery of all sent messages - assert_ok!(Pallet::::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(Ok(( - TEST_LANE_ID, - InboundLaneData { - last_confirmed_nonce: 1, - relayers: vec![UnrewardedRelayer { - relayer: 0, - messages: delivered_messages, - }] - .into_iter() - .collect(), - }, - ))), - UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - total_messages: max_messages_to_prune, - last_delivered_nonce: max_messages_to_prune, - ..Default::default() - }, - )); - - // when next message is sent, MAX messages are pruned - let weight_when_max_messages_are_pruned = send_regular_message(); - assert_eq!( - weight_when_max_messages_are_pruned, - when_zero_messages_are_pruned + - crate::mock::DbWeight::get().writes(max_messages_to_prune), - ); - }); - } - #[test] fn message_accepted_callbacks_are_called() { run_test(|| { @@ -2302,27 +1831,6 @@ mod tests { }); } - #[test] - fn message_accepted_refunds_non_zero_weight() { - run_test(|| { - TestOnMessageAccepted::set_consumed_weight_per_message( - crate::mock::DbWeight::get().writes(1), - ); - let actual_callback_weight = send_regular_message(); - let pre_dispatch_weight = ::WeightInfo::send_message_weight( - ®ULAR_PAYLOAD, - crate::mock::DbWeight::get(), - ); - let prune_weight = crate::mock::DbWeight::get() - .writes(::MaxMessagesToPruneAtOnce::get()); - - assert_eq!( - pre_dispatch_weight.saturating_sub(actual_callback_weight), - crate::mock::DbWeight::get().reads(1).saturating_add(prune_weight) - ); - }); - } - #[test] fn storage_keys_computed_properly() { assert_eq!( @@ -2360,9 +1868,6 @@ mod tests { nonce: 0, dispatch_weight: Weight::from_ref_time(0), size: 0, - delivery_and_dispatch_fee: 0, - dispatch_fee_payment: - bp_runtime::messages::DispatchFeePayment::AtTargetChain, }, ), InboundMessageDetails { dispatch_weight: REGULAR_PAYLOAD.declared_weight }, diff --git a/bridges/modules/messages/src/mock.rs b/bridges/modules/messages/src/mock.rs index fd4c45a0eaa9c..afda37ba8be7b 100644 --- a/bridges/modules/messages/src/mock.rs +++ b/bridges/modules/messages/src/mock.rs @@ -26,10 +26,11 @@ use bp_messages::{ OnMessageAccepted, TargetHeaderChain, }, target_chain::{ - DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain, + DispatchMessage, DispatchMessageData, MessageDispatch, ProvedLaneMessages, ProvedMessages, + SourceHeaderChain, }, - DeliveredMessages, InboundLaneData, LaneId, Message, MessageData, MessageKey, MessageNonce, - OutboundLaneData, Parameter as MessagesParameter, UnrewardedRelayer, + DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, + OutboundLaneData, UnrewardedRelayer, }; use bp_runtime::{messages::MessageDispatchResult, Size}; use codec::{Decode, Encode}; @@ -42,7 +43,7 @@ use sp_core::H256; use sp_runtime::{ testing::Header as SubstrateHeader, traits::{BlakeTwo256, IdentityLookup}, - FixedU128, Perbill, + Perbill, }; use std::{ collections::{BTreeMap, VecDeque}, @@ -55,6 +56,8 @@ pub type Balance = u64; pub struct TestPayload { /// Field that may be used to identify messages. pub id: u64, + /// Reject this message by lane verifier? + pub reject_by_lane_verifier: bool, /// Dispatch weight that is declared by the message sender. pub declared_weight: Weight, /// Message dispatch result. @@ -140,38 +143,20 @@ parameter_types! { pub const MaxMessagesToPruneAtOnce: u64 = 10; pub const MaxUnrewardedRelayerEntriesAtInboundLane: u64 = 16; pub const MaxUnconfirmedMessagesAtInboundLane: u64 = 32; - pub storage TokenConversionRate: FixedU128 = 1.into(); pub const TestBridgedChainId: bp_runtime::ChainId = *b"test"; } -#[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, TypeInfo)] -pub enum TestMessagesParameter { - TokenConversionRate(FixedU128), -} - -impl MessagesParameter for TestMessagesParameter { - fn save(&self) { - match *self { - TestMessagesParameter::TokenConversionRate(conversion_rate) => - TokenConversionRate::set(&conversion_rate), - } - } -} - impl Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type WeightInfo = (); - type Parameter = TestMessagesParameter; type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce; type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; type MaximalOutboundPayloadSize = frame_support::traits::ConstU32; type OutboundPayload = TestPayload; - type OutboundMessageFee = TestMessageFee; type InboundPayload = TestPayload; - type InboundMessageFee = TestMessageFee; type InboundRelayer = TestRelayer; type TargetHeaderChain = TestTargetHeaderChain; @@ -219,7 +204,7 @@ pub const REGULAR_PAYLOAD: TestPayload = message_payload(0, 50); pub const PAYLOAD_REJECTED_BY_TARGET_CHAIN: TestPayload = message_payload(1, 50); /// Vec of proved messages, grouped by lane. -pub type MessagesByLaneVec = Vec<(LaneId, ProvedLaneMessages>)>; +pub type MessagesByLaneVec = Vec<(LaneId, ProvedLaneMessages)>; /// Test messages proof. #[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo)] @@ -233,14 +218,12 @@ impl Size for TestMessagesProof { } } -impl From>, ()>> for TestMessagesProof { - fn from(result: Result>, ()>) -> Self { +impl From, ()>> for TestMessagesProof { + fn from(result: Result, ()>) -> Self { Self { result: result.map(|messages| { - let mut messages_by_lane: BTreeMap< - LaneId, - ProvedLaneMessages>, - > = BTreeMap::new(); + let mut messages_by_lane: BTreeMap> = + BTreeMap::new(); for message in messages { messages_by_lane.entry(message.key.lane_id).or_default().messages.push(message); } @@ -288,17 +271,16 @@ impl TargetHeaderChain for TestTargetHeaderChain { #[derive(Debug, Default)] pub struct TestLaneMessageVerifier; -impl LaneMessageVerifier for TestLaneMessageVerifier { +impl LaneMessageVerifier for TestLaneMessageVerifier { type Error = &'static str; fn verify_message( _submitter: &RuntimeOrigin, - delivery_and_dispatch_fee: &TestMessageFee, _lane: &LaneId, _lane_outbound_data: &OutboundLaneData, - _payload: &TestPayload, + payload: &TestPayload, ) -> Result<(), Self::Error> { - if *delivery_and_dispatch_fee != 0 { + if !payload.reject_by_lane_verifier { Ok(()) } else { Err(TEST_ERROR) @@ -311,18 +293,6 @@ impl LaneMessageVerifier for TestLan pub struct TestMessageDeliveryAndDispatchPayment; impl TestMessageDeliveryAndDispatchPayment { - /// Reject all payments. - pub fn reject_payments() { - frame_support::storage::unhashed::put(b":reject-message-fee:", &true); - } - - /// Returns true if given fee has been paid by given submitter. - pub fn is_fee_paid(submitter: AccountId, fee: TestMessageFee) -> bool { - let raw_origin: Result, _> = - RuntimeOrigin::signed(submitter).into(); - frame_support::storage::unhashed::get(b":message-fee:") == Some((raw_origin.unwrap(), fee)) - } - /// Returns true if given relayer has been rewarded with given balance. The reward-paid flag is /// cleared after the call. pub fn is_reward_paid(relayer: AccountId, fee: TestMessageFee) -> bool { @@ -331,34 +301,21 @@ impl TestMessageDeliveryAndDispatchPayment { } } -impl MessageDeliveryAndDispatchPayment +impl MessageDeliveryAndDispatchPayment for TestMessageDeliveryAndDispatchPayment { type Error = &'static str; - fn pay_delivery_and_dispatch_fee( - submitter: &RuntimeOrigin, - fee: &TestMessageFee, - ) -> Result<(), Self::Error> { - if frame_support::storage::unhashed::get(b":reject-message-fee:") == Some(true) { - return Err(TEST_ERROR) - } - - let raw_origin: Result, _> = submitter.clone().into(); - frame_support::storage::unhashed::put(b":message-fee:", &(raw_origin.unwrap(), fee)); - Ok(()) - } - fn pay_relayers_rewards( - lane_id: LaneId, + _lane_id: LaneId, message_relayers: VecDeque>, _confirmation_relayer: &AccountId, received_range: &RangeInclusive, ) { let relayers_rewards = - calc_relayers_rewards::(lane_id, message_relayers, received_range); + calc_relayers_rewards::(message_relayers, received_range); for (relayer, reward) in &relayers_rewards { - let key = (b":relayer-reward:", relayer, reward.reward).encode(); + let key = (b":relayer-reward:", relayer, reward).encode(); frame_support::storage::unhashed::put(&key, &true); } } @@ -450,7 +407,7 @@ impl OnDeliveryConfirmed for TestOnDeliveryConfirmed2 { #[derive(Debug)] pub struct TestSourceHeaderChain; -impl SourceHeaderChain for TestSourceHeaderChain { +impl SourceHeaderChain for TestSourceHeaderChain { type Error = &'static str; type MessagesProof = TestMessagesProof; @@ -458,7 +415,7 @@ impl SourceHeaderChain for TestSourceHeaderChain { fn verify_messages_proof( proof: Self::MessagesProof, _messages_count: u32, - ) -> Result>, Self::Error> { + ) -> Result, Self::Error> { proof.result.map(|proof| proof.into_iter().collect()).map_err(|_| TEST_ERROR) } } @@ -467,10 +424,10 @@ impl SourceHeaderChain for TestSourceHeaderChain { #[derive(Debug)] pub struct TestMessageDispatch; -impl MessageDispatch for TestMessageDispatch { +impl MessageDispatch for TestMessageDispatch { type DispatchPayload = TestPayload; - fn dispatch_weight(message: &mut DispatchMessage) -> Weight { + fn dispatch_weight(message: &mut DispatchMessage) -> Weight { match message.data.payload.as_ref() { Ok(payload) => payload.declared_weight, Err(_) => Weight::from_ref_time(0), @@ -479,7 +436,7 @@ impl MessageDispatch for TestMessageDispatch { fn dispatch( _relayer_account: &AccountId, - message: DispatchMessage, + message: DispatchMessage, ) -> MessageDispatchResult { match message.data.payload.as_ref() { Ok(payload) => payload.dispatch_result.clone(), @@ -489,25 +446,31 @@ impl MessageDispatch for TestMessageDispatch { } /// Return test lane message with given nonce and payload. -pub fn message(nonce: MessageNonce, payload: TestPayload) -> Message { - Message { key: MessageKey { lane_id: TEST_LANE_ID, nonce }, data: message_data(payload) } +pub fn message(nonce: MessageNonce, payload: TestPayload) -> Message { + Message { key: MessageKey { lane_id: TEST_LANE_ID, nonce }, payload: payload.encode() } +} + +/// Return valid outbound message data, constructed from given payload. +pub fn outbound_message_data(payload: TestPayload) -> MessagePayload { + payload.encode() +} + +/// Return valid inbound (dispatch) message data, constructed from given payload. +pub fn inbound_message_data(payload: TestPayload) -> DispatchMessageData { + DispatchMessageData { payload: Ok(payload) } } /// Constructs message payload using given arguments and zero unspent weight. pub const fn message_payload(id: u64, declared_weight: u64) -> TestPayload { TestPayload { id, + reject_by_lane_verifier: false, declared_weight: Weight::from_ref_time(declared_weight), dispatch_result: dispatch_result(0), extra: Vec::new(), } } -/// Return message data with valid fee for given payload. -pub fn message_data(payload: TestPayload) -> MessageData { - MessageData { payload: payload.encode(), fee: 1 } -} - /// Returns message dispatch result with given unspent weight. pub const fn dispatch_result(unspent_weight: u64) -> MessageDispatchResult { MessageDispatchResult { diff --git a/bridges/modules/messages/src/outbound_lane.rs b/bridges/modules/messages/src/outbound_lane.rs index bdd503c811e73..890b85072ab9d 100644 --- a/bridges/modules/messages/src/outbound_lane.rs +++ b/bridges/modules/messages/src/outbound_lane.rs @@ -20,19 +20,14 @@ use crate::Config; use bitvec::prelude::*; use bp_messages::{ - DeliveredMessages, DispatchResultsBitVec, LaneId, MessageData, MessageNonce, OutboundLaneData, - UnrewardedRelayer, + DeliveredMessages, DispatchResultsBitVec, LaneId, MessageNonce, MessagePayload, + OutboundLaneData, UnrewardedRelayer, }; -use codec::{Decode, Encode, EncodeLike, MaxEncodedLen}; -use frame_support::{traits::Get, RuntimeDebug}; -use scale_info::{Type, TypeInfo}; +use frame_support::{BoundedVec, RuntimeDebug}; use sp_std::collections::vec_deque::VecDeque; /// Outbound lane storage. pub trait OutboundLaneStorage { - /// Delivery and dispatch fee type on source chain. - type MessageFee; - /// Lane id. fn id(&self) -> LaneId; /// Get lane data from the storage. @@ -41,64 +36,15 @@ pub trait OutboundLaneStorage { fn set_data(&mut self, data: OutboundLaneData); /// Returns saved outbound message payload. #[cfg(test)] - fn message(&self, nonce: &MessageNonce) -> Option>; + fn message(&self, nonce: &MessageNonce) -> Option; /// Save outbound message in the storage. - fn save_message(&mut self, nonce: MessageNonce, message_data: MessageData); + fn save_message(&mut self, nonce: MessageNonce, message_payload: MessagePayload); /// Remove outbound message from the storage. fn remove_message(&mut self, nonce: &MessageNonce); } /// Outbound message data wrapper that implements `MaxEncodedLen`. -/// -/// We have already had `MaxEncodedLen`-like functionality before, but its usage has -/// been localized and we haven't been passing it everywhere. This wrapper allows us -/// to avoid passing these generic bounds all over the code. -/// -/// The encoding of this type matches encoding of the corresponding `MessageData`. -#[derive(Encode, Decode, Clone, RuntimeDebug, PartialEq, Eq)] -pub struct StoredMessageData, I: 'static>(pub MessageData); - -impl, I: 'static> sp_std::ops::Deref for StoredMessageData { - type Target = MessageData; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl, I: 'static> sp_std::ops::DerefMut for StoredMessageData { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl, I: 'static> From> - for MessageData -{ - fn from(data: StoredMessageData) -> Self { - data.0 - } -} - -impl, I: 'static> TypeInfo for StoredMessageData { - type Identity = Self; - - fn type_info() -> Type { - MessageData::::type_info() - } -} - -impl, I: 'static> EncodeLike> - for MessageData -{ -} - -impl, I: 'static> MaxEncodedLen for StoredMessageData { - fn max_encoded_len() -> usize { - T::OutboundMessageFee::max_encoded_len() - .saturating_add(T::MaximalOutboundPayloadSize::get() as usize) - } -} +pub type StoredMessagePayload = BoundedVec>::MaximalOutboundPayloadSize>; /// Result of messages receival confirmation. #[derive(RuntimeDebug, PartialEq, Eq)] @@ -143,12 +89,12 @@ impl OutboundLane { /// Send message over lane. /// /// Returns new message nonce. - pub fn send_message(&mut self, message_data: MessageData) -> MessageNonce { + pub fn send_message(&mut self, message_payload: MessagePayload) -> MessageNonce { let mut data = self.storage.data(); let nonce = data.latest_generated_nonce + 1; data.latest_generated_nonce = nonce; - self.storage.save_message(nonce, message_data); + self.storage.save_message(nonce, message_payload); self.storage.set_data(data); nonce @@ -295,8 +241,8 @@ mod tests { use super::*; use crate::{ mock::{ - message_data, run_test, unrewarded_relayer, TestRelayer, TestRuntime, REGULAR_PAYLOAD, - TEST_LANE_ID, + outbound_message_data, run_test, unrewarded_relayer, TestRelayer, TestRuntime, + REGULAR_PAYLOAD, TEST_LANE_ID, }, outbound_lane, }; @@ -324,9 +270,9 @@ mod tests { ) -> ReceivalConfirmationResult { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); - lane.send_message(message_data(REGULAR_PAYLOAD)); - lane.send_message(message_data(REGULAR_PAYLOAD)); - lane.send_message(message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 0); let result = lane.confirm_delivery(3, latest_received_nonce, relayers); @@ -341,7 +287,7 @@ mod tests { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); assert_eq!(lane.storage.data().latest_generated_nonce, 0); - assert_eq!(lane.send_message(message_data(REGULAR_PAYLOAD)), 1); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1); assert!(lane.storage.message(&1).is_some()); assert_eq!(lane.storage.data().latest_generated_nonce, 1); }); @@ -351,9 +297,9 @@ mod tests { fn confirm_delivery_works() { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); - assert_eq!(lane.send_message(message_data(REGULAR_PAYLOAD)), 1); - assert_eq!(lane.send_message(message_data(REGULAR_PAYLOAD)), 2); - assert_eq!(lane.send_message(message_data(REGULAR_PAYLOAD)), 3); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 2); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 3); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 0); assert_eq!( @@ -369,9 +315,9 @@ mod tests { fn confirm_delivery_rejects_nonce_lesser_than_latest_received() { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); - lane.send_message(message_data(REGULAR_PAYLOAD)); - lane.send_message(message_data(REGULAR_PAYLOAD)); - lane.send_message(message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 0); assert_eq!( @@ -470,9 +416,9 @@ mod tests { assert_eq!(lane.prune_messages(100), 0); assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); // when nothing is confirmed, nothing is pruned - lane.send_message(message_data(REGULAR_PAYLOAD)); - lane.send_message(message_data(REGULAR_PAYLOAD)); - lane.send_message(message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); assert_eq!(lane.prune_messages(100), 0); assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); // after confirmation, some messages are received @@ -496,9 +442,9 @@ mod tests { fn confirm_delivery_detects_when_more_than_expected_messages_are_confirmed() { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); - lane.send_message(message_data(REGULAR_PAYLOAD)); - lane.send_message(message_data(REGULAR_PAYLOAD)); - lane.send_message(message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); assert_eq!( lane.confirm_delivery(0, 3, &unrewarded_relayers(1..=3)), ReceivalConfirmationResult::TryingToConfirmMoreMessagesThanExpected(3), diff --git a/bridges/modules/messages/src/weights.rs b/bridges/modules/messages/src/weights.rs index 3801b57b61a4c..2ae60c17fafb9 100644 --- a/bridges/modules/messages/src/weights.rs +++ b/bridges/modules/messages/src/weights.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for `pallet_bridge_messages` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-10-17, STEPS: 50, REPEAT: 20 +//! DATE: 2022-11-17, STEPS: 50, REPEAT: 20 //! LOW RANGE: [], HIGH RANGE: [] //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled //! CHAIN: Some("dev"), DB CACHE: 1024 @@ -50,11 +50,6 @@ use sp_std::marker::PhantomData; /// Weight functions needed for `pallet_bridge_messages`. pub trait WeightInfo { - fn send_minimal_message_worst_case() -> Weight; - fn send_1_kb_message_worst_case() -> Weight; - fn send_16_kb_message_worst_case() -> Weight; - fn maximal_increase_message_fee() -> Weight; - fn increase_message_fee(i: u32) -> Weight; fn receive_single_message_proof() -> Weight; fn receive_two_messages_proof() -> Weight; fn receive_single_message_proof_with_outbound_lane_state() -> Weight; @@ -71,150 +66,98 @@ pub trait WeightInfo { /// Those weights are test only and must never be used in production. pub struct BridgeWeight(PhantomData); impl WeightInfo for BridgeWeight { - fn send_minimal_message_worst_case() -> Weight { - Weight::from_ref_time(61_807_000 as u64) - .saturating_add(T::DbWeight::get().reads(5 as u64)) - .saturating_add(T::DbWeight::get().writes(10 as u64)) - } - fn send_1_kb_message_worst_case() -> Weight { - Weight::from_ref_time(65_074_000 as u64) - .saturating_add(T::DbWeight::get().reads(5 as u64)) - .saturating_add(T::DbWeight::get().writes(10 as u64)) - } - fn send_16_kb_message_worst_case() -> Weight { - Weight::from_ref_time(73_584_000 as u64) - .saturating_add(T::DbWeight::get().reads(5 as u64)) - .saturating_add(T::DbWeight::get().writes(10 as u64)) - } - fn maximal_increase_message_fee() -> Weight { - Weight::from_ref_time(2_522_629_000 as u64) - .saturating_add(T::DbWeight::get().reads(3 as u64)) - .saturating_add(T::DbWeight::get().writes(1 as u64)) - } - fn increase_message_fee(i: u32) -> Weight { - Weight::from_ref_time(27_072_000 as u64) - .saturating_add(Weight::from_ref_time(892 as u64).saturating_mul(i as u64)) - .saturating_add(T::DbWeight::get().reads(3 as u64)) - .saturating_add(T::DbWeight::get().writes(1 as u64)) - } fn receive_single_message_proof() -> Weight { - Weight::from_ref_time(49_628_000 as u64) + Weight::from_ref_time(50_596_000 as u64) .saturating_add(T::DbWeight::get().reads(4 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } fn receive_two_messages_proof() -> Weight { - Weight::from_ref_time(61_514_000 as u64) + Weight::from_ref_time(77_041_000 as u64) .saturating_add(T::DbWeight::get().reads(4 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } fn receive_single_message_proof_with_outbound_lane_state() -> Weight { - Weight::from_ref_time(65_960_000 as u64) + Weight::from_ref_time(58_331_000 as u64) .saturating_add(T::DbWeight::get().reads(4 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } fn receive_single_message_proof_1_kb() -> Weight { - Weight::from_ref_time(48_009_000 as u64) + Weight::from_ref_time(48_061_000 as u64) .saturating_add(T::DbWeight::get().reads(3 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } fn receive_single_message_proof_16_kb() -> Weight { - Weight::from_ref_time(100_439_000 as u64) + Weight::from_ref_time(101_601_000 as u64) .saturating_add(T::DbWeight::get().reads(3 as u64)) .saturating_add(T::DbWeight::get().writes(1 as u64)) } fn receive_single_prepaid_message_proof() -> Weight { - Weight::from_ref_time(50_463_000 as u64) + Weight::from_ref_time(49_646_000 as u64) .saturating_add(T::DbWeight::get().reads(4 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } fn receive_delivery_proof_for_single_message() -> Weight { - Weight::from_ref_time(57_383_000 as u64) - .saturating_add(T::DbWeight::get().reads(5 as u64)) + Weight::from_ref_time(55_108_000 as u64) + .saturating_add(T::DbWeight::get().reads(4 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { - Weight::from_ref_time(62_003_000 as u64) - .saturating_add(T::DbWeight::get().reads(6 as u64)) + Weight::from_ref_time(53_917_000 as u64) + .saturating_add(T::DbWeight::get().reads(4 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { - Weight::from_ref_time(64_401_000 as u64) - .saturating_add(T::DbWeight::get().reads(7 as u64)) + Weight::from_ref_time(57_335_000 as u64) + .saturating_add(T::DbWeight::get().reads(5 as u64)) .saturating_add(T::DbWeight::get().writes(3 as u64)) } } // For backwards compatibility and tests impl WeightInfo for () { - fn send_minimal_message_worst_case() -> Weight { - Weight::from_ref_time(61_807_000 as u64) - .saturating_add(RocksDbWeight::get().reads(5 as u64)) - .saturating_add(RocksDbWeight::get().writes(10 as u64)) - } - fn send_1_kb_message_worst_case() -> Weight { - Weight::from_ref_time(65_074_000 as u64) - .saturating_add(RocksDbWeight::get().reads(5 as u64)) - .saturating_add(RocksDbWeight::get().writes(10 as u64)) - } - fn send_16_kb_message_worst_case() -> Weight { - Weight::from_ref_time(73_584_000 as u64) - .saturating_add(RocksDbWeight::get().reads(5 as u64)) - .saturating_add(RocksDbWeight::get().writes(10 as u64)) - } - fn maximal_increase_message_fee() -> Weight { - Weight::from_ref_time(2_522_629_000 as u64) - .saturating_add(RocksDbWeight::get().reads(3 as u64)) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) - } - fn increase_message_fee(i: u32) -> Weight { - Weight::from_ref_time(27_072_000 as u64) - .saturating_add(Weight::from_ref_time(892 as u64).saturating_mul(i as u64)) - .saturating_add(RocksDbWeight::get().reads(3 as u64)) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) - } fn receive_single_message_proof() -> Weight { - Weight::from_ref_time(49_628_000 as u64) + Weight::from_ref_time(50_596_000 as u64) .saturating_add(RocksDbWeight::get().reads(4 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } fn receive_two_messages_proof() -> Weight { - Weight::from_ref_time(61_514_000 as u64) + Weight::from_ref_time(77_041_000 as u64) .saturating_add(RocksDbWeight::get().reads(4 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } fn receive_single_message_proof_with_outbound_lane_state() -> Weight { - Weight::from_ref_time(65_960_000 as u64) + Weight::from_ref_time(58_331_000 as u64) .saturating_add(RocksDbWeight::get().reads(4 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } fn receive_single_message_proof_1_kb() -> Weight { - Weight::from_ref_time(48_009_000 as u64) + Weight::from_ref_time(48_061_000 as u64) .saturating_add(RocksDbWeight::get().reads(3 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } fn receive_single_message_proof_16_kb() -> Weight { - Weight::from_ref_time(100_439_000 as u64) + Weight::from_ref_time(101_601_000 as u64) .saturating_add(RocksDbWeight::get().reads(3 as u64)) .saturating_add(RocksDbWeight::get().writes(1 as u64)) } fn receive_single_prepaid_message_proof() -> Weight { - Weight::from_ref_time(50_463_000 as u64) + Weight::from_ref_time(49_646_000 as u64) .saturating_add(RocksDbWeight::get().reads(4 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } fn receive_delivery_proof_for_single_message() -> Weight { - Weight::from_ref_time(57_383_000 as u64) - .saturating_add(RocksDbWeight::get().reads(5 as u64)) + Weight::from_ref_time(55_108_000 as u64) + .saturating_add(RocksDbWeight::get().reads(4 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { - Weight::from_ref_time(62_003_000 as u64) - .saturating_add(RocksDbWeight::get().reads(6 as u64)) + Weight::from_ref_time(53_917_000 as u64) + .saturating_add(RocksDbWeight::get().reads(4 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { - Weight::from_ref_time(64_401_000 as u64) - .saturating_add(RocksDbWeight::get().reads(7 as u64)) + Weight::from_ref_time(57_335_000 as u64) + .saturating_add(RocksDbWeight::get().reads(5 as u64)) .saturating_add(RocksDbWeight::get().writes(3 as u64)) } } diff --git a/bridges/modules/messages/src/weights_ext.rs b/bridges/modules/messages/src/weights_ext.rs index 80a1b9cdf8ad5..5ad86c817dcee 100644 --- a/bridges/modules/messages/src/weights_ext.rs +++ b/bridges/modules/messages/src/weights_ext.rs @@ -35,82 +35,16 @@ const SIGNED_EXTENSIONS_SIZE: u32 = 1024; pub const EXTRA_STORAGE_PROOF_SIZE: u32 = 1024; /// Ensure that weights from `WeightInfoExt` implementation are looking correct. -pub fn ensure_weights_are_correct( - expected_default_message_delivery_tx_weight: Weight, - expected_additional_byte_delivery_weight: Weight, - expected_messages_delivery_confirmation_tx_weight: Weight, - expected_pay_inbound_dispatch_fee_weight: Weight, - db_weight: RuntimeDbWeight, -) { - // verify `send_message` weight components - assert_ne!(W::send_message_overhead(), Weight::zero()); - assert_ne!(W::send_message_size_overhead(0), Weight::zero()); - +pub fn ensure_weights_are_correct() { // verify `receive_messages_proof` weight components assert_ne!(W::receive_messages_proof_overhead(), Weight::zero()); assert_ne!(W::receive_messages_proof_messages_overhead(1), Weight::zero()); assert_ne!(W::receive_messages_proof_outbound_lane_state_overhead(), Weight::zero()); assert_ne!(W::storage_proof_size_overhead(1), Weight::zero()); - // verify that the hardcoded value covers `receive_messages_proof` weight - let actual_single_regular_message_delivery_tx_weight = W::receive_messages_proof_weight( - &PreComputedSize( - (EXPECTED_DEFAULT_MESSAGE_LENGTH + W::expected_extra_storage_proof_size()) as usize, - ), - 1, - Weight::zero(), - ); - assert!( - actual_single_regular_message_delivery_tx_weight - .all_lte(expected_default_message_delivery_tx_weight), - "Default message delivery transaction weight {} is larger than expected weight {}", - actual_single_regular_message_delivery_tx_weight, - expected_default_message_delivery_tx_weight, - ); - - // verify that hardcoded value covers additional byte length of `receive_messages_proof` weight - let actual_additional_byte_delivery_weight = W::storage_proof_size_overhead(1); - assert!( - actual_additional_byte_delivery_weight.all_lte(expected_additional_byte_delivery_weight), - "Single additional byte delivery weight {} is larger than expected weight {}", - actual_additional_byte_delivery_weight, - expected_additional_byte_delivery_weight, - ); - // verify `receive_messages_delivery_proof` weight components assert_ne!(W::receive_messages_delivery_proof_overhead(), Weight::zero()); assert_ne!(W::storage_proof_size_overhead(1), Weight::zero()); - - // `receive_messages_delivery_proof_messages_overhead` and - // `receive_messages_delivery_proof_relayers_overhead` may return zero if rewards are not paid - // during confirmations delivery, so we're not checking it here - - // verify that the hardcoded value covers `receive_messages_delivery_proof` weight - let actual_messages_delivery_confirmation_tx_weight = W::receive_messages_delivery_proof_weight( - &PreComputedSize(W::expected_extra_storage_proof_size() as usize), - &UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - total_messages: 1, - ..Default::default() - }, - db_weight, - ); - assert!( - actual_messages_delivery_confirmation_tx_weight - .all_lte(expected_messages_delivery_confirmation_tx_weight), - "Messages delivery confirmation transaction weight {} is larger than expected weight {}", - actual_messages_delivery_confirmation_tx_weight, - expected_messages_delivery_confirmation_tx_weight, - ); - - // verify pay-dispatch-fee overhead for inbound messages - let actual_pay_inbound_dispatch_fee_weight = W::pay_inbound_dispatch_fee_overhead(); - assert!( - actual_pay_inbound_dispatch_fee_weight.all_lte(expected_pay_inbound_dispatch_fee_weight), - "Weight {} of pay-dispatch-fee overhead for inbound messages is larger than expected weight {}", - actual_pay_inbound_dispatch_fee_weight, - expected_pay_inbound_dispatch_fee_weight, - ); } /// Ensure that we're able to receive maximal (by-size and by-weight) message from other chain. @@ -198,17 +132,6 @@ pub trait WeightInfoExt: WeightInfo { // Functions that are directly mapped to extrinsics weights. - /// Weight of message send extrinsic. - fn send_message_weight(message: &impl Size, db_weight: RuntimeDbWeight) -> Weight { - let transaction_overhead = Self::send_message_overhead(); - let message_size_overhead = Self::send_message_size_overhead(message.size()); - let call_back_overhead = Self::single_message_callback_overhead(db_weight); - - transaction_overhead - .saturating_add(message_size_overhead) - .saturating_add(call_back_overhead) - } - /// Weight of message delivery extrinsic. fn receive_messages_proof_weight( proof: &impl Size, @@ -274,20 +197,6 @@ pub trait WeightInfoExt: WeightInfo { // Functions that are used by extrinsics weights formulas. - /// Returns weight of message send transaction (`send_message`). - fn send_message_overhead() -> Weight { - Self::send_minimal_message_worst_case() - } - - /// Returns weight that needs to be accounted when message of given size is sent - /// (`send_message`). - fn send_message_size_overhead(message_size: u32) -> Weight { - let message_size_in_kb = (1024u64 + message_size as u64) / 1024; - let single_kb_weight = - (Self::send_16_kb_message_worst_case() - Self::send_1_kb_message_worst_case()) / 15; - message_size_in_kb * single_kb_weight - } - /// Returns weight overhead of message delivery transaction (`receive_messages_proof`). fn receive_messages_proof_overhead() -> Weight { let weight_of_two_messages_and_two_tx_overheads = diff --git a/bridges/modules/parachains/src/weights.rs b/bridges/modules/parachains/src/weights.rs index 43cd68b01d1dc..5c9206d0ca0a8 100644 --- a/bridges/modules/parachains/src/weights.rs +++ b/bridges/modules/parachains/src/weights.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for `pallet_bridge_parachains` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-10-04, STEPS: 50, REPEAT: 20 +//! DATE: 2022-11-17, STEPS: 50, REPEAT: 20 //! LOW RANGE: [], HIGH RANGE: [] //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled //! CHAIN: Some("dev"), DB CACHE: 1024 @@ -61,19 +61,19 @@ pub trait WeightInfo { pub struct BridgeWeight(PhantomData); impl WeightInfo for BridgeWeight { fn submit_parachain_heads_with_n_parachains(p: u32) -> Weight { - Weight::from_ref_time(0 as u64) - .saturating_add(Weight::from_ref_time(24_869_000 as u64).saturating_mul(p as u64)) + Weight::from_ref_time(51_173_000 as u64) + .saturating_add(Weight::from_ref_time(24_495_968 as u64).saturating_mul(p as u64)) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().reads((2 as u64).saturating_mul(p as u64))) .saturating_add(T::DbWeight::get().writes((3 as u64).saturating_mul(p as u64))) } fn submit_parachain_heads_with_1kb_proof() -> Weight { - Weight::from_ref_time(56_262_000 as u64) + Weight::from_ref_time(58_175_000 as u64) .saturating_add(T::DbWeight::get().reads(4 as u64)) .saturating_add(T::DbWeight::get().writes(3 as u64)) } fn submit_parachain_heads_with_16kb_proof() -> Weight { - Weight::from_ref_time(105_189_000 as u64) + Weight::from_ref_time(101_796_000 as u64) .saturating_add(T::DbWeight::get().reads(4 as u64)) .saturating_add(T::DbWeight::get().writes(3 as u64)) } @@ -82,19 +82,19 @@ impl WeightInfo for BridgeWeight { // For backwards compatibility and tests impl WeightInfo for () { fn submit_parachain_heads_with_n_parachains(p: u32) -> Weight { - Weight::from_ref_time(0 as u64) - .saturating_add(Weight::from_ref_time(24_869_000 as u64).saturating_mul(p as u64)) + Weight::from_ref_time(51_173_000 as u64) + .saturating_add(Weight::from_ref_time(24_495_968 as u64).saturating_mul(p as u64)) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().reads((2 as u64).saturating_mul(p as u64))) .saturating_add(RocksDbWeight::get().writes((3 as u64).saturating_mul(p as u64))) } fn submit_parachain_heads_with_1kb_proof() -> Weight { - Weight::from_ref_time(56_262_000 as u64) + Weight::from_ref_time(58_175_000 as u64) .saturating_add(RocksDbWeight::get().reads(4 as u64)) .saturating_add(RocksDbWeight::get().writes(3 as u64)) } fn submit_parachain_heads_with_16kb_proof() -> Weight { - Weight::from_ref_time(105_189_000 as u64) + Weight::from_ref_time(101_796_000 as u64) .saturating_add(RocksDbWeight::get().reads(4 as u64)) .saturating_add(RocksDbWeight::get().writes(3 as u64)) } diff --git a/bridges/modules/relayers/src/mock.rs b/bridges/modules/relayers/src/mock.rs index d090da3e6da56..f2ae936ae8c9b 100644 --- a/bridges/modules/relayers/src/mock.rs +++ b/bridges/modules/relayers/src/mock.rs @@ -97,17 +97,14 @@ parameter_types! { impl pallet_bridge_messages::Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type WeightInfo = (); - type Parameter = (); type MaxMessagesToPruneAtOnce = frame_support::traits::ConstU64<0>; type MaxUnrewardedRelayerEntriesAtInboundLane = frame_support::traits::ConstU64<8>; type MaxUnconfirmedMessagesAtInboundLane = frame_support::traits::ConstU64<8>; type MaximalOutboundPayloadSize = frame_support::traits::ConstU32<1024>; type OutboundPayload = (); - type OutboundMessageFee = Balance; type InboundPayload = (); - type InboundMessageFee = Balance; type InboundRelayer = AccountId; type TargetHeaderChain = ForbidOutboundMessages; diff --git a/bridges/modules/relayers/src/payment_adapter.rs b/bridges/modules/relayers/src/payment_adapter.rs index d472810c5ccff..772d07d2ad971 100644 --- a/bridges/modules/relayers/src/payment_adapter.rs +++ b/bridges/modules/relayers/src/payment_adapter.rs @@ -20,43 +20,31 @@ use crate::{Config, RelayerRewards}; use bp_messages::source_chain::{MessageDeliveryAndDispatchPayment, RelayersRewards}; -use frame_support::{sp_runtime::SaturatedConversion, traits::Get}; -use sp_arithmetic::traits::{Saturating, Zero}; +use frame_support::sp_runtime::SaturatedConversion; +use sp_arithmetic::traits::{Saturating, UniqueSaturatedFrom, Zero}; use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData, ops::RangeInclusive}; /// Adapter that allows relayers pallet to be used as a delivery+dispatch payment mechanism /// for the messages pallet. -pub struct MessageDeliveryAndDispatchPaymentAdapter( - PhantomData<(T, MessagesInstance, GetConfirmationFee)>, +pub struct MessageDeliveryAndDispatchPaymentAdapter( + PhantomData<(T, MessagesInstance)>, ); -impl - MessageDeliveryAndDispatchPayment - for MessageDeliveryAndDispatchPaymentAdapter +impl MessageDeliveryAndDispatchPayment + for MessageDeliveryAndDispatchPaymentAdapter where - T: Config + pallet_bridge_messages::Config, + T: Config + pallet_bridge_messages::Config, MessagesInstance: 'static, - GetConfirmationFee: Get, { type Error = &'static str; - fn pay_delivery_and_dispatch_fee( - _submitter: &T::RuntimeOrigin, - _fee: &T::Reward, - ) -> Result<(), Self::Error> { - // nothing shall happen here, because XCM deals with fee payment (planned to be burnt? - // or transferred to the treasury?) - Ok(()) - } - fn pay_relayers_rewards( - lane_id: bp_messages::LaneId, + _lane_id: bp_messages::LaneId, messages_relayers: VecDeque>, confirmation_relayer: &T::AccountId, received_range: &RangeInclusive, ) { let relayers_rewards = pallet_bridge_messages::calc_relayers_rewards::( - lane_id, messages_relayers, received_range, ); @@ -64,7 +52,10 @@ where register_relayers_rewards::( confirmation_relayer, relayers_rewards, - GetConfirmationFee::get(), + // TODO (https://github.com/paritytech/parity-bridges-common/issues/1318): this shall be fixed + // in some way. ATM the future of the `register_relayers_rewards` is not yet known + 100_000_u32.into(), + 10_000_u32.into(), ); } } @@ -72,13 +63,17 @@ where // Update rewards to given relayers, optionally rewarding confirmation relayer. fn register_relayers_rewards( confirmation_relayer: &T::AccountId, - relayers_rewards: RelayersRewards, + relayers_rewards: RelayersRewards, + delivery_fee: T::Reward, confirmation_fee: T::Reward, ) { // reward every relayer except `confirmation_relayer` let mut confirmation_relayer_reward = T::Reward::zero(); - for (relayer, reward) in relayers_rewards { - let mut relayer_reward = reward.reward; + for (relayer, messages) in relayers_rewards { + // sane runtime configurations guarantee that the number of messages will be below + // `u32::MAX` + let mut relayer_reward = + T::Reward::unique_saturated_from(messages).saturating_mul(delivery_fee); if relayer != *confirmation_relayer { // If delivery confirmation is submitted by other relayer, let's deduct confirmation fee @@ -87,12 +82,11 @@ fn register_relayers_rewards( // If confirmation fee has been increased (or if it was the only component of message // fee), then messages relayer may receive zero reward. let mut confirmation_reward = - T::Reward::saturated_from(reward.messages).saturating_mul(confirmation_fee); + T::Reward::saturated_from(messages).saturating_mul(confirmation_fee); confirmation_reward = sp_std::cmp::min(confirmation_reward, relayer_reward); relayer_reward = relayer_reward.saturating_sub(confirmation_reward); confirmation_relayer_reward = confirmation_relayer_reward.saturating_add(confirmation_reward); - register_relayer_reward::(&relayer, relayer_reward); } else { // If delivery confirmation is submitted by this relayer, let's add confirmation fee @@ -134,32 +128,27 @@ mod tests { const RELAYER_2: AccountId = 2; const RELAYER_3: AccountId = 3; - fn relayers_rewards() -> RelayersRewards { - vec![ - (RELAYER_1, bp_messages::source_chain::RelayerRewards { reward: 100, messages: 2 }), - (RELAYER_2, bp_messages::source_chain::RelayerRewards { reward: 100, messages: 3 }), - ] - .into_iter() - .collect() + fn relayers_rewards() -> RelayersRewards { + vec![(RELAYER_1, 2), (RELAYER_2, 3)].into_iter().collect() } #[test] fn confirmation_relayer_is_rewarded_if_it_has_also_delivered_messages() { run_test(|| { - register_relayers_rewards::(&RELAYER_2, relayers_rewards(), 10); + register_relayers_rewards::(&RELAYER_2, relayers_rewards(), 50, 10); assert_eq!(RelayerRewards::::get(RELAYER_1), Some(80)); - assert_eq!(RelayerRewards::::get(RELAYER_2), Some(120)); + assert_eq!(RelayerRewards::::get(RELAYER_2), Some(170)); }); } #[test] fn confirmation_relayer_is_rewarded_if_it_has_not_delivered_any_delivered_messages() { run_test(|| { - register_relayers_rewards::(&RELAYER_3, relayers_rewards(), 10); + register_relayers_rewards::(&RELAYER_3, relayers_rewards(), 50, 10); assert_eq!(RelayerRewards::::get(RELAYER_1), Some(80)); - assert_eq!(RelayerRewards::::get(RELAYER_2), Some(70)); + assert_eq!(RelayerRewards::::get(RELAYER_2), Some(120)); assert_eq!(RelayerRewards::::get(RELAYER_3), Some(50)); }); } @@ -167,11 +156,11 @@ mod tests { #[test] fn only_confirmation_relayer_is_rewarded_if_confirmation_fee_has_significantly_increased() { run_test(|| { - register_relayers_rewards::(&RELAYER_3, relayers_rewards(), 1000); + register_relayers_rewards::(&RELAYER_3, relayers_rewards(), 50, 1000); assert_eq!(RelayerRewards::::get(RELAYER_1), None); assert_eq!(RelayerRewards::::get(RELAYER_2), None); - assert_eq!(RelayerRewards::::get(RELAYER_3), Some(200)); + assert_eq!(RelayerRewards::::get(RELAYER_3), Some(250)); }); } } diff --git a/bridges/modules/relayers/src/weights.rs b/bridges/modules/relayers/src/weights.rs index b8df8c94499cc..7bcd8711a9eac 100644 --- a/bridges/modules/relayers/src/weights.rs +++ b/bridges/modules/relayers/src/weights.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for `pallet_bridge_relayers` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-10-04, STEPS: 50, REPEAT: 20 +//! DATE: 2022-11-17, STEPS: 50, REPEAT: 20 //! LOW RANGE: [], HIGH RANGE: [] //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled //! CHAIN: Some("dev"), DB CACHE: 1024 @@ -59,7 +59,7 @@ pub trait WeightInfo { pub struct BridgeWeight(PhantomData); impl WeightInfo for BridgeWeight { fn claim_rewards() -> Weight { - Weight::from_ref_time(55_856_000 as u64) + Weight::from_ref_time(59_334_000 as u64) .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } @@ -68,7 +68,7 @@ impl WeightInfo for BridgeWeight { // For backwards compatibility and tests impl WeightInfo for () { fn claim_rewards() -> Weight { - Weight::from_ref_time(55_856_000 as u64) + Weight::from_ref_time(59_334_000 as u64) .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } diff --git a/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs b/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs index 0d1a81be10292..aa65f378542a6 100644 --- a/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs @@ -27,12 +27,12 @@ use bp_runtime::{ use frame_support::{ dispatch::DispatchClass, parameter_types, - sp_runtime::{FixedU128, MultiAddress, MultiSigner}, + sp_runtime::{MultiAddress, MultiSigner}, weights::{ constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, }, - Parameter, RuntimeDebug, + RuntimeDebug, }; use sp_std::prelude::*; diff --git a/bridges/primitives/chain-bridge-hub-wococo/src/lib.rs b/bridges/primitives/chain-bridge-hub-wococo/src/lib.rs index 33c4dcca127e3..5cee3f14dd6dd 100644 --- a/bridges/primitives/chain-bridge-hub-wococo/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-wococo/src/lib.rs @@ -27,16 +27,14 @@ pub use bp_bridge_hub_rococo::{ account_info_storage_key, AccountId, AccountPublic, AccountSigner, Address, Balance, BlockLength, BlockNumber, BlockWeights, Hash, Hasher, Hashing, Header, Index, Nonce, SS58Prefix, Signature, SignedBlock, SignedExtensions, UncheckedExtrinsic, WeightToFee, - ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT, DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT, - EXTRA_STORAGE_PROOF_SIZE, MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT, MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, - PAY_INBOUND_DISPATCH_FEE_WEIGHT, TX_EXTRA_BYTES, + TX_EXTRA_BYTES, }; use bp_messages::*; use bp_runtime::{ decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, }; -use frame_support::{dispatch::DispatchClass, sp_runtime::FixedU128, Parameter, RuntimeDebug}; +use frame_support::{dispatch::DispatchClass, RuntimeDebug}; use sp_std::prelude::*; /// BridgeHubWococo parachain. diff --git a/bridges/primitives/chain-millau/src/lib.rs b/bridges/primitives/chain-millau/src/lib.rs index 9c0b4782e37eb..07cdb0c27f6ed 100644 --- a/bridges/primitives/chain-millau/src/lib.rs +++ b/bridges/primitives/chain-millau/src/lib.rs @@ -27,14 +27,14 @@ use bp_runtime::{decl_bridge_runtime_apis, Chain}; use frame_support::{ dispatch::DispatchClass, weights::{constants::WEIGHT_PER_SECOND, IdentityFee, Weight}, - Parameter, RuntimeDebug, + RuntimeDebug, }; use frame_system::limits; use scale_info::TypeInfo; use sp_core::{storage::StateVersion, Hasher as HasherT}; use sp_runtime::{ traits::{IdentifyAccount, Verify}, - FixedU128, MultiSignature, MultiSigner, Perbill, + MultiSignature, MultiSigner, Perbill, }; use sp_std::prelude::*; use sp_trie::{LayoutV0, LayoutV1, TrieConfiguration}; @@ -69,38 +69,6 @@ pub const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 128; /// Maximal number of unconfirmed messages in Millau confirmation transaction. pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 128; -/// Weight of single regular message delivery transaction on Millau chain. -/// -/// This value is a result of `pallet_bridge_messages::Pallet::receive_messages_proof_weight()` call -/// for the case when single message of `pallet_bridge_messages::EXPECTED_DEFAULT_MESSAGE_LENGTH` -/// bytes is delivered. The message must have dispatch weight set to zero. The result then must be -/// rounded up to account possible future runtime upgrades. -pub const DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT: Weight = Weight::from_ref_time(1_500_000_000); - -/// Increase of delivery transaction weight on Millau chain with every additional message byte. -/// -/// This value is a result of -/// `pallet_bridge_messages::WeightInfoExt::storage_proof_size_overhead(1)` call. The result then -/// must be rounded up to account possible future runtime upgrades. -pub const ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT: Weight = Weight::from_ref_time(25_000); - -/// Maximal weight of single message delivery confirmation transaction on Millau chain. -/// -/// This value is a result of `pallet_bridge_messages::Pallet::receive_messages_delivery_proof` -/// weight formula computation for the case when single message is confirmed. The result then must -/// be rounded up to account possible future runtime upgrades. -pub const MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT: Weight = - Weight::from_ref_time(2_000_000_000); - -/// Weight of pay-dispatch-fee operation for inbound messages at Millau chain. -/// -/// This value corresponds to the result of -/// `pallet_bridge_messages::WeightInfoExt::pay_inbound_dispatch_fee_overhead()` call for your -/// chain. Don't put too much reserve there, because it is used to **decrease** -/// `DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT` cost. So putting large reserve would make delivery -/// transactions cheaper. -pub const PAY_INBOUND_DISPATCH_FEE_WEIGHT: Weight = Weight::from_ref_time(700_000_000); - /// The target length of a session (how often authorities change) on Millau measured in of number of /// blocks. /// @@ -237,13 +205,4 @@ pub const WITH_MILLAU_MESSAGES_PALLET_NAME: &str = "BridgeMillauMessages"; /// Name of the transaction payment pallet at the Millau runtime. pub const TRANSACTION_PAYMENT_PALLET_NAME: &str = "TransactionPayment"; -/// Name of the Rialto->Millau (actually DOT->KSM) conversion rate stored in the Millau runtime. -pub const RIALTO_TO_MILLAU_CONVERSION_RATE_PARAMETER_NAME: &str = "RialtoToMillauConversionRate"; -/// Name of the RialtoParachain->Millau (actually DOT->KSM) conversion rate stored in the Millau -/// runtime. -pub const RIALTO_PARACHAIN_TO_MILLAU_CONVERSION_RATE_PARAMETER_NAME: &str = - "RialtoParachainToMillauConversionRate"; -/// Name of the RialtoParachain fee multiplier parameter, stored in the Millau runtime. -pub const RIALTO_PARACHAIN_FEE_MULTIPLIER_PARAMETER_NAME: &str = "RialtoParachainFeeMultiplier"; - decl_bridge_runtime_apis!(millau); diff --git a/bridges/primitives/chain-rialto-parachain/src/lib.rs b/bridges/primitives/chain-rialto-parachain/src/lib.rs index 584882425b4db..82b6a12c182a3 100644 --- a/bridges/primitives/chain-rialto-parachain/src/lib.rs +++ b/bridges/primitives/chain-rialto-parachain/src/lib.rs @@ -25,13 +25,13 @@ use bp_runtime::{decl_bridge_runtime_apis, Chain, Parachain}; use frame_support::{ dispatch::DispatchClass, weights::{constants::WEIGHT_PER_SECOND, IdentityFee, Weight}, - Parameter, RuntimeDebug, + RuntimeDebug, }; use frame_system::limits; use sp_core::Hasher as HasherT; use sp_runtime::{ traits::{BlakeTwo256, IdentifyAccount, Verify}, - FixedU128, MultiSignature, MultiSigner, Perbill, + MultiSignature, MultiSigner, Perbill, }; use sp_std::vec::Vec; @@ -66,39 +66,6 @@ pub const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 1024; /// Maximal number of unconfirmed messages in Rialto confirmation transaction. pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 1024; -/// Weight of single regular message delivery transaction on RialtoParachain chain. -/// -/// This value is a result of `pallet_bridge_messages::Pallet::receive_messages_proof_weight()` call -/// for the case when single message of `pallet_bridge_messages::EXPECTED_DEFAULT_MESSAGE_LENGTH` -/// bytes is delivered. The message must have dispatch weight set to zero. The result then must be -/// rounded up to account possible future runtime upgrades. -pub const DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT: Weight = Weight::from_ref_time(1_500_000_000); - -/// Increase of delivery transaction weight on RialtoParachain chain with every additional message -/// byte. -/// -/// This value is a result of -/// `pallet_bridge_messages::WeightInfoExt::storage_proof_size_overhead(1)` call. The result then -/// must be rounded up to account possible future runtime upgrades. -pub const ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT: Weight = Weight::from_ref_time(25_000); - -/// Maximal weight of single message delivery confirmation transaction on RialtoParachain chain. -/// -/// This value is a result of `pallet_bridge_messages::Pallet::receive_messages_delivery_proof` -/// weight formula computation for the case when single message is confirmed. The result then must -/// be rounded up to account possible future runtime upgrades. -pub const MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT: Weight = - Weight::from_ref_time(2_000_000_000); - -/// Weight of pay-dispatch-fee operation for inbound messages at Rialto chain. -/// -/// This value corresponds to the result of -/// `pallet_bridge_messages::WeightInfoExt::pay_inbound_dispatch_fee_overhead()` call for your -/// chain. Don't put too much reserve there, because it is used to **decrease** -/// `DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT` cost. So putting large reserve would make delivery -/// transactions cheaper. -pub const PAY_INBOUND_DISPATCH_FEE_WEIGHT: Weight = Weight::from_ref_time(600_000_000); - /// Block number type used in Rialto. pub type BlockNumber = u32; @@ -176,11 +143,4 @@ pub const WITH_RIALTO_PARACHAIN_MESSAGES_PALLET_NAME: &str = "BridgeRialtoParach /// Name of the transaction payment pallet at the Rialto parachain runtime. pub const TRANSACTION_PAYMENT_PALLET_NAME: &str = "TransactionPayment"; -/// Name of the Millau->RialtoParachain (actually KSM->DOT) conversion rate stored in the Rialto -/// parachain runtime. -pub const MILLAU_TO_RIALTO_PARACHAIN_CONVERSION_RATE_PARAMETER_NAME: &str = - "MillauToRialtoParachainConversionRate"; -/// Name of the Millau fee multiplier parameter, stored in the Rialto parachain runtime. -pub const MILLAU_FEE_MULTIPLIER_PARAMETER_NAME: &str = "MillauFeeMultiplier"; - decl_bridge_runtime_apis!(rialto_parachain); diff --git a/bridges/primitives/chain-rialto/src/lib.rs b/bridges/primitives/chain-rialto/src/lib.rs index 4d272fe68399f..dfb727829d9aa 100644 --- a/bridges/primitives/chain-rialto/src/lib.rs +++ b/bridges/primitives/chain-rialto/src/lib.rs @@ -25,13 +25,13 @@ use bp_runtime::{decl_bridge_runtime_apis, Chain}; use frame_support::{ dispatch::DispatchClass, weights::{constants::WEIGHT_PER_SECOND, IdentityFee, Weight}, - Parameter, RuntimeDebug, + RuntimeDebug, }; use frame_system::limits; use sp_core::Hasher as HasherT; use sp_runtime::{ traits::{BlakeTwo256, IdentifyAccount, Verify}, - FixedU128, MultiSignature, MultiSigner, Perbill, + MultiSignature, MultiSigner, Perbill, }; use sp_std::prelude::*; @@ -60,38 +60,6 @@ pub const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 1024; /// Maximal number of unconfirmed messages in Rialto confirmation transaction. pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 1024; -/// Weight of single regular message delivery transaction on Rialto chain. -/// -/// This value is a result of `pallet_bridge_messages::Pallet::receive_messages_proof_weight()` call -/// for the case when single message of `pallet_bridge_messages::EXPECTED_DEFAULT_MESSAGE_LENGTH` -/// bytes is delivered. The message must have dispatch weight set to zero. The result then must be -/// rounded up to account possible future runtime upgrades. -pub const DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT: Weight = Weight::from_ref_time(1_500_000_000); - -/// Increase of delivery transaction weight on Rialto chain with every additional message byte. -/// -/// This value is a result of -/// `pallet_bridge_messages::WeightInfoExt::storage_proof_size_overhead(1)` call. The result then -/// must be rounded up to account possible future runtime upgrades. -pub const ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT: Weight = Weight::from_ref_time(25_000); - -/// Maximal weight of single message delivery confirmation transaction on Rialto chain. -/// -/// This value is a result of `pallet_bridge_messages::Pallet::receive_messages_delivery_proof` -/// weight formula computation for the case when single message is confirmed. The result then must -/// be rounded up to account possible future runtime upgrades. -pub const MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT: Weight = - Weight::from_ref_time(2_000_000_000); - -/// Weight of pay-dispatch-fee operation for inbound messages at Rialto chain. -/// -/// This value corresponds to the result of -/// `pallet_bridge_messages::WeightInfoExt::pay_inbound_dispatch_fee_overhead()` call for your -/// chain. Don't put too much reserve there, because it is used to **decrease** -/// `DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT` cost. So putting large reserve would make delivery -/// transactions cheaper. -pub const PAY_INBOUND_DISPATCH_FEE_WEIGHT: Weight = Weight::from_ref_time(700_000_000); - /// The target length of a session (how often authorities change) on Rialto measured in of number of /// blocks. /// @@ -203,9 +171,6 @@ pub const WITH_RIALTO_MESSAGES_PALLET_NAME: &str = "BridgeRialtoMessages"; /// Name of the With-Rialto parachains bridge pallet instance that is deployed at bridged chains. pub const WITH_RIALTO_BRIDGE_PARAS_PALLET_NAME: &str = "BridgeRialtoParachains"; -/// Name of the Millau->Rialto (actually KSM->DOT) conversion rate stored in the Rialto runtime. -pub const MILLAU_TO_RIALTO_CONVERSION_RATE_PARAMETER_NAME: &str = "MillauToRialtoConversionRate"; - /// Name of the parachain registrar pallet in the Rialto runtime. pub const PARAS_REGISTRAR_PALLET_NAME: &str = "Registrar"; diff --git a/bridges/primitives/chain-statemine/Cargo.toml b/bridges/primitives/chain-statemine/Cargo.toml deleted file mode 100644 index 18d186ba41ef5..0000000000000 --- a/bridges/primitives/chain-statemine/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "bp-statemine" -description = "Primitives of Statemine runtime." -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2021" -license = "GPL-3.0-or-later WITH Classpath-exception-2.0" - -[dependencies] - -# Bridge Dependencies - -bp-polkadot-core = { path = "../polkadot-core", default-features = false } - -# Substrate Based Dependencies - -sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } - -[features] -default = ["std"] -std = [ - "bp-polkadot-core/std", - "sp-version/std", -] diff --git a/bridges/primitives/chain-statemine/src/lib.rs b/bridges/primitives/chain-statemine/src/lib.rs deleted file mode 100644 index 613e4a4f4501a..0000000000000 --- a/bridges/primitives/chain-statemine/src/lib.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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 . - -#![cfg_attr(not(feature = "std"), no_std)] -// RuntimeApi generated functions -#![allow(clippy::too_many_arguments)] - -pub use bp_polkadot_core::*; - -use sp_version::RuntimeVersion; - -/// Statemine Chain. -pub type Statemine = PolkadotLike; - -/// Known Statemine runtime version. -pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: sp_version::create_runtime_str!("statemine"), - impl_name: sp_version::create_runtime_str!("statemine"), - authoring_version: 1, - spec_version: 9300, - impl_version: 0, - apis: sp_version::create_apis_vec![[]], - transaction_version: 8, - state_version: 1, -}; diff --git a/bridges/primitives/messages/src/lib.rs b/bridges/primitives/messages/src/lib.rs index 8742ff8448d72..f535a40a9db9b 100644 --- a/bridges/primitives/messages/src/lib.rs +++ b/bridges/primitives/messages/src/lib.rs @@ -21,7 +21,7 @@ #![allow(clippy::too_many_arguments)] use bitvec::prelude::*; -use bp_runtime::{messages::DispatchFeePayment, BasicOperatingMode, OperatingMode}; +use bp_runtime::{BasicOperatingMode, OperatingMode}; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::RuntimeDebug; use scale_info::TypeInfo; @@ -65,16 +65,6 @@ impl OperatingMode for MessagesOperatingMode { } } -/// Messages pallet parameter. -pub trait Parameter: frame_support::Parameter { - /// Save parameter value in the runtime storage. - fn save(&self); -} - -impl Parameter for () { - fn save(&self) {} -} - /// Lane identifier. pub type LaneId = [u8; 4]; @@ -96,22 +86,13 @@ pub struct MessageKey { pub nonce: MessageNonce, } -/// Message data as it is stored in the storage. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] -pub struct MessageData { - /// Message payload. - pub payload: MessagePayload, - /// Message delivery and dispatch fee, paid by the submitter. - pub fee: Fee, -} - /// Message as it is stored in the storage. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] -pub struct Message { +pub struct Message { /// Message key. pub key: MessageKey, - /// Message data. - pub data: MessageData, + /// Message payload. + pub payload: MessagePayload, } /// Inbound lane data. @@ -198,7 +179,7 @@ impl InboundLaneData { /// Outbound message details, returned by runtime APIs. #[derive(Clone, Encode, Decode, RuntimeDebug, PartialEq, Eq)] -pub struct OutboundMessageDetails { +pub struct OutboundMessageDetails { /// Nonce assigned to the message. pub nonce: MessageNonce, /// Message dispatch weight. @@ -208,10 +189,6 @@ pub struct OutboundMessageDetails { pub dispatch_weight: Weight, /// Size of the encoded message. pub size: u32, - /// Delivery+dispatch fee paid by the message submitter at the source chain. - pub delivery_and_dispatch_fee: OutboundMessageFee, - /// Where the fee for dispatching message is paid? - pub dispatch_fee_payment: DispatchFeePayment, } /// Inbound message details, returned by runtime APIs. diff --git a/bridges/primitives/messages/src/source_chain.rs b/bridges/primitives/messages/src/source_chain.rs index 8050f994dd3f1..6a22ececf8efc 100644 --- a/bridges/primitives/messages/src/source_chain.rs +++ b/bridges/primitives/messages/src/source_chain.rs @@ -27,17 +27,8 @@ use sp_std::{ ops::RangeInclusive, }; -/// Relayers rewards, grouped by relayer account id. -pub type RelayersRewards = BTreeMap>; - -/// Single relayer rewards. -#[derive(RuntimeDebug, Default)] -pub struct RelayerRewards { - /// Total rewards that are to be paid to the relayer. - pub reward: Balance, - /// Total number of messages relayed by this relayer. - pub messages: MessageNonce, -} +/// Number of messages, delivered by relayers. +pub type RelayersRewards = BTreeMap; /// Target chain API. Used by source chain to verify target chain proofs. /// @@ -83,7 +74,7 @@ pub trait TargetHeaderChain { /// Lane3 until some block, ...), then it may be built using this verifier. /// /// Any fee requirements should also be enforced here. -pub trait LaneMessageVerifier { +pub trait LaneMessageVerifier { /// Error type. type Error: Debug + Into<&'static str>; @@ -91,7 +82,6 @@ pub trait LaneMessageVerifier { /// lane. fn verify_message( submitter: &SenderOrigin, - delivery_and_dispatch_fee: &Fee, lane: &LaneId, outbound_data: &OutboundLaneData, payload: &Payload, @@ -107,21 +97,10 @@ pub trait LaneMessageVerifier { /// 3) message-dispatch fee. It is paid by relayer for processing message by target chain; /// 4) message-receiving-delivery-transaction-fee. It is submitted to the source node /// by relayer. -/// -/// So to be sure that any non-altruist relayer would agree to deliver message, submitter -/// should set `delivery_and_dispatch_fee` to at least (equivalent of): sum of fees from (2) -/// to (4) above, plus some interest for the relayer. -pub trait MessageDeliveryAndDispatchPayment { +pub trait MessageDeliveryAndDispatchPayment { /// Error type. type Error: Debug + Into<&'static str>; - /// Withhold/write-off delivery_and_dispatch_fee from submitter account to - /// some relayers-fund account. - fn pay_delivery_and_dispatch_fee( - submitter: &SenderOrigin, - fee: &Balance, - ) -> Result<(), Self::Error>; - /// Pay rewards for delivering messages to the given relayers. /// /// The implementation may also choose to pay reward to the `confirmation_relayer`, which is @@ -134,18 +113,9 @@ pub trait MessageDeliveryAndDispatchPayment { ); } -impl - MessageDeliveryAndDispatchPayment for () -{ +impl MessageDeliveryAndDispatchPayment for () { type Error = &'static str; - fn pay_delivery_and_dispatch_fee( - _submitter: &SenderOrigin, - _fee: &Balance, - ) -> Result<(), Self::Error> { - Ok(()) - } - fn pay_relayers_rewards( _lane_id: LaneId, _messages_relayers: VecDeque>, @@ -165,7 +135,7 @@ pub struct SendMessageArtifacts { } /// Messages bridge API to be used from other pallets. -pub trait MessagesBridge { +pub trait MessagesBridge { /// Error type. type Error: Debug; @@ -176,7 +146,6 @@ pub trait MessagesBridge { sender: SenderOrigin, lane: LaneId, message: Payload, - delivery_and_dispatch_fee: Balance, ) -> Result; } @@ -184,16 +153,13 @@ pub trait MessagesBridge { #[derive(Eq, RuntimeDebug, PartialEq)] pub struct NoopMessagesBridge; -impl MessagesBridge - for NoopMessagesBridge -{ +impl MessagesBridge for NoopMessagesBridge { type Error = &'static str; fn send_message( _sender: SenderOrigin, _lane: LaneId, _message: Payload, - _delivery_and_dispatch_fee: Balance, ) -> Result { Ok(SendMessageArtifacts { nonce: 0, weight: Weight::zero() }) } @@ -266,14 +232,11 @@ impl TargetHeaderChain for ForbidOutboun } } -impl LaneMessageVerifier - for ForbidOutboundMessages -{ +impl LaneMessageVerifier for ForbidOutboundMessages { type Error = &'static str; fn verify_message( _submitter: &SenderOrigin, - _delivery_and_dispatch_fee: &Fee, _lane: &LaneId, _outbound_data: &OutboundLaneData, _payload: &Payload, @@ -282,18 +245,11 @@ impl LaneMessageVerifier } } -impl - MessageDeliveryAndDispatchPayment for ForbidOutboundMessages +impl MessageDeliveryAndDispatchPayment + for ForbidOutboundMessages { type Error = &'static str; - fn pay_delivery_and_dispatch_fee( - _submitter: &SenderOrigin, - _fee: &Balance, - ) -> Result<(), Self::Error> { - Err(ALL_OUTBOUND_MESSAGES_REJECTED) - } - fn pay_relayers_rewards( _lane_id: LaneId, _messages_relayers: VecDeque>, diff --git a/bridges/primitives/messages/src/target_chain.rs b/bridges/primitives/messages/src/target_chain.rs index 58419c398bb33..5f682dee16666 100644 --- a/bridges/primitives/messages/src/target_chain.rs +++ b/bridges/primitives/messages/src/target_chain.rs @@ -16,7 +16,7 @@ //! Primitives of messages module, that are used on the target chain. -use crate::{LaneId, Message, MessageData, MessageKey, OutboundLaneData}; +use crate::{LaneId, Message, MessageKey, MessagePayload, OutboundLaneData}; use bp_runtime::{messages::MessageDispatchResult, Size}; use codec::{Decode, Encode, Error as CodecError}; @@ -38,20 +38,18 @@ pub struct ProvedLaneMessages { /// Message data with decoded dispatch payload. #[derive(RuntimeDebug)] -pub struct DispatchMessageData { +pub struct DispatchMessageData { /// Result of dispatch payload decoding. pub payload: Result, - /// Message delivery and dispatch fee, paid by the submitter. - pub fee: Fee, } /// Message with decoded dispatch payload. #[derive(RuntimeDebug)] -pub struct DispatchMessage { +pub struct DispatchMessage { /// Message key. pub key: MessageKey, /// Message data with decoded dispatch payload. - pub data: DispatchMessageData, + pub data: DispatchMessageData, } /// Source chain API. Used by target chain, to verify source chain proofs. @@ -59,7 +57,7 @@ pub struct DispatchMessage { /// All implementations of this trait should only work with finalized data that /// can't change. Wrong implementation may lead to invalid lane states (i.e. lane /// that's stuck) and/or processing messages without paying fees. -pub trait SourceHeaderChain { +pub trait SourceHeaderChain { /// Error type. type Error: Debug + Into<&'static str>; @@ -81,11 +79,11 @@ pub trait SourceHeaderChain { fn verify_messages_proof( proof: Self::MessagesProof, messages_count: u32, - ) -> Result>, Self::Error>; + ) -> Result, Self::Error>; } /// Called when inbound message is received. -pub trait MessageDispatch { +pub trait MessageDispatch { /// Decoded message payload type. Valid message may contain invalid payload. In this case /// message is delivered, but dispatch fails. Therefore, two separate types of payload /// (opaque `MessagePayload` used in delivery and this `DispatchPayload` used in dispatch). @@ -96,7 +94,7 @@ pub trait MessageDispatch { /// This function must return correct upper bound of dispatch weight. The return value /// of this function is expected to match return value of the corresponding /// `FromInboundLaneApi::message_details().dispatch_weight` call. - fn dispatch_weight(message: &mut DispatchMessage) -> Weight; + fn dispatch_weight(message: &mut DispatchMessage) -> Weight; /// Called when inbound message is received. /// @@ -107,7 +105,7 @@ pub trait MessageDispatch { /// it must be paid inside this method to the `relayer_account`. fn dispatch( relayer_account: &AccountId, - message: DispatchMessage, + message: DispatchMessage, ) -> MessageDispatchResult; } @@ -117,20 +115,15 @@ impl Default for ProvedLaneMessages { } } -impl From> for DispatchMessage { - fn from(message: Message) -> Self { - DispatchMessage { key: message.key, data: message.data.into() } +impl From for DispatchMessage { + fn from(message: Message) -> Self { + DispatchMessage { key: message.key, data: message.payload.into() } } } -impl From> - for DispatchMessageData -{ - fn from(data: MessageData) -> Self { - DispatchMessageData { - payload: DispatchPayload::decode(&mut &data.payload[..]), - fee: data.fee, - } +impl From for DispatchMessageData { + fn from(payload: MessagePayload) -> Self { + DispatchMessageData { payload: DispatchPayload::decode(&mut &payload[..]) } } } @@ -142,29 +135,26 @@ pub struct ForbidInboundMessages; const ALL_INBOUND_MESSAGES_REJECTED: &str = "This chain is configured to reject all inbound messages"; -impl SourceHeaderChain for ForbidInboundMessages { +impl SourceHeaderChain for ForbidInboundMessages { type Error = &'static str; type MessagesProof = (); fn verify_messages_proof( _proof: Self::MessagesProof, _messages_count: u32, - ) -> Result>, Self::Error> { + ) -> Result, Self::Error> { Err(ALL_INBOUND_MESSAGES_REJECTED) } } -impl MessageDispatch for ForbidInboundMessages { +impl MessageDispatch for ForbidInboundMessages { type DispatchPayload = (); - fn dispatch_weight(_message: &mut DispatchMessage) -> Weight { + fn dispatch_weight(_message: &mut DispatchMessage) -> Weight { Weight::MAX } - fn dispatch( - _: &AccountId, - _: DispatchMessage, - ) -> MessageDispatchResult { + fn dispatch(_: &AccountId, _: DispatchMessage) -> MessageDispatchResult { MessageDispatchResult { dispatch_result: false, unspent_weight: Weight::zero(), diff --git a/bridges/primitives/polkadot-core/src/lib.rs b/bridges/primitives/polkadot-core/src/lib.rs index 34eb4ae13b19a..878c3dc38ebcf 100644 --- a/bridges/primitives/polkadot-core/src/lib.rs +++ b/bridges/primitives/polkadot-core/src/lib.rs @@ -126,49 +126,12 @@ pub const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 128; /// Maximal number of unconfirmed messages at inbound lane. pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 8192; -// One important thing about weight-related constants here is that actually we may have -// different weights on different Polkadot-like chains. But now all deployments are -// almost the same, so we're exporting constants from this crate. - -/// Maximal weight of single message delivery confirmation transaction on Polkadot-like chain. -/// -/// This value is a result of `pallet_bridge_messages::Pallet::receive_messages_delivery_proof` -/// weight formula computation for the case when single message is confirmed. The result then must -/// be rounded up to account possible future runtime upgrades. -pub const MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT: Weight = - Weight::from_ref_time(2_000_000_000); - -/// Increase of delivery transaction weight on Polkadot-like chain with every additional message -/// byte. -/// -/// This value is a result of -/// `pallet_bridge_messages::WeightInfoExt::storage_proof_size_overhead(1)` call. The result then -/// must be rounded up to account possible future runtime upgrades. -pub const ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT: Weight = Weight::from_ref_time(25_000); - /// Maximal number of bytes, included in the signed Polkadot-like transaction apart from the encoded /// call itself. /// /// Can be computed by subtracting encoded call size from raw transaction size. pub const TX_EXTRA_BYTES: u32 = 256; -/// Weight of single regular message delivery transaction on Polkadot-like chain. -/// -/// This value is a result of `pallet_bridge_messages::Pallet::receive_messages_proof_weight()` call -/// for the case when single message of `pallet_bridge_messages::EXPECTED_DEFAULT_MESSAGE_LENGTH` -/// bytes is delivered. The message must have dispatch weight set to zero. The result then must be -/// rounded up to account possible future runtime upgrades. -pub const DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT: Weight = Weight::from_ref_time(1_500_000_000); - -/// Weight of pay-dispatch-fee operation for inbound messages at Polkadot-like chain. -/// -/// This value corresponds to the result of -/// `pallet_bridge_messages::WeightInfoExt::pay_inbound_dispatch_fee_overhead()` call for your -/// chain. Don't put too much reserve there, because it is used to **decrease** -/// `DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT` cost. So putting large reserve would make delivery -/// transactions cheaper. -pub const PAY_INBOUND_DISPATCH_FEE_WEIGHT: Weight = Weight::from_ref_time(600_000_000); - /// Re-export `time_units` to make usage easier. pub use time_units::*; diff --git a/bridges/primitives/runtime/src/chain.rs b/bridges/primitives/runtime/src/chain.rs index 6f43c0f354900..d4a8d5aa020b5 100644 --- a/bridges/primitives/runtime/src/chain.rs +++ b/bridges/primitives/runtime/src/chain.rs @@ -300,21 +300,7 @@ macro_rules! decl_bridge_messages_runtime_apis { /// /// This API is implemented by runtimes that are receiving messages from this chain, not by this /// chain's runtime itself. - pub trait [] { - /// Estimate message delivery and dispatch fee that needs to be paid by the sender on - /// this chain. - /// - /// Returns `None` if message is too expensive to be sent to this chain from the bridged chain. - /// - /// Please keep in mind that this method returns the lowest message fee required for message - /// to be accepted to the lane. It may be a good idea to pay a bit over this price to account - /// for future exchange rate changes and guarantee that relayer would deliver your message - /// to the target chain. - fn estimate_message_delivery_and_dispatch_fee( - lane_id: LaneId, - payload: OutboundPayload, - [<$chain:lower _to_this_conversion_rate>]: Option, - ) -> Option; + pub trait [] { /// Returns dispatch weight, encoded payload size and delivery+dispatch fee of all /// messages in given inclusive range. /// @@ -324,7 +310,7 @@ macro_rules! decl_bridge_messages_runtime_apis { lane: LaneId, begin: MessageNonce, end: MessageNonce, - ) -> Vec>; + ) -> Vec; } /// Inbound message lane API for messages sent by this chain. @@ -334,11 +320,11 @@ macro_rules! decl_bridge_messages_runtime_apis { /// /// Entries of the resulting vector are matching entries of the `messages` vector. Entries of the /// `messages` vector may (and need to) be read using `ToOutboundLaneApi::message_details`. - pub trait [] { + pub trait [] { /// Return details of given inbound messages. fn message_details( lane: LaneId, - messages: Vec<(MessagePayload, OutboundMessageDetails)>, + messages: Vec<(MessagePayload, OutboundMessageDetails)>, ) -> Vec; } } @@ -346,7 +332,7 @@ macro_rules! decl_bridge_messages_runtime_apis { pub use [<$chain _messages_api>]::*; } - } + }; } /// Convenience macro that declares bridge finality runtime apis, bridge messages runtime apis diff --git a/bridges/primitives/runtime/src/messages.rs b/bridges/primitives/runtime/src/messages.rs index 7a6687c18b776..d77b1df7515c6 100644 --- a/bridges/primitives/runtime/src/messages.rs +++ b/bridges/primitives/runtime/src/messages.rs @@ -20,20 +20,6 @@ use codec::{Decode, Encode}; use frame_support::{weights::Weight, RuntimeDebug}; use scale_info::TypeInfo; -/// Where message dispatch fee is paid? -#[derive(Encode, Decode, RuntimeDebug, Clone, Copy, PartialEq, Eq, TypeInfo)] -pub enum DispatchFeePayment { - /// The dispatch fee is paid at the source chain. - AtSourceChain, - /// The dispatch fee is paid at the target chain. - /// - /// The fee will be paid right before the message is dispatched. So in case of any other - /// issues (like invalid call encoding, invalid signature, ...) the dispatch module won't - /// do any direct transfers. Instead, it'll return fee related to this message dispatch to the - /// relayer. - AtTargetChain, -} - /// Message dispatch result. #[derive(Encode, Decode, RuntimeDebug, Clone, PartialEq, Eq, TypeInfo)] pub struct MessageDispatchResult { diff --git a/bridges/relays/bin-substrate/Cargo.toml b/bridges/relays/bin-substrate/Cargo.toml index c214471eb6bdf..9ae6a98868e39 100644 --- a/bridges/relays/bin-substrate/Cargo.toml +++ b/bridges/relays/bin-substrate/Cargo.toml @@ -30,7 +30,6 @@ bp-rialto = { path = "../../primitives/chain-rialto" } bp-rialto-parachain = { path = "../../primitives/chain-rialto-parachain" } bp-rococo = { path = "../../primitives/chain-rococo" } bp-runtime = { path = "../../primitives/runtime" } -bp-statemine = { path = "../../primitives/chain-statemine" } bp-westend = { path = "../../primitives/chain-westend" } bp-wococo = { path = "../../primitives/chain-wococo" } bridge-runtime-common = { path = "../../bin/runtime-common" } @@ -45,7 +44,6 @@ relay-rialto-parachain-client = { path = "../client-rialto-parachain" } relay-bridge-hub-rococo-client = { path = "../client-bridge-hub-rococo" } relay-bridge-hub-wococo-client = { path = "../client-bridge-hub-wococo" } relay-rococo-client = { path = "../client-rococo" } -relay-statemine-client = { path = "../client-statemine" } relay-substrate-client = { path = "../client-substrate" } relay-utils = { path = "../utils" } relay-westend-client = { path = "../client-westend" } diff --git a/bridges/relays/bin-substrate/src/chains/bridge_hub_rococo_messages_to_bridge_hub_wococo.rs b/bridges/relays/bin-substrate/src/chains/bridge_hub_rococo_messages_to_bridge_hub_wococo.rs index 915dd82969852..78ef00f6d6248 100644 --- a/bridges/relays/bin-substrate/src/chains/bridge_hub_rococo_messages_to_bridge_hub_wococo.rs +++ b/bridges/relays/bin-substrate/src/chains/bridge_hub_rococo_messages_to_bridge_hub_wococo.rs @@ -18,7 +18,6 @@ use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge}; use bp_messages::Weight; -use messages_relay::relay_strategy::MixStrategy; use relay_bridge_hub_rococo_client::BridgeHubRococo; use relay_bridge_hub_wococo_client::BridgeHubWococo; use substrate_relay_helper::messages_lane::SubstrateMessageLane; @@ -55,15 +54,6 @@ substrate_relay_helper::generate_mocked_receive_message_delivery_proof_call_buil pub struct BridgeHubRococoMessagesToBridgeHubWococoMessageLane; impl SubstrateMessageLane for BridgeHubRococoMessagesToBridgeHubWococoMessageLane { - const SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = None; - const TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = None; - - const SOURCE_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None; - const TARGET_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None; - - const AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None; - const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None; - type SourceChain = BridgeHubRococo; type TargetChain = BridgeHubWococo; @@ -71,8 +61,4 @@ impl SubstrateMessageLane for BridgeHubRococoMessagesToBridgeHubWococoMessageLan BridgeHubRococoMessagesToBridgeHubWococoMessageLaneReceiveMessagesProofCallBuilder; type ReceiveMessagesDeliveryProofCallBuilder = BridgeHubRococoMessagesToBridgeHubWococoMessageLaneReceiveMessagesDeliveryProofCallBuilder; - - type TargetToSourceChainConversionRateUpdateBuilder = (); - - type RelayStrategy = MixStrategy; } diff --git a/bridges/relays/bin-substrate/src/chains/bridge_hub_wococo_messages_to_bridge_hub_rococo.rs b/bridges/relays/bin-substrate/src/chains/bridge_hub_wococo_messages_to_bridge_hub_rococo.rs index 179b9076ba72d..51e1020e74953 100644 --- a/bridges/relays/bin-substrate/src/chains/bridge_hub_wococo_messages_to_bridge_hub_rococo.rs +++ b/bridges/relays/bin-substrate/src/chains/bridge_hub_wococo_messages_to_bridge_hub_rococo.rs @@ -18,7 +18,6 @@ use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge}; use bp_messages::Weight; -use messages_relay::relay_strategy::MixStrategy; use relay_bridge_hub_rococo_client::BridgeHubRococo; use relay_bridge_hub_wococo_client::BridgeHubWococo; use substrate_relay_helper::messages_lane::SubstrateMessageLane; @@ -55,15 +54,6 @@ substrate_relay_helper::generate_mocked_receive_message_delivery_proof_call_buil pub struct BridgeHubWococoMessagesToBridgeHubRococoMessageLane; impl SubstrateMessageLane for BridgeHubWococoMessagesToBridgeHubRococoMessageLane { - const SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = None; - const TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = None; - - const SOURCE_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None; - const TARGET_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None; - - const AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None; - const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None; - type SourceChain = BridgeHubWococo; type TargetChain = BridgeHubRococo; @@ -71,8 +61,4 @@ impl SubstrateMessageLane for BridgeHubWococoMessagesToBridgeHubRococoMessageLan BridgeHubWococoMessagesToBridgeHubRococoMessageLaneReceiveMessagesProofCallBuilder; type ReceiveMessagesDeliveryProofCallBuilder = BridgeHubWococoMessagesToBridgeHubRococoMessageLaneReceiveMessagesDeliveryProofCallBuilder; - - type TargetToSourceChainConversionRateUpdateBuilder = (); - - type RelayStrategy = MixStrategy; } diff --git a/bridges/relays/bin-substrate/src/chains/millau.rs b/bridges/relays/bin-substrate/src/chains/millau.rs index 92fc43fbe36fe..705755506f78c 100644 --- a/bridges/relays/bin-substrate/src/chains/millau.rs +++ b/bridges/relays/bin-substrate/src/chains/millau.rs @@ -16,16 +16,10 @@ //! Millau chain specification for CLI. -use crate::cli::{ - bridge, - encode_message::{CliEncodeMessage, RawMessage}, - CliChain, -}; -use bp_messages::LaneId; +use crate::cli::{bridge, encode_message::CliEncodeMessage, CliChain}; use bp_rialto_parachain::RIALTO_PARACHAIN_ID; use bp_runtime::EncodedOrDecodedCall; use relay_millau_client::Millau; -use relay_substrate_client::BalanceOf; use sp_version::RuntimeVersion; use xcm::latest::prelude::*; @@ -56,37 +50,6 @@ impl CliEncodeMessage for Millau { }) .into()) } - - fn encode_send_message_call( - lane: LaneId, - payload: RawMessage, - fee: BalanceOf, - bridge_instance_index: u8, - ) -> anyhow::Result> { - Ok(match bridge_instance_index { - bridge::MILLAU_TO_RIALTO_INDEX => millau_runtime::RuntimeCall::BridgeRialtoMessages( - millau_runtime::MessagesCall::send_message { - lane_id: lane, - payload, - delivery_and_dispatch_fee: fee, - }, - ) - .into(), - bridge::MILLAU_TO_RIALTO_PARACHAIN_INDEX => - millau_runtime::RuntimeCall::BridgeRialtoParachainMessages( - millau_runtime::MessagesCall::send_message { - lane_id: lane, - payload, - delivery_and_dispatch_fee: fee, - }, - ) - .into(), - _ => anyhow::bail!( - "Unsupported target bridge pallet with instance index: {}", - bridge_instance_index - ), - }) - } } impl CliChain for Millau { 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 332721e217f0d..b9920db53d85d 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 @@ -16,7 +16,6 @@ //! Millau-to-Rialto messages sync entrypoint. -use messages_relay::relay_strategy::MixStrategy; use relay_millau_client::Millau; use relay_rialto_client::Rialto; use substrate_relay_helper::messages_lane::{ @@ -27,25 +26,8 @@ use substrate_relay_helper::messages_lane::{ /// Description of Millau -> Rialto messages bridge. #[derive(Clone, Debug)] pub struct MillauMessagesToRialto; -substrate_relay_helper::generate_direct_update_conversion_rate_call_builder!( - Millau, - MillauMessagesToRialtoUpdateConversionRateCallBuilder, - millau_runtime::Runtime, - millau_runtime::WithRialtoMessagesInstance, - millau_runtime::rialto_messages::MillauToRialtoMessagesParameter::RialtoToMillauConversionRate -); impl SubstrateMessageLane for MillauMessagesToRialto { - const SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = - Some(bp_rialto::MILLAU_TO_RIALTO_CONVERSION_RATE_PARAMETER_NAME); - const TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = - Some(bp_millau::RIALTO_TO_MILLAU_CONVERSION_RATE_PARAMETER_NAME); - - const SOURCE_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None; - const TARGET_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None; - const AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None; - const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None; - type SourceChain = Millau; type TargetChain = Rialto; @@ -59,9 +41,4 @@ impl SubstrateMessageLane for MillauMessagesToRialto { millau_runtime::Runtime, millau_runtime::WithRialtoMessagesInstance, >; - - type TargetToSourceChainConversionRateUpdateBuilder = - MillauMessagesToRialtoUpdateConversionRateCallBuilder; - - type RelayStrategy = MixStrategy; } diff --git a/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto_parachain.rs b/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto_parachain.rs index 04b2b1e46e66a..70cb887fa35d4 100644 --- a/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto_parachain.rs +++ b/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto_parachain.rs @@ -16,7 +16,6 @@ //! Millau-to-RialtoParachain messages sync entrypoint. -use messages_relay::relay_strategy::MixStrategy; use relay_millau_client::Millau; use relay_rialto_parachain_client::RialtoParachain; use substrate_relay_helper::messages_lane::{ @@ -27,30 +26,8 @@ use substrate_relay_helper::messages_lane::{ /// Description of Millau -> RialtoParachain messages bridge. #[derive(Clone, Debug)] pub struct MillauMessagesToRialtoParachain; -substrate_relay_helper::generate_direct_update_conversion_rate_call_builder!( - Millau, - MillauMessagesToRialtoParachainUpdateConversionRateCallBuilder, - millau_runtime::Runtime, - millau_runtime::WithRialtoParachainMessagesInstance, - millau_runtime::rialto_parachain_messages::MillauToRialtoParachainMessagesParameter::RialtoParachainToMillauConversionRate -); impl SubstrateMessageLane for MillauMessagesToRialtoParachain { - const SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = - Some(bp_rialto_parachain::MILLAU_TO_RIALTO_PARACHAIN_CONVERSION_RATE_PARAMETER_NAME); - const TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = - Some(bp_millau::RIALTO_PARACHAIN_TO_MILLAU_CONVERSION_RATE_PARAMETER_NAME); - - const SOURCE_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = - Some(bp_rialto_parachain::MILLAU_FEE_MULTIPLIER_PARAMETER_NAME); - const TARGET_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = - Some(bp_millau::RIALTO_PARACHAIN_FEE_MULTIPLIER_PARAMETER_NAME); - - const AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = - Some(bp_millau::TRANSACTION_PAYMENT_PALLET_NAME); - const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = - Some(bp_rialto_parachain::TRANSACTION_PAYMENT_PALLET_NAME); - type SourceChain = Millau; type TargetChain = RialtoParachain; @@ -64,9 +41,4 @@ impl SubstrateMessageLane for MillauMessagesToRialtoParachain { millau_runtime::Runtime, millau_runtime::WithRialtoParachainMessagesInstance, >; - - type TargetToSourceChainConversionRateUpdateBuilder = - MillauMessagesToRialtoParachainUpdateConversionRateCallBuilder; - - type RelayStrategy = MixStrategy; } diff --git a/bridges/relays/bin-substrate/src/chains/mod.rs b/bridges/relays/bin-substrate/src/chains/mod.rs index 6bd444cc3959f..7caba7561ddc1 100644 --- a/bridges/relays/bin-substrate/src/chains/mod.rs +++ b/bridges/relays/bin-substrate/src/chains/mod.rs @@ -37,7 +37,6 @@ mod millau; mod rialto; mod rialto_parachain; mod rococo; -mod statemine; mod westend; mod wococo; diff --git a/bridges/relays/bin-substrate/src/chains/rialto.rs b/bridges/relays/bin-substrate/src/chains/rialto.rs index 43ec9dbd224e4..83bccf626b9ed 100644 --- a/bridges/relays/bin-substrate/src/chains/rialto.rs +++ b/bridges/relays/bin-substrate/src/chains/rialto.rs @@ -16,15 +16,9 @@ //! Rialto chain specification for CLI. -use crate::cli::{ - bridge, - encode_message::{CliEncodeMessage, RawMessage}, - CliChain, -}; -use bp_messages::LaneId; +use crate::cli::{bridge, encode_message::CliEncodeMessage, CliChain}; use bp_runtime::EncodedOrDecodedCall; use relay_rialto_client::Rialto; -use relay_substrate_client::BalanceOf; use sp_version::RuntimeVersion; use xcm::latest::prelude::*; @@ -48,28 +42,6 @@ impl CliEncodeMessage for Rialto { }) .into()) } - - fn encode_send_message_call( - lane: LaneId, - payload: RawMessage, - fee: BalanceOf, - bridge_instance_index: u8, - ) -> anyhow::Result> { - Ok(match bridge_instance_index { - bridge::RIALTO_TO_MILLAU_INDEX => rialto_runtime::RuntimeCall::BridgeMillauMessages( - rialto_runtime::MessagesCall::send_message { - lane_id: lane, - payload, - delivery_and_dispatch_fee: fee, - }, - ) - .into(), - _ => anyhow::bail!( - "Unsupported target bridge pallet with instance index: {}", - bridge_instance_index - ), - }) - } } impl CliChain for Rialto { 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 e922659ab9a8b..80b6b9fdbc6b0 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 @@ -16,7 +16,6 @@ //! Rialto-to-Millau messages sync entrypoint. -use messages_relay::relay_strategy::MixStrategy; use relay_millau_client::Millau; use relay_rialto_client::Rialto; use substrate_relay_helper::messages_lane::{ @@ -27,25 +26,8 @@ use substrate_relay_helper::messages_lane::{ /// Description of Rialto -> Millau messages bridge. #[derive(Clone, Debug)] pub struct RialtoMessagesToMillau; -substrate_relay_helper::generate_direct_update_conversion_rate_call_builder!( - Rialto, - RialtoMessagesToMillauUpdateConversionRateCallBuilder, - rialto_runtime::Runtime, - rialto_runtime::WithMillauMessagesInstance, - rialto_runtime::millau_messages::RialtoToMillauMessagesParameter::MillauToRialtoConversionRate -); impl SubstrateMessageLane for RialtoMessagesToMillau { - const SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = - Some(bp_millau::RIALTO_TO_MILLAU_CONVERSION_RATE_PARAMETER_NAME); - const TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = - Some(bp_rialto::MILLAU_TO_RIALTO_CONVERSION_RATE_PARAMETER_NAME); - - const SOURCE_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None; - const TARGET_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None; - const AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None; - const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None; - type SourceChain = Rialto; type TargetChain = Millau; @@ -59,9 +41,4 @@ impl SubstrateMessageLane for RialtoMessagesToMillau { rialto_runtime::Runtime, rialto_runtime::WithMillauMessagesInstance, >; - - type TargetToSourceChainConversionRateUpdateBuilder = - RialtoMessagesToMillauUpdateConversionRateCallBuilder; - - type RelayStrategy = MixStrategy; } diff --git a/bridges/relays/bin-substrate/src/chains/rialto_parachain.rs b/bridges/relays/bin-substrate/src/chains/rialto_parachain.rs index 546cd04bdde15..a480dc3eebbc6 100644 --- a/bridges/relays/bin-substrate/src/chains/rialto_parachain.rs +++ b/bridges/relays/bin-substrate/src/chains/rialto_parachain.rs @@ -16,15 +16,9 @@ //! Rialto parachain specification for CLI. -use crate::cli::{ - bridge, - encode_message::{CliEncodeMessage, RawMessage}, - CliChain, -}; -use bp_messages::LaneId; +use crate::cli::{bridge, encode_message::CliEncodeMessage, CliChain}; use bp_runtime::EncodedOrDecodedCall; use relay_rialto_parachain_client::RialtoParachain; -use relay_substrate_client::BalanceOf; use sp_version::RuntimeVersion; use xcm::latest::prelude::*; @@ -50,29 +44,6 @@ impl CliEncodeMessage for RialtoParachain { ) .into()) } - - fn encode_send_message_call( - lane: LaneId, - payload: RawMessage, - fee: BalanceOf, - bridge_instance_index: u8, - ) -> anyhow::Result> { - Ok(match bridge_instance_index { - bridge::RIALTO_PARACHAIN_TO_MILLAU_INDEX => - rialto_parachain_runtime::RuntimeCall::BridgeMillauMessages( - rialto_parachain_runtime::MessagesCall::send_message { - lane_id: lane, - payload, - delivery_and_dispatch_fee: fee, - }, - ) - .into(), - _ => anyhow::bail!( - "Unsupported target bridge pallet with instance index: {}", - bridge_instance_index - ), - }) - } } impl CliChain for RialtoParachain { diff --git a/bridges/relays/bin-substrate/src/chains/rialto_parachain_messages_to_millau.rs b/bridges/relays/bin-substrate/src/chains/rialto_parachain_messages_to_millau.rs index ef13920cf8554..5cca26105b87d 100644 --- a/bridges/relays/bin-substrate/src/chains/rialto_parachain_messages_to_millau.rs +++ b/bridges/relays/bin-substrate/src/chains/rialto_parachain_messages_to_millau.rs @@ -16,7 +16,6 @@ //! RialtoParachain-to-Millau messages sync entrypoint. -use messages_relay::relay_strategy::MixStrategy; use relay_millau_client::Millau; use relay_rialto_parachain_client::RialtoParachain; use substrate_relay_helper::messages_lane::{ @@ -27,30 +26,8 @@ use substrate_relay_helper::messages_lane::{ /// Description of RialtoParachain -> Millau messages bridge. #[derive(Clone, Debug)] pub struct RialtoParachainMessagesToMillau; -substrate_relay_helper::generate_direct_update_conversion_rate_call_builder!( - RialtoParachain, - RialtoParachainMessagesToMillauUpdateConversionRateCallBuilder, - rialto_parachain_runtime::Runtime, - rialto_parachain_runtime::WithMillauMessagesInstance, - rialto_parachain_runtime::millau_messages::RialtoParachainToMillauMessagesParameter::MillauToRialtoParachainConversionRate -); impl SubstrateMessageLane for RialtoParachainMessagesToMillau { - const SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = - Some(bp_millau::RIALTO_PARACHAIN_TO_MILLAU_CONVERSION_RATE_PARAMETER_NAME); - const TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = - Some(bp_rialto_parachain::MILLAU_TO_RIALTO_PARACHAIN_CONVERSION_RATE_PARAMETER_NAME); - - const SOURCE_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = - Some(bp_millau::RIALTO_PARACHAIN_FEE_MULTIPLIER_PARAMETER_NAME); - const TARGET_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = - Some(bp_rialto_parachain::MILLAU_FEE_MULTIPLIER_PARAMETER_NAME); - - const AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = - Some(bp_rialto_parachain::TRANSACTION_PAYMENT_PALLET_NAME); - const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = - Some(bp_millau::TRANSACTION_PAYMENT_PALLET_NAME); - type SourceChain = RialtoParachain; type TargetChain = Millau; @@ -64,9 +41,4 @@ impl SubstrateMessageLane for RialtoParachainMessagesToMillau { rialto_parachain_runtime::Runtime, rialto_parachain_runtime::WithMillauMessagesInstance, >; - - type TargetToSourceChainConversionRateUpdateBuilder = - RialtoParachainMessagesToMillauUpdateConversionRateCallBuilder; - - type RelayStrategy = MixStrategy; } diff --git a/bridges/relays/bin-substrate/src/chains/statemine.rs b/bridges/relays/bin-substrate/src/chains/statemine.rs deleted file mode 100644 index 0c0edd2f3e484..0000000000000 --- a/bridges/relays/bin-substrate/src/chains/statemine.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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 . - -//! Statemine chain specification for CLI. - -use crate::cli::CliChain; -use relay_statemine_client::Statemine; -use sp_version::RuntimeVersion; - -impl CliChain for Statemine { - const RUNTIME_VERSION: Option = Some(bp_statemine::VERSION); - - type KeyPair = sp_core::sr25519::Pair; - - fn ss58_format() -> u16 { - sp_core::crypto::Ss58AddressFormat::from( - sp_core::crypto::Ss58AddressFormatRegistry::KusamaAccount, - ) - .into() - } -} diff --git a/bridges/relays/bin-substrate/src/cli/bridge.rs b/bridges/relays/bin-substrate/src/cli/bridge.rs index 0bed036d91a9b..ae2a36cd1d553 100644 --- a/bridges/relays/bin-substrate/src/cli/bridge.rs +++ b/bridges/relays/bin-substrate/src/cli/bridge.rs @@ -15,7 +15,6 @@ // along with Parity Bridges Common. If not, see . use crate::cli::CliChain; -use messages_relay::relay_strategy::MixStrategy; use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber}; use parachains_relay::ParachainsPipeline; use relay_substrate_client::{AccountKeyPairOf, Chain, ChainWithTransactions, RelayChain}; @@ -46,7 +45,7 @@ impl FullBridge { Self::MillauToRialtoParachain => MILLAU_TO_RIALTO_PARACHAIN_INDEX, Self::RialtoParachainToMillau => RIALTO_PARACHAIN_TO_MILLAU_INDEX, Self::BridgeHubRococoToBridgeHubWococo | Self::BridgeHubWococoToBridgeHubRococo => - unimplemented!("TODO: (bridge_instance_index) do we need it or refactor or remove?"), + unimplemented!("Relay doesn't support send-message subcommand on bridge hubs"), } } } @@ -102,9 +101,5 @@ pub trait MessagesCliBridge: CliBridgeBase { /// defined bridge. const ESTIMATE_MESSAGE_FEE_METHOD: &'static str; /// The Source -> Destination messages synchronization pipeline. - type MessagesLane: SubstrateMessageLane< - SourceChain = Self::Source, - TargetChain = Self::Target, - RelayStrategy = MixStrategy, - >; + type MessagesLane: SubstrateMessageLane; } diff --git a/bridges/relays/bin-substrate/src/cli/encode_message.rs b/bridges/relays/bin-substrate/src/cli/encode_message.rs index 9f9ef37ff0eaa..c7ca5d51f7993 100644 --- a/bridges/relays/bin-substrate/src/cli/encode_message.rs +++ b/bridges/relays/bin-substrate/src/cli/encode_message.rs @@ -15,8 +15,8 @@ // along with Parity Bridges Common. If not, see . use crate::cli::{ExplicitOrMaximal, HexBytes}; -use bp_messages::LaneId; use bp_runtime::EncodedOrDecodedCall; +use codec::Encode; use relay_substrate_client::Chain; use structopt::StructOpt; @@ -47,14 +47,6 @@ pub trait CliEncodeMessage: Chain { message: xcm::VersionedXcm<()>, bridge_instance_index: u8, ) -> anyhow::Result>; - - /// Encode a send message call of the bridge-messages pallet. - fn encode_send_message_call( - lane: LaneId, - message: RawMessage, - fee: Self::Balance, - bridge_instance_index: u8, - ) -> anyhow::Result>; } /// Encode message payload passed through CLI flags. @@ -63,15 +55,36 @@ pub(crate) fn encode_message( ) -> anyhow::Result { Ok(match message { Message::Raw { ref data } => data.0.clone(), - Message::Sized { ref size } => match *size { - ExplicitOrMaximal::Explicit(size) => vec![42; size as usize], - ExplicitOrMaximal::Maximal => { - let maximal_size = compute_maximal_message_size( + Message::Sized { ref size } => { + let expected_xcm_size = match *size { + ExplicitOrMaximal::Explicit(size) => size, + ExplicitOrMaximal::Maximal => compute_maximal_message_size( Source::max_extrinsic_size(), Target::max_extrinsic_size(), + ), + }; + + // there's no way to craft XCM of the given size - we'll be using `ExpectPallet` + // instruction, which has byte vector inside + let mut current_vec_size = expected_xcm_size; + let xcm = loop { + let xcm = xcm::VersionedXcm::<()>::V3( + vec![xcm::v3::Instruction::ExpectPallet { + index: 0, + name: vec![42; current_vec_size as usize], + module_name: vec![], + crate_major: 0, + min_crate_minor: 0, + }] + .into(), ); - vec![42; maximal_size as usize] - }, + if xcm.encode().len() <= expected_xcm_size as usize { + break xcm + } + + current_vec_size -= 1; + }; + xcm.encode() }, }) } @@ -95,3 +108,38 @@ pub(crate) fn compute_maximal_message_size( maximal_message_size } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::cli::send_message::decode_xcm; + use bp_runtime::Chain; + use relay_millau_client::Millau; + use relay_rialto_client::Rialto; + + #[test] + fn encode_explicit_size_message_works() { + let msg = encode_message::(&Message::Sized { + size: ExplicitOrMaximal::Explicit(100), + }) + .unwrap(); + assert_eq!(msg.len(), 100); + // check that it decodes to valid xcm + let _ = decode_xcm(msg).unwrap(); + } + + #[test] + fn encode_maximal_size_message_works() { + let maximal_size = compute_maximal_message_size( + Rialto::max_extrinsic_size(), + Millau::max_extrinsic_size(), + ); + + let msg = + encode_message::(&Message::Sized { size: ExplicitOrMaximal::Maximal }) + .unwrap(); + assert_eq!(msg.len(), maximal_size as usize); + // check that it decodes to valid xcm + let _ = decode_xcm(msg).unwrap(); + } +} diff --git a/bridges/relays/bin-substrate/src/cli/estimate_fee.rs b/bridges/relays/bin-substrate/src/cli/estimate_fee.rs deleted file mode 100644 index 00a175187778c..0000000000000 --- a/bridges/relays/bin-substrate/src/cli/estimate_fee.rs +++ /dev/null @@ -1,292 +0,0 @@ -// 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 . - -use crate::{ - chains::{ - millau_headers_to_rialto::MillauToRialtoCliBridge, - millau_headers_to_rialto_parachain::MillauToRialtoParachainCliBridge, - rialto_headers_to_millau::RialtoToMillauCliBridge, - rialto_parachains_to_millau::RialtoParachainToMillauCliBridge, - }, - cli::{ - bridge::{FullBridge, MessagesCliBridge}, - chain_schema::*, - relay_headers_and_messages::CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO, - Balance, HexBytes, HexLaneId, - }, -}; -use async_trait::async_trait; -use bp_runtime::BalanceOf; -use codec::{Decode, Encode}; -use relay_substrate_client::{Chain, ChainBase}; -use sp_runtime::FixedU128; -use std::fmt::Display; -use structopt::StructOpt; -use strum::VariantNames; -use substrate_relay_helper::helpers::tokens_conversion_rate_from_metrics; - -/// Estimate Delivery & Dispatch Fee command. -#[derive(StructOpt, Debug, PartialEq)] -pub struct EstimateFee { - /// A bridge instance to encode call for. - #[structopt(possible_values = FullBridge::VARIANTS, case_insensitive = true)] - bridge: FullBridge, - #[structopt(flatten)] - source: SourceConnectionParams, - /// Hex-encoded id of lane that will be delivering the message. - #[structopt(long, default_value = "00000000")] - lane: HexLaneId, - /// A way to override conversion rate between bridge tokens. - /// - /// If not specified, conversion rate from runtime storage is used. It may be obsolete and - /// your message won't be relayed. - #[structopt(long)] - conversion_rate_override: Option, - /// Payload to send over the bridge. - #[structopt(flatten)] - payload: crate::cli::encode_message::Message, -} - -/// A way to override conversion rate between bridge tokens. -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum ConversionRateOverride { - /// The actual conversion rate is computed in the same way how rate metric works. - Metric, - /// The actual conversion rate is specified explicitly. - Explicit(f64), -} - -impl std::str::FromStr for ConversionRateOverride { - type Err = String; - - fn from_str(s: &str) -> Result { - if s.to_lowercase() == "metric" { - return Ok(ConversionRateOverride::Metric) - } - - f64::from_str(s) - .map(ConversionRateOverride::Explicit) - .map_err(|e| format!("Failed to parse '{e:?}'. Expected 'metric' or explicit value")) - } -} - -#[async_trait] -trait FeeEstimator: MessagesCliBridge -where - ::Balance: Display + Into, -{ - async fn estimate_fee(data: EstimateFee) -> anyhow::Result<()> { - let source_client = data.source.into_client::().await?; - let lane = data.lane.into(); - let payload = - crate::cli::encode_message::encode_message::(&data.payload) - .map_err(|e| anyhow::format_err!("{:?}", e))?; - - let fee = estimate_message_delivery_and_dispatch_fee::( - &source_client, - data.conversion_rate_override, - Self::ESTIMATE_MESSAGE_FEE_METHOD, - lane, - &payload, - ) - .await?; - - log::info!(target: "bridge", "Fee: {:?}", Balance(fee.into())); - println!("{fee}"); - Ok(()) - } -} - -impl FeeEstimator for MillauToRialtoCliBridge {} -impl FeeEstimator for RialtoToMillauCliBridge {} -impl FeeEstimator for MillauToRialtoParachainCliBridge {} -impl FeeEstimator for RialtoParachainToMillauCliBridge {} - -impl EstimateFee { - /// Run the command. - pub async fn run(self) -> anyhow::Result<()> { - match self.bridge { - FullBridge::MillauToRialto => MillauToRialtoCliBridge::estimate_fee(self), - FullBridge::RialtoToMillau => RialtoToMillauCliBridge::estimate_fee(self), - FullBridge::MillauToRialtoParachain => - MillauToRialtoParachainCliBridge::estimate_fee(self), - FullBridge::RialtoParachainToMillau => - RialtoParachainToMillauCliBridge::estimate_fee(self), - FullBridge::BridgeHubRococoToBridgeHubWococo | - FullBridge::BridgeHubWococoToBridgeHubRococo => - unimplemented!("TODO: (EstimateFee) do we need it or refactor or remove?"), - } - .await - } -} - -/// The caller may provide target to source tokens conversion rate override to use in fee -/// computation. -pub(crate) async fn estimate_message_delivery_and_dispatch_fee< - Source: Chain, - Target: Chain, - P: Clone + Encode, ->( - client: &relay_substrate_client::Client, - conversion_rate_override: Option, - estimate_fee_method: &str, - lane: bp_messages::LaneId, - payload: &P, -) -> anyhow::Result> { - // actual conversion rate CAN be lesser than the rate stored in the runtime. So we may try to - // pay lesser fee for the message delivery. But in this case, message may be rejected by the - // lane. So we MUST use the larger of two fees - one computed with stored fee and the one - // computed with actual fee. - - let conversion_rate_override = - match (conversion_rate_override, Source::TOKEN_ID, Target::TOKEN_ID) { - (Some(ConversionRateOverride::Explicit(v)), _, _) => { - let conversion_rate_override = FixedU128::from_float(v); - log::info!( - target: "bridge", - "{} -> {} conversion rate override: {:?} (explicit)", - Target::NAME, - Source::NAME, - conversion_rate_override.to_float(), - ); - Some(conversion_rate_override) - }, - ( - Some(ConversionRateOverride::Metric), - Some(source_token_id), - Some(target_token_id), - ) => { - let conversion_rate_override = - tokens_conversion_rate_from_metrics(target_token_id, source_token_id).await?; - // So we have current actual conversion rate and rate that is stored in the runtime. - // And we may simply choose the maximal of these. But what if right now there's - // rate update transaction on the way, that is updating rate to 10 seconds old - // actual rate, which is bigger than the current rate? Then our message will be - // rejected. - // - // So let's increase the actual rate by the same value that the conversion rate - // updater is using. - let increased_conversion_rate_override = FixedU128::from_float( - conversion_rate_override * (1.0 + CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO), - ); - log::info!( - target: "bridge", - "{} -> {} conversion rate override: {} (value from metric - {})", - Target::NAME, - Source::NAME, - increased_conversion_rate_override.to_float(), - conversion_rate_override, - ); - Some(increased_conversion_rate_override) - }, - _ => None, - }; - - let without_override = do_estimate_message_delivery_and_dispatch_fee( - client, - estimate_fee_method, - lane, - payload, - None, - ) - .await?; - let with_override = do_estimate_message_delivery_and_dispatch_fee( - client, - estimate_fee_method, - lane, - payload, - conversion_rate_override, - ) - .await?; - let maximal_fee = std::cmp::max(without_override, with_override); - - log::info!( - target: "bridge", - "Estimated message fee: {:?} = max of {:?} (without rate override) and {:?} (with override to {:?})", - maximal_fee, - without_override, - with_override, - conversion_rate_override, - ); - - Ok(maximal_fee) -} - -/// Estimate message delivery and dispatch fee with given conversion rate override. -async fn do_estimate_message_delivery_and_dispatch_fee( - client: &relay_substrate_client::Client, - estimate_fee_method: &str, - lane: bp_messages::LaneId, - payload: &P, - conversion_rate_override: Option, -) -> anyhow::Result> { - let encoded_response = client - .state_call( - estimate_fee_method.into(), - (lane, payload, conversion_rate_override).encode().into(), - None, - ) - .await?; - let decoded_response: Option> = Decode::decode(&mut &encoded_response.0[..]) - .map_err(relay_substrate_client::Error::ResponseParseFailed)?; - let fee = decoded_response.ok_or_else(|| { - anyhow::format_err!("Unable to decode fee from: {:?}", HexBytes(encoded_response.to_vec())) - })?; - Ok(fee) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn should_parse_cli_options() { - // when - let res = EstimateFee::from_iter(vec![ - "estimate_fee", - "rialto-to-millau", - "--source-port", - "1234", - "--conversion-rate-override", - "42.5", - "raw", - "1234", - ]); - - // then - assert_eq!( - res, - EstimateFee { - bridge: FullBridge::RialtoToMillau, - lane: HexLaneId([0, 0, 0, 0]), - conversion_rate_override: Some(ConversionRateOverride::Explicit(42.5)), - source: SourceConnectionParams { - source_host: "127.0.0.1".into(), - source_port: 1234, - source_secure: false, - source_runtime_version: SourceRuntimeVersionParams { - source_version_mode: RuntimeVersionType::Bundle, - source_spec_version: None, - source_transaction_version: None, - } - }, - payload: crate::cli::encode_message::Message::Raw { - data: HexBytes(vec![0x12, 0x34]) - } - } - ); - } -} diff --git a/bridges/relays/bin-substrate/src/cli/mod.rs b/bridges/relays/bin-substrate/src/cli/mod.rs index 2f2f1f227b70b..2086008bc9566 100644 --- a/bridges/relays/bin-substrate/src/cli/mod.rs +++ b/bridges/relays/bin-substrate/src/cli/mod.rs @@ -26,7 +26,6 @@ use bp_messages::LaneId; pub(crate) mod bridge; pub(crate) mod encode_message; -pub(crate) mod estimate_fee; pub(crate) mod send_message; mod chain_schema; @@ -74,8 +73,6 @@ pub enum Command { /// The message is being sent to the source chain, delivered to the target chain and dispatched /// there. SendMessage(send_message::SendMessage), - /// Estimate Delivery and Dispatch Fee required for message submission to messages pallet. - EstimateFee(estimate_fee::EstimateFee), /// Resubmit transactions with increased tip if they are stalled. ResubmitTransactions(resubmit_transactions::ResubmitTransactions), /// Register parachain. @@ -111,7 +108,6 @@ impl Command { Self::RelayHeadersAndMessages(arg) => arg.run().await?, Self::InitBridge(arg) => arg.run().await?, Self::SendMessage(arg) => arg.run().await?, - Self::EstimateFee(arg) => arg.run().await?, Self::ResubmitTransactions(arg) => arg.run().await?, Self::RegisterParachain(arg) => arg.run().await?, Self::RelayParachains(arg) => arg.run().await?, diff --git a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/mod.rs b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/mod.rs index 1feba9d6284e5..49e9c5aa1560f 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/mod.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/mod.rs @@ -31,7 +31,6 @@ mod relay_to_parachain; use async_trait::async_trait; use std::{marker::PhantomData, sync::Arc}; use structopt::StructOpt; -use strum::VariantNames; use futures::{FutureExt, TryFutureExt}; use relay_to_parachain::*; @@ -50,40 +49,27 @@ use crate::{ RelayToRelayHeadersCliBridge, }, chain_schema::*, - relay_messages::RelayerMode, CliChain, HexLaneId, PrometheusParams, }, declare_chain_cli_schema, }; use bp_messages::LaneId; use bp_runtime::{BalanceOf, BlockNumberOf}; -use messages_relay::relay_strategy::MixStrategy; use relay_substrate_client::{ AccountIdOf, AccountKeyPairOf, Chain, ChainWithBalances, ChainWithTransactions, Client, }; use relay_utils::metrics::MetricsParams; use sp_core::Pair; use substrate_relay_helper::{ - messages_lane::MessagesRelayParams, messages_metrics::StandaloneMessagesMetrics, - on_demand::OnDemandRelay, TaggedAccount, TransactionParams, + messages_lane::MessagesRelayParams, on_demand::OnDemandRelay, TaggedAccount, TransactionParams, }; -/// Maximal allowed conversion rate error ratio (abs(real - stored) / stored) that we allow. -/// -/// If it is zero, then transaction will be submitted every time we see difference between -/// stored and real conversion rates. If it is large enough (e.g. > than 10 percents, which is 0.1), -/// then rational relayers may stop relaying messages because they were submitted using -/// lesser conversion rate. -pub(crate) const CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO: f64 = 0.05; - /// Parameters that have the same names across all bridges. #[derive(Debug, PartialEq, StructOpt)] pub struct HeadersAndMessagesSharedParams { /// Hex-encoded lane identifiers that should be served by the complex relay. #[structopt(long, default_value = "00000000")] pub lane: Vec, - #[structopt(long, possible_values = RelayerMode::VARIANTS, case_insensitive = true, default_value = "rational")] - pub relayer_mode: RelayerMode, /// If passed, only mandatory headers (headers that are changing the GRANDPA authorities set) /// are relayed. #[structopt(long)] @@ -101,8 +87,6 @@ pub struct Full2WayBridgeCommonParams< pub right: BridgeEndCommonParams, pub metrics_params: MetricsParams, - pub left_to_right_metrics: StandaloneMessagesMetrics, - pub right_to_left_metrics: StandaloneMessagesMetrics, } impl @@ -116,19 +100,8 @@ impl(left.client.clone(), right.client.clone())?; - let right_to_left_metrics = left_to_right_metrics.clone().reverse(); - - Ok(Self { - shared, - left, - right, - metrics_params, - left_to_right_metrics, - right_to_left_metrics, - }) + + Ok(Self { shared, left, right, metrics_params }) } } @@ -146,11 +119,9 @@ struct FullBridge< Target: ChainWithTransactions + CliChain, Bridge: MessagesCliBridge, > { - shared: &'a HeadersAndMessagesSharedParams, source: &'a mut BridgeEndCommonParams, target: &'a mut BridgeEndCommonParams, metrics_params: &'a MetricsParams, - metrics: &'a StandaloneMessagesMetrics, _phantom_data: PhantomData, } @@ -166,55 +137,11 @@ where BalanceOf: TryFrom> + Into, { fn new( - shared: &'a HeadersAndMessagesSharedParams, source: &'a mut BridgeEndCommonParams, target: &'a mut BridgeEndCommonParams, metrics_params: &'a MetricsParams, - metrics: &'a StandaloneMessagesMetrics, ) -> Self { - Self { shared, source, target, metrics_params, metrics, _phantom_data: Default::default() } - } - - fn start_conversion_rate_update_loop(&mut self) -> anyhow::Result<()> { - if let Some(ref messages_pallet_owner) = self.source.messages_pallet_owner { - let format_err = || { - anyhow::format_err!( - "Cannon run conversion rate updater: {} -> {}", - Target::NAME, - Source::NAME - ) - }; - substrate_relay_helper::conversion_rate_update::run_conversion_rate_update_loop::< - Bridge::MessagesLane, - >( - self.source.client.clone(), - TransactionParams { - signer: messages_pallet_owner.clone(), - mortality: self.source.transactions_mortality, - }, - self.metrics - .target_to_source_conversion_rate - .as_ref() - .ok_or_else(format_err)? - .shared_value_ref(), - self.metrics - .target_to_base_conversion_rate - .as_ref() - .ok_or_else(format_err)? - .shared_value_ref(), - self.metrics - .source_to_base_conversion_rate - .as_ref() - .ok_or_else(format_err)? - .shared_value_ref(), - CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO, - ); - self.source.accounts.push(TaggedAccount::MessagesPalletOwner { - id: messages_pallet_owner.public().into(), - bridged_chain: Target::NAME.to_string(), - }); - } - Ok(()) + Self { source, target, metrics_params, _phantom_data: Default::default() } } fn messages_relay_params( @@ -223,9 +150,6 @@ where target_to_source_headers_relay: Arc>>, lane_id: LaneId, ) -> MessagesRelayParams { - let relayer_mode = self.shared.relayer_mode.into(); - let relay_strategy = MixStrategy::new(relayer_mode); - MessagesRelayParams { source_client: self.source.client.clone(), source_transaction_params: TransactionParams { @@ -241,8 +165,6 @@ where target_to_source_headers_relay: Some(target_to_source_headers_relay), lane_id, metrics_params: self.metrics_params.clone().disable(), - standalone_metrics: Some(self.metrics.clone()), - relay_strategy, } } } @@ -314,22 +236,18 @@ where fn left_to_right(&mut self) -> FullBridge { let common = self.mut_base().mut_common(); FullBridge::<_, _, Self::L2R>::new( - &common.shared, &mut common.left, &mut common.right, &common.metrics_params, - &common.left_to_right_metrics, ) } fn right_to_left(&mut self) -> FullBridge { let common = self.mut_base().mut_common(); FullBridge::<_, _, Self::R2L>::new( - &common.shared, &mut common.right, &mut common.left, &common.metrics_params, - &common.right_to_left_metrics, ) } @@ -347,10 +265,6 @@ where }); } - // start conversion rate update loops for left/right chains - self.left_to_right().start_conversion_rate_update_loop()?; - self.right_to_left().start_conversion_rate_update_loop()?; - // start on-demand header relays let (left_to_right_on_demand_headers, right_to_left_on_demand_headers) = self.mut_base().start_on_demand_headers_relayers().await?; @@ -528,7 +442,6 @@ mod tests { HexLaneId([0x00, 0x00, 0x00, 0x00]), HexLaneId([0x73, 0x77, 0x61, 0x70]) ], - relayer_mode: RelayerMode::Rational, only_mandatory_headers: false, prometheus_params: PrometheusParams { no_prometheus: false, @@ -641,7 +554,6 @@ mod tests { MillauRialtoParachainHeadersAndMessages { shared: HeadersAndMessagesSharedParams { lane: vec![HexLaneId([0x00, 0x00, 0x00, 0x00])], - relayer_mode: RelayerMode::Rational, only_mandatory_headers: false, prometheus_params: PrometheusParams { no_prometheus: false, diff --git a/bridges/relays/bin-substrate/src/cli/relay_messages.rs b/bridges/relays/bin-substrate/src/cli/relay_messages.rs index 23f9bf0c113f7..7f4dc34ac8bff 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_messages.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_messages.rs @@ -17,7 +17,7 @@ use async_trait::async_trait; use sp_core::Pair; use structopt::StructOpt; -use strum::{EnumString, EnumVariantNames, VariantNames}; +use strum::VariantNames; use crate::chains::{ bridge_hub_rococo_messages_to_bridge_hub_wococo::BridgeHubRococoToBridgeHubWococoMessagesCliBridge, @@ -27,32 +27,11 @@ use crate::chains::{ rialto_headers_to_millau::RialtoToMillauCliBridge, rialto_parachains_to_millau::RialtoParachainToMillauCliBridge, }; -use messages_relay::relay_strategy::MixStrategy; use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, BalanceOf, ChainWithTransactions}; use substrate_relay_helper::{messages_lane::MessagesRelayParams, TransactionParams}; use crate::cli::{bridge::*, chain_schema::*, CliChain, HexLaneId, PrometheusParams}; -/// Relayer operating mode. -#[derive(Debug, EnumString, EnumVariantNames, Clone, Copy, PartialEq, Eq)] -#[strum(serialize_all = "kebab_case")] -pub enum RelayerMode { - /// The relayer doesn't care about rewards. - Altruistic, - /// The relayer will deliver all messages and confirmations as long as he's not losing any - /// funds. - Rational, -} - -impl From for messages_relay::message_lane_loop::RelayerMode { - fn from(mode: RelayerMode) -> Self { - match mode { - RelayerMode::Altruistic => Self::Altruistic, - RelayerMode::Rational => Self::Rational, - } - } -} - /// Start messages relayer process. #[derive(StructOpt)] pub struct RelayMessages { @@ -62,8 +41,6 @@ pub struct RelayMessages { /// Hex-encoded lane id that should be served by the relay. Defaults to `00000000`. #[structopt(long, default_value = "00000000")] lane: HexLaneId, - #[structopt(long, possible_values = RelayerMode::VARIANTS, case_insensitive = true, default_value = "rational")] - relayer_mode: RelayerMode, #[structopt(flatten)] source: SourceConnectionParams, #[structopt(flatten)] @@ -91,8 +68,6 @@ where let target_client = data.target.into_client::().await?; let target_sign = data.target_sign.to_keypair::()?; let target_transactions_mortality = data.target_sign.transactions_mortality()?; - let relayer_mode = data.relayer_mode.into(); - let relay_strategy = MixStrategy::new(relayer_mode); substrate_relay_helper::messages_lane::run::(MessagesRelayParams { source_client, @@ -109,8 +84,6 @@ where target_to_source_headers_relay: None, lane_id: data.lane.into(), metrics_params: data.prometheus_params.into(), - standalone_metrics: None, - relay_strategy, }) .await .map_err(|e| anyhow::format_err!("{}", e)) @@ -142,43 +115,3 @@ impl RelayMessages { .await } } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn should_use_rational_relayer_mode_by_default() { - assert_eq!( - RelayMessages::from_iter(vec![ - "relay-messages", - "rialto-to-millau", - "--source-port=0", - "--source-signer=//Alice", - "--target-port=0", - "--target-signer=//Alice", - "--lane=00000000", - ]) - .relayer_mode, - RelayerMode::Rational, - ); - } - - #[test] - fn should_accept_altruistic_relayer_mode() { - assert_eq!( - RelayMessages::from_iter(vec![ - "relay-messages", - "rialto-to-millau", - "--source-port=0", - "--source-signer=//Alice", - "--target-port=0", - "--target-signer=//Alice", - "--lane=00000000", - "--relayer-mode=altruistic", - ]) - .relayer_mode, - RelayerMode::Altruistic, - ); - } -} diff --git a/bridges/relays/bin-substrate/src/cli/send_message.rs b/bridges/relays/bin-substrate/src/cli/send_message.rs index bb46762cee880..d492d3422c706 100644 --- a/bridges/relays/bin-substrate/src/cli/send_message.rs +++ b/bridges/relays/bin-substrate/src/cli/send_message.rs @@ -25,8 +25,7 @@ use crate::{ bridge::{FullBridge, MessagesCliBridge}, chain_schema::*, encode_message::{self, CliEncodeMessage, RawMessage}, - estimate_fee::{estimate_message_delivery_and_dispatch_fee, ConversionRateOverride}, - Balance, CliChain, HexLaneId, + CliChain, }, }; use async_trait::async_trait; @@ -35,30 +34,11 @@ use relay_substrate_client::{ AccountIdOf, AccountKeyPairOf, Chain, ChainBase, ChainWithTransactions, SignParam, UnsignedTransaction, }; -use sp_core::{Bytes, Pair}; +use sp_core::Pair; use sp_runtime::AccountId32; -use std::fmt::{Debug, Display}; +use std::fmt::Display; use structopt::StructOpt; -use strum::{EnumString, EnumVariantNames, VariantNames}; - -/// Relayer operating mode. -#[derive(Debug, EnumString, EnumVariantNames, Clone, Copy, PartialEq, Eq)] -#[strum(serialize_all = "kebab_case")] -pub enum DispatchFeePayment { - /// The dispatch fee is paid at the source chain. - AtSourceChain, - /// The dispatch fee is paid at the target chain. - AtTargetChain, -} - -impl From for bp_runtime::messages::DispatchFeePayment { - fn from(dispatch_fee_payment: DispatchFeePayment) -> Self { - match dispatch_fee_payment { - DispatchFeePayment::AtSourceChain => Self::AtSourceChain, - DispatchFeePayment::AtTargetChain => Self::AtTargetChain, - } - } -} +use strum::VariantNames; /// Send bridge message. #[derive(StructOpt)] @@ -70,23 +50,6 @@ pub struct SendMessage { source: SourceConnectionParams, #[structopt(flatten)] source_sign: SourceSigningParams, - /// Send message using XCM pallet instead. By default message is sent using - /// bridge messages pallet. - #[structopt(long)] - use_xcm_pallet: bool, - /// Hex-encoded lane id. Defaults to `00000000`. - #[structopt(long, default_value = "00000000")] - lane: HexLaneId, - /// A way to override conversion rate between bridge tokens. - /// - /// If not specified, conversion rate from runtime storage is used. It may be obsolete and - /// your message won't be relayed. - #[structopt(long)] - conversion_rate_override: Option, - /// Delivery and dispatch fee in source chain base currency units. If not passed, determined - /// automatically. - #[structopt(long)] - fee: Option, /// Message type. #[structopt(subcommand)] message: crate::cli::encode_message::Message, @@ -111,53 +74,14 @@ where let source_client = data.source.into_client::().await?; let source_sign = data.source_sign.to_keypair::()?; - let lane = data.lane.clone().into(); - let conversion_rate_override = data.conversion_rate_override; - let fee = match data.fee { - Some(fee) => fee, - None => Balance( - estimate_message_delivery_and_dispatch_fee::( - &source_client, - conversion_rate_override, - Self::ESTIMATE_MESSAGE_FEE_METHOD, - lane, - &payload, - ) - .await? - .into(), - ), - }; let payload_len = payload.encoded_size(); - let send_message_call = if data.use_xcm_pallet { - Self::Source::encode_send_xcm( - decode_xcm(payload)?, - data.bridge.bridge_instance_index(), - )? - } else { - Self::Source::encode_send_message_call( - data.lane.0, - payload, - fee.cast().into(), - data.bridge.bridge_instance_index(), - )? - }; + let send_message_call = Self::Source::encode_send_xcm( + decode_xcm(payload)?, + data.bridge.bridge_instance_index(), + )?; 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( - Self::Source::sign_transaction( - SignParam { - spec_version, - transaction_version, - genesis_hash: source_genesis_hash, - signer: source_sign.clone(), - }, - UnsignedTransaction::new(send_message_call.clone(), 0), - )? - .encode(), - )) - .await?; source_client .submit_signed_extrinsic( source_sign.public().into(), @@ -171,22 +95,10 @@ where let unsigned = UnsignedTransaction::new(send_message_call, transaction_nonce); log::info!( target: "bridge", - "Sending message to {}. Lane: {:?}. Size: {}. Fee: {}", + "Sending message to {}. Size: {}", Self::Target::NAME, - lane, payload_len, - fee, - ); - log::info!( - target: "bridge", - "The source account ({:?}) balance will be reduced by (at most) {} (message fee) - + {} (tx fee ) = {} {} tokens", AccountId32::from(source_sign.public()), - fee.0, - estimated_transaction_fee.inclusion_fee(), - fee.0.saturating_add(estimated_transaction_fee.inclusion_fee().into()), - Self::Source::NAME, ); - Ok(unsigned) }, ) @@ -223,7 +135,7 @@ impl SendMessage { } /// Decode SCALE encoded raw XCM message. -fn decode_xcm(message: RawMessage) -> anyhow::Result> { +pub(crate) fn decode_xcm(message: RawMessage) -> anyhow::Result> { Decode::decode(&mut &message[..]) .map_err(|e| anyhow::format_err!("Failed to decode XCM program: {:?}", e)) } @@ -243,8 +155,6 @@ mod tests { "1234", "--source-signer", "//Alice", - "--conversion-rate-override", - "0.75", "raw", "dead", ]); @@ -253,10 +163,6 @@ mod tests { assert_eq!(send_message.bridge, FullBridge::RialtoToMillau); assert_eq!(send_message.source.source_port, 1234); assert_eq!(send_message.source_sign.source_signer, Some("//Alice".into())); - assert_eq!( - send_message.conversion_rate_override, - Some(ConversionRateOverride::Explicit(0.75)) - ); assert_eq!( send_message.message, crate::cli::encode_message::Message::Raw { data: HexBytes(vec![0xDE, 0xAD]) } @@ -273,8 +179,6 @@ mod tests { "1234", "--source-signer", "//Alice", - "--conversion-rate-override", - "metric", "sized", "max", ]); @@ -283,7 +187,6 @@ mod tests { assert_eq!(send_message.bridge, FullBridge::RialtoToMillau); assert_eq!(send_message.source.source_port, 1234); assert_eq!(send_message.source_sign.source_signer, Some("//Alice".into())); - assert_eq!(send_message.conversion_rate_override, Some(ConversionRateOverride::Metric)); assert_eq!( send_message.message, crate::cli::encode_message::Message::Sized { size: ExplicitOrMaximal::Maximal } diff --git a/bridges/relays/client-bridge-hub-rococo/src/lib.rs b/bridges/relays/client-bridge-hub-rococo/src/lib.rs index 375f11423a524..e4740490cb5d0 100644 --- a/bridges/relays/client-bridge-hub-rococo/src/lib.rs +++ b/bridges/relays/client-bridge-hub-rococo/src/lib.rs @@ -60,7 +60,6 @@ impl Chain for BridgeHubRococo { const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = bp_bridge_hub_rococo::BEST_FINALIZED_BRIDGE_HUB_ROCOCO_HEADER_METHOD; const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); - const STORAGE_PROOF_OVERHEAD: u32 = bp_bridge_hub_rococo::EXTRA_STORAGE_PROOF_SIZE; type SignedBlock = bp_bridge_hub_rococo::SignedBlock; type Call = runtime::Call; @@ -126,8 +125,6 @@ impl ChainWithMessages for BridgeHubRococo { const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = bp_bridge_hub_rococo::FROM_BRIDGE_HUB_ROCOCO_MESSAGE_DETAILS_METHOD; - const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight = - bp_bridge_hub_rococo::PAY_INBOUND_DISPATCH_FEE_WEIGHT; const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = bp_bridge_hub_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = diff --git a/bridges/relays/client-bridge-hub-wococo/src/lib.rs b/bridges/relays/client-bridge-hub-wococo/src/lib.rs index f00aa6a9fa910..3199b3b4fc1c8 100644 --- a/bridges/relays/client-bridge-hub-wococo/src/lib.rs +++ b/bridges/relays/client-bridge-hub-wococo/src/lib.rs @@ -60,7 +60,6 @@ impl Chain for BridgeHubWococo { const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = bp_bridge_hub_wococo::BEST_FINALIZED_BRIDGE_HUB_WOCOCO_HEADER_METHOD; const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); - const STORAGE_PROOF_OVERHEAD: u32 = bp_bridge_hub_wococo::EXTRA_STORAGE_PROOF_SIZE; type SignedBlock = bp_bridge_hub_wococo::SignedBlock; type Call = runtime::Call; @@ -126,8 +125,6 @@ impl ChainWithMessages for BridgeHubWococo { const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = bp_bridge_hub_wococo::FROM_BRIDGE_HUB_WOCOCO_MESSAGE_DETAILS_METHOD; - const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight = - bp_bridge_hub_wococo::PAY_INBOUND_DISPATCH_FEE_WEIGHT; const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = bp_bridge_hub_wococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = diff --git a/bridges/relays/client-kusama/src/lib.rs b/bridges/relays/client-kusama/src/lib.rs index cdf7213df9bbb..355f26b849660 100644 --- a/bridges/relays/client-kusama/src/lib.rs +++ b/bridges/relays/client-kusama/src/lib.rs @@ -54,7 +54,6 @@ impl Chain for Kusama { const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = bp_kusama::BEST_FINALIZED_KUSAMA_HEADER_METHOD; const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); - const STORAGE_PROOF_OVERHEAD: u32 = bp_kusama::EXTRA_STORAGE_PROOF_SIZE; type SignedBlock = bp_kusama::SignedBlock; type Call = (); diff --git a/bridges/relays/client-millau/src/lib.rs b/bridges/relays/client-millau/src/lib.rs index 77f09a89f153a..f8b350d3d0c2e 100644 --- a/bridges/relays/client-millau/src/lib.rs +++ b/bridges/relays/client-millau/src/lib.rs @@ -65,8 +65,6 @@ impl ChainWithMessages for Millau { bp_millau::TO_MILLAU_MESSAGE_DETAILS_METHOD; const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = bp_millau::FROM_MILLAU_MESSAGE_DETAILS_METHOD; - const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight = - bp_millau::PAY_INBOUND_DISPATCH_FEE_WEIGHT; const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = bp_millau::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = @@ -82,7 +80,6 @@ impl Chain for Millau { const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = bp_millau::BEST_FINALIZED_MILLAU_HEADER_METHOD; const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(5); - const STORAGE_PROOF_OVERHEAD: u32 = bp_millau::EXTRA_STORAGE_PROOF_SIZE; type SignedBlock = millau_runtime::SignedBlock; type Call = millau_runtime::RuntimeCall; diff --git a/bridges/relays/client-polkadot/src/lib.rs b/bridges/relays/client-polkadot/src/lib.rs index bb3867fda5318..101b62b9c35ee 100644 --- a/bridges/relays/client-polkadot/src/lib.rs +++ b/bridges/relays/client-polkadot/src/lib.rs @@ -54,7 +54,6 @@ impl Chain for Polkadot { const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = bp_polkadot::BEST_FINALIZED_POLKADOT_HEADER_METHOD; const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); - const STORAGE_PROOF_OVERHEAD: u32 = bp_polkadot::EXTRA_STORAGE_PROOF_SIZE; type SignedBlock = bp_polkadot::SignedBlock; type Call = (); diff --git a/bridges/relays/client-rialto-parachain/src/lib.rs b/bridges/relays/client-rialto-parachain/src/lib.rs index fe7c2c816162f..8cf74bdf9b1f5 100644 --- a/bridges/relays/client-rialto-parachain/src/lib.rs +++ b/bridges/relays/client-rialto-parachain/src/lib.rs @@ -62,7 +62,6 @@ impl Chain for RialtoParachain { const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = bp_rialto_parachain::BEST_FINALIZED_RIALTO_PARACHAIN_HEADER_METHOD; const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(5); - const STORAGE_PROOF_OVERHEAD: u32 = bp_rialto_parachain::EXTRA_STORAGE_PROOF_SIZE; type SignedBlock = rialto_parachain_runtime::SignedBlock; type Call = rialto_parachain_runtime::RuntimeCall; @@ -86,8 +85,6 @@ impl ChainWithMessages for RialtoParachain { bp_rialto_parachain::TO_RIALTO_PARACHAIN_MESSAGE_DETAILS_METHOD; const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = bp_rialto_parachain::FROM_RIALTO_PARACHAIN_MESSAGE_DETAILS_METHOD; - const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight = - bp_rialto_parachain::PAY_INBOUND_DISPATCH_FEE_WEIGHT; const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = bp_rialto_parachain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = @@ -157,7 +154,7 @@ impl ChainWithTransactions for RialtoParachain { } fn parse_transaction(_tx: Self::SignedTransaction) -> Option> { - unimplemented!("TODO") + None } } diff --git a/bridges/relays/client-rialto/src/lib.rs b/bridges/relays/client-rialto/src/lib.rs index 45166559b365a..23ecbbd47f6d3 100644 --- a/bridges/relays/client-rialto/src/lib.rs +++ b/bridges/relays/client-rialto/src/lib.rs @@ -62,7 +62,6 @@ impl Chain for Rialto { const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = bp_rialto::BEST_FINALIZED_RIALTO_HEADER_METHOD; const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(5); - const STORAGE_PROOF_OVERHEAD: u32 = bp_rialto::EXTRA_STORAGE_PROOF_SIZE; type SignedBlock = rialto_runtime::SignedBlock; type Call = rialto_runtime::RuntimeCall; @@ -85,8 +84,6 @@ impl ChainWithMessages for Rialto { bp_rialto::TO_RIALTO_MESSAGE_DETAILS_METHOD; const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = bp_rialto::FROM_RIALTO_MESSAGE_DETAILS_METHOD; - const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight = - bp_rialto::PAY_INBOUND_DISPATCH_FEE_WEIGHT; const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = bp_rialto::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = diff --git a/bridges/relays/client-rococo/src/lib.rs b/bridges/relays/client-rococo/src/lib.rs index 5f1ff033559cd..fc3aa76eb4491 100644 --- a/bridges/relays/client-rococo/src/lib.rs +++ b/bridges/relays/client-rococo/src/lib.rs @@ -57,7 +57,6 @@ impl Chain for Rococo { const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = bp_rococo::BEST_FINALIZED_ROCOCO_HEADER_METHOD; const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); - const STORAGE_PROOF_OVERHEAD: u32 = bp_rococo::EXTRA_STORAGE_PROOF_SIZE; type SignedBlock = bp_rococo::SignedBlock; type Call = (); diff --git a/bridges/relays/client-statemine/Cargo.toml b/bridges/relays/client-statemine/Cargo.toml deleted file mode 100644 index 249f9fd6f4305..0000000000000 --- a/bridges/relays/client-statemine/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "relay-statemine-client" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2021" -license = "GPL-3.0-or-later WITH Classpath-exception-2.0" - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.1.5" } -relay-substrate-client = { path = "../client-substrate" } -relay-utils = { path = "../utils" } -scale-info = { version = "2.1.1", features = ["derive"] } - -# Bridge dependencies - -bp-polkadot-core = { path = "../../primitives/polkadot-core" } -bp-statemine = { path = "../../primitives/chain-statemine" } - -# Substrate Dependencies - -frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/bridges/relays/client-statemine/src/lib.rs b/bridges/relays/client-statemine/src/lib.rs deleted file mode 100644 index a5f6fed79f434..0000000000000 --- a/bridges/relays/client-statemine/src/lib.rs +++ /dev/null @@ -1,112 +0,0 @@ -// 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 . - -//! Types used to connect to the Statemine chain. - -use codec::Encode; -use frame_support::weights::Weight; -use relay_substrate_client::{ - Chain, ChainBase, ChainWithTransactions, Error as SubstrateError, SignParam, - UnsignedTransaction, -}; -use sp_core::Pair; -use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; -use std::time::Duration; - -pub mod runtime; - -/// Statemine chain definition -#[derive(Debug, Clone, Copy)] -pub struct Statemine; - -impl ChainBase for Statemine { - type BlockNumber = bp_statemine::BlockNumber; - type Hash = bp_statemine::Hash; - type Hasher = bp_statemine::Hasher; - type Header = bp_statemine::Header; - - type AccountId = bp_statemine::AccountId; - type Balance = bp_statemine::Balance; - type Index = bp_statemine::Nonce; - type Signature = bp_statemine::Signature; - - fn max_extrinsic_size() -> u32 { - bp_statemine::Statemine::max_extrinsic_size() - } - - fn max_extrinsic_weight() -> Weight { - bp_statemine::Statemine::max_extrinsic_weight() - } -} - -impl Chain for Statemine { - const NAME: &'static str = "Statemine"; - const TOKEN_ID: Option<&'static str> = Some("kusama"); - const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = ""; - const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); - const STORAGE_PROOF_OVERHEAD: u32 = bp_statemine::EXTRA_STORAGE_PROOF_SIZE; - - type SignedBlock = bp_statemine::SignedBlock; - type Call = runtime::Call; -} - -impl ChainWithTransactions for Statemine { - type AccountKeyPair = sp_core::sr25519::Pair; - type SignedTransaction = runtime::UncheckedExtrinsic; - - fn sign_transaction( - param: SignParam, - unsigned: UnsignedTransaction, - ) -> Result { - let raw_payload = SignedPayload::new( - unsigned.call.clone(), - bp_statemine::SignedExtensions::new( - param.spec_version, - param.transaction_version, - unsigned.era, - param.genesis_hash, - unsigned.nonce, - unsigned.tip, - ), - ) - .expect("SignedExtension never fails."); - 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(); - - Ok(runtime::UncheckedExtrinsic::new_signed( - call, - signer.into_account().into(), - signature.into(), - extra, - )) - } - - fn is_signed(tx: &Self::SignedTransaction) -> bool { - tx.signature.is_some() - } - - fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool { - tx.signature - .as_ref() - .map(|(address, _, _)| *address == bp_statemine::Address::Id(signer.public().into())) - .unwrap_or(false) - } - - fn parse_transaction(_tx: Self::SignedTransaction) -> Option> { - unimplemented!("not used on Statemine") - } -} diff --git a/bridges/relays/client-statemine/src/runtime.rs b/bridges/relays/client-statemine/src/runtime.rs deleted file mode 100644 index 92924555769e4..0000000000000 --- a/bridges/relays/client-statemine/src/runtime.rs +++ /dev/null @@ -1,68 +0,0 @@ -// 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 . - -//! Types that are specific to the Statemine runtime. - -use codec::{Decode, Encode}; -use scale_info::TypeInfo; -use sp_runtime::FixedU128; - -/// Unchecked Statemine extrinsic. -pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic; - -/// Statemine Runtime `Call` enum. -/// -/// The enum represents a subset of possible `Call`s we can send to Statemine chain. -/// Ideally this code would be auto-generated from metadata, because we want to -/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s. -/// -/// All entries here (like pretty much in the entire file) must be kept in sync with Statemine -/// `construct_runtime`, so that we maintain SCALE-compatibility. -/// -/// See: [link](https://github.com/paritytech/cumulus/blob/master/parachains/runtimes/assets/statemine/src/lib.rs) -#[allow(clippy::large_enum_variant)] -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -pub enum Call { - /// With-Statemint bridge pallet. - // TODO (https://github.com/paritytech/parity-bridges-common/issues/1626): - // must be updated when we'll make appropriate changes in the Statemine runtime - #[codec(index = 42)] - WithStatemintBridgePallet(WithStatemintBridgePalletCall), -} - -/// Calls of the with-Statemint bridge pallet. -// TODO (https://github.com/paritytech/parity-bridges-common/issues/1626): -// must be updated when we'll make appropriate changes in the Statemine runtime -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum WithStatemintBridgePalletCall { - #[codec(index = 42)] - update_dot_to_ksm_conversion_rate(FixedU128), -} - -impl sp_runtime::traits::Dispatchable for Call { - type RuntimeOrigin = (); - type Config = (); - type Info = (); - type PostInfo = (); - - fn dispatch( - self, - _origin: Self::RuntimeOrigin, - ) -> sp_runtime::DispatchResultWithInfo { - unimplemented!("The Call is not expected to be dispatched.") - } -} diff --git a/bridges/relays/client-substrate/src/chain.rs b/bridges/relays/client-substrate/src/chain.rs index 5763d4a61357b..0e19cf92b778f 100644 --- a/bridges/relays/client-substrate/src/chain.rs +++ b/bridges/relays/client-substrate/src/chain.rs @@ -19,7 +19,7 @@ use bp_runtime::{ Chain as ChainBase, EncodedOrDecodedCall, HashOf, TransactionEra, TransactionEraOf, }; use codec::{Codec, Encode}; -use frame_support::weights::{Weight, WeightToFee}; +use frame_support::weights::WeightToFee; use jsonrpsee::core::{DeserializeOwned, Serialize}; use num_traits::Zero; use sc_transaction_pool_api::TransactionStatus; @@ -52,8 +52,6 @@ pub trait Chain: ChainBase + Clone { /// How often blocks are produced on that chain. It's suggested to set this value /// to match the block time of the chain. const AVERAGE_BLOCK_INTERVAL: Duration; - /// Maximal expected storage proof overhead (in bytes). - const STORAGE_PROOF_OVERHEAD: u32; /// Block type. type SignedBlock: Member + Serialize + DeserializeOwned + BlockWithJustification; @@ -106,10 +104,6 @@ pub trait ChainWithMessages: Chain { /// The method is provided by the runtime that is bridged with this `ChainWithMessages`. const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str; - /// Additional weight of the dispatch fee payment if dispatch is paid at the target chain - /// and this `ChainWithMessages` is the target chain. - const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight; - /// Maximal number of unrewarded relayers in a single confirmation transaction at this /// `ChainWithMessages`. const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce; diff --git a/bridges/relays/client-substrate/src/metrics/mod.rs b/bridges/relays/client-substrate/src/metrics/mod.rs index 3b63099e00036..fe200e2d3dca7 100644 --- a/bridges/relays/client-substrate/src/metrics/mod.rs +++ b/bridges/relays/client-substrate/src/metrics/mod.rs @@ -17,7 +17,5 @@ //! Contains several Substrate-specific metrics that may be exposed by relay. pub use float_storage_value::{FixedU128OrOne, FloatStorageValue, FloatStorageValueMetric}; -pub use storage_proof_overhead::StorageProofOverheadMetric; mod float_storage_value; -mod storage_proof_overhead; diff --git a/bridges/relays/client-substrate/src/metrics/storage_proof_overhead.rs b/bridges/relays/client-substrate/src/metrics/storage_proof_overhead.rs deleted file mode 100644 index 6e0b74020b70b..0000000000000 --- a/bridges/relays/client-substrate/src/metrics/storage_proof_overhead.rs +++ /dev/null @@ -1,101 +0,0 @@ -// 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 . - -use crate::{chain::Chain, client::Client, error::Error}; - -use async_trait::async_trait; -use relay_utils::metrics::{ - metric_name, register, Gauge, Metric, PrometheusError, Registry, StandaloneMetric, U64, -}; -use sp_core::storage::StorageKey; -use sp_runtime::traits::Header as HeaderT; -use sp_storage::well_known_keys::CODE; -use std::time::Duration; - -/// Storage proof overhead update interval (in blocks). -const UPDATE_INTERVAL_IN_BLOCKS: u32 = 100; - -/// Metric that represents extra size of storage proof as unsigned integer gauge. -/// -/// There's one thing to keep in mind when using this metric: the overhead may be slightly -/// different for other values, but this metric gives a good estimation. -#[derive(Debug)] -pub struct StorageProofOverheadMetric { - client: Client, - metric: Gauge, -} - -impl Clone for StorageProofOverheadMetric { - fn clone(&self) -> Self { - StorageProofOverheadMetric { client: self.client.clone(), metric: self.metric.clone() } - } -} - -impl StorageProofOverheadMetric { - /// Create new metric instance with given name and help. - pub fn new(client: Client, name: String, help: String) -> Result { - Ok(StorageProofOverheadMetric { - client, - metric: Gauge::new(metric_name(None, &name), help)?, - }) - } - - /// Returns approximate storage proof size overhead. - async fn compute_storage_proof_overhead(&self) -> Result { - let best_header_hash = self.client.best_finalized_header_hash().await?; - let best_header = self.client.header_by_hash(best_header_hash).await?; - - let storage_proof = self - .client - .prove_storage(vec![StorageKey(CODE.to_vec())], best_header_hash) - .await?; - let storage_proof_size: usize = storage_proof.iter_nodes().map(|n| n.len()).sum(); - - let storage_value_reader = bp_runtime::StorageProofChecker::::new( - *best_header.state_root(), - storage_proof, - ) - .map_err(Error::StorageProofError)?; - let maybe_encoded_storage_value = - storage_value_reader.read_value(CODE).map_err(Error::StorageProofError)?; - let encoded_storage_value_size = - maybe_encoded_storage_value.ok_or(Error::MissingMandatoryStorageValue)?.len(); - - Ok(storage_proof_size - encoded_storage_value_size) - } -} - -impl Metric for StorageProofOverheadMetric { - fn register(&self, registry: &Registry) -> Result<(), PrometheusError> { - register(self.metric.clone(), registry).map(drop) - } -} - -#[async_trait] -impl StandaloneMetric for StorageProofOverheadMetric { - fn update_interval(&self) -> Duration { - C::AVERAGE_BLOCK_INTERVAL * UPDATE_INTERVAL_IN_BLOCKS - } - - async fn update(&self) { - relay_utils::metrics::set_gauge_value( - &self.metric, - self.compute_storage_proof_overhead() - .await - .map(|overhead| Some(overhead as u64)), - ); - } -} diff --git a/bridges/relays/client-substrate/src/test_chain.rs b/bridges/relays/client-substrate/src/test_chain.rs index 8e1832db08453..4589687d39de1 100644 --- a/bridges/relays/client-substrate/src/test_chain.rs +++ b/bridges/relays/client-substrate/src/test_chain.rs @@ -54,7 +54,6 @@ impl Chain for TestChain { const TOKEN_ID: Option<&'static str> = None; const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = "TestMethod"; const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_millis(0); - const STORAGE_PROOF_OVERHEAD: u32 = 0; type SignedBlock = sp_runtime::generic::SignedBlock< sp_runtime::generic::Block, diff --git a/bridges/relays/client-westend/src/lib.rs b/bridges/relays/client-westend/src/lib.rs index 0f650e9e2847f..6a2944629bed1 100644 --- a/bridges/relays/client-westend/src/lib.rs +++ b/bridges/relays/client-westend/src/lib.rs @@ -57,7 +57,6 @@ impl Chain for Westend { const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = bp_westend::BEST_FINALIZED_WESTEND_HEADER_METHOD; const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); - const STORAGE_PROOF_OVERHEAD: u32 = bp_westend::EXTRA_STORAGE_PROOF_SIZE; type SignedBlock = bp_westend::SignedBlock; type Call = (); @@ -114,7 +113,6 @@ impl Chain for Westmint { const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = bp_westend::BEST_FINALIZED_WESTMINT_HEADER_METHOD; const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); - const STORAGE_PROOF_OVERHEAD: u32 = bp_westend::EXTRA_STORAGE_PROOF_SIZE; type SignedBlock = bp_westend::SignedBlock; type Call = (); diff --git a/bridges/relays/client-wococo/src/lib.rs b/bridges/relays/client-wococo/src/lib.rs index b4e9dd74d1985..04b5193afd33a 100644 --- a/bridges/relays/client-wococo/src/lib.rs +++ b/bridges/relays/client-wococo/src/lib.rs @@ -57,7 +57,6 @@ impl Chain for Wococo { const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = bp_wococo::BEST_FINALIZED_WOCOCO_HEADER_METHOD; const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); - const STORAGE_PROOF_OVERHEAD: u32 = bp_wococo::EXTRA_STORAGE_PROOF_SIZE; type SignedBlock = bp_wococo::SignedBlock; type Call = (); diff --git a/bridges/relays/lib-substrate-relay/src/conversion_rate_update.rs b/bridges/relays/lib-substrate-relay/src/conversion_rate_update.rs deleted file mode 100644 index 3bd9a5a6a1985..0000000000000 --- a/bridges/relays/lib-substrate-relay/src/conversion_rate_update.rs +++ /dev/null @@ -1,439 +0,0 @@ -// 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 . - -//! Tools for updating conversion rate that is stored in the runtime storage. - -use crate::{messages_lane::SubstrateMessageLane, TransactionParams}; - -use relay_substrate_client::{ - transaction_stall_timeout, AccountIdOf, AccountKeyPairOf, CallOf, Chain, ChainWithTransactions, - Client, SignParam, TransactionEra, UnsignedTransaction, -}; -use relay_utils::metrics::F64SharedRef; -use sp_core::Pair; -use std::time::{Duration, Instant}; - -/// Duration between updater iterations. -const SLEEP_DURATION: Duration = Duration::from_secs(60); - -/// Duration which will almost never expire. Since changing conversion rate may require manual -/// intervention (e.g. if call is made through `multisig` pallet), we don't want relayer to -/// resubmit transaction often. -const ALMOST_NEVER_DURATION: Duration = Duration::from_secs(60 * 60 * 24 * 30); - -/// Update-conversion-rate transaction status. -#[derive(Debug, Clone, Copy, PartialEq)] -enum TransactionStatus { - /// We have not submitted any transaction recently. - Idle, - /// We have recently submitted transaction that should update conversion rate. - Submitted(Instant, f64), -} - -/// Different ways of building 'update conversion rate' calls. -pub trait UpdateConversionRateCallBuilder { - /// Given conversion rate, build call that updates conversion rate in given chain runtime - /// storage. - fn build_update_conversion_rate_call(conversion_rate: f64) -> anyhow::Result>; -} - -impl UpdateConversionRateCallBuilder for () { - fn build_update_conversion_rate_call(_conversion_rate: f64) -> anyhow::Result> { - Err(anyhow::format_err!("Conversion rate update is not supported at {}", C::NAME)) - } -} - -/// Macro that generates `UpdateConversionRateCallBuilder` implementation for the case when -/// you have a direct access to the source chain runtime. -#[rustfmt::skip] -#[macro_export] -macro_rules! generate_direct_update_conversion_rate_call_builder { - ( - $source_chain:ident, - $mocked_builder:ident, - $runtime:ty, - $instance:ty, - $parameter:path - ) => { - pub struct $mocked_builder; - - impl $crate::conversion_rate_update::UpdateConversionRateCallBuilder<$source_chain> - for $mocked_builder - { - fn build_update_conversion_rate_call( - conversion_rate: f64, - ) -> anyhow::Result> { - Ok(pallet_bridge_messages::Call::update_pallet_parameter::<$runtime, $instance> { - parameter: $parameter(sp_runtime::FixedU128::from_float(conversion_rate)), - }.into()) - } - } - }; -} - -/// Macro that generates `UpdateConversionRateCallBuilder` implementation for the case when -/// you only have an access to the mocked version of source chain runtime. In this case you -/// should provide "name" of the call variant for the bridge messages calls, the "name" of -/// the variant for the `update_pallet_parameter` call within that first option and the name -/// of the conversion rate parameter itself. -#[rustfmt::skip] -#[macro_export] -macro_rules! generate_mocked_update_conversion_rate_call_builder { - ( - $source_chain:ident, - $mocked_builder:ident, - $bridge_messages:path, - $update_pallet_parameter:path, - $parameter:path - ) => { - pub struct $mocked_builder; - - impl $crate::conversion_rate_update::UpdateConversionRateCallBuilder<$source_chain> - for $mocked_builder - { - fn build_update_conversion_rate_call( - conversion_rate: f64, - ) -> anyhow::Result> { - Ok($bridge_messages($update_pallet_parameter($parameter( - sp_runtime::FixedU128::from_float(conversion_rate), - )))) - } - } - }; -} - -/// Run infinite conversion rate updater loop. -/// -/// The loop is maintaining the Left -> Right conversion rate, used as `RightTokens = LeftTokens * -/// Rate`. -pub fn run_conversion_rate_update_loop( - client: Client, - transaction_params: TransactionParams>, - left_to_right_stored_conversion_rate: F64SharedRef, - left_to_base_conversion_rate: F64SharedRef, - right_to_base_conversion_rate: F64SharedRef, - max_difference_ratio: f64, -) where - Lane: SubstrateMessageLane, - Lane::SourceChain: ChainWithTransactions, - AccountIdOf: From< as Pair>::Public>, -{ - let stall_timeout = transaction_stall_timeout( - transaction_params.mortality, - Lane::SourceChain::AVERAGE_BLOCK_INTERVAL, - ALMOST_NEVER_DURATION, - ); - - log::info!( - target: "bridge", - "Starting {} -> {} conversion rate (on {}) update loop. Stall timeout: {}s", - Lane::TargetChain::NAME, - Lane::SourceChain::NAME, - Lane::SourceChain::NAME, - stall_timeout.as_secs(), - ); - - async_std::task::spawn(async move { - let mut transaction_status = TransactionStatus::Idle; - loop { - async_std::task::sleep(SLEEP_DURATION).await; - let maybe_new_conversion_rate = maybe_select_new_conversion_rate( - stall_timeout, - &mut transaction_status, - &left_to_right_stored_conversion_rate, - &left_to_base_conversion_rate, - &right_to_base_conversion_rate, - max_difference_ratio, - ) - .await; - if let Some((prev_conversion_rate, new_conversion_rate)) = maybe_new_conversion_rate { - log::info!( - target: "bridge", - "Going to update {} -> {} (on {}) conversion rate to {}.", - Lane::TargetChain::NAME, - Lane::SourceChain::NAME, - Lane::SourceChain::NAME, - new_conversion_rate, - ); - - let result = update_target_to_source_conversion_rate::( - client.clone(), - transaction_params.clone(), - new_conversion_rate, - ) - .await; - match result { - Ok(()) => { - transaction_status = - TransactionStatus::Submitted(Instant::now(), prev_conversion_rate); - }, - Err(error) => { - log::error!( - target: "bridge", - "Failed to submit conversion rate update transaction: {:?}", - error, - ); - }, - } - } - } - }); -} - -/// Select new conversion rate to submit to the node. -async fn maybe_select_new_conversion_rate( - stall_timeout: Duration, - transaction_status: &mut TransactionStatus, - left_to_right_stored_conversion_rate: &F64SharedRef, - left_to_base_conversion_rate: &F64SharedRef, - right_to_base_conversion_rate: &F64SharedRef, - max_difference_ratio: f64, -) -> Option<(f64, f64)> { - let left_to_right_stored_conversion_rate = - (*left_to_right_stored_conversion_rate.read().await)?; - match *transaction_status { - TransactionStatus::Idle => (), - TransactionStatus::Submitted(submitted_at, _) - if Instant::now() - submitted_at > stall_timeout => - { - log::error!( - target: "bridge", - "Conversion rate update transaction has been lost and loop stalled. Restarting", - ); - - // we assume that our transaction has been lost - *transaction_status = TransactionStatus::Idle; - }, - TransactionStatus::Submitted(_, previous_left_to_right_stored_conversion_rate) => { - // we can't compare float values from different sources directly, so we only care - // whether the stored rate has been changed or not. If it has been changed, then we - // assume that our proposal has been accepted. - // - // float comparison is ok here, because we compare same-origin (stored in runtime - // storage) values and if they are different, it means that the value has actually been - // updated - #[allow(clippy::float_cmp)] - if previous_left_to_right_stored_conversion_rate == left_to_right_stored_conversion_rate - { - // the rate has not been changed => we won't submit any transactions until it is - // accepted, or the rate is changed by someone else - return None - } - - *transaction_status = TransactionStatus::Idle; - }, - } - - let left_to_base_conversion_rate = (*left_to_base_conversion_rate.read().await)?; - let right_to_base_conversion_rate = (*right_to_base_conversion_rate.read().await)?; - let actual_left_to_right_conversion_rate = - left_to_base_conversion_rate / right_to_base_conversion_rate; - - let rate_difference = - (actual_left_to_right_conversion_rate - left_to_right_stored_conversion_rate).abs(); - let rate_difference_ratio = rate_difference / left_to_right_stored_conversion_rate; - if rate_difference_ratio < max_difference_ratio { - return None - } - - Some((left_to_right_stored_conversion_rate, actual_left_to_right_conversion_rate)) -} - -/// Update Target -> Source tokens conversion rate, stored in the Source runtime storage. -pub async fn update_target_to_source_conversion_rate( - client: Client, - transaction_params: TransactionParams>, - updated_rate: f64, -) -> anyhow::Result<()> -where - Lane: SubstrateMessageLane, - Lane::SourceChain: ChainWithTransactions, - AccountIdOf: From< as Pair>::Public>, -{ - let genesis_hash = *client.genesis_hash(); - let signer_id = transaction_params.signer.public().into(); - let (spec_version, transaction_version) = client.simple_runtime_version().await?; - let call = - Lane::TargetToSourceChainConversionRateUpdateBuilder::build_update_conversion_rate_call( - updated_rate, - )?; - client - .submit_signed_extrinsic( - signer_id, - SignParam:: { - spec_version, - transaction_version, - genesis_hash, - signer: transaction_params.signer, - }, - move |best_block_id, transaction_nonce| { - Ok(UnsignedTransaction::new(call.into(), transaction_nonce) - .era(TransactionEra::new(best_block_id, transaction_params.mortality))) - }, - ) - .await - .map(drop) - .map_err(|err| anyhow::format_err!("{:?}", err)) -} - -#[cfg(test)] -mod tests { - use super::*; - use async_std::sync::{Arc, RwLock}; - - const TEST_STALL_TIMEOUT: Duration = Duration::from_secs(60); - - fn test_maybe_select_new_conversion_rate( - mut transaction_status: TransactionStatus, - stored_conversion_rate: Option, - left_to_base_conversion_rate: Option, - right_to_base_conversion_rate: Option, - max_difference_ratio: f64, - ) -> (Option<(f64, f64)>, TransactionStatus) { - let stored_conversion_rate = Arc::new(RwLock::new(stored_conversion_rate)); - let left_to_base_conversion_rate = Arc::new(RwLock::new(left_to_base_conversion_rate)); - let right_to_base_conversion_rate = Arc::new(RwLock::new(right_to_base_conversion_rate)); - let result = async_std::task::block_on(maybe_select_new_conversion_rate( - TEST_STALL_TIMEOUT, - &mut transaction_status, - &stored_conversion_rate, - &left_to_base_conversion_rate, - &right_to_base_conversion_rate, - max_difference_ratio, - )); - (result, transaction_status) - } - - #[test] - fn rate_is_not_updated_when_transaction_is_submitted() { - let status = TransactionStatus::Submitted(Instant::now(), 10.0); - assert_eq!( - test_maybe_select_new_conversion_rate(status, Some(10.0), Some(1.0), Some(1.0), 0.0), - (None, status), - ); - } - - #[test] - fn transaction_state_is_changed_to_idle_when_stored_rate_shanges() { - assert_eq!( - test_maybe_select_new_conversion_rate( - TransactionStatus::Submitted(Instant::now(), 1.0), - Some(10.0), - Some(1.0), - Some(1.0), - 100.0 - ), - (None, TransactionStatus::Idle), - ); - } - - #[test] - fn transaction_is_not_submitted_when_left_to_base_rate_is_unknown() { - assert_eq!( - test_maybe_select_new_conversion_rate( - TransactionStatus::Idle, - Some(10.0), - None, - Some(1.0), - 0.0 - ), - (None, TransactionStatus::Idle), - ); - } - - #[test] - fn transaction_is_not_submitted_when_right_to_base_rate_is_unknown() { - assert_eq!( - test_maybe_select_new_conversion_rate( - TransactionStatus::Idle, - Some(10.0), - Some(1.0), - None, - 0.0 - ), - (None, TransactionStatus::Idle), - ); - } - - #[test] - fn transaction_is_not_submitted_when_stored_rate_is_unknown() { - assert_eq!( - test_maybe_select_new_conversion_rate( - TransactionStatus::Idle, - None, - Some(1.0), - Some(1.0), - 0.0 - ), - (None, TransactionStatus::Idle), - ); - } - - #[test] - fn transaction_is_not_submitted_when_difference_is_below_threshold() { - assert_eq!( - test_maybe_select_new_conversion_rate( - TransactionStatus::Idle, - Some(1.0), - Some(1.0), - Some(1.01), - 0.02 - ), - (None, TransactionStatus::Idle), - ); - } - - #[test] - fn transaction_is_submitted_when_difference_is_above_threshold() { - let left_to_right_stored_conversion_rate = 1.0; - let left_to_base_conversion_rate = 18f64; - let right_to_base_conversion_rate = 180f64; - - assert!(left_to_base_conversion_rate < right_to_base_conversion_rate); - - assert_eq!( - test_maybe_select_new_conversion_rate( - TransactionStatus::Idle, - Some(left_to_right_stored_conversion_rate), - Some(left_to_base_conversion_rate), - Some(right_to_base_conversion_rate), - 0.02 - ), - ( - Some(( - left_to_right_stored_conversion_rate, - left_to_base_conversion_rate / right_to_base_conversion_rate, - )), - TransactionStatus::Idle - ), - ); - } - - #[test] - fn transaction_expires() { - let status = TransactionStatus::Submitted(Instant::now() - TEST_STALL_TIMEOUT / 2, 10.0); - assert_eq!( - test_maybe_select_new_conversion_rate(status, Some(10.0), Some(1.0), Some(1.0), 0.0), - (None, status), - ); - - let status = TransactionStatus::Submitted(Instant::now() - TEST_STALL_TIMEOUT * 2, 10.0); - assert_eq!( - test_maybe_select_new_conversion_rate(status, Some(10.0), Some(1.0), Some(1.0), 0.0), - (Some((10.0, 1.0)), TransactionStatus::Idle), - ); - } -} diff --git a/bridges/relays/lib-substrate-relay/src/helpers.rs b/bridges/relays/lib-substrate-relay/src/helpers.rs deleted file mode 100644 index 0b824708a8996..0000000000000 --- a/bridges/relays/lib-substrate-relay/src/helpers.rs +++ /dev/null @@ -1,106 +0,0 @@ -// 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 . - -//! Substrate relay helpers - -use relay_utils::metrics::{FloatJsonValueMetric, PrometheusError, StandaloneMetric}; - -/// Creates standalone token price metric. -pub fn token_price_metric(token_id: &str) -> Result { - FloatJsonValueMetric::new( - format!("https://api.coingecko.com/api/v3/simple/price?ids={token_id}&vs_currencies=btc"), - format!("$.{token_id}.btc"), - format!("{}_to_base_conversion_rate", token_id.replace('-', "_")), - format!("Rate used to convert from {} to some BASE tokens", token_id.to_uppercase()), - ) -} - -/// Compute conversion rate between two tokens immediately, without spawning any metrics. -/// -/// Returned rate may be used in expression: `from_tokens * rate -> to_tokens`. -pub async fn tokens_conversion_rate_from_metrics( - from_token_id: &str, - to_token_id: &str, -) -> anyhow::Result { - let from_token_metric = token_price_metric(from_token_id)?; - from_token_metric.update().await; - let to_token_metric = token_price_metric(to_token_id)?; - to_token_metric.update().await; - - let from_token_value = *from_token_metric.shared_value_ref().read().await; - let to_token_value = *to_token_metric.shared_value_ref().read().await; - // `FloatJsonValueMetric` guarantees that the value is positive && normal, so no additional - // checks required here - match (from_token_value, to_token_value) { - (Some(from_token_value), Some(to_token_value)) => - Ok(tokens_conversion_rate(from_token_value, to_token_value)), - _ => Err(anyhow::format_err!( - "Failed to compute conversion rate from {} to {}", - from_token_id, - to_token_id, - )), - } -} - -/// Compute conversion rate between two tokens, given token prices. -/// -/// Returned rate may be used in expression: `from_tokens * rate -> to_tokens`. -/// -/// Both prices are assumed to be normal and non-negative. -pub fn tokens_conversion_rate(from_token_value: f64, to_token_value: f64) -> f64 { - from_token_value / to_token_value -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn rialto_to_millau_conversion_rate_is_correct() { - let rialto_price = 18.18; - let millau_price = 136.35; - assert!(rialto_price < millau_price); - - let conversion_rate = tokens_conversion_rate(rialto_price, millau_price); - let rialto_amount = 100.0; - let millau_amount = rialto_amount * conversion_rate; - assert!( - rialto_amount > millau_amount, - "{} RLT * {} = {} MLU", - rialto_amount, - conversion_rate, - millau_amount, - ); - } - - #[test] - fn millau_to_rialto_conversion_rate_is_correct() { - let rialto_price = 18.18; - let millau_price = 136.35; - assert!(rialto_price < millau_price); - - let conversion_rate = tokens_conversion_rate(millau_price, rialto_price); - let millau_amount = 100.0; - let rialto_amount = millau_amount * conversion_rate; - assert!( - rialto_amount > millau_amount, - "{} MLU * {} = {} RLT", - millau_amount, - conversion_rate, - rialto_amount, - ); - } -} diff --git a/bridges/relays/lib-substrate-relay/src/lib.rs b/bridges/relays/lib-substrate-relay/src/lib.rs index 86e652716f643..62ae756e0031e 100644 --- a/bridges/relays/lib-substrate-relay/src/lib.rs +++ b/bridges/relays/lib-substrate-relay/src/lib.rs @@ -18,10 +18,8 @@ #![warn(missing_docs)] -pub mod conversion_rate_update; pub mod error; pub mod finality; -pub mod helpers; pub mod messages_lane; pub mod messages_metrics; pub mod messages_source; diff --git a/bridges/relays/lib-substrate-relay/src/messages_lane.rs b/bridges/relays/lib-substrate-relay/src/messages_lane.rs index 09d02f7448e4d..da138a3d1258f 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_lane.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_lane.rs @@ -17,8 +17,6 @@ //! Tools for supporting message lanes between two Substrate-based chains. use crate::{ - conversion_rate_update::UpdateConversionRateCallBuilder, - messages_metrics::StandaloneMessagesMetrics, messages_source::{SubstrateMessagesProof, SubstrateMessagesSource}, messages_target::{SubstrateMessagesDeliveryProof, SubstrateMessagesTarget}, on_demand::OnDemandRelay, @@ -33,49 +31,21 @@ use bridge_runtime_common::messages::{ }; use codec::Encode; use frame_support::{dispatch::GetDispatchInfo, weights::Weight}; -use messages_relay::{message_lane::MessageLane, relay_strategy::RelayStrategy}; +use messages_relay::message_lane::MessageLane; use pallet_bridge_messages::{Call as BridgeMessagesCall, Config as BridgeMessagesConfig}; use relay_substrate_client::{ transaction_stall_timeout, AccountKeyPairOf, BalanceOf, BlockNumberOf, CallOf, Chain, ChainWithMessages, ChainWithTransactions, Client, HashOf, }; -use relay_utils::{metrics::MetricsParams, STALL_TIMEOUT}; +use relay_utils::{ + metrics::{GlobalMetrics, MetricsParams, StandaloneMetric}, + STALL_TIMEOUT, +}; use sp_core::Pair; use std::{convert::TryFrom, fmt::Debug, marker::PhantomData}; /// Substrate -> Substrate messages synchronization pipeline. pub trait SubstrateMessageLane: 'static + Clone + Debug + Send + Sync { - /// Name of the source -> target tokens conversion rate parameter. - /// - /// The parameter is stored at the target chain and the storage key is computed using - /// `bp_runtime::storage_parameter_key` function. If value is unknown, it is assumed - /// to be 1. - const SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str>; - /// Name of the target -> source tokens conversion rate parameter. - /// - /// The parameter is stored at the source chain and the storage key is computed using - /// `bp_runtime::storage_parameter_key` function. If value is unknown, it is assumed - /// to be 1. - const TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str>; - - /// Name of the source chain fee multiplier parameter. - /// - /// The parameter is stored at the target chain and the storage key is computed using - /// `bp_runtime::storage_parameter_key` function. If value is unknown, it is assumed - /// to be 1. - const SOURCE_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str>; - /// Name of the target chain fee multiplier parameter. - /// - /// The parameter is stored at the source chain and the storage key is computed using - /// `bp_runtime::storage_parameter_key` function. If value is unknown, it is assumed - /// to be 1. - const TARGET_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str>; - - /// Name of the transaction payment pallet, deployed at the source chain. - const AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str>; - /// Name of the transaction payment pallet, deployed at the target chain. - const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str>; - /// Messages of this chain are relayed to the `TargetChain`. type SourceChain: ChainWithMessages + ChainWithTransactions; /// Messages from the `SourceChain` are dispatched on this chain. @@ -85,16 +55,6 @@ pub trait SubstrateMessageLane: 'static + Clone + Debug + Send + Sync { type ReceiveMessagesProofCallBuilder: ReceiveMessagesProofCallBuilder; /// How receive messages delivery proof call is built? type ReceiveMessagesDeliveryProofCallBuilder: ReceiveMessagesDeliveryProofCallBuilder; - - /// `TargetChain` tokens to `SourceChain` tokens conversion rate update builder. - /// - /// If not applicable to this bridge, you may use `()` here. - type TargetToSourceChainConversionRateUpdateBuilder: UpdateConversionRateCallBuilder< - Self::SourceChain, - >; - - /// Message relay strategy. - type RelayStrategy: RelayStrategy; } /// Adapter that allows all `SubstrateMessageLane` to act as `MessageLane`. @@ -138,10 +98,6 @@ pub struct MessagesRelayParams { pub lane_id: LaneId, /// Metrics parameters. pub metrics_params: MetricsParams, - /// Pre-registered standalone metrics. - pub standalone_metrics: Option>, - /// Relay strategy. - pub relay_strategy: P::RelayStrategy, } /// Run Substrate-to-Substrate messages sync loop. @@ -170,13 +126,6 @@ where let (max_messages_in_single_batch, max_messages_weight_in_single_batch) = (max_messages_in_single_batch / 2, max_messages_weight_in_single_batch / 2); - let standalone_metrics = params.standalone_metrics.map(Ok).unwrap_or_else(|| { - crate::messages_metrics::standalone_metrics::

( - source_client.clone(), - target_client.clone(), - ) - })?; - log::info!( target: "bridge", "Starting {} -> {} messages relay.\n\t\ @@ -220,7 +169,6 @@ where max_messages_in_single_batch, max_messages_weight_in_single_batch, max_messages_size_in_single_batch, - relay_strategy: params.relay_strategy, }, }, SubstrateMessagesSource::

::new( @@ -236,10 +184,12 @@ where params.lane_id, relayer_id_at_source, params.target_transaction_params, - standalone_metrics.clone(), params.source_to_target_headers_relay, ), - standalone_metrics.register_and_spawn(params.metrics_params)?, + { + GlobalMetrics::new()?.register_and_spawn(¶ms.metrics_params.registry)?; + params.metrics_params + }, futures::future::pending(), ) .await @@ -271,7 +221,6 @@ where R: BridgeMessagesConfig>, I: 'static, R::SourceHeaderChain: bp_messages::target_chain::SourceHeaderChain< - R::InboundMessageFee, MessagesProof = FromBridgedChainMessagesProof>, >, CallOf: From> + GetDispatchInfo, diff --git a/bridges/relays/lib-substrate-relay/src/messages_metrics.rs b/bridges/relays/lib-substrate-relay/src/messages_metrics.rs index 805d002b65f87..37a6d67baae43 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_metrics.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_metrics.rs @@ -16,260 +16,20 @@ //! Tools for supporting message lanes between two Substrate-based chains. -use crate::{helpers::tokens_conversion_rate, messages_lane::SubstrateMessageLane, TaggedAccount}; +use crate::TaggedAccount; use codec::Decode; use frame_system::AccountInfo; use pallet_balances::AccountData; use relay_substrate_client::{ - metrics::{ - FixedU128OrOne, FloatStorageValue, FloatStorageValueMetric, StorageProofOverheadMetric, - }, + metrics::{FloatStorageValue, FloatStorageValueMetric}, AccountIdOf, BalanceOf, Chain, ChainWithBalances, Client, Error as SubstrateError, IndexOf, }; -use relay_utils::metrics::{ - FloatJsonValueMetric, GlobalMetrics, MetricsParams, PrometheusError, StandaloneMetric, -}; +use relay_utils::metrics::{MetricsParams, StandaloneMetric}; use sp_core::storage::StorageData; use sp_runtime::{FixedPointNumber, FixedU128}; use std::{convert::TryFrom, fmt::Debug, marker::PhantomData}; -/// Name of the `NextFeeMultiplier` storage value within the transaction payment pallet. -const NEXT_FEE_MULTIPLIER_VALUE_NAME: &str = "NextFeeMultiplier"; - -/// Shared references to the standalone metrics of the message lane relay loop. -#[derive(Debug, Clone)] -pub struct StandaloneMessagesMetrics { - /// Global metrics. - pub global: GlobalMetrics, - /// Storage chain proof overhead metric. - pub source_storage_proof_overhead: StorageProofOverheadMetric, - /// Target chain proof overhead metric. - pub target_storage_proof_overhead: StorageProofOverheadMetric, - /// Source tokens to base conversion rate metric. - pub source_to_base_conversion_rate: Option, - /// Target tokens to base conversion rate metric. - pub target_to_base_conversion_rate: Option, - /// Source tokens to target tokens conversion rate metric. This rate is stored by the target - /// chain. - pub source_to_target_conversion_rate: Option>, - /// Target tokens to source tokens conversion rate metric. This rate is stored by the source - /// chain. - pub target_to_source_conversion_rate: Option>, - - /// Actual source chain fee multiplier. - pub source_fee_multiplier: Option>, - /// Source chain fee multiplier, stored at the target chain. - pub source_fee_multiplier_at_target: Option>, - /// Actual target chain fee multiplier. - pub target_fee_multiplier: Option>, - /// Target chain fee multiplier, stored at the target chain. - pub target_fee_multiplier_at_source: Option>, -} - -impl StandaloneMessagesMetrics { - /// Swap source and target sides. - pub fn reverse(self) -> StandaloneMessagesMetrics { - StandaloneMessagesMetrics { - global: self.global, - source_storage_proof_overhead: self.target_storage_proof_overhead, - target_storage_proof_overhead: self.source_storage_proof_overhead, - source_to_base_conversion_rate: self.target_to_base_conversion_rate, - target_to_base_conversion_rate: self.source_to_base_conversion_rate, - source_to_target_conversion_rate: self.target_to_source_conversion_rate, - target_to_source_conversion_rate: self.source_to_target_conversion_rate, - source_fee_multiplier: self.target_fee_multiplier, - source_fee_multiplier_at_target: self.target_fee_multiplier_at_source, - target_fee_multiplier: self.source_fee_multiplier, - target_fee_multiplier_at_source: self.source_fee_multiplier_at_target, - } - } - - /// Register all metrics in the registry. - pub fn register_and_spawn( - self, - metrics: MetricsParams, - ) -> Result { - self.global.register_and_spawn(&metrics.registry)?; - self.source_storage_proof_overhead.register_and_spawn(&metrics.registry)?; - self.target_storage_proof_overhead.register_and_spawn(&metrics.registry)?; - if let Some(m) = self.source_to_base_conversion_rate { - m.register_and_spawn(&metrics.registry)?; - } - if let Some(m) = self.target_to_base_conversion_rate { - m.register_and_spawn(&metrics.registry)?; - } - if let Some(m) = self.target_to_source_conversion_rate { - m.register_and_spawn(&metrics.registry)?; - } - if let Some(m) = self.source_fee_multiplier { - m.register_and_spawn(&metrics.registry)?; - } - if let Some(m) = self.source_fee_multiplier_at_target { - m.register_and_spawn(&metrics.registry)?; - } - if let Some(m) = self.target_fee_multiplier { - m.register_and_spawn(&metrics.registry)?; - } - if let Some(m) = self.target_fee_multiplier_at_source { - m.register_and_spawn(&metrics.registry)?; - } - Ok(metrics) - } - - /// Return conversion rate from target to source tokens. - pub async fn target_to_source_conversion_rate(&self) -> Option { - let from_token_value = - (*self.target_to_base_conversion_rate.as_ref()?.shared_value_ref().read().await)?; - let to_token_value = - (*self.source_to_base_conversion_rate.as_ref()?.shared_value_ref().read().await)?; - Some(tokens_conversion_rate(from_token_value, to_token_value)) - } -} - -/// Create symmetric standalone metrics for the message lane relay loop. -/// -/// All metrics returned by this function are exposed by loops that are serving given lane (`P`) -/// and by loops that are serving reverse lane (`P` with swapped `TargetChain` and `SourceChain`). -/// We assume that either conversion rate parameters have values in the storage, or they are -/// initialized with 1:1. -pub fn standalone_metrics( - source_client: Client, - target_client: Client, -) -> anyhow::Result> { - Ok(StandaloneMessagesMetrics { - global: GlobalMetrics::new()?, - source_storage_proof_overhead: StorageProofOverheadMetric::new( - source_client.clone(), - format!("{}_storage_proof_overhead", P::SourceChain::NAME.to_lowercase()), - format!("{} storage proof overhead", P::SourceChain::NAME), - )?, - target_storage_proof_overhead: StorageProofOverheadMetric::new( - target_client.clone(), - format!("{}_storage_proof_overhead", P::TargetChain::NAME.to_lowercase()), - format!("{} storage proof overhead", P::TargetChain::NAME), - )?, - source_to_base_conversion_rate: P::SourceChain::TOKEN_ID - .map(|source_chain_token_id| { - crate::helpers::token_price_metric(source_chain_token_id).map(Some) - }) - .unwrap_or(Ok(None))?, - target_to_base_conversion_rate: P::TargetChain::TOKEN_ID - .map(|target_chain_token_id| { - crate::helpers::token_price_metric(target_chain_token_id).map(Some) - }) - .unwrap_or(Ok(None))?, - source_to_target_conversion_rate: P::SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME - .map(bp_runtime::storage_parameter_key) - .map(|key| { - FloatStorageValueMetric::new( - FixedU128OrOne::default(), - target_client.clone(), - key, - format!( - "{}_{}_to_{}_conversion_rate", - P::TargetChain::NAME, - P::SourceChain::NAME, - P::TargetChain::NAME - ), - format!( - "{} to {} tokens conversion rate (used by {})", - P::SourceChain::NAME, - P::TargetChain::NAME, - P::TargetChain::NAME - ), - ) - .map(Some) - }) - .unwrap_or(Ok(None))?, - target_to_source_conversion_rate: P::TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME - .map(bp_runtime::storage_parameter_key) - .map(|key| { - FloatStorageValueMetric::new( - FixedU128OrOne::default(), - source_client.clone(), - key, - format!( - "{}_{}_to_{}_conversion_rate", - P::SourceChain::NAME, - P::TargetChain::NAME, - P::SourceChain::NAME - ), - format!( - "{} to {} tokens conversion rate (used by {})", - P::TargetChain::NAME, - P::SourceChain::NAME, - P::SourceChain::NAME - ), - ) - .map(Some) - }) - .unwrap_or(Ok(None))?, - source_fee_multiplier: P::AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME - .map(|pallet| bp_runtime::storage_value_key(pallet, NEXT_FEE_MULTIPLIER_VALUE_NAME)) - .map(|key| { - log::trace!(target: "bridge", "{}_fee_multiplier", P::SourceChain::NAME); - FloatStorageValueMetric::new( - FixedU128OrOne::default(), - source_client.clone(), - key, - format!("{}_fee_multiplier", P::SourceChain::NAME,), - format!("{} fee multiplier", P::SourceChain::NAME,), - ) - .map(Some) - }) - .unwrap_or(Ok(None))?, - source_fee_multiplier_at_target: P::SOURCE_FEE_MULTIPLIER_PARAMETER_NAME - .map(bp_runtime::storage_parameter_key) - .map(|key| { - FloatStorageValueMetric::new( - FixedU128OrOne::default(), - target_client.clone(), - key, - format!("{}_{}_fee_multiplier", P::TargetChain::NAME, P::SourceChain::NAME,), - format!( - "{} fee multiplier stored at {}", - P::SourceChain::NAME, - P::TargetChain::NAME, - ), - ) - .map(Some) - }) - .unwrap_or(Ok(None))?, - target_fee_multiplier: P::AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME - .map(|pallet| bp_runtime::storage_value_key(pallet, NEXT_FEE_MULTIPLIER_VALUE_NAME)) - .map(|key| { - log::trace!(target: "bridge", "{}_fee_multiplier", P::TargetChain::NAME); - FloatStorageValueMetric::new( - FixedU128OrOne::default(), - target_client, - key, - format!("{}_fee_multiplier", P::TargetChain::NAME,), - format!("{} fee multiplier", P::TargetChain::NAME,), - ) - .map(Some) - }) - .unwrap_or(Ok(None))?, - target_fee_multiplier_at_source: P::TARGET_FEE_MULTIPLIER_PARAMETER_NAME - .map(bp_runtime::storage_parameter_key) - .map(|key| { - FloatStorageValueMetric::new( - FixedU128OrOne::default(), - source_client, - key, - format!("{}_{}_fee_multiplier", P::SourceChain::NAME, P::TargetChain::NAME,), - format!( - "{} fee multiplier stored at {}", - P::TargetChain::NAME, - P::SourceChain::NAME, - ), - ) - .map(Some) - }) - .unwrap_or(Ok(None))?, - }) -} - /// Add relay accounts balance metrics. pub async fn add_relay_balances_metrics( client: Client, @@ -359,9 +119,6 @@ fn convert_to_token_balance(balance: u128, token_decimals: u32) -> FixedU128 { #[cfg(test)] mod tests { use super::*; - use frame_support::storage::generator::StorageValue; - use sp_core::storage::StorageKey; - #[test] fn token_decimals_used_properly() { let plancks = 425_000_000_000; @@ -369,12 +126,4 @@ mod tests { let dots = convert_to_token_balance(plancks, token_decimals); assert_eq!(dots, FixedU128::saturating_from_rational(425, 10)); } - - #[test] - fn next_fee_multiplier_storage_key_is_correct() { - assert_eq!( - bp_runtime::storage_value_key("TransactionPayment", NEXT_FEE_MULTIPLIER_VALUE_NAME), - StorageKey(pallet_transaction_payment::NextFeeMultiplier::::storage_value_final_key().to_vec()), - ); - } } diff --git a/bridges/relays/lib-substrate-relay/src/messages_source.rs b/bridges/relays/lib-substrate-relay/src/messages_source.rs index c02db3fb48a63..57f84eb6bb19d 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_source.rs @@ -31,13 +31,11 @@ use async_std::sync::Arc; use async_trait::async_trait; use bp_messages::{ storage_keys::{operating_mode_key, outbound_lane_data_key}, - InboundMessageDetails, LaneId, MessageData, MessageNonce, MessagePayload, - MessagesOperatingMode, OutboundLaneData, OutboundMessageDetails, UnrewardedRelayersState, -}; -use bp_runtime::{messages::DispatchFeePayment, BasicOperatingMode, HeaderIdProvider}; -use bridge_runtime_common::messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, + InboundMessageDetails, LaneId, MessageNonce, MessagePayload, MessagesOperatingMode, + OutboundLaneData, OutboundMessageDetails, }; +use bp_runtime::{BasicOperatingMode, HeaderIdProvider}; +use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; use codec::{Decode, Encode}; use frame_support::weights::Weight; use messages_relay::{ @@ -47,11 +45,11 @@ use messages_relay::{ SourceClientState, }, }; -use num_traits::{Bounded, Zero}; +use num_traits::Zero; use relay_substrate_client::{ - AccountIdOf, AccountKeyPairOf, BalanceOf, BlockNumberOf, Chain, ChainWithMessages, - ChainWithTransactions, Client, Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, SignParam, - TransactionEra, TransactionTracker, UnsignedTransaction, + AccountIdOf, AccountKeyPairOf, BalanceOf, BlockNumberOf, Chain, ChainWithMessages, Client, + Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, SignParam, TransactionEra, + TransactionTracker, UnsignedTransaction, }; use relay_utils::{relay_loop::Client as RelayClient, HeaderId}; use sp_core::{Bytes, Pair}; @@ -62,7 +60,7 @@ use std::ops::RangeInclusive; /// required to submit to the target node: cumulative dispatch weight of bundled messages and /// the proof itself. pub type SubstrateMessagesProof = (Weight, FromBridgedChainMessagesProof>); -type MessagesToRefine<'a, Balance> = Vec<(MessagePayload, &'a mut OutboundMessageDetails)>; +type MessagesToRefine<'a> = Vec<(MessagePayload, &'a mut OutboundMessageDetails)>; /// Substrate client as Substrate messages source. pub struct SubstrateMessagesSource { @@ -207,9 +205,7 @@ where // prepare arguments of the inbound message details call (if we need it) let mut msgs_to_refine = vec![]; for out_msg_details in out_msgs_details.iter_mut() { - if out_msg_details.dispatch_fee_payment != DispatchFeePayment::AtTargetChain { - continue - } + // in our current strategy all messages are supposed to be paid at the target chain // for pay-at-target messages we may want to ask target chain for // refined dispatch weight @@ -218,7 +214,7 @@ where &self.lane_id, out_msg_details.nonce, ); - let msg_data: MessageData> = + let msg_payload: MessagePayload = self.source_client.storage_value(msg_key, Some(id.1)).await?.ok_or_else(|| { SubstrateError::Custom(format!( "Message to {} {:?}/{} is missing from runtime the storage of {} at {:?}", @@ -230,7 +226,7 @@ where )) })?; - msgs_to_refine.push((msg_data.payload, out_msg_details)); + msgs_to_refine.push((msg_payload, out_msg_details)); } for mut msgs_to_refine_batch in @@ -277,8 +273,7 @@ where MessageDetails { dispatch_weight: out_msg_details.dispatch_weight, size: out_msg_details.size as _, - reward: out_msg_details.delivery_and_dispatch_fee, - dispatch_fee_payment: out_msg_details.dispatch_fee_payment, + reward: Zero::zero(), }, ); } @@ -370,39 +365,6 @@ where target_to_source_headers_relay.require_more_headers(id.0).await; } } - - async fn estimate_confirmation_transaction( - &self, - ) -> as MessageLane>::SourceChainBalance { - let runtime_version = match self.source_client.runtime_version().await { - Ok(v) => v, - Err(_) => return BalanceOf::::max_value(), - }; - async { - let dummy_tx = P::SourceChain::sign_transaction( - SignParam:: { - spec_version: runtime_version.spec_version, - transaction_version: runtime_version.transaction_version, - genesis_hash: *self.source_client.genesis_hash(), - signer: self.transaction_params.signer.clone(), - }, - make_messages_delivery_proof_transaction::

( - &self.transaction_params, - HeaderId(Default::default(), Default::default()), - Zero::zero(), - prepare_dummy_messages_delivery_proof::(), - false, - )?, - )? - .encode(); - self.source_client - .estimate_extrinsic_fee(Bytes(dummy_tx)) - .await - .map(|fee| fee.inclusion_fee()) - } - .await - .unwrap_or_else(|_| BalanceOf::::max_value()) - } } /// Ensure that the messages pallet at source chain is active. @@ -441,30 +403,6 @@ fn make_messages_delivery_proof_transaction( .era(TransactionEra::new(source_best_block_id, source_transaction_params.mortality))) } -/// Prepare 'dummy' messages delivery proof that will compose the delivery confirmation transaction. -/// -/// We don't care about proof actually being the valid proof, because its validity doesn't -/// affect the call weight - we only care about its size. -fn prepare_dummy_messages_delivery_proof( -) -> SubstrateMessagesDeliveryProof { - let single_message_confirmation_size = - bp_messages::InboundLaneData::<()>::encoded_size_hint_u32(1, 1); - let proof_size = TC::STORAGE_PROOF_OVERHEAD.saturating_add(single_message_confirmation_size); - ( - UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - messages_in_oldest_entry: 1, - total_messages: 1, - last_delivered_nonce: 1, - }, - FromBridgedChainMessagesDeliveryProof { - bridged_header_hash: Default::default(), - storage_proof: vec![vec![0; proof_size as usize]], - lane: Default::default(), - }, - ) -} - /// Read best blocks from given client. /// /// This function assumes that the chain that is followed by the `self_client` has @@ -552,7 +490,7 @@ where } fn validate_out_msgs_details( - out_msgs_details: &[OutboundMessageDetails], + out_msgs_details: &[OutboundMessageDetails], nonces: RangeInclusive, ) -> Result<(), SubstrateError> { let make_missing_nonce_error = |expected_nonce| { @@ -601,8 +539,8 @@ fn validate_out_msgs_details( fn split_msgs_to_refine( lane_id: LaneId, - msgs_to_refine: MessagesToRefine, -) -> Result>, SubstrateError> { + msgs_to_refine: MessagesToRefine, +) -> Result, SubstrateError> { let max_batch_size = Target::max_extrinsic_size() as usize; let mut batches = vec![]; @@ -635,23 +573,20 @@ fn split_msgs_to_refine( #[cfg(test)] mod tests { use super::*; - use bp_runtime::{messages::DispatchFeePayment, Chain as ChainBase}; - use codec::MaxEncodedLen; + use bp_runtime::Chain as ChainBase; use relay_rialto_client::Rialto; use relay_rococo_client::Rococo; use relay_wococo_client::Wococo; fn message_details_from_rpc( nonces: RangeInclusive, - ) -> Vec> { + ) -> Vec { nonces .into_iter() .map(|nonce| bp_messages::OutboundMessageDetails { nonce, dispatch_weight: Weight::zero(), size: 0, - delivery_and_dispatch_fee: 0, - dispatch_fee_payment: DispatchFeePayment::AtSourceChain, }) .collect() } @@ -704,31 +639,16 @@ mod tests { )); } - #[test] - fn prepare_dummy_messages_delivery_proof_works() { - let expected_minimal_size = - bp_wococo::AccountId::max_encoded_len() as u32 + Rococo::STORAGE_PROOF_OVERHEAD; - let dummy_proof = prepare_dummy_messages_delivery_proof::(); - assert!( - dummy_proof.1.encode().len() as u32 > expected_minimal_size, - "Expected proof size at least {}. Got: {}", - expected_minimal_size, - dummy_proof.1.encode().len(), - ); - } - fn check_split_msgs_to_refine( payload_sizes: Vec, expected_batches: Result, ()>, ) { let mut out_msgs_details = vec![]; for (idx, _) in payload_sizes.iter().enumerate() { - out_msgs_details.push(OutboundMessageDetails::> { + out_msgs_details.push(OutboundMessageDetails { nonce: idx as MessageNonce, dispatch_weight: Weight::zero(), size: 0, - delivery_and_dispatch_fee: 0, - dispatch_fee_payment: DispatchFeePayment::AtTargetChain, }); } diff --git a/bridges/relays/lib-substrate-relay/src/messages_target.rs b/bridges/relays/lib-substrate-relay/src/messages_target.rs index ed4d040b5d869..22a50acf37eb6 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_target.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_target.rs @@ -20,7 +20,6 @@ use crate::{ messages_lane::{MessageLaneAdapter, ReceiveMessagesProofCallBuilder, SubstrateMessageLane}, - messages_metrics::StandaloneMessagesMetrics, messages_source::{ensure_messages_pallet_active, read_client_state, SubstrateMessagesProof}, on_demand::OnDemandRelay, TransactionParams, @@ -32,24 +31,18 @@ use bp_messages::{ storage_keys::inbound_lane_data_key, total_unrewarded_messages, InboundLaneData, LaneId, MessageNonce, UnrewardedRelayersState, }; -use bridge_runtime_common::messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, -}; -use codec::Encode; -use frame_support::weights::{Weight, WeightToFee}; +use bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof; use messages_relay::{ message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf}, message_lane_loop::{NoncesSubmitArtifacts, TargetClient, TargetClientState}, }; -use num_traits::{Bounded, Zero}; use relay_substrate_client::{ - AccountIdOf, AccountKeyPairOf, BalanceOf, BlockNumberOf, Chain, ChainWithMessages, - ChainWithTransactions, Client, Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, SignParam, - TransactionEra, TransactionTracker, UnsignedTransaction, WeightToFeeOf, + AccountIdOf, AccountKeyPairOf, BalanceOf, BlockNumberOf, Chain, ChainWithMessages, Client, + Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, SignParam, TransactionEra, + TransactionTracker, UnsignedTransaction, }; -use relay_utils::{relay_loop::Client as RelayClient, HeaderId}; -use sp_core::{Bytes, Pair}; -use sp_runtime::{traits::Saturating, FixedPointNumber, FixedU128}; +use relay_utils::relay_loop::Client as RelayClient; +use sp_core::Pair; use std::{collections::VecDeque, convert::TryFrom, ops::RangeInclusive}; /// Message receiving proof returned by the target Substrate node. @@ -63,7 +56,6 @@ pub struct SubstrateMessagesTarget { lane_id: LaneId, relayer_id_at_source: AccountIdOf, transaction_params: TransactionParams>, - metric_values: StandaloneMessagesMetrics, source_to_target_headers_relay: Option>>>, } @@ -75,7 +67,6 @@ impl SubstrateMessagesTarget

{ lane_id: LaneId, relayer_id_at_source: AccountIdOf, transaction_params: TransactionParams>, - metric_values: StandaloneMessagesMetrics, source_to_target_headers_relay: Option< Arc>>, >, @@ -86,7 +77,6 @@ impl SubstrateMessagesTarget

{ lane_id, relayer_id_at_source, transaction_params, - metric_values, source_to_target_headers_relay, } } @@ -121,7 +111,6 @@ impl Clone for SubstrateMessagesTarget

{ lane_id: self.lane_id, relayer_id_at_source: self.relayer_id_at_source.clone(), transaction_params: self.transaction_params.clone(), - metric_values: self.metric_values.clone(), source_to_target_headers_relay: self.source_to_target_headers_relay.clone(), } } @@ -283,142 +272,6 @@ where source_to_target_headers_relay.require_more_headers(id.0).await; } } - - async fn estimate_delivery_transaction_in_source_tokens( - &self, - nonces: RangeInclusive, - total_prepaid_nonces: MessageNonce, - total_dispatch_weight: Weight, - total_size: u32, - ) -> Result< as MessageLane>::SourceChainBalance, SubstrateError> { - let conversion_rate = - self.metric_values.target_to_source_conversion_rate().await.ok_or_else(|| { - SubstrateError::Custom(format!( - "Failed to compute conversion rate from {} to {}", - P::TargetChain::NAME, - P::SourceChain::NAME, - )) - })?; - - let (spec_version, transaction_version) = - self.target_client.simple_runtime_version().await?; - // Prepare 'dummy' delivery transaction - we only care about its length and dispatch weight. - let delivery_tx = P::TargetChain::sign_transaction( - SignParam { - spec_version, - transaction_version, - genesis_hash: Default::default(), - signer: self.transaction_params.signer.clone(), - }, - make_messages_delivery_transaction::

( - &self.transaction_params, - HeaderId(Default::default(), Default::default()), - Zero::zero(), - self.relayer_id_at_source.clone(), - nonces.clone(), - prepare_dummy_messages_proof::( - nonces.clone(), - total_dispatch_weight, - total_size, - ), - false, - )?, - )? - .encode(); - let delivery_tx_fee = self.target_client.estimate_extrinsic_fee(Bytes(delivery_tx)).await?; - let inclusion_fee_in_target_tokens = delivery_tx_fee.inclusion_fee(); - - // The pre-dispatch cost of delivery transaction includes additional fee to cover dispatch - // fee payment (Currency::transfer in regular deployment). But if message dispatch has - // already been paid at the Source chain, the delivery transaction will refund relayer with - // this additional cost. But `estimate_extrinsic_fee` obviously just returns pre-dispatch - // cost of the transaction. So if transaction delivers prepaid message, then it may happen - // that pre-dispatch cost is larger than reward and `Rational` relayer will refuse to - // deliver this message. - // - // The most obvious solution would be to deduct total weight of dispatch fee payments from - // the `total_dispatch_weight` and use regular `estimate_extrinsic_fee` call. But what if - // `total_dispatch_weight` is less than total dispatch fee payments weight? Weight is - // strictly positive, so we can't use this option. - // - // Instead we'll be directly using `WeightToFee` and `NextFeeMultiplier` of the Target - // chain. This requires more knowledge of the Target chain, but seems there's no better way - // to solve this now. - let expected_refund_in_target_tokens = if total_prepaid_nonces != 0 { - const WEIGHT_DIFFERENCE: Weight = Weight::from_ref_time(100); - - let (spec_version, transaction_version) = - self.target_client.simple_runtime_version().await?; - let larger_dispatch_weight = total_dispatch_weight.saturating_add(WEIGHT_DIFFERENCE); - let dummy_tx = P::TargetChain::sign_transaction( - SignParam { - spec_version, - transaction_version, - genesis_hash: Default::default(), - signer: self.transaction_params.signer.clone(), - }, - make_messages_delivery_transaction::

( - &self.transaction_params, - HeaderId(Default::default(), Default::default()), - Zero::zero(), - self.relayer_id_at_source.clone(), - nonces.clone(), - prepare_dummy_messages_proof::( - nonces.clone(), - larger_dispatch_weight, - total_size, - ), - false, - )?, - )? - .encode(); - let larger_delivery_tx_fee = - self.target_client.estimate_extrinsic_fee(Bytes(dummy_tx)).await?; - - compute_prepaid_messages_refund::( - total_prepaid_nonces, - compute_fee_multiplier::( - delivery_tx_fee.adjusted_weight_fee, - total_dispatch_weight, - larger_delivery_tx_fee.adjusted_weight_fee, - larger_dispatch_weight, - ), - ) - } else { - Zero::zero() - }; - - let delivery_fee_in_source_tokens = - convert_target_tokens_to_source_tokens::( - FixedU128::from_float(conversion_rate), - inclusion_fee_in_target_tokens.saturating_sub(expected_refund_in_target_tokens), - ); - - log::trace!( - target: "bridge", - "Estimated {} -> {} messages delivery transaction.\n\t\ - Total nonces: {:?}\n\t\ - Prepaid messages: {}\n\t\ - Total messages size: {}\n\t\ - Total messages dispatch weight: {}\n\t\ - Inclusion fee (in {1} tokens): {:?}\n\t\ - Expected refund (in {1} tokens): {:?}\n\t\ - {1} -> {0} conversion rate: {:?}\n\t\ - Expected delivery tx fee (in {0} tokens): {:?}", - P::SourceChain::NAME, - P::TargetChain::NAME, - nonces, - total_prepaid_nonces, - total_size, - total_dispatch_weight, - inclusion_fee_in_target_tokens, - expected_refund_in_target_tokens, - conversion_rate, - delivery_fee_in_source_tokens, - ); - - Ok(delivery_fee_in_source_tokens) - } } /// Make messages delivery transaction from given proof. @@ -443,153 +296,3 @@ fn make_messages_delivery_transaction( Ok(UnsignedTransaction::new(call.into(), transaction_nonce) .era(TransactionEra::new(target_best_block_id, target_transaction_params.mortality))) } - -/// Prepare 'dummy' messages proof that will compose the delivery transaction. -/// -/// We don't care about proof actually being the valid proof, because its validity doesn't -/// affect the call weight - we only care about its size. -fn prepare_dummy_messages_proof( - nonces: RangeInclusive, - total_dispatch_weight: Weight, - total_size: u32, -) -> SubstrateMessagesProof { - ( - total_dispatch_weight, - FromBridgedChainMessagesProof { - bridged_header_hash: Default::default(), - storage_proof: vec![vec![ - 0; - SC::STORAGE_PROOF_OVERHEAD.saturating_add(total_size) as usize - ]], - lane: Default::default(), - nonces_start: *nonces.start(), - nonces_end: *nonces.end(), - }, - ) -} - -/// Given delivery transaction fee in target chain tokens and conversion rate to the source -/// chain tokens, compute transaction cost in source chain tokens. -fn convert_target_tokens_to_source_tokens( - target_to_source_conversion_rate: FixedU128, - target_transaction_fee: TC::Balance, -) -> SC::Balance -where - SC::Balance: TryFrom, -{ - SC::Balance::try_from( - target_to_source_conversion_rate.saturating_mul_int(target_transaction_fee), - ) - .unwrap_or_else(|_| SC::Balance::max_value()) -} - -/// Compute fee multiplier that is used by the chain, given a couple of fees for transactions -/// that are only differ in dispatch weights. -/// -/// This function assumes that standard transaction payment pallet is used by the chain. -/// The only fee component that depends on dispatch weight is the `adjusted_weight_fee`. -/// -/// **WARNING**: this functions will only be accurate if weight-to-fee conversion function -/// is linear. For non-linear polynomials the error will grow with `weight_difference` growth. -/// So better to use smaller differences. -fn compute_fee_multiplier( - smaller_adjusted_weight_fee: BalanceOf, - smaller_tx_weight: Weight, - larger_adjusted_weight_fee: BalanceOf, - larger_tx_weight: Weight, -) -> FixedU128 { - let adjusted_weight_fee_difference = - larger_adjusted_weight_fee.saturating_sub(smaller_adjusted_weight_fee); - let smaller_tx_unadjusted_weight_fee = WeightToFeeOf::::weight_to_fee(&smaller_tx_weight); - let larger_tx_unadjusted_weight_fee = WeightToFeeOf::::weight_to_fee(&larger_tx_weight); - FixedU128::saturating_from_rational( - adjusted_weight_fee_difference, - larger_tx_unadjusted_weight_fee.saturating_sub(smaller_tx_unadjusted_weight_fee), - ) -} - -/// Compute fee that will be refunded to the relayer because dispatch of `total_prepaid_nonces` -/// messages has been paid at the source chain. -fn compute_prepaid_messages_refund( - total_prepaid_nonces: MessageNonce, - fee_multiplier: FixedU128, -) -> BalanceOf { - fee_multiplier.saturating_mul_int(WeightToFeeOf::::weight_to_fee( - &C::PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN.saturating_mul(total_prepaid_nonces), - )) -} - -#[cfg(test)] -mod tests { - use super::*; - use relay_rialto_client::Rialto; - use relay_rococo_client::Rococo; - use relay_wococo_client::Wococo; - - #[test] - fn prepare_dummy_messages_proof_works() { - const DISPATCH_WEIGHT: Weight = Weight::from_ref_time(1_000_000); - const SIZE: u32 = 1_000; - let dummy_proof = prepare_dummy_messages_proof::(1..=10, DISPATCH_WEIGHT, SIZE); - assert_eq!(dummy_proof.0, DISPATCH_WEIGHT); - assert!( - dummy_proof.1.encode().len() as u32 > SIZE, - "Expected proof size at least {}. Got: {}", - SIZE, - dummy_proof.1.encode().len(), - ); - } - - #[test] - fn convert_target_tokens_to_source_tokens_works() { - assert_eq!( - convert_target_tokens_to_source_tokens::((150, 100).into(), 1_000), - 1_500 - ); - assert_eq!( - convert_target_tokens_to_source_tokens::((50, 100).into(), 1_000), - 500 - ); - assert_eq!( - convert_target_tokens_to_source_tokens::((100, 100).into(), 1_000), - 1_000 - ); - } - - #[test] - fn compute_fee_multiplier_returns_sane_results() { - let multiplier: FixedU128 = - bp_rialto::WeightToFee::weight_to_fee(&Weight::from_ref_time(1)).into(); - - let smaller_weight = 1_000_000; - let smaller_adjusted_weight_fee = multiplier.saturating_mul_int( - WeightToFeeOf::::weight_to_fee(&Weight::from_ref_time(smaller_weight)), - ); - - let larger_weight = smaller_weight + 200_000; - let larger_adjusted_weight_fee = multiplier.saturating_mul_int( - WeightToFeeOf::::weight_to_fee(&Weight::from_ref_time(larger_weight)), - ); - assert_eq!( - compute_fee_multiplier::( - smaller_adjusted_weight_fee, - Weight::from_ref_time(smaller_weight), - larger_adjusted_weight_fee, - Weight::from_ref_time(larger_weight), - ), - multiplier, - ); - } - - #[test] - fn compute_prepaid_messages_refund_returns_sane_results() { - assert!( - compute_prepaid_messages_refund::( - 10, - FixedU128::saturating_from_rational(110, 100), - ) > Rialto::PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN - .saturating_mul(10u64) - .ref_time() as _ - ); - } -} diff --git a/bridges/relays/messages/src/lib.rs b/bridges/relays/messages/src/lib.rs index c9e460300342f..9c62cee5ee3db 100644 --- a/bridges/relays/messages/src/lib.rs +++ b/bridges/relays/messages/src/lib.rs @@ -29,9 +29,9 @@ mod metrics; pub mod message_lane; pub mod message_lane_loop; -pub mod relay_strategy; mod message_race_delivery; +mod message_race_limits; mod message_race_loop; mod message_race_receiving; mod message_race_strategy; diff --git a/bridges/relays/messages/src/message_lane_loop.rs b/bridges/relays/messages/src/message_lane_loop.rs index 8d9f3ded08741..6b28dcbaa602c 100644 --- a/bridges/relays/messages/src/message_lane_loop.rs +++ b/bridges/relays/messages/src/message_lane_loop.rs @@ -30,7 +30,6 @@ use async_trait::async_trait; use futures::{channel::mpsc::unbounded, future::FutureExt, stream::StreamExt}; use bp_messages::{LaneId, MessageNonce, UnrewardedRelayersState, Weight}; -use bp_runtime::messages::DispatchFeePayment; use relay_utils::{ interval, metrics::MetricsParams, process_future_result, relay_loop::Client as RelayClient, retry_backoff, FailedClient, TransactionTracker, @@ -41,12 +40,11 @@ use crate::{ message_race_delivery::run as run_message_delivery_race, message_race_receiving::run as run_message_receiving_race, metrics::MessageLaneLoopMetrics, - relay_strategy::RelayStrategy, }; /// Message lane loop configuration params. #[derive(Debug, Clone)] -pub struct Params { +pub struct Params { /// Id of lane this loop is servicing. pub lane: LaneId, /// Interval at which we ask target node about its updates. @@ -56,22 +54,12 @@ pub struct Params { /// Delay between moments when connection error happens and our reconnect attempt. pub reconnect_delay: Duration, /// Message delivery race parameters. - pub delivery_params: MessageDeliveryParams, -} - -/// Relayer operating mode. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum RelayerMode { - /// The relayer doesn't care about rewards. - Altruistic, - /// The relayer will deliver all messages and confirmations as long as he's not losing any - /// funds. - Rational, + pub delivery_params: MessageDeliveryParams, } /// Message delivery race parameters. #[derive(Debug, Clone)] -pub struct MessageDeliveryParams { +pub struct MessageDeliveryParams { /// Maximal number of unconfirmed relayer entries at the inbound lane. If there's that number /// of entries in the `InboundLaneData::relayers` set, all new messages will be rejected until /// reward payment will be proved (by including outbound lane state to the message delivery @@ -87,8 +75,6 @@ pub struct MessageDeliveryParams { pub max_messages_weight_in_single_batch: Weight, /// Maximal cumulative size of relayed messages in single delivery transaction. pub max_messages_size_in_single_batch: u32, - /// Relay strategy - pub relay_strategy: Strategy, } /// Message details. @@ -100,8 +86,6 @@ pub struct MessageDetails { pub size: u32, /// The relayer reward paid in the source chain tokens. pub reward: SourceChainBalance, - /// Where the fee for dispatching message is paid? - pub dispatch_fee_payment: DispatchFeePayment, } /// Messages details map. @@ -173,9 +157,6 @@ pub trait SourceClient: RelayClient { /// We need given finalized target header on source to continue synchronization. async fn require_target_header_on_source(&self, id: TargetHeaderIdOf

); - - /// Estimate cost of single message confirmation transaction in source chain tokens. - async fn estimate_confirmation_transaction(&self) -> P::SourceChainBalance; } /// Target client trait. @@ -221,18 +202,6 @@ pub trait TargetClient: RelayClient { /// We need given finalized source header on target to continue synchronization. async fn require_source_header_on_target(&self, id: SourceHeaderIdOf

); - - /// Estimate cost of messages delivery transaction in source chain tokens. - /// - /// Please keep in mind that the returned cost must be converted to the source chain - /// tokens, even though the transaction fee will be paid in the target chain tokens. - async fn estimate_delivery_transaction_in_source_tokens( - &self, - nonces: RangeInclusive, - total_prepaid_nonces: MessageNonce, - total_dispatch_weight: Weight, - total_size: u32, - ) -> Result; } /// State of the client. @@ -272,8 +241,8 @@ pub fn metrics_prefix(lane: &LaneId) -> String { } /// Run message lane service loop. -pub async fn run( - params: Params, +pub async fn run( + params: Params, source_client: impl SourceClient

, target_client: impl TargetClient

, metrics_params: MetricsParams, @@ -283,11 +252,7 @@ pub async fn run( relay_utils::relay_loop(source_client, target_client) .reconnect_delay(params.reconnect_delay) .with_metrics(metrics_params) - .loop_metric(MessageLaneLoopMetrics::new( - Some(&metrics_prefix::

(¶ms.lane)), - P::SOURCE_NAME, - P::TARGET_NAME, - )?)? + .loop_metric(MessageLaneLoopMetrics::new(Some(&metrics_prefix::

(¶ms.lane)))?)? .expose() .await? .run(metrics_prefix::

(¶ms.lane), move |source_client, target_client, metrics| { @@ -304,13 +269,8 @@ pub async fn run( /// Run one-way message delivery loop until connection with target or source node is lost, or exit /// signal is received. -async fn run_until_connection_lost< - P: MessageLane, - Strategy: RelayStrategy, - SC: SourceClient

, - TC: TargetClient

, ->( - params: Params, +async fn run_until_connection_lost, TC: TargetClient

>( + params: Params, source_client: SC, target_client: TC, metrics_msg: Option, @@ -477,17 +437,12 @@ pub(crate) mod tests { use relay_utils::{HeaderId, MaybeConnectionError, TrackedTransactionStatus}; - use crate::relay_strategy::AltruisticStrategy; - use super::*; pub fn header_id(number: TestSourceHeaderNumber) -> TestSourceHeaderId { HeaderId(number, number) } - pub const CONFIRMATION_TRANSACTION_COST: TestSourceChainBalance = 1; - pub const BASE_MESSAGE_DELIVERY_TRANSACTION_COST: TestSourceChainBalance = 1; - pub type TestSourceChainBalance = u64; pub type TestSourceHeaderId = HeaderId; pub type TestTargetHeaderId = HeaderId; @@ -681,7 +636,6 @@ pub(crate) mod tests { dispatch_weight: Weight::from_ref_time(1), size: 1, reward: 1, - dispatch_fee_payment: DispatchFeePayment::AtSourceChain, }, ) }) @@ -737,10 +691,6 @@ pub(crate) mod tests { (self.tick)(&mut data); (self.post_tick)(&mut data); } - - async fn estimate_confirmation_transaction(&self) -> TestSourceChainBalance { - CONFIRMATION_TRANSACTION_COST - } } #[derive(Clone)] @@ -871,20 +821,6 @@ pub(crate) mod tests { (self.tick)(&mut data); (self.post_tick)(&mut data); } - - async fn estimate_delivery_transaction_in_source_tokens( - &self, - nonces: RangeInclusive, - _total_prepaid_nonces: MessageNonce, - total_dispatch_weight: Weight, - total_size: u32, - ) -> Result { - Ok((Weight::from_ref_time(BASE_MESSAGE_DELIVERY_TRANSACTION_COST) * - (nonces.end() - nonces.start() + 1) + - total_dispatch_weight + - Weight::from_ref_time(total_size as u64)) - .ref_time()) - } } fn run_loop_test( @@ -920,7 +856,6 @@ pub(crate) mod tests { max_messages_in_single_batch: 4, max_messages_weight_in_single_batch: Weight::from_ref_time(4), max_messages_size_in_single_batch: 4, - relay_strategy: AltruisticStrategy, }, }, source_client, diff --git a/bridges/relays/messages/src/message_race_delivery.rs b/bridges/relays/messages/src/message_race_delivery.rs index 9481e47faf88f..b49a05dac5cf9 100644 --- a/bridges/relays/messages/src/message_race_delivery.rs +++ b/bridges/relays/messages/src/message_race_delivery.rs @@ -28,23 +28,23 @@ use crate::{ SourceClient as MessageLaneSourceClient, SourceClientState, TargetClient as MessageLaneTargetClient, TargetClientState, }, + message_race_limits::{MessageRaceLimits, RelayMessagesBatchReference}, message_race_loop::{ MessageRace, NoncesRange, RaceState, RaceStrategy, SourceClient, SourceClientNonces, TargetClient, TargetClientNonces, }, message_race_strategy::BasicStrategy, metrics::MessageLaneLoopMetrics, - relay_strategy::{EnforcementStrategy, RelayMessagesBatchReference, RelayStrategy}, }; /// Run message delivery race. -pub async fn run( +pub async fn run( source_client: impl MessageLaneSourceClient

, source_state_updates: impl FusedStream>, target_client: impl MessageLaneTargetClient

, target_state_updates: impl FusedStream>, metrics_msg: Option, - params: MessageDeliveryParams, + params: MessageDeliveryParams, ) -> Result<(), FailedClient> { crate::message_race_loop::run( MessageDeliveryRaceSource { @@ -59,7 +59,7 @@ pub async fn run( _phantom: Default::default(), }, target_state_updates, - MessageDeliveryStrategy:: { + MessageDeliveryStrategy:: { lane_source_client: source_client, lane_target_client: target_client, max_unrewarded_relayer_entries_at_target: params @@ -68,7 +68,6 @@ pub async fn run( max_messages_in_single_batch: params.max_messages_in_single_batch, max_messages_weight_in_single_batch: params.max_messages_weight_in_single_batch, max_messages_size_in_single_batch: params.max_messages_size_in_single_batch, - relay_strategy: params.relay_strategy, latest_confirmed_nonces_at_source: VecDeque::new(), target_nonces: None, strategy: BasicStrategy::new(), @@ -231,7 +230,7 @@ struct DeliveryRaceTargetNoncesData { } /// Messages delivery strategy. -struct MessageDeliveryStrategy { +struct MessageDeliveryStrategy { /// The client that is connected to the message lane source node. lane_source_client: SC, /// The client that is connected to the message lane target node. @@ -246,8 +245,6 @@ struct MessageDeliveryStrategy max_messages_weight_in_single_batch: Weight, /// Maximal messages size in the single delivery transaction. max_messages_size_in_single_batch: u32, - /// Relayer operating mode. - relay_strategy: Strategy, /// Latest confirmed nonces at the source client + the header id where we have first met this /// nonce. latest_confirmed_nonces_at_source: VecDeque<(SourceHeaderIdOf

, MessageNonce)>, @@ -268,9 +265,7 @@ type MessageDeliveryStrategyBase

= BasicStrategy<

::MessagesProof, >; -impl std::fmt::Debug - for MessageDeliveryStrategy -{ +impl std::fmt::Debug for MessageDeliveryStrategy { fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { fmt.debug_struct("MessageDeliveryStrategy") .field( @@ -288,7 +283,7 @@ impl std::fmt::Debug } } -impl MessageDeliveryStrategy { +impl MessageDeliveryStrategy { /// Returns total weight of all undelivered messages. fn total_queued_dispatch_weight(&self) -> Weight { self.strategy @@ -300,9 +295,8 @@ impl MessageDeliveryStrategy - RaceStrategy, TargetHeaderIdOf

, P::MessagesProof> - for MessageDeliveryStrategy +impl RaceStrategy, TargetHeaderIdOf

, P::MessagesProof> + for MessageDeliveryStrategy where P: MessageLane, SC: MessageLaneSourceClient

, @@ -524,8 +518,7 @@ where metrics: self.metrics_msg.clone(), }; - let mut strategy = EnforcementStrategy::new(self.relay_strategy.clone()); - let range_end = strategy.decide(reference).await?; + let range_end = MessageRaceLimits::decide(reference).await?; let range_begin = source_queue[0].1.begin(); let selected_nonces = range_begin..=range_end; @@ -562,38 +555,27 @@ impl NoncesRange for MessageDetailsMap; type TestStrategy = - MessageDeliveryStrategy; + MessageDeliveryStrategy; fn source_nonces( new_nonces: RangeInclusive, confirmed_nonce: MessageNonce, reward: TestSourceChainBalance, - dispatch_fee_payment: DispatchFeePayment, ) -> SourceClientNonces> { SourceClientNonces { new_nonces: new_nonces @@ -605,7 +587,6 @@ mod tests { dispatch_weight: DEFAULT_DISPATCH_WEIGHT, size: DEFAULT_SIZE, reward, - dispatch_fee_payment, }, ) }) @@ -648,13 +629,11 @@ mod tests { }, }), strategy: BasicStrategy::new(), - relay_strategy: MixStrategy::new(RelayerMode::Altruistic), }; - race_strategy.strategy.source_nonces_updated( - header_id(1), - source_nonces(20..=23, 19, DEFAULT_REWARD, DispatchFeePayment::AtSourceChain), - ); + race_strategy + .strategy + .source_nonces_updated(header_id(1), source_nonces(20..=23, 19, 0)); let target_nonces = TargetClientNonces { latest_nonce: 19, nonces_data: () }; race_strategy @@ -687,7 +666,6 @@ mod tests { dispatch_weight: Weight::from_ref_time(idx), size: idx as _, reward: idx as _, - dispatch_fee_payment: DispatchFeePayment::AtSourceChain, }, ) }) @@ -978,83 +956,6 @@ mod tests { assert_eq!(strategy.required_source_header_at_target(&header_id(1)), Some(header_id(2))); } - #[async_std::test] - async fn rational_relayer_is_delivering_messages_if_cost_is_equal_to_reward() { - let (state, mut strategy) = prepare_strategy(); - strategy.relay_strategy = MixStrategy::new(RelayerMode::Rational); - - // so now we have: - // - 20..=23 with reward = cost - // => strategy shall select all 20..=23 - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=23), proof_parameters(false, 4))) - ); - } - - #[async_std::test] - async fn rational_relayer_is_not_delivering_messages_if_cost_is_larger_than_reward() { - let (mut state, mut strategy) = prepare_strategy(); - let nonces = source_nonces( - 24..=25, - 19, - DEFAULT_REWARD - BASE_MESSAGE_DELIVERY_TRANSACTION_COST, - DispatchFeePayment::AtSourceChain, - ); - strategy.strategy.source_nonces_updated(header_id(2), nonces); - state.best_finalized_source_header_id_at_best_target = Some(header_id(2)); - strategy.relay_strategy = MixStrategy::new(RelayerMode::Rational); - - // so now we have: - // - 20..=23 with reward = cost - // - 24..=25 with reward less than cost - // => strategy shall only select 20..=23 - assert_eq!( - strategy.select_nonces_to_deliver(state).await, - Some(((20..=23), proof_parameters(false, 4))) - ); - } - - #[async_std::test] - async fn rational_relayer_is_delivering_unpaid_messages() { - async fn test_with_dispatch_fee_payment( - dispatch_fee_payment: DispatchFeePayment, - ) -> Option<(RangeInclusive, MessageProofParameters)> { - let (mut state, mut strategy) = prepare_strategy(); - let nonces = source_nonces( - 24..=24, - 19, - DEFAULT_REWARD - DEFAULT_DISPATCH_WEIGHT.ref_time(), - dispatch_fee_payment, - ); - strategy.strategy.source_nonces_updated(header_id(2), nonces); - state.best_finalized_source_header_id_at_best_target = Some(header_id(2)); - strategy.max_unrewarded_relayer_entries_at_target = 100; - strategy.max_unconfirmed_nonces_at_target = 100; - strategy.max_messages_in_single_batch = 100; - strategy.max_messages_weight_in_single_batch = Weight::from_ref_time(100); - strategy.max_messages_size_in_single_batch = 100; - strategy.relay_strategy = MixStrategy::new(RelayerMode::Rational); - - // so now we have: - // - 20..=23 with reward = cost - // - 24..=24 with reward less than cost, but we're deducting `DEFAULT_DISPATCH_WEIGHT` - // from the cost, so it should be fine; - // => when MSG#24 fee is paid at the target chain, strategy shall select all 20..=24 - // => when MSG#25 fee is paid at the source chain, strategy shall only select 20..=23 - strategy.select_nonces_to_deliver(state).await - } - - assert_eq!( - test_with_dispatch_fee_payment(DispatchFeePayment::AtTargetChain).await, - Some(((20..=24), proof_parameters(false, 5))) - ); - assert_eq!( - test_with_dispatch_fee_payment(DispatchFeePayment::AtSourceChain).await, - Some(((20..=23), proof_parameters(false, 4))) - ); - } - #[async_std::test] async fn relayer_uses_flattened_view_of_the_source_queue_to_select_nonces() { // Real scenario that has happened on test deployments: @@ -1066,7 +967,7 @@ mod tests { // This was happening because selector (`select_nonces_for_delivery_transaction`) has been // called for every `source_queue` entry separately without preserving any context. let (mut state, mut strategy) = prepare_strategy(); - let nonces = source_nonces(24..=25, 19, DEFAULT_REWARD, DispatchFeePayment::AtSourceChain); + let nonces = source_nonces(24..=25, 19, 0); strategy.strategy.source_nonces_updated(header_id(2), nonces); strategy.max_unrewarded_relayer_entries_at_target = 100; strategy.max_unconfirmed_nonces_at_target = 100; diff --git a/bridges/relays/messages/src/relay_strategy/enforcement_strategy.rs b/bridges/relays/messages/src/message_race_limits.rs similarity index 56% rename from bridges/relays/messages/src/relay_strategy/enforcement_strategy.rs rename to bridges/relays/messages/src/message_race_limits.rs index 59e1b445bdcd5..a28d9ba63da96 100644 --- a/bridges/relays/messages/src/relay_strategy/enforcement_strategy.rs +++ b/bridges/relays/messages/src/message_race_limits.rs @@ -17,43 +17,88 @@ //! enforcement strategy use num_traits::Zero; +use std::ops::Range; use bp_messages::{MessageNonce, Weight}; -use bp_runtime::messages::DispatchFeePayment; use crate::{ message_lane::MessageLane, message_lane_loop::{ - MessageDetails, SourceClient as MessageLaneSourceClient, + MessageDetails, MessageDetailsMap, SourceClient as MessageLaneSourceClient, TargetClient as MessageLaneTargetClient, }, message_race_loop::NoncesRange, - relay_strategy::{RelayMessagesBatchReference, RelayReference, RelayStrategy}, + message_race_strategy::SourceRangesQueue, + metrics::MessageLaneLoopMetrics, }; -/// Do hard check and run soft check strategy -#[derive(Clone)] -pub struct EnforcementStrategy { - strategy: Strategy, +/// Reference data for participating in relay +pub struct RelayReference< + P: MessageLane, + SourceClient: MessageLaneSourceClient

, + TargetClient: MessageLaneTargetClient

, +> { + /// The client that is connected to the message lane source node. + pub lane_source_client: SourceClient, + /// The client that is connected to the message lane target node. + pub lane_target_client: TargetClient, + /// Metrics reference. + pub metrics: Option, + /// Messages size summary + pub selected_size: u32, + + /// Hard check begin nonce + pub hard_selected_begin_nonce: MessageNonce, + + /// Index by all ready nonces + pub index: usize, + /// Current nonce + pub nonce: MessageNonce, + /// Current nonce details + pub details: MessageDetails, } -impl EnforcementStrategy { - pub fn new(strategy: Strategy) -> Self { - Self { strategy } - } +/// Relay reference data +pub struct RelayMessagesBatchReference< + P: MessageLane, + SourceClient: MessageLaneSourceClient

, + TargetClient: MessageLaneTargetClient

, +> { + /// Maximal number of relayed messages in single delivery transaction. + pub max_messages_in_this_batch: MessageNonce, + /// Maximal cumulative dispatch weight of relayed messages in single delivery transaction. + pub max_messages_weight_in_single_batch: Weight, + /// Maximal cumulative size of relayed messages in single delivery transaction. + pub max_messages_size_in_single_batch: u32, + /// The client that is connected to the message lane source node. + pub lane_source_client: SourceClient, + /// The client that is connected to the message lane target node. + pub lane_target_client: TargetClient, + /// Metrics reference. + pub metrics: Option, + /// Source queue. + pub nonces_queue: SourceRangesQueue< + P::SourceHeaderHash, + P::SourceHeaderNumber, + MessageDetailsMap, + >, + /// Source queue range + pub nonces_queue_range: Range, } -impl EnforcementStrategy { +/// Limits of the message race transactions. +#[derive(Clone)] +pub struct MessageRaceLimits; + +impl MessageRaceLimits { pub async fn decide< P: MessageLane, SourceClient: MessageLaneSourceClient

, TargetClient: MessageLaneTargetClient

, >( - &mut self, reference: RelayMessagesBatchReference, ) -> Option { let mut hard_selected_count = 0; - let mut soft_selected_count = 0; let mut selected_weight = Weight::zero(); let mut selected_count: MessageNonce = 0; @@ -67,17 +112,9 @@ impl EnforcementStrategy { lane_target_client: reference.lane_target_client.clone(), metrics: reference.metrics.clone(), - selected_reward: P::SourceChainBalance::zero(), - selected_cost: P::SourceChainBalance::zero(), selected_size: 0, - total_reward: P::SourceChainBalance::zero(), - total_confirmations_cost: P::SourceChainBalance::zero(), - total_cost: P::SourceChainBalance::zero(), - hard_selected_begin_nonce, - selected_prepaid_nonces: 0, - selected_unpaid_weight: Weight::zero(), index: 0, nonce: 0, @@ -85,7 +122,6 @@ impl EnforcementStrategy { dispatch_weight: Weight::zero(), size: 0, reward: P::SourceChainBalance::zero(), - dispatch_fee_payment: DispatchFeePayment::AtSourceChain, }, }; @@ -148,74 +184,14 @@ impl EnforcementStrategy { } relay_reference.selected_size = new_selected_size; - // If dispatch fee has been paid at the source chain, it means that it is **relayer** - // who's paying for dispatch at the target chain AND reward must cover this dispatch - // fee. - // - // If dispatch fee is paid at the target chain, it means that it'll be withdrawn from - // the dispatch origin account AND reward is not covering this fee. - // - // So in the latter case we're not adding the dispatch weight to the delivery - // transaction weight. - let mut new_selected_prepaid_nonces = relay_reference.selected_prepaid_nonces; - let new_selected_unpaid_weight = match details.dispatch_fee_payment { - DispatchFeePayment::AtSourceChain => { - new_selected_prepaid_nonces += 1; - relay_reference.selected_unpaid_weight.saturating_add(details.dispatch_weight) - }, - DispatchFeePayment::AtTargetChain => relay_reference.selected_unpaid_weight, - }; - relay_reference.selected_prepaid_nonces = new_selected_prepaid_nonces; - relay_reference.selected_unpaid_weight = new_selected_unpaid_weight; - - // now the message has passed all 'strong' checks, and we CAN deliver it. But do we WANT - // to deliver it? It depends on the relayer strategy. - if self.strategy.decide(&mut relay_reference).await { - soft_selected_count = index + 1; - } - hard_selected_count = index + 1; selected_weight = new_selected_weight; selected_count = new_selected_count; } - if hard_selected_count != soft_selected_count { - let hard_selected_end_nonce = - hard_selected_begin_nonce + hard_selected_count as MessageNonce - 1; - let soft_selected_begin_nonce = hard_selected_begin_nonce; - let soft_selected_end_nonce = - soft_selected_begin_nonce + soft_selected_count as MessageNonce - 1; - log::warn!( - target: "bridge", - "Relayer may deliver nonces [{:?}; {:?}], but because of its strategy it has selected \ - nonces [{:?}; {:?}].", - hard_selected_begin_nonce, - hard_selected_end_nonce, - soft_selected_begin_nonce, - soft_selected_end_nonce, - ); - - hard_selected_count = soft_selected_count; - } - if hard_selected_count != 0 { - if relay_reference.selected_reward != P::SourceChainBalance::zero() && - relay_reference.selected_cost != P::SourceChainBalance::zero() - { - log::trace!( - target: "bridge", - "Expected reward from delivering nonces [{:?}; {:?}] is: {:?} - {:?} = {:?}", - hard_selected_begin_nonce, - hard_selected_begin_nonce + hard_selected_count as MessageNonce - 1, - &relay_reference.selected_reward, - &relay_reference.selected_cost, - relay_reference.selected_reward - relay_reference.selected_cost, - ); - } - let selected_max_nonce = hard_selected_begin_nonce + hard_selected_count as MessageNonce - 1; - self.strategy.on_final_decision(&relay_reference); Some(selected_max_nonce) } else { None diff --git a/bridges/relays/messages/src/metrics.rs b/bridges/relays/messages/src/metrics.rs index f5cc8831c0286..4decb7e092e71 100644 --- a/bridges/relays/messages/src/metrics.rs +++ b/bridges/relays/messages/src/metrics.rs @@ -24,7 +24,7 @@ use crate::{ use bp_messages::MessageNonce; use finality_relay::SyncLoopMetrics; use relay_utils::metrics::{ - metric_name, register, Counter, GaugeVec, Metric, Opts, PrometheusError, Registry, U64, + metric_name, register, GaugeVec, Metric, Opts, PrometheusError, Registry, U64, }; /// Message lane relay metrics. @@ -39,17 +39,11 @@ pub struct MessageLaneLoopMetrics { /// Lane state nonces: "source_latest_generated", "source_latest_confirmed", /// "target_latest_received", "target_latest_confirmed". lane_state_nonces: GaugeVec, - /// Count of unprofitable message delivery transactions that we have submitted so far. - unprofitable_delivery_transactions: Counter, } impl MessageLaneLoopMetrics { /// Create and register messages loop metrics. - pub fn new( - prefix: Option<&str>, - source_name: &str, - target_name: &str, - ) -> Result { + pub fn new(prefix: Option<&str>) -> Result { Ok(MessageLaneLoopMetrics { source_to_target_finality_metrics: SyncLoopMetrics::new( prefix, @@ -65,13 +59,6 @@ impl MessageLaneLoopMetrics { Opts::new(metric_name(prefix, "lane_state_nonces"), "Nonces of the lane state"), &["type"], )?, - unprofitable_delivery_transactions: Counter::new( - metric_name(prefix, "unprofitable_delivery_transactions"), - format!( - "Count of unprofitable message delivery transactions from {} to {}", - source_name, target_name - ), - )?, }) } @@ -140,11 +127,6 @@ impl MessageLaneLoopMetrics { .with_label_values(&["target_latest_confirmed"]) .set(target_latest_confirmed_nonce); } - - /// Note unprofitable delivery transaction. - pub fn note_unprofitable_delivery_transactions(&self) { - self.unprofitable_delivery_transactions.inc() - } } impl Metric for MessageLaneLoopMetrics { @@ -152,7 +134,6 @@ impl Metric for MessageLaneLoopMetrics { self.source_to_target_finality_metrics.register(registry)?; self.target_to_source_finality_metrics.register(registry)?; register(self.lane_state_nonces.clone(), registry)?; - register(self.unprofitable_delivery_transactions.clone(), registry)?; Ok(()) } } diff --git a/bridges/relays/messages/src/relay_strategy/altruistic_strategy.rs b/bridges/relays/messages/src/relay_strategy/altruistic_strategy.rs deleted file mode 100644 index 7e00678e1317f..0000000000000 --- a/bridges/relays/messages/src/relay_strategy/altruistic_strategy.rs +++ /dev/null @@ -1,81 +0,0 @@ -// 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 . - -//! Altruistic relay strategy - -use async_trait::async_trait; - -use crate::{ - message_lane::MessageLane, - message_lane_loop::{ - SourceClient as MessageLaneSourceClient, TargetClient as MessageLaneTargetClient, - }, - relay_strategy::{RelayReference, RelayStrategy}, -}; - -/// The relayer doesn't care about rewards. -#[derive(Clone)] -pub struct AltruisticStrategy; - -#[async_trait] -impl RelayStrategy for AltruisticStrategy { - async fn decide< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - >( - &mut self, - reference: &mut RelayReference, - ) -> bool { - // We don't care about costs and rewards, but we want to report unprofitable transactions. - if let Err(e) = reference.update_cost_and_reward().await { - log::debug!( - target: "bridge", - "Failed to update transaction cost and reward: {:?}. \ - The `unprofitable_delivery_transactions` metric will be inaccurate", - e, - ); - } - - true - } - - fn on_final_decision< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - >( - &self, - reference: &RelayReference, - ) { - if let Some(ref metrics) = reference.metrics { - if !reference.is_profitable() { - log::debug!( - target: "bridge", - "The relayer has submitted unprofitable {} -> {} message delivery transaction \ - with {} messages: total cost = {:?}, total reward = {:?}", - P::SOURCE_NAME, - P::TARGET_NAME, - reference.index + 1, - reference.total_cost, - reference.total_reward, - ); - - metrics.note_unprofitable_delivery_transactions(); - } - } - } -} diff --git a/bridges/relays/messages/src/relay_strategy/mix_strategy.rs b/bridges/relays/messages/src/relay_strategy/mix_strategy.rs deleted file mode 100644 index 331f77b012d22..0000000000000 --- a/bridges/relays/messages/src/relay_strategy/mix_strategy.rs +++ /dev/null @@ -1,72 +0,0 @@ -// 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 . - -//! Adapter for using `enum RelayerMode` in a context which requires `RelayStrategy`. - -use async_trait::async_trait; - -use crate::{ - message_lane::MessageLane, - message_lane_loop::{ - RelayerMode, SourceClient as MessageLaneSourceClient, - TargetClient as MessageLaneTargetClient, - }, - relay_strategy::{AltruisticStrategy, RationalStrategy, RelayReference, RelayStrategy}, -}; - -/// `RelayerMode` adapter. -#[derive(Clone)] -pub struct MixStrategy { - relayer_mode: RelayerMode, -} - -impl MixStrategy { - /// Create mix strategy instance - pub fn new(relayer_mode: RelayerMode) -> Self { - Self { relayer_mode } - } -} - -#[async_trait] -impl RelayStrategy for MixStrategy { - async fn decide< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - >( - &mut self, - reference: &mut RelayReference, - ) -> bool { - match self.relayer_mode { - RelayerMode::Altruistic => AltruisticStrategy.decide(reference).await, - RelayerMode::Rational => RationalStrategy.decide(reference).await, - } - } - - fn on_final_decision< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - >( - &self, - reference: &RelayReference, - ) { - match self.relayer_mode { - RelayerMode::Altruistic => AltruisticStrategy.on_final_decision(reference), - RelayerMode::Rational => RationalStrategy.on_final_decision(reference), - } - } -} diff --git a/bridges/relays/messages/src/relay_strategy/mod.rs b/bridges/relays/messages/src/relay_strategy/mod.rs deleted file mode 100644 index aa28e63582fd7..0000000000000 --- a/bridges/relays/messages/src/relay_strategy/mod.rs +++ /dev/null @@ -1,224 +0,0 @@ -// 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 . - -//! Relayer strategy - -use async_trait::async_trait; -use bp_messages::{MessageNonce, Weight}; -use sp_arithmetic::traits::Saturating; -use std::ops::Range; - -use crate::{ - message_lane::MessageLane, - message_lane_loop::{ - MessageDetails, MessageDetailsMap, SourceClient as MessageLaneSourceClient, - TargetClient as MessageLaneTargetClient, - }, - message_race_strategy::SourceRangesQueue, - metrics::MessageLaneLoopMetrics, -}; - -pub(crate) use self::enforcement_strategy::*; -pub use self::{altruistic_strategy::*, mix_strategy::*, rational_strategy::*}; - -mod altruistic_strategy; -mod enforcement_strategy; -mod mix_strategy; -mod rational_strategy; - -/// Relayer strategy trait -#[async_trait] -pub trait RelayStrategy: 'static + Clone + Send + Sync { - /// The relayer decide how to process nonce by reference. - /// From given set of source nonces, that are ready to be delivered, select nonces - /// to fit into single delivery transaction. - /// - /// The function returns last nonce that must be delivered to the target chain. - async fn decide< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - >( - &mut self, - reference: &mut RelayReference, - ) -> bool; - - /// Notification that the following maximal nonce has been selected for the delivery. - fn on_final_decision< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - >( - &self, - reference: &RelayReference, - ); -} - -/// Total cost of mesage delivery and confirmation. -struct MessagesDeliveryCost { - /// Cost of message delivery transaction. - pub delivery_transaction_cost: SourceChainBalance, - /// Cost of confirmation delivery transaction. - pub confirmation_transaction_cost: SourceChainBalance, -} - -/// Reference data for participating in relay -pub struct RelayReference< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, -> { - /// The client that is connected to the message lane source node. - pub lane_source_client: SourceClient, - /// The client that is connected to the message lane target node. - pub lane_target_client: TargetClient, - /// Metrics reference. - pub metrics: Option, - /// Current block reward summary - pub selected_reward: P::SourceChainBalance, - /// Current block cost summary - pub selected_cost: P::SourceChainBalance, - /// Messages size summary - pub selected_size: u32, - - /// Current block reward summary - pub total_reward: P::SourceChainBalance, - /// All confirmations cost - pub total_confirmations_cost: P::SourceChainBalance, - /// Current block cost summary - pub total_cost: P::SourceChainBalance, - - /// Hard check begin nonce - pub hard_selected_begin_nonce: MessageNonce, - /// Count prepaid nonces - pub selected_prepaid_nonces: MessageNonce, - /// Unpaid nonces weight summary - pub selected_unpaid_weight: Weight, - - /// Index by all ready nonces - pub index: usize, - /// Current nonce - pub nonce: MessageNonce, - /// Current nonce details - pub details: MessageDetails, -} - -impl< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - > RelayReference -{ - /// Returns whether the current `RelayReference` is profitable. - pub fn is_profitable(&self) -> bool { - self.total_reward >= self.total_cost - } - - async fn estimate_messages_delivery_cost( - &self, - ) -> Result, TargetClient::Error> { - // technically, multiple confirmations will be delivered in a single transaction, - // meaning less loses for relayer. But here we don't know the final relayer yet, so - // we're adding a separate transaction for every message. Normally, this cost is covered - // by the message sender. Probably reconsider this? - let confirmation_transaction_cost = - self.lane_source_client.estimate_confirmation_transaction().await; - - let delivery_transaction_cost = self - .lane_target_client - .estimate_delivery_transaction_in_source_tokens( - self.hard_selected_begin_nonce..= - (self.hard_selected_begin_nonce + self.index as MessageNonce), - self.selected_prepaid_nonces, - self.selected_unpaid_weight, - self.selected_size, - ) - .await?; - - Ok(MessagesDeliveryCost { confirmation_transaction_cost, delivery_transaction_cost }) - } - - async fn update_cost_and_reward(&mut self) -> Result<(), TargetClient::Error> { - let prev_is_profitable = self.is_profitable(); - let prev_total_cost = self.total_cost; - let prev_total_reward = self.total_reward; - - let MessagesDeliveryCost { confirmation_transaction_cost, delivery_transaction_cost } = - self.estimate_messages_delivery_cost().await?; - self.total_confirmations_cost = - self.total_confirmations_cost.saturating_add(confirmation_transaction_cost); - self.total_reward = self.total_reward.saturating_add(self.details.reward); - self.total_cost = self.total_confirmations_cost.saturating_add(delivery_transaction_cost); - - if prev_is_profitable && !self.is_profitable() { - // if it is the first message that makes reward less than cost, let's log it - log::debug!( - target: "bridge", - "Message with nonce {} (reward = {:?}) changes total cost {:?}->{:?} and makes it larger than \ - total reward {:?}->{:?}", - self.nonce, - self.details.reward, - prev_total_cost, - self.total_cost, - prev_total_reward, - self.total_reward, - ); - } else if !prev_is_profitable && self.is_profitable() { - // if this message makes batch profitable again, let's log it - log::debug!( - target: "bridge", - "Message with nonce {} (reward = {:?}) changes total cost {:?}->{:?} and makes it less than or \ - equal to the total reward {:?}->{:?} (again)", - self.nonce, - self.details.reward, - prev_total_cost, - self.total_cost, - prev_total_reward, - self.total_reward, - ); - } - - Ok(()) - } -} - -/// Relay reference data -pub struct RelayMessagesBatchReference< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, -> { - /// Maximal number of relayed messages in single delivery transaction. - pub max_messages_in_this_batch: MessageNonce, - /// Maximal cumulative dispatch weight of relayed messages in single delivery transaction. - pub max_messages_weight_in_single_batch: Weight, - /// Maximal cumulative size of relayed messages in single delivery transaction. - pub max_messages_size_in_single_batch: u32, - /// The client that is connected to the message lane source node. - pub lane_source_client: SourceClient, - /// The client that is connected to the message lane target node. - pub lane_target_client: TargetClient, - /// Metrics reference. - pub metrics: Option, - /// Source queue. - pub nonces_queue: SourceRangesQueue< - P::SourceHeaderHash, - P::SourceHeaderNumber, - MessageDetailsMap, - >, - /// Source queue range - pub nonces_queue_range: Range, -} diff --git a/bridges/relays/messages/src/relay_strategy/rational_strategy.rs b/bridges/relays/messages/src/relay_strategy/rational_strategy.rs deleted file mode 100644 index 1791670fa45a8..0000000000000 --- a/bridges/relays/messages/src/relay_strategy/rational_strategy.rs +++ /dev/null @@ -1,75 +0,0 @@ -// 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 . - -//! Rational relay strategy - -use async_trait::async_trait; - -use crate::{ - message_lane::MessageLane, - message_lane_loop::{ - SourceClient as MessageLaneSourceClient, TargetClient as MessageLaneTargetClient, - }, - relay_strategy::{RelayReference, RelayStrategy}, -}; - -/// The relayer will deliver all messages and confirmations as long as he's not losing any -/// funds. -#[derive(Clone)] -pub struct RationalStrategy; - -#[async_trait] -impl RelayStrategy for RationalStrategy { - async fn decide< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - >( - &mut self, - reference: &mut RelayReference, - ) -> bool { - if let Err(e) = reference.update_cost_and_reward().await { - log::debug!( - target: "bridge", - "Failed to update transaction cost and reward: {:?}. No nonces selected for delivery", - e, - ); - - return false - } - - // Rational relayer never wants to lose his funds. - if reference.is_profitable() { - reference.selected_reward = reference.total_reward; - reference.selected_cost = reference.total_cost; - return true - } - - false - } - - fn on_final_decision< - P: MessageLane, - SourceClient: MessageLaneSourceClient

, - TargetClient: MessageLaneTargetClient

, - >( - &self, - _reference: &RelayReference, - ) { - // rational relayer would never submit unprofitable transactions, so we don't need to do - // anything here - } -}