Skip to content

Commit

Permalink
DeliveryConfirmationPayments trait for paying relayer rewards at the …
Browse files Browse the repository at this point in the history
…source chain (paritytech#1653)

* DeliveryConfirmationPayments

* ref proper PR in TODO
  • Loading branch information
svyatonik authored and serban300 committed Apr 10, 2024
1 parent 3611293 commit f04c67d
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 93 deletions.
10 changes: 6 additions & 4 deletions bridges/bin/millau/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,9 +475,10 @@ impl pallet_bridge_messages::Config<WithRialtoMessagesInstance> for Runtime {
type TargetHeaderChain = crate::rialto_messages::Rialto;
type LaneMessageVerifier = crate::rialto_messages::ToRialtoMessageVerifier;
type MessageDeliveryAndDispatchPayment =
pallet_bridge_relayers::MessageDeliveryAndDispatchPaymentAdapter<
pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
Runtime,
WithRialtoMessagesInstance,
frame_support::traits::ConstU64<100_000>,
frame_support::traits::ConstU64<100_000>,
>;

type SourceHeaderChain = crate::rialto_messages::Rialto;
Expand Down Expand Up @@ -505,9 +506,10 @@ impl pallet_bridge_messages::Config<WithRialtoParachainMessagesInstance> for Run
type TargetHeaderChain = crate::rialto_parachain_messages::RialtoParachain;
type LaneMessageVerifier = crate::rialto_parachain_messages::ToRialtoParachainMessageVerifier;
type MessageDeliveryAndDispatchPayment =
pallet_bridge_relayers::MessageDeliveryAndDispatchPaymentAdapter<
pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
Runtime,
WithRialtoParachainMessagesInstance,
frame_support::traits::ConstU64<100_000>,
frame_support::traits::ConstU64<100_000>,
>;

type SourceHeaderChain = crate::rialto_parachain_messages::RialtoParachain;
Expand Down
5 changes: 3 additions & 2 deletions bridges/bin/rialto-parachain/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,9 +570,10 @@ impl pallet_bridge_messages::Config<WithMillauMessagesInstance> for Runtime {
type TargetHeaderChain = crate::millau_messages::Millau;
type LaneMessageVerifier = crate::millau_messages::ToMillauMessageVerifier;
type MessageDeliveryAndDispatchPayment =
pallet_bridge_relayers::MessageDeliveryAndDispatchPaymentAdapter<
pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
Runtime,
WithMillauMessagesInstance,
frame_support::traits::ConstU64<100_000>,
frame_support::traits::ConstU64<100_000>,
>;

type SourceHeaderChain = crate::millau_messages::Millau;
Expand Down
5 changes: 3 additions & 2 deletions bridges/bin/rialto/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,10 @@ impl pallet_bridge_messages::Config<WithMillauMessagesInstance> for Runtime {
type TargetHeaderChain = crate::millau_messages::Millau;
type LaneMessageVerifier = crate::millau_messages::ToMillauMessageVerifier;
type MessageDeliveryAndDispatchPayment =
pallet_bridge_relayers::MessageDeliveryAndDispatchPaymentAdapter<
pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
Runtime,
WithMillauMessagesInstance,
frame_support::traits::ConstU64<100_000>,
frame_support::traits::ConstU64<100_000>,
>;

type SourceHeaderChain = crate::millau_messages::Millau;
Expand Down
36 changes: 4 additions & 32 deletions bridges/modules/messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,21 @@ use crate::{

use bp_messages::{
source_chain::{
LaneMessageVerifier, MessageDeliveryAndDispatchPayment, RelayersRewards,
SendMessageArtifacts, TargetHeaderChain,
LaneMessageVerifier, MessageDeliveryAndDispatchPayment, SendMessageArtifacts,
TargetHeaderChain,
},
target_chain::{
DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain,
},
total_unrewarded_messages, DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId,
MessageKey, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData,
OutboundMessageDetails, UnrewardedRelayer, UnrewardedRelayersState,
OutboundMessageDetails, UnrewardedRelayersState,
};
use bp_runtime::{BasicOperatingMode, ChainId, OwnedBridgeModule, Size};
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{dispatch::PostDispatchInfo, ensure, fail, traits::Get};
use sp_runtime::traits::UniqueSaturatedFrom;
use sp_std::{
cell::RefCell, collections::vec_deque::VecDeque, marker::PhantomData, ops::RangeInclusive,
prelude::*,
};
use sp_std::{cell::RefCell, marker::PhantomData, prelude::*};

mod inbound_lane;
mod outbound_lane;
Expand Down Expand Up @@ -725,31 +722,6 @@ fn send_message<T: Config<I>, I: 'static>(
Ok(SendMessageArtifacts { nonce, weight: actual_weight })
}

/// Calculate the number of messages that the relayers have delivered.
pub fn calc_relayers_rewards<T, I>(
messages_relayers: VecDeque<UnrewardedRelayer<T::AccountId>>,
received_range: &RangeInclusive<MessageNonce>,
) -> RelayersRewards<T::AccountId>
where
T: frame_system::Config + crate::Config<I>,
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::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;
}
}
relayers_rewards
}

/// Ensure that the pallet is in normal operational mode.
fn ensure_normal_operating_mode<T: Config<I>, I: 'static>() -> Result<(), Error<T, I>> {
if PalletOperatingMode::<T, I>::get() ==
Expand Down
6 changes: 3 additions & 3 deletions bridges/modules/messages/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
// From construct_runtime macro
#![allow(clippy::from_over_into)]

use crate::{calc_relayers_rewards, Config};
use crate::Config;

use bp_messages::{
calc_relayers_rewards,
source_chain::{LaneMessageVerifier, MessageDeliveryAndDispatchPayment, TargetHeaderChain},
target_chain::{
DispatchMessage, DispatchMessageData, MessageDispatch, ProvedLaneMessages, ProvedMessages,
Expand Down Expand Up @@ -311,8 +312,7 @@ impl MessageDeliveryAndDispatchPayment<RuntimeOrigin, AccountId>
_confirmation_relayer: &AccountId,
received_range: &RangeInclusive<MessageNonce>,
) {
let relayers_rewards =
calc_relayers_rewards::<TestRuntime, ()>(message_relayers, received_range);
let relayers_rewards = calc_relayers_rewards(message_relayers, received_range);
for (relayer, reward) in &relayers_rewards {
let key = (b":relayer-reward:", relayer, reward).encode();
frame_support::storage::unhashed::put(&key, &true);
Expand Down
2 changes: 0 additions & 2 deletions bridges/modules/relayers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ scale-info = { version = "2.1.1", default-features = false, features = ["derive"

bp-messages = { path = "../../primitives/messages", default-features = false }
bp-relayers = { path = "../../primitives/relayers", default-features = false }
pallet-bridge-messages = { path = "../messages", default-features = false }

# Substrate Dependencies

Expand All @@ -41,7 +40,6 @@ std = [
"frame-support/std",
"frame-system/std",
"log/std",
"pallet-bridge-messages/std",
"scale-info/std",
"sp-arithmetic/std",
"sp-std/std",
Expand Down
2 changes: 1 addition & 1 deletion bridges/modules/relayers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use sp_std::marker::PhantomData;
use weights::WeightInfo;

pub use pallet::*;
pub use payment_adapter::MessageDeliveryAndDispatchPaymentAdapter;
pub use payment_adapter::DeliveryConfirmationPaymentsAdapter;

pub mod benchmarking;

Expand Down
33 changes: 1 addition & 32 deletions bridges/modules/relayers/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@

use crate as pallet_bridge_relayers;

use bp_messages::{
source_chain::ForbidOutboundMessages, target_chain::ForbidInboundMessages, LaneId,
};
use bp_messages::LaneId;
use bp_relayers::PaymentProcedure;
use frame_support::{parameter_types, weights::RuntimeDbWeight};
use sp_core::H256;
Expand All @@ -43,7 +41,6 @@ frame_support::construct_runtime! {
{
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
Balances: pallet_balances::{Pallet, Event<T>},
Messages: pallet_bridge_messages::{Pallet, Event<T>},
Relayers: pallet_bridge_relayers::{Pallet, Call, Event<T>},
}
}
Expand Down Expand Up @@ -91,34 +88,6 @@ impl pallet_balances::Config for TestRuntime {
type ReserveIdentifier = ();
}

parameter_types! {
pub const TestBridgedChainId: bp_runtime::ChainId = *b"test";
pub ActiveOutboundLanes: &'static [bp_messages::LaneId] = &[[0, 0, 0, 0]];
}

// we're not testing messages pallet here, so values in this config might be crazy
impl pallet_bridge_messages::Config for TestRuntime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
type ActiveOutboundLanes = ActiveOutboundLanes;
type MaxUnrewardedRelayerEntriesAtInboundLane = frame_support::traits::ConstU64<8>;
type MaxUnconfirmedMessagesAtInboundLane = frame_support::traits::ConstU64<8>;

type MaximalOutboundPayloadSize = frame_support::traits::ConstU32<1024>;
type OutboundPayload = ();

type InboundPayload = ();
type InboundRelayer = AccountId;

type TargetHeaderChain = ForbidOutboundMessages;
type LaneMessageVerifier = ForbidOutboundMessages;
type MessageDeliveryAndDispatchPayment = ();

type SourceHeaderChain = ForbidInboundMessages;
type MessageDispatch = ForbidInboundMessages;
type BridgedChainId = TestBridgedChainId;
}

impl pallet_bridge_relayers::Config for TestRuntime {
type RuntimeEvent = RuntimeEvent;
type Reward = Balance;
Expand Down
55 changes: 41 additions & 14 deletions bridges/modules/relayers/src/payment_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,25 @@

use crate::{Config, Pallet};

use bp_messages::source_chain::{MessageDeliveryAndDispatchPayment, RelayersRewards};
use frame_support::sp_runtime::SaturatedConversion;
use bp_messages::source_chain::{
DeliveryConfirmationPayments, MessageDeliveryAndDispatchPayment, 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};

/// Adapter that allows relayers pallet to be used as a delivery+dispatch payment mechanism
/// for the messages pallet.
pub struct MessageDeliveryAndDispatchPaymentAdapter<T, MessagesInstance>(
PhantomData<(T, MessagesInstance)>,
pub struct DeliveryConfirmationPaymentsAdapter<T, DeliveryReward, ConfirmationReward>(
PhantomData<(T, DeliveryReward, ConfirmationReward)>,
);

impl<T, MessagesInstance> MessageDeliveryAndDispatchPayment<T::RuntimeOrigin, T::AccountId>
for MessageDeliveryAndDispatchPaymentAdapter<T, MessagesInstance>
// TODO (https://github.com/paritytech/parity-bridges-common/pull/1652): this impl must be removed
impl<T, DeliveryReward, ConfirmationReward>
MessageDeliveryAndDispatchPayment<T::RuntimeOrigin, T::AccountId>
for DeliveryConfirmationPaymentsAdapter<T, DeliveryReward, ConfirmationReward>
where
T: Config + pallet_bridge_messages::Config<MessagesInstance>,
MessagesInstance: 'static,
T: Config,
{
type Error = &'static str;

Expand All @@ -44,23 +47,47 @@ where
confirmation_relayer: &T::AccountId,
received_range: &RangeInclusive<bp_messages::MessageNonce>,
) {
let relayers_rewards = pallet_bridge_messages::calc_relayers_rewards::<T, MessagesInstance>(
messages_relayers,
received_range,
);
let relayers_rewards =
bp_messages::calc_relayers_rewards::<T::AccountId>(messages_relayers, received_range);

register_relayers_rewards::<T>(
confirmation_relayer,
relayers_rewards,
lane_id,
// TODO (https://github.com/paritytech/parity-bridges-common/issues/1318): this shall be fixed
// in some way. ATM the future of the `register_relayer_reward` is not yet known
100_000_u32.into(),
10_000_u32.into(),
);
}
}

impl<T, DeliveryReward, ConfirmationReward> DeliveryConfirmationPayments<T::AccountId>
for DeliveryConfirmationPaymentsAdapter<T, DeliveryReward, ConfirmationReward>
where
T: Config,
DeliveryReward: Get<T::Reward>,
ConfirmationReward: Get<T::Reward>,
{
type Error = &'static str;

fn pay_reward(
lane_id: bp_messages::LaneId,
messages_relayers: VecDeque<bp_messages::UnrewardedRelayer<T::AccountId>>,
confirmation_relayer: &T::AccountId,
received_range: &RangeInclusive<bp_messages::MessageNonce>,
) {
let relayers_rewards =
bp_messages::calc_relayers_rewards::<T::AccountId>(messages_relayers, received_range);

register_relayers_rewards::<T>(
confirmation_relayer,
relayers_rewards,
lane_id,
DeliveryReward::get(),
ConfirmationReward::get(),
);
}
}

// Update rewards to given relayers, optionally rewarding confirmation relayer.
fn register_relayers_rewards<T: Config>(
confirmation_relayer: &T::AccountId,
Expand Down
26 changes: 25 additions & 1 deletion bridges/primitives/messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::RuntimeDebug;
use scale_info::TypeInfo;
use sp_core::TypeId;
use sp_std::{collections::vec_deque::VecDeque, prelude::*};
use sp_std::{collections::vec_deque::VecDeque, ops::RangeInclusive, prelude::*};

pub mod source_chain;
pub mod storage_keys;
Expand Down Expand Up @@ -360,6 +360,30 @@ pub fn total_unrewarded_messages<RelayerId>(
}
}

/// Calculate the number of messages that the relayers have delivered.
pub fn calc_relayers_rewards<AccountId>(
messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
received_range: &RangeInclusive<MessageNonce>,
) -> source_chain::RelayersRewards<AccountId>
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();
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;
}
}
relayers_rewards
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
31 changes: 31 additions & 0 deletions bridges/primitives/messages/src/source_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,37 @@ impl<SenderOrigin, AccountId> MessageDeliveryAndDispatchPayment<SenderOrigin, Ac
}
}

/// Manages payments that are happening at the source chain during delivery confirmation
/// transaction.
pub trait DeliveryConfirmationPayments<AccountId> {
/// 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_reward(
lane_id: LaneId,
messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
confirmation_relayer: &AccountId,
received_range: &RangeInclusive<MessageNonce>,
);
}

impl<AccountId> DeliveryConfirmationPayments<AccountId> for () {
type Error = &'static str;

fn pay_reward(
_lane_id: LaneId,
_messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
_confirmation_relayer: &AccountId,
_received_range: &RangeInclusive<MessageNonce>,
) {
// this implementation is not rewarding relayers at all
}
}

/// Send message artifacts.
#[derive(Eq, RuntimeDebug, PartialEq)]
pub struct SendMessageArtifacts {
Expand Down

0 comments on commit f04c67d

Please sign in to comment.