Skip to content
This repository was archived by the owner on Feb 29, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add OrderCreated event
  • Loading branch information
boundless-forest committed May 23, 2022
commit 7ddeec677f5476126254a6a9aac6697d975d63ad
2 changes: 1 addition & 1 deletion modules/fee-market/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ For simplicity, if count of relayers in current market are less than MIN_ASSIGNE
2. **_Pn_** is consumed in the module relayer fund account.
4. Message delivery and confirmed by bridger.
5. Reward and Slash Strategy.
1. If the order is confirmed in Rn's slot, then Rn can claim 60% from the reward Pn, and message relayer can claim 80% * (1 - 60%) from Pn, confirm relayer can claim 20% * (1 - 60%) from Pn, (P3 - Pn) will go to treasury.
1. If the order is confirmed in Rn's slot, then Rn can claim 60% from the reward Pn, and message relayer can claim 80% * (1 - 60%) from Pn, confirm relayer can claim 20% * (1 - 60%) from Pn, (P3 - Pn) will go to treasury_sum.
2. If the order is confirmed beyond all assigned relayers slot, and then The reward will be S(t) where S(t) > P3, the part S(t) - P3 comes from funds slashed from R1, R2, R3's collateral. Message relayer can claim 80% from S(t), confirm relayer can claim 20% from S(t).

Note: The ratio parameters in the strategy can be defined in runtime, and there might be update to them for refinement after more benchmark and statistics.
Expand Down
4 changes: 3 additions & 1 deletion modules/fee-market/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ pub mod pallet {
UpdateAssignedRelayersNumber(u32),
/// Slash report
FeeMarketSlash(SlashReport<T::AccountId, T::BlockNumber, BalanceOf<T, I>>),
/// Order reward \[lane_id, message_nonce, rewards\]
/// Order Create. \[lane_id, message_nonce, order_fee, out_of_slot_time\]
OrderCreated(LaneId, MessageNonce, BalanceOf<T, I>, Option<T::BlockNumber>),
/// Order reward. \[lane_id, message_nonce, rewards\]
OrderReward(LaneId, MessageNonce, RewardItem<T::AccountId, BalanceOf<T, I>>),
}

Expand Down
14 changes: 11 additions & 3 deletions modules/fee-market/src/s2s/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,19 @@ impl<T: Config<I>, I: 'static> OnMessageAccepted for FeeMarketMessageAcceptedHan
);
// Store the create order
<Orders<T, I>>::insert((order.lane, order.message), order.clone());

Pallet::<T, I>::deposit_event(Event::OrderCreated(
order.lane,
order.message,
order.fee(),
order.range_end(),
));
}

// one read for assigned relayers
// one write for store order
<T as frame_system::Config>::DbWeight::get().reads_writes(1, 1)
// Storage: FeeMarket AssignedRelayers (r:1 w:0)
// Storage: FeeMarket Orders (r:0 w:1)
// Storage: System Events (r:0 w:1)
<T as frame_system::Config>::DbWeight::get().reads_writes(1, 2)
}
}

Expand Down
58 changes: 29 additions & 29 deletions modules/fee-market/src/s2s/payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ where
received_range: &RangeInclusive<MessageNonce>,
relayer_fund_account: &T::AccountId,
) {
let RewardsBook { for_deliver, for_confirm, slot_relayer, treasury } =
let RewardsBook { deliver_sum, confirm_sum, slot_relayer_sum, treasury_sum } =
slash_and_calculate_rewards::<T, I>(
lane_id,
messages_relayers,
Expand All @@ -99,25 +99,25 @@ where
);

// Pay confirmation relayer rewards
do_reward::<T, I>(relayer_fund_account, confirmation_relayer, for_confirm);
do_reward::<T, I>(relayer_fund_account, confirmation_relayer, confirm_sum);
// Pay messages relayers rewards
for (relayer, reward) in for_deliver {
for (relayer, reward) in deliver_sum {
do_reward::<T, I>(relayer_fund_account, &relayer, reward);
}
// Pay assign relayer reward
for (relayer, reward) in slot_relayer {
for (relayer, reward) in slot_relayer_sum {
do_reward::<T, I>(relayer_fund_account, &relayer, reward);
}
// Pay treasury reward
// Pay treasury_sum reward
do_reward::<T, I>(
relayer_fund_account,
&T::TreasuryPalletId::get().into_account(),
treasury,
treasury_sum,
);
}
}

/// Slash and calculate rewards for messages_relayers, confirmation relayers, treasury,
/// Slash and calculate rewards for messages_relayers, confirmation relayers, treasury_sum,
/// assigned_relayers
pub fn slash_and_calculate_rewards<T, I>(
lane_id: LaneId,
Expand All @@ -136,10 +136,8 @@ where
let nonce_end = sp_std::cmp::min(entry.messages.end, *received_range.end());

for message_nonce in nonce_begin..nonce_end + 1 {
// The order created when message was accepted, so we can always get the order info
// below.
// The order created when message was accepted, so we can always get the order info.
if let Some(order) = <Orders<T, I>>::get(&(lane_id, message_nonce)) {
println!("find the order");
// The confirm_time of the order is set in the `OnDeliveryConfirmed` callback. And
// the callback function was called as source chain received message delivery proof,
// before the reward payment.
Expand All @@ -154,20 +152,22 @@ where
if let Some((who, base_fee)) =
order.required_delivery_relayer_for_time(order_confirm_time)
{
// message fee - base fee => treasury
// message fee - base fee => treasury_sum
reward_item.to_treasury = Some(message_fee.saturating_sub(base_fee));

// 60% * base fee => slot_relayer_reward
// AssignedRelayersRewardRatio * base fee => slot relayer
let slot_relayer_reward = T::AssignedRelayersRewardRatio::get() * base_fee;
reward_item.to_slot_relayer = Some((who, slot_relayer_reward));

let bridger_relayers_reward = base_fee.saturating_sub(slot_relayer_reward);
// 80% * (1 - 60%) * base_fee => message relayer
// MessageRelayersRewardRatio * (1 - AssignedRelayersRewardRatio) * base_fee =>
// message relayer
message_reward = T::MessageRelayersRewardRatio::get() * bridger_relayers_reward;
// 20% * (1 - 60%) * base_fee => confirm relayer
// ConfirmRelayersRewardRatio * (1 - AssignedRelayersRewardRatio) * base_fee =>
// confirm relayer
confirm_reward = T::ConfirmRelayersRewardRatio::get() * bridger_relayers_reward;
} else {
// The order delivery is delay
// The order delivery is delay, slash occurs.
let mut total_slash = message_fee;

// calculate slash amount
Expand All @@ -193,9 +193,9 @@ where
}
total_slash += assigned_relayers_slash;

// 80% total slash => message relayer
// MessageRelayersRewardRatio total slash => message relayer
message_reward = T::MessageRelayersRewardRatio::get() * total_slash;
// 20% total slash => confirm relayer
// ConfirmRelayersRewardRatio total slash => confirm relayer
confirm_reward = T::ConfirmRelayersRewardRatio::get() * total_slash;
}

Expand Down Expand Up @@ -301,43 +301,43 @@ impl<AccountId, Balance> RewardItem<AccountId, Balance> {
/// Record the calculation rewards result
#[derive(Clone, Debug, Eq, PartialEq, TypeInfo)]
pub struct RewardsBook<T: Config<I>, I: 'static> {
pub for_deliver: BTreeMap<T::AccountId, BalanceOf<T, I>>,
pub for_confirm: BalanceOf<T, I>,
pub slot_relayer: BTreeMap<T::AccountId, BalanceOf<T, I>>,
pub treasury: BalanceOf<T, I>,
pub deliver_sum: BTreeMap<T::AccountId, BalanceOf<T, I>>,
pub confirm_sum: BalanceOf<T, I>,
pub slot_relayer_sum: BTreeMap<T::AccountId, BalanceOf<T, I>>,
pub treasury_sum: BalanceOf<T, I>,
}

impl<T: Config<I>, I: 'static> RewardsBook<T, I> {
fn new() -> Self {
Self {
for_deliver: BTreeMap::new(),
for_confirm: BalanceOf::<T, I>::zero(),
slot_relayer: BTreeMap::new(),
treasury: BalanceOf::<T, I>::zero(),
deliver_sum: BTreeMap::new(),
confirm_sum: BalanceOf::<T, I>::zero(),
slot_relayer_sum: BTreeMap::new(),
treasury_sum: BalanceOf::<T, I>::zero(),
}
}

fn add_reward_item(&mut self, item: RewardItem<T::AccountId, BalanceOf<T, I>>) {
if let Some((id, reward)) = item.to_slot_relayer {
self.slot_relayer
self.slot_relayer_sum
.entry(id)
.and_modify(|r| *r = r.saturating_add(reward))
.or_insert(reward);
}

if let Some(reward) = item.to_treasury {
self.treasury = self.treasury.saturating_add(reward);
self.treasury_sum = self.treasury_sum.saturating_add(reward);
}

if let Some((id, reward)) = item.to_message_relayer {
self.for_deliver
self.deliver_sum
.entry(id)
.and_modify(|r| *r = r.saturating_add(reward))
.or_insert(reward);
}

if let Some((_id, reward)) = item.to_confirm_relayer {
self.for_confirm = self.for_confirm.saturating_add(reward);
self.confirm_sum = self.confirm_sum.saturating_add(reward);
}
}
}
34 changes: 14 additions & 20 deletions modules/fee-market/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,36 +290,30 @@ impl MessageDeliveryAndDispatchPayment<Origin, AccountId, TestMessageFee>
received_range: &RangeInclusive<MessageNonce>,
relayer_fund_account: &AccountId,
) {
let RewardsBook {
for_deliver,
for_confirm,
slot_relayer,
treasury,
} = slash_and_calculate_rewards::<Test, ()>(
lane_id,
message_relayers,
confirmation_relayer.clone(),
received_range,
relayer_fund_account,
);

let confimation_key =
(b":relayer-reward:", confirmation_relayer, for_confirm).encode();
let RewardsBook { deliver_sum, confirm_sum, slot_relayer_sum, treasury_sum } =
slash_and_calculate_rewards::<Test, ()>(
lane_id,
message_relayers,
confirmation_relayer.clone(),
received_range,
relayer_fund_account,
);

let confimation_key = (b":relayer-reward:", confirmation_relayer, confirm_sum).encode();
frame_support::storage::unhashed::put(&confimation_key, &true);

for (relayer, reward) in &for_deliver {
for (relayer, reward) in &deliver_sum {
let key = (b":relayer-reward:", relayer, reward).encode();
frame_support::storage::unhashed::put(&key, &true);
}

for (relayer, reward) in &slot_relayer {
for (relayer, reward) in &slot_relayer_sum {
let key = (b":relayer-reward:", relayer, reward).encode();
frame_support::storage::unhashed::put(&key, &true);
}

let treasury_account: AccountId = <Test as Config>::TreasuryPalletId::get().into_account();
let treasury_key =
(b":relayer-reward:", &treasury_account, treasury).encode();
let treasury_key = (b":relayer-reward:", &treasury_account, treasury_sum).encode();
frame_support::storage::unhashed::put(&treasury_key, &true);
}
}
Expand Down Expand Up @@ -843,7 +837,7 @@ fn test_payment_cal_reward_normally_single_message() {
// 1. assigned_relayers [(1, 30, 2-52),(2, 50, 52-102),(3, 100, 102-152)] -> id: 1, reward =
// 60% * 30 = 18 2. message relayer -> id: 100, reward = 40% * 30 * 80% = 9.6 ~ 10
// 3. confirmation relayer -> id: 5, reward = 40% * 30 * 20% = 2.4 ~ 2
// 4. treasury reward -> reward: 100 - 30 = 70
// 4. treasury_sum reward -> reward: 100 - 30 = 70
let t: AccountId = <Test as Config>::TreasuryPalletId::get().into_account();
assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(t, 70));
assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(1, 18));
Expand Down