From 8fc636ab761e74267eccfcdc73f4c0432ba79ea8 Mon Sep 17 00:00:00 2001 From: Guantong Date: Sun, 23 Apr 2023 10:45:02 +0800 Subject: [PATCH] Companion for paritytech/parity-bridges-common#1652 --- modules/messages/src/lib.rs | 47 ++++++++++++++--------- modules/messages/src/mock.rs | 51 +++++++++++++++++++------ modules/relayers/src/payment_adapter.rs | 35 +---------------- primitives/messages/src/lib.rs | 8 ++-- primitives/messages/src/source_chain.rs | 44 +-------------------- primitives/messages/src/target_chain.rs | 35 ++++++++++++++++- 6 files changed, 108 insertions(+), 112 deletions(-) diff --git a/modules/messages/src/lib.rs b/modules/messages/src/lib.rs index ca9fef25..fdcb0431 100644 --- a/modules/messages/src/lib.rs +++ b/modules/messages/src/lib.rs @@ -67,11 +67,11 @@ use crate::{ }; use bp_messages::{ source_chain::{ - LaneMessageVerifier, MessageDeliveryAndDispatchPayment, RelayersRewards, - SendMessageArtifacts, TargetHeaderChain, + DeliveryConfirmationPayments, LaneMessageVerifier, SendMessageArtifacts, TargetHeaderChain, }, target_chain::{ - DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain, + DeliveryPayments, DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, + SourceHeaderChain, }, total_unrewarded_messages, DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId, MessageKey, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData, @@ -145,6 +145,8 @@ pub mod pallet { /// Identifier of relayer that deliver messages to this chain. Relayer reward is paid on the /// bridged chain. type InboundRelayer: Parameter + MaxEncodedLen; + /// Delivery payments. + type DeliveryPayments: DeliveryPayments; /// A type which can be turned into an AccountId from a 256-bit hash. /// @@ -157,11 +159,8 @@ pub mod pallet { type TargetHeaderChain: TargetHeaderChain; /// Message payload verifier. type LaneMessageVerifier: LaneMessageVerifier; - /// Message delivery payment. - type MessageDeliveryAndDispatchPayment: MessageDeliveryAndDispatchPayment< - Self::RuntimeOrigin, - Self::AccountId, - >; + /// Delivery confirmation payments. + type DeliveryConfirmationPayments: DeliveryConfirmationPayments; // Types that are used by inbound_lane (on target chain). @@ -391,9 +390,17 @@ pub mod pallet { messages_received_status.push(lane_messages_received_status); } + // let's now deal with relayer payments + T::DeliveryPayments::pay_reward( + relayer_id_at_this_chain, + total_messages, + valid_messages, + actual_weight, + ); + log::debug!( target: LOG_TARGET, - "Received messages: total={}, valid={}. Weight used: {}/{}", + "Received messages: total={}, valid={}. Weight used: {}/{}.", total_messages, valid_messages, actual_weight, @@ -402,7 +409,7 @@ pub mod pallet { Self::deposit_event(Event::MessagesReceived(messages_received_status)); - Ok(PostDispatchInfo { actual_weight: Some(actual_weight), pays_fee: Pays::Yes }) + Ok(PostDispatchInfo { actual_weight: Some(actual_weight), pays_fee: Pays::No }) } /// Receive messages delivery proof from bridged chain. @@ -490,7 +497,7 @@ pub mod pallet { }); // if some new messages have been confirmed, reward relayers - >::MessageDeliveryAndDispatchPayment::pay_relayers_rewards( + T::DeliveryConfirmationPayments::pay_reward( lane_id, lane_data.relayers, &confirmation_relayer, @@ -899,10 +906,10 @@ mod tests { use super::*; use crate::mock::{ message, message_payload, run_test, unrewarded_relayer, DbWeight, - RuntimeEvent as TestEvent, RuntimeOrigin, TestMessageDeliveryAndDispatchPayment, - TestMessagesDeliveryProof, TestMessagesProof, TestRuntime, MAX_OUTBOUND_PAYLOAD_SIZE, - PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_LANE_ID_2, - TEST_LANE_ID_3, TEST_RELAYER_A, TEST_RELAYER_B, + RuntimeEvent as TestEvent, RuntimeOrigin, TestDeliveryConfirmationPayments, + TestDeliveryPayments, TestMessagesDeliveryProof, TestMessagesProof, TestRuntime, + MAX_OUTBOUND_PAYLOAD_SIZE, PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID, + TEST_LANE_ID_2, TEST_LANE_ID_3, TEST_RELAYER_A, TEST_RELAYER_B, }; use bp_messages::{UnrewardedRelayer, UnrewardedRelayersState}; use bp_test_utils::generate_owned_bridge_module_tests; @@ -1165,6 +1172,8 @@ mod tests { )); assert_eq!(InboundLanes::::get(TEST_LANE_ID).0.last_delivered_nonce(), 1); + + assert!(TestDeliveryPayments::is_reward_paid(1)); }); } @@ -1326,8 +1335,8 @@ mod tests { ..Default::default() }, )); - assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_A, 1)); - assert!(!TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_B, 1)); + assert!(TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_A, 1)); + assert!(!TestDeliveryConfirmationPayments::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 @@ -1352,8 +1361,8 @@ mod tests { ..Default::default() }, )); - assert!(!TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_A, 1)); - assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_B, 1)); + assert!(!TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_A, 1)); + assert!(TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_B, 1)); }); } diff --git a/modules/messages/src/mock.rs b/modules/messages/src/mock.rs index 3795e8ba..1f131863 100644 --- a/modules/messages/src/mock.rs +++ b/modules/messages/src/mock.rs @@ -29,10 +29,10 @@ use scale_info::TypeInfo; use crate as pallet_bridge_messages; use crate::*; use bp_messages::{ - source_chain::{LaneMessageVerifier, MessageDeliveryAndDispatchPayment, TargetHeaderChain}, + source_chain::{DeliveryConfirmationPayments, LaneMessageVerifier, TargetHeaderChain}, target_chain::{ - DispatchMessage, DispatchMessageData, MessageDispatch, ProvedLaneMessages, ProvedMessages, - SourceHeaderChain, + DeliveryPayments, DispatchMessage, DispatchMessageData, MessageDispatch, + ProvedLaneMessages, ProvedMessages, SourceHeaderChain, }, DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, UnrewardedRelayer, @@ -190,12 +190,14 @@ impl Config for TestRuntime { type BridgedChainId = TestBridgedChainId; type InboundPayload = TestPayload; type InboundRelayer = TestRelayer; + type DeliveryPayments = TestDeliveryPayments; type LaneMessageVerifier = TestLaneMessageVerifier; type ActiveOutboundLanes = ActiveOutboundLanes; type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; type MaximalOutboundPayloadSize = frame_support::traits::ConstU32; type MessageDeliveryAndDispatchPayment = TestMessageDeliveryAndDispatchPayment; + type DeliveryConfirmationPayments = TestDeliveryConfirmationPayments; type MessageDispatch = TestMessageDispatch; type OutboundPayload = TestPayload; type RuntimeEvent = RuntimeEvent; @@ -286,10 +288,37 @@ impl LaneMessageVerifier for TestLaneMessageVerifier } } -/// Message fee payment system that is used in tests. +/// Reward payments at the target chain during delivery transaction. #[derive(Debug, Default)] -pub struct TestMessageDeliveryAndDispatchPayment; -impl TestMessageDeliveryAndDispatchPayment { +pub struct TestDeliveryPayments; +impl TestDeliveryPayments { + /// 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) -> bool { + let key = (b":delivery-relayer-reward:", relayer).encode(); + frame_support::storage::unhashed::take::(&key).is_some() + } +} + +impl DeliveryPayments for TestDeliveryPayments { + type Error = &'static str; + + fn pay_reward( + relayer: AccountId, + _total_messages: MessageNonce, + _valid_messages: MessageNonce, + _actual_weight: Weight, + ) { + let key = (b":delivery-relayer-reward:", relayer).encode(); + frame_support::storage::unhashed::put(&key, &true); + } +} + +/// Reward payments at the source chain during delivery confirmation transaction. +#[derive(Debug, Default)] +pub struct TestDeliveryConfirmationPayments; + +impl TestDeliveryConfirmationPayments { /// 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 { @@ -297,14 +326,12 @@ impl TestMessageDeliveryAndDispatchPayment { frame_support::storage::unhashed::take::(&key).is_some() } } -impl MessageDeliveryAndDispatchPayment - for TestMessageDeliveryAndDispatchPayment -{ +impl DeliveryConfirmationPayments for TestDeliveryConfirmationPayments { type Error = &'static str; - fn pay_relayers_rewards( + fn pay_reward( _lane_id: LaneId, - message_relayers: VecDeque>, + messages_relayers: VecDeque>, _confirmation_relayer: &AccountId, received_range: &RangeInclusive, _relayer_fund_account: &AccountId, @@ -321,7 +348,7 @@ impl MessageDeliveryAndDispatchPayment messages: MessageNonce, } - let relayers_rewards = calc_relayers_rewards(message_relayers, received_range); + let relayers_rewards = calc_relayers_rewards(messages_relayers, received_range); for (relayer, reward) in &relayers_rewards { let key = (b":relayer-reward:", relayer, reward).encode(); frame_support::storage::unhashed::put(&key, &true); diff --git a/modules/relayers/src/payment_adapter.rs b/modules/relayers/src/payment_adapter.rs index e2d47841..75f5c865 100644 --- a/modules/relayers/src/payment_adapter.rs +++ b/modules/relayers/src/payment_adapter.rs @@ -14,14 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -//! Code that allows relayers pallet to be used as a delivery+dispatch payment mechanism -//! for the messages pallet. +//! Code that allows relayers pallet to be used as a payment mechanism for the messages pallet. use crate::{Config, Pallet}; -use bp_messages::source_chain::{ - DeliveryConfirmationPayments, MessageDeliveryAndDispatchPayment, RelayersRewards, -}; +use bp_messages::source_chain::{DeliveryConfirmationPayments, RelayersRewards}; use frame_support::{sp_runtime::SaturatedConversion, traits::Get}; use sp_arithmetic::traits::{Saturating, UniqueSaturatedFrom, Zero}; use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData, ops::RangeInclusive}; @@ -32,34 +29,6 @@ pub struct DeliveryConfirmationPaymentsAdapter, ); -// TODO (https://github.com/paritytech/parity-bridges-common/pull/1652): this impl must be removed -impl - MessageDeliveryAndDispatchPayment - for DeliveryConfirmationPaymentsAdapter -where - T: Config, -{ - type Error = &'static str; - - fn pay_relayers_rewards( - lane_id: bp_messages::LaneId, - messages_relayers: VecDeque>, - confirmation_relayer: &T::AccountId, - received_range: &RangeInclusive, - ) { - let relayers_rewards = - bp_messages::calc_relayers_rewards::(messages_relayers, received_range); - - register_relayers_rewards::( - confirmation_relayer, - relayers_rewards, - lane_id, - 100_000_u32.into(), - 10_000_u32.into(), - ); - } -} - impl DeliveryConfirmationPayments for DeliveryConfirmationPaymentsAdapter where diff --git a/primitives/messages/src/lib.rs b/primitives/messages/src/lib.rs index fb826800..1202c037 100644 --- a/primitives/messages/src/lib.rs +++ b/primitives/messages/src/lib.rs @@ -29,6 +29,7 @@ use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; // darwinia-network use bp_runtime::{BasicOperatingMode, OperatingMode}; +use source_chain::RelayersRewards; // paritytech use frame_support::RuntimeDebug; use sp_std::{collections::vec_deque::VecDeque, ops::RangeInclusive, prelude::*}; @@ -350,19 +351,16 @@ pub fn total_unrewarded_messages( pub fn calc_relayers_rewards( messages_relayers: VecDeque>, received_range: &RangeInclusive, -) -> source_chain::RelayersRewards +) -> RelayersRewards where AccountId: sp_std::cmp::Ord, { // remember to reward relayers that have delivered messages // this loop is bounded by `T::MaxUnrewardedRelayerEntriesAtInboundLane` on the bridged chain - let mut relayers_rewards = source_chain::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 if nonce_end >= nonce_begin { *relayers_rewards.entry(entry.relayer).or_default() += nonce_end - nonce_begin + 1; } diff --git a/primitives/messages/src/source_chain.rs b/primitives/messages/src/source_chain.rs index 76ed2763..c842983d 100644 --- a/primitives/messages/src/source_chain.rs +++ b/primitives/messages/src/source_chain.rs @@ -90,44 +90,6 @@ pub trait LaneMessageVerifier { ) -> Result<(), Self::Error>; } -/// Message delivery payment. It is called as a part of submit-message transaction. Transaction -/// submitter is paying (in source chain tokens/assets) for: -/// -/// 1) submit-message-transaction-fee itself. This fee is not included in the -/// `delivery_and_dispatch_fee` and is withheld by the regular transaction payment mechanism; -/// 2) message-delivery-transaction-fee. It is submitted to the target node by relayer; -/// 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. -pub trait MessageDeliveryAndDispatchPayment { - /// Error type. - type Error: Debug + Into<&'static str>; - - /// Pay rewards for delivering messages to the given relayers. - /// - /// The implementation may also choose to pay reward to the `confirmation_relayer`, which is - /// a relayer that has submitted delivery confirmation transaction. - fn pay_relayers_rewards( - lane_id: LaneId, - messages_relayers: VecDeque>, - confirmation_relayer: &AccountId, - received_range: &RangeInclusive, - relayer_fund_account: &AccountId, - ); -} -impl MessageDeliveryAndDispatchPayment for () { - type Error = &'static str; - - fn pay_relayers_rewards( - _lane_id: LaneId, - _messages_relayers: VecDeque>, - _confirmation_relayer: &AccountId, - _received_range: &RangeInclusive, - _relayer_fund_account: &AccountId, - ) { - } -} - /// Manages payments that are happening at the source chain during delivery confirmation /// transaction. pub trait DeliveryConfirmationPayments { @@ -228,12 +190,10 @@ impl LaneMessageVerifier for Forbi Err(ALL_OUTBOUND_MESSAGES_REJECTED) } } -impl MessageDeliveryAndDispatchPayment - for ForbidOutboundMessages -{ +impl DeliveryConfirmationPayments for ForbidOutboundMessages { type Error = &'static str; - fn pay_relayers_rewards( + fn pay_reward( _lane_id: LaneId, _messages_relayers: VecDeque>, _confirmation_relayer: &AccountId, diff --git a/primitives/messages/src/target_chain.rs b/primitives/messages/src/target_chain.rs index 9f13ac2b..269ea662 100644 --- a/primitives/messages/src/target_chain.rs +++ b/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, MessageKey, MessagePayload, OutboundLaneData}; +use crate::{LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData}; use bp_runtime::{messages::MessageDispatchResult, Size}; use codec::{Decode, Encode, Error as CodecError}; @@ -108,6 +108,26 @@ pub struct ProvedLaneMessages { /// Messages sent through this lane. pub messages: Vec, } + +/// Manages payments that are happening at the target chain during message delivery transaction. +pub trait DeliveryPayments { + /// Error type. + type Error: Debug + Into<&'static str>; + + /// Pay rewards for delivering messages to the given relayer. + /// + /// This method is called during message delivery transaction which has been submitted + /// by the `relayer`. The transaction brings `total_messages` messages but only + /// `valid_messages` have been accepted. The post-dispatch transaction weight is the + /// `actual_weight`. + fn pay_reward( + relayer: AccountId, + total_messages: MessageNonce, + valid_messages: MessageNonce, + actual_weight: Weight, + ); +} + impl Default for ProvedLaneMessages { fn default() -> Self { ProvedLaneMessages { lane_state: None, messages: Vec::new() } @@ -140,6 +160,19 @@ impl From for DispatchMessage } } +impl DeliveryPayments for () { + type Error = &'static str; + + fn pay_reward( + _relayer: AccountId, + _total_messages: MessageNonce, + _valid_messages: MessageNonce, + _actual_weight: Weight, + ) { + // this implementation is not rewarding relayer at all + } +} + /// Structure that may be used in place of `SourceHeaderChain` and `MessageDispatch` on chains, /// where inbound messages are forbidden. pub struct ForbidInboundMessages;