New relayer rewards scheme integration (#1652)

* relayer rewards integration: initial commit

* added refund-relayer-extension to the millau runtime

* spelling

* spelling again

* new -> Default
This commit is contained in:
Svyatoslav Nikolsky
2022-12-09 17:19:02 +03:00
committed by Bastian Köcher
parent 161d861d9b
commit 2c5e2f09eb
11 changed files with 158 additions and 138 deletions
+28 -12
View File
@@ -471,15 +471,15 @@ impl pallet_bridge_messages::Config<WithRialtoMessagesInstance> for Runtime {
type InboundPayload = crate::rialto_messages::FromRialtoMessagePayload; type InboundPayload = crate::rialto_messages::FromRialtoMessagePayload;
type InboundRelayer = bp_rialto::AccountId; type InboundRelayer = bp_rialto::AccountId;
type DeliveryPayments = ();
type TargetHeaderChain = crate::rialto_messages::Rialto; type TargetHeaderChain = crate::rialto_messages::Rialto;
type LaneMessageVerifier = crate::rialto_messages::ToRialtoMessageVerifier; type LaneMessageVerifier = crate::rialto_messages::ToRialtoMessageVerifier;
type MessageDeliveryAndDispatchPayment = type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime,
Runtime, frame_support::traits::ConstU64<100_000>,
frame_support::traits::ConstU64<100_000>, frame_support::traits::ConstU64<100_000>,
frame_support::traits::ConstU64<100_000>, >;
>;
type SourceHeaderChain = crate::rialto_messages::Rialto; type SourceHeaderChain = crate::rialto_messages::Rialto;
type MessageDispatch = crate::rialto_messages::FromRialtoMessageDispatch; type MessageDispatch = crate::rialto_messages::FromRialtoMessageDispatch;
@@ -502,15 +502,15 @@ impl pallet_bridge_messages::Config<WithRialtoParachainMessagesInstance> for Run
type InboundPayload = crate::rialto_parachain_messages::FromRialtoParachainMessagePayload; type InboundPayload = crate::rialto_parachain_messages::FromRialtoParachainMessagePayload;
type InboundRelayer = bp_rialto_parachain::AccountId; type InboundRelayer = bp_rialto_parachain::AccountId;
type DeliveryPayments = ();
type TargetHeaderChain = crate::rialto_parachain_messages::RialtoParachain; type TargetHeaderChain = crate::rialto_parachain_messages::RialtoParachain;
type LaneMessageVerifier = crate::rialto_parachain_messages::ToRialtoParachainMessageVerifier; type LaneMessageVerifier = crate::rialto_parachain_messages::ToRialtoParachainMessageVerifier;
type MessageDeliveryAndDispatchPayment = type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime,
Runtime, frame_support::traits::ConstU64<100_000>,
frame_support::traits::ConstU64<100_000>, frame_support::traits::ConstU64<100_000>,
frame_support::traits::ConstU64<100_000>, >;
>;
type SourceHeaderChain = crate::rialto_parachain_messages::RialtoParachain; type SourceHeaderChain = crate::rialto_parachain_messages::RialtoParachain;
type MessageDispatch = crate::rialto_parachain_messages::FromRialtoParachainMessageDispatch; type MessageDispatch = crate::rialto_parachain_messages::FromRialtoParachainMessageDispatch;
@@ -518,6 +518,8 @@ impl pallet_bridge_messages::Config<WithRialtoParachainMessagesInstance> for Run
} }
parameter_types! { parameter_types! {
pub const RialtoParachainMessagesLane: bp_messages::LaneId = rialto_parachain_messages::XCM_LANE;
pub const RialtoParachainId: u32 = bp_rialto_parachain::RIALTO_PARACHAIN_ID;
pub const RialtoParasPalletName: &'static str = bp_rialto::PARAS_PALLET_NAME; pub const RialtoParasPalletName: &'static str = bp_rialto::PARAS_PALLET_NAME;
pub const WestendParasPalletName: &'static str = bp_westend::PARAS_PALLET_NAME; pub const WestendParasPalletName: &'static str = bp_westend::PARAS_PALLET_NAME;
pub const MaxRialtoParaHeadSize: u32 = bp_rialto::MAX_NESTED_PARACHAIN_HEAD_SIZE; pub const MaxRialtoParaHeadSize: u32 = bp_rialto::MAX_NESTED_PARACHAIN_HEAD_SIZE;
@@ -613,6 +615,19 @@ generate_bridge_reject_obsolete_headers_and_messages! {
BridgeRialtoMessages, BridgeRialtoParachainMessages BridgeRialtoMessages, BridgeRialtoParachainMessages
} }
/// Signed extension that refunds relayers that are delivering messages from the Rialto parachain.
pub type BridgeRefundRialtoParachainRelayers =
bridge_runtime_common::refund_relayer_extension::RefundRelayerForMessagesFromParachain<
Runtime,
RialtoGrandpaInstance,
WithRialtoParachainsInstance,
WithRialtoParachainMessagesInstance,
BridgeRejectObsoleteHeadersAndMessages,
RialtoParachainId,
RialtoParachainMessagesLane,
Runtime,
>;
/// The address format for describing accounts. /// The address format for describing accounts.
pub type Address = AccountId; pub type Address = AccountId;
/// Block header type as expected by this runtime. /// Block header type as expected by this runtime.
@@ -634,6 +649,7 @@ pub type SignedExtra = (
frame_system::CheckWeight<Runtime>, frame_system::CheckWeight<Runtime>,
pallet_transaction_payment::ChargeTransactionPayment<Runtime>, pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
BridgeRejectObsoleteHeadersAndMessages, BridgeRejectObsoleteHeadersAndMessages,
BridgeRefundRialtoParachainRelayers,
); );
/// The payload being signed in transactions. /// The payload being signed in transactions.
pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>; pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
@@ -566,15 +566,15 @@ impl pallet_bridge_messages::Config<WithMillauMessagesInstance> for Runtime {
type InboundPayload = crate::millau_messages::FromMillauMessagePayload; type InboundPayload = crate::millau_messages::FromMillauMessagePayload;
type InboundRelayer = bp_millau::AccountId; type InboundRelayer = bp_millau::AccountId;
type DeliveryPayments = ();
type TargetHeaderChain = crate::millau_messages::Millau; type TargetHeaderChain = crate::millau_messages::Millau;
type LaneMessageVerifier = crate::millau_messages::ToMillauMessageVerifier; type LaneMessageVerifier = crate::millau_messages::ToMillauMessageVerifier;
type MessageDeliveryAndDispatchPayment = type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime,
Runtime, frame_support::traits::ConstU128<100_000>,
frame_support::traits::ConstU64<100_000>, frame_support::traits::ConstU128<100_000>,
frame_support::traits::ConstU64<100_000>, >;
>;
type SourceHeaderChain = crate::millau_messages::Millau; type SourceHeaderChain = crate::millau_messages::Millau;
type MessageDispatch = crate::millau_messages::FromMillauMessageDispatch; type MessageDispatch = crate::millau_messages::FromMillauMessageDispatch;
+6 -6
View File
@@ -453,15 +453,15 @@ impl pallet_bridge_messages::Config<WithMillauMessagesInstance> for Runtime {
type InboundPayload = crate::millau_messages::FromMillauMessagePayload; type InboundPayload = crate::millau_messages::FromMillauMessagePayload;
type InboundRelayer = bp_millau::AccountId; type InboundRelayer = bp_millau::AccountId;
type DeliveryPayments = ();
type TargetHeaderChain = crate::millau_messages::Millau; type TargetHeaderChain = crate::millau_messages::Millau;
type LaneMessageVerifier = crate::millau_messages::ToMillauMessageVerifier; type LaneMessageVerifier = crate::millau_messages::ToMillauMessageVerifier;
type MessageDeliveryAndDispatchPayment = type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime,
Runtime, frame_support::traits::ConstU128<100_000>,
frame_support::traits::ConstU64<100_000>, frame_support::traits::ConstU128<100_000>,
frame_support::traits::ConstU64<100_000>, >;
>;
type SourceHeaderChain = crate::millau_messages::Millau; type SourceHeaderChain = crate::millau_messages::Millau;
type MessageDispatch = crate::millau_messages::FromMillauMessageDispatch; type MessageDispatch = crate::millau_messages::FromMillauMessageDispatch;
@@ -33,7 +33,7 @@ use codec::{Decode, Encode};
use frame_support::{ use frame_support::{
dispatch::{CallableCallFor, DispatchInfo, Dispatchable, PostDispatchInfo}, dispatch::{CallableCallFor, DispatchInfo, Dispatchable, PostDispatchInfo},
traits::IsSubType, traits::IsSubType,
CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, CloneNoBound, DefaultNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound,
}; };
use pallet_bridge_grandpa::{ use pallet_bridge_grandpa::{
BridgedChain, Call as GrandpaCall, Config as GrandpaConfig, Pallet as GrandpaPallet, BridgedChain, Call as GrandpaCall, Config as GrandpaConfig, Pallet as GrandpaPallet,
@@ -95,7 +95,14 @@ where
/// ///
/// Extension does not refund transaction tip due to security reasons. /// Extension does not refund transaction tip due to security reasons.
#[derive( #[derive(
CloneNoBound, Decode, Encode, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, CloneNoBound,
Decode,
DefaultNoBound,
Encode,
EqNoBound,
PartialEqNoBound,
RuntimeDebugNoBound,
TypeInfo,
)] )]
#[scale_info(skip_type_params(RT, GI, PI, MI, BE, PID, LID, FEE))] #[scale_info(skip_type_params(RT, GI, PI, MI, BE, PID, LID, FEE))]
#[allow(clippy::type_complexity)] // TODO: get rid of that in https://github.com/paritytech/parity-bridges-common/issues/1666 #[allow(clippy::type_complexity)] // TODO: get rid of that in https://github.com/paritytech/parity-bridges-common/issues/1666
+28 -19
View File
@@ -52,11 +52,11 @@ use crate::{
use bp_messages::{ use bp_messages::{
source_chain::{ source_chain::{
LaneMessageVerifier, MessageDeliveryAndDispatchPayment, SendMessageArtifacts, DeliveryConfirmationPayments, LaneMessageVerifier, SendMessageArtifacts, TargetHeaderChain,
TargetHeaderChain,
}, },
target_chain::{ target_chain::{
DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain, DeliveryPayments, DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages,
SourceHeaderChain,
}, },
total_unrewarded_messages, DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId, total_unrewarded_messages, DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId,
MessageKey, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData, MessageKey, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData,
@@ -143,6 +143,8 @@ pub mod pallet {
/// Identifier of relayer that deliver messages to this chain. Relayer reward is paid on the /// Identifier of relayer that deliver messages to this chain. Relayer reward is paid on the
/// bridged chain. /// bridged chain.
type InboundRelayer: Parameter + MaxEncodedLen; type InboundRelayer: Parameter + MaxEncodedLen;
/// Delivery payments.
type DeliveryPayments: DeliveryPayments<Self::AccountId>;
// Types that are used by outbound_lane (on source chain). // Types that are used by outbound_lane (on source chain).
@@ -150,11 +152,8 @@ pub mod pallet {
type TargetHeaderChain: TargetHeaderChain<Self::OutboundPayload, Self::AccountId>; type TargetHeaderChain: TargetHeaderChain<Self::OutboundPayload, Self::AccountId>;
/// Message payload verifier. /// Message payload verifier.
type LaneMessageVerifier: LaneMessageVerifier<Self::RuntimeOrigin, Self::OutboundPayload>; type LaneMessageVerifier: LaneMessageVerifier<Self::RuntimeOrigin, Self::OutboundPayload>;
/// Message delivery payment. /// Delivery confirmation payments.
type MessageDeliveryAndDispatchPayment: MessageDeliveryAndDispatchPayment< type DeliveryConfirmationPayments: DeliveryConfirmationPayments<Self::AccountId>;
Self::RuntimeOrigin,
Self::AccountId,
>;
// Types that are used by inbound_lane (on target chain). // Types that are used by inbound_lane (on target chain).
@@ -377,9 +376,17 @@ pub mod pallet {
messages_received_status.push(lane_messages_received_status); 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!( log::debug!(
target: LOG_TARGET, target: LOG_TARGET,
"Received messages: total={}, valid={}. Weight used: {}/{}", "Received messages: total={}, valid={}. Weight used: {}/{}.",
total_messages, total_messages,
valid_messages, valid_messages,
actual_weight, actual_weight,
@@ -388,7 +395,7 @@ pub mod pallet {
Self::deposit_event(Event::MessagesReceived(messages_received_status)); 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. /// Receive messages delivery proof from bridged chain.
@@ -475,7 +482,7 @@ pub mod pallet {
}); });
// if some new messages have been confirmed, reward relayers // if some new messages have been confirmed, reward relayers
<T as Config<I>>::MessageDeliveryAndDispatchPayment::pay_relayers_rewards( T::DeliveryConfirmationPayments::pay_reward(
lane_id, lane_id,
lane_data.relayers, lane_data.relayers,
&confirmation_relayer, &confirmation_relayer,
@@ -879,10 +886,10 @@ mod tests {
use super::*; use super::*;
use crate::mock::{ use crate::mock::{
message, message_payload, run_test, unrewarded_relayer, DbWeight, message, message_payload, run_test, unrewarded_relayer, DbWeight,
RuntimeEvent as TestEvent, RuntimeOrigin, TestMessageDeliveryAndDispatchPayment, RuntimeEvent as TestEvent, RuntimeOrigin, TestDeliveryConfirmationPayments,
TestMessagesDeliveryProof, TestMessagesProof, TestRuntime, MAX_OUTBOUND_PAYLOAD_SIZE, TestDeliveryPayments, TestMessagesDeliveryProof, TestMessagesProof, TestRuntime,
PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_LANE_ID_2, MAX_OUTBOUND_PAYLOAD_SIZE, PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID,
TEST_LANE_ID_3, TEST_RELAYER_A, TEST_RELAYER_B, TEST_LANE_ID_2, TEST_LANE_ID_3, TEST_RELAYER_A, TEST_RELAYER_B,
}; };
use bp_messages::{UnrewardedRelayer, UnrewardedRelayersState}; use bp_messages::{UnrewardedRelayer, UnrewardedRelayersState};
use bp_test_utils::generate_owned_bridge_module_tests; use bp_test_utils::generate_owned_bridge_module_tests;
@@ -1165,6 +1172,8 @@ mod tests {
)); ));
assert_eq!(InboundLanes::<TestRuntime>::get(TEST_LANE_ID).0.last_delivered_nonce(), 1); assert_eq!(InboundLanes::<TestRuntime>::get(TEST_LANE_ID).0.last_delivered_nonce(), 1);
assert!(TestDeliveryPayments::is_reward_paid(1));
}); });
} }
@@ -1326,8 +1335,8 @@ mod tests {
..Default::default() ..Default::default()
}, },
)); ));
assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_A, 1)); assert!(TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_A, 1));
assert!(!TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_B, 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 // this reports delivery of both message 1 and message 2 => reward is paid only to
// TEST_RELAYER_B // TEST_RELAYER_B
@@ -1352,8 +1361,8 @@ mod tests {
..Default::default() ..Default::default()
}, },
)); ));
assert!(!TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_A, 1)); assert!(!TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_A, 1));
assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_B, 1)); assert!(TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_B, 1));
}); });
} }
+39 -13
View File
@@ -21,10 +21,10 @@ use crate::Config;
use bp_messages::{ use bp_messages::{
calc_relayers_rewards, calc_relayers_rewards,
source_chain::{LaneMessageVerifier, MessageDeliveryAndDispatchPayment, TargetHeaderChain}, source_chain::{DeliveryConfirmationPayments, LaneMessageVerifier, TargetHeaderChain},
target_chain::{ target_chain::{
DispatchMessage, DispatchMessageData, MessageDispatch, ProvedLaneMessages, ProvedMessages, DeliveryPayments, DispatchMessage, DispatchMessageData, MessageDispatch,
SourceHeaderChain, ProvedLaneMessages, ProvedMessages, SourceHeaderChain,
}, },
DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload,
OutboundLaneData, UnrewardedRelayer, OutboundLaneData, UnrewardedRelayer,
@@ -154,10 +154,11 @@ impl Config for TestRuntime {
type InboundPayload = TestPayload; type InboundPayload = TestPayload;
type InboundRelayer = TestRelayer; type InboundRelayer = TestRelayer;
type DeliveryPayments = TestDeliveryPayments;
type TargetHeaderChain = TestTargetHeaderChain; type TargetHeaderChain = TestTargetHeaderChain;
type LaneMessageVerifier = TestLaneMessageVerifier; type LaneMessageVerifier = TestLaneMessageVerifier;
type MessageDeliveryAndDispatchPayment = TestMessageDeliveryAndDispatchPayment; type DeliveryConfirmationPayments = TestDeliveryConfirmationPayments;
type SourceHeaderChain = TestSourceHeaderChain; type SourceHeaderChain = TestSourceHeaderChain;
type MessageDispatch = TestMessageDispatch; type MessageDispatch = TestMessageDispatch;
@@ -288,11 +289,38 @@ impl LaneMessageVerifier<RuntimeOrigin, TestPayload> for TestLaneMessageVerifier
} }
} }
/// Message fee payment system that is used in tests. /// Reward payments at the target chain during delivery transaction.
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct TestMessageDeliveryAndDispatchPayment; pub struct TestDeliveryPayments;
impl TestMessageDeliveryAndDispatchPayment { 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::<bool>(&key).is_some()
}
}
impl DeliveryPayments<AccountId> 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 /// Returns true if given relayer has been rewarded with given balance. The reward-paid flag is
/// cleared after the call. /// cleared after the call.
pub fn is_reward_paid(relayer: AccountId, fee: TestMessageFee) -> bool { pub fn is_reward_paid(relayer: AccountId, fee: TestMessageFee) -> bool {
@@ -301,18 +329,16 @@ impl TestMessageDeliveryAndDispatchPayment {
} }
} }
impl MessageDeliveryAndDispatchPayment<RuntimeOrigin, AccountId> impl DeliveryConfirmationPayments<AccountId> for TestDeliveryConfirmationPayments {
for TestMessageDeliveryAndDispatchPayment
{
type Error = &'static str; type Error = &'static str;
fn pay_relayers_rewards( fn pay_reward(
_lane_id: LaneId, _lane_id: LaneId,
message_relayers: VecDeque<UnrewardedRelayer<AccountId>>, messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
_confirmation_relayer: &AccountId, _confirmation_relayer: &AccountId,
received_range: &RangeInclusive<MessageNonce>, received_range: &RangeInclusive<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 { for (relayer, reward) in &relayers_rewards {
let key = (b":relayer-reward:", relayer, reward).encode(); let key = (b":relayer-reward:", relayer, reward).encode();
frame_support::storage::unhashed::put(&key, &true); frame_support::storage::unhashed::put(&key, &true);
@@ -14,14 +14,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>. // along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! Code that allows relayers pallet to be used as a delivery+dispatch payment mechanism //! Code that allows relayers pallet to be used as a payment mechanism for the messages pallet.
//! for the messages pallet.
use crate::{Config, Pallet}; use crate::{Config, Pallet};
use bp_messages::source_chain::{ use bp_messages::source_chain::{DeliveryConfirmationPayments, RelayersRewards};
DeliveryConfirmationPayments, MessageDeliveryAndDispatchPayment, RelayersRewards,
};
use frame_support::{sp_runtime::SaturatedConversion, traits::Get}; use frame_support::{sp_runtime::SaturatedConversion, traits::Get};
use sp_arithmetic::traits::{Saturating, UniqueSaturatedFrom, Zero}; use sp_arithmetic::traits::{Saturating, UniqueSaturatedFrom, Zero};
use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData, ops::RangeInclusive}; use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData, ops::RangeInclusive};
@@ -32,34 +29,6 @@ pub struct DeliveryConfirmationPaymentsAdapter<T, DeliveryReward, ConfirmationRe
PhantomData<(T, DeliveryReward, ConfirmationReward)>, PhantomData<(T, DeliveryReward, ConfirmationReward)>,
); );
// 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,
{
type Error = &'static str;
fn pay_relayers_rewards(
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,
100_000_u32.into(),
10_000_u32.into(),
);
}
}
impl<T, DeliveryReward, ConfirmationReward> DeliveryConfirmationPayments<T::AccountId> impl<T, DeliveryReward, ConfirmationReward> DeliveryConfirmationPayments<T::AccountId>
for DeliveryConfirmationPaymentsAdapter<T, DeliveryReward, ConfirmationReward> for DeliveryConfirmationPaymentsAdapter<T, DeliveryReward, ConfirmationReward>
where where
+3 -5
View File
@@ -24,6 +24,7 @@ use bp_runtime::{BasicOperatingMode, OperatingMode};
use codec::{Decode, Encode, MaxEncodedLen}; use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::RuntimeDebug; use frame_support::RuntimeDebug;
use scale_info::TypeInfo; use scale_info::TypeInfo;
use source_chain::RelayersRewards;
use sp_core::TypeId; use sp_core::TypeId;
use sp_std::{collections::vec_deque::VecDeque, ops::RangeInclusive, prelude::*}; use sp_std::{collections::vec_deque::VecDeque, ops::RangeInclusive, prelude::*};
@@ -364,19 +365,16 @@ pub fn total_unrewarded_messages<RelayerId>(
pub fn calc_relayers_rewards<AccountId>( pub fn calc_relayers_rewards<AccountId>(
messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>, messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
received_range: &RangeInclusive<MessageNonce>, received_range: &RangeInclusive<MessageNonce>,
) -> source_chain::RelayersRewards<AccountId> ) -> RelayersRewards<AccountId>
where where
AccountId: sp_std::cmp::Ord, AccountId: sp_std::cmp::Ord,
{ {
// remember to reward relayers that have delivered messages // remember to reward relayers that have delivered messages
// this loop is bounded by `T::MaxUnrewardedRelayerEntriesAtInboundLane` on the bridged chain // 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 { for entry in messages_relayers {
let nonce_begin = sp_std::cmp::max(entry.messages.begin, *received_range.start()); 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()); 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 { if nonce_end >= nonce_begin {
*relayers_rewards.entry(entry.relayer).or_default() += nonce_end - nonce_begin + 1; *relayers_rewards.entry(entry.relayer).or_default() += nonce_end - nonce_begin + 1;
} }
@@ -88,43 +88,6 @@ pub trait LaneMessageVerifier<SenderOrigin, Payload> {
) -> Result<(), Self::Error>; ) -> 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<SenderOrigin, 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_relayers_rewards(
lane_id: LaneId,
messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
confirmation_relayer: &AccountId,
received_range: &RangeInclusive<MessageNonce>,
);
}
impl<SenderOrigin, AccountId> MessageDeliveryAndDispatchPayment<SenderOrigin, AccountId> for () {
type Error = &'static str;
fn pay_relayers_rewards(
_lane_id: LaneId,
_messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
_confirmation_relayer: &AccountId,
_received_range: &RangeInclusive<MessageNonce>,
) {
}
}
/// Manages payments that are happening at the source chain during delivery confirmation /// Manages payments that are happening at the source chain during delivery confirmation
/// transaction. /// transaction.
pub trait DeliveryConfirmationPayments<AccountId> { pub trait DeliveryConfirmationPayments<AccountId> {
@@ -233,12 +196,10 @@ impl<SenderOrigin, Payload> LaneMessageVerifier<SenderOrigin, Payload> for Forbi
} }
} }
impl<SenderOrigin, AccountId> MessageDeliveryAndDispatchPayment<SenderOrigin, AccountId> impl<AccountId> DeliveryConfirmationPayments<AccountId> for ForbidOutboundMessages {
for ForbidOutboundMessages
{
type Error = &'static str; type Error = &'static str;
fn pay_relayers_rewards( fn pay_reward(
_lane_id: LaneId, _lane_id: LaneId,
_messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>, _messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
_confirmation_relayer: &AccountId, _confirmation_relayer: &AccountId,
@@ -16,7 +16,7 @@
//! Primitives of messages module, that are used on the target chain. //! 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 bp_runtime::{messages::MessageDispatchResult, Size};
use codec::{Decode, Encode, Error as CodecError}; use codec::{Decode, Encode, Error as CodecError};
@@ -112,6 +112,25 @@ pub trait MessageDispatch<AccountId> {
) -> MessageDispatchResult<Self::DispatchLevelResult>; ) -> MessageDispatchResult<Self::DispatchLevelResult>;
} }
/// Manages payments that are happening at the target chain during message delivery transaction.
pub trait DeliveryPayments<AccountId> {
/// 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<Message> Default for ProvedLaneMessages<Message> { impl<Message> Default for ProvedLaneMessages<Message> {
fn default() -> Self { fn default() -> Self {
ProvedLaneMessages { lane_state: None, messages: Vec::new() } ProvedLaneMessages { lane_state: None, messages: Vec::new() }
@@ -130,6 +149,19 @@ impl<DispatchPayload: Decode> From<MessagePayload> for DispatchMessageData<Dispa
} }
} }
impl<AccountId> DeliveryPayments<AccountId> 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, /// Structure that may be used in place of `SourceHeaderChain` and `MessageDispatch` on chains,
/// where inbound messages are forbidden. /// where inbound messages are forbidden.
pub struct ForbidInboundMessages; pub struct ForbidInboundMessages;
+2
View File
@@ -114,6 +114,7 @@ impl ChainWithTransactions for Millau {
frame_system::CheckWeight::<millau_runtime::Runtime>::new(), frame_system::CheckWeight::<millau_runtime::Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<millau_runtime::Runtime>::from(unsigned.tip), pallet_transaction_payment::ChargeTransactionPayment::<millau_runtime::Runtime>::from(unsigned.tip),
millau_runtime::BridgeRejectObsoleteHeadersAndMessages, millau_runtime::BridgeRejectObsoleteHeadersAndMessages,
millau_runtime::BridgeRefundRialtoParachainRelayers::default(),
), ),
( (
(), (),
@@ -125,6 +126,7 @@ impl ChainWithTransactions for Millau {
(), (),
(), (),
(), (),
()
), ),
); );
let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload)); let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload));