Skip to content
This repository has been archived by the owner on Feb 29, 2024. It is now read-only.

Commit

Permalink
Update fee-market terminology (#192) (#199)
Browse files Browse the repository at this point in the history
  • Loading branch information
boundless-forest authored Sep 29, 2022
1 parent fddfd8a commit e05d876
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 83 deletions.
160 changes: 124 additions & 36 deletions modules/fee-market/README.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,142 @@
# Design of Relayer Fee Market
# Design Of Cross-Chain Fee Market

## Requirements

1. Users use native tokens of the source chain as the only method of payment;
2. The estimated fee of the message to be transferred is supported by a pricing system on the source chain which is connected to a Relayer Fee Market;
3. The cost on the target chain is at the expense of the relayer who claims the handling fee on the source chain with the proof of delivery after delivery is completed successfully. To incentivize relayers, the pricing system should ensure the gain is greater than the cost in long term. If an automatic pricing mechanism is infeasible, relayers should be able to give their offers manually and shoulder the cost of offering. The relayers should be punished if they fail to relay the message as expected.
4. Relayers and Users constitute a secondary supply-and-demand market, where prices rise when supply is low and fall when supply is abundant. There are no access restrictions for relayers, and anyone can enter. Relayer should evaluate and quote at their own discretion as an economically rational person. An incomplete list of risks that relayers should take into account is as follows:
1. Fluctuation in token prices and exchange ratios;
2. Time delay between quoting and claiming;
3. Loss of staking funds due to software or network failures
1. Users use native tokens of the source chain as the only method of cross-chain payment.
2. The cross-chain fees paid by users are generated by the fee market system and the final price quoted by the fee market is influenced by all relayers involved in the delivery of messages throughout the market.
3. The cost on the target chain is at the expense of the relayer who claims the handling fee on the source chain with the proof of delivery after delivery is completed successfully. To incentivize relayers, the fee market system should ensure the relayers gain is greater than the cost in long term. If an automatic pricing mechanism is infeasible, relayers should be able to give their offers manually and shoulder the cost of offering. The relayers should be punished if they fail to relay the message as expected.
4. Relayers and Users constitute a secondary supply-and-demand market, where quotes rise when relayers number is low and fall when relayers number is abundant. There are no access restrictions for relayers, and anyone can enter. Relayer should evaluate and quote at their own discretion as an economically rational person. An incomplete list of risks that relayers should take into account is as follows:
* Fluctuation in token prices and exchange ratios;
* Time delay between quoting and claiming;
* Loss of staking funds due to software or network failures;

## Tiered Quotation Market
## Tiered Quotation Mechanism

This approach is suitable for scenarios with lower gas fee on the source chain and shorter finality time. It has better versatility, reliability, and robustness. Such networks include Heco, BSC, Polygon and Darwinia.
> This approach is suitable for scenarios with lower gas fee on the source chain and shorter finality time. It has better versatility, reliability, and robustness. Such networks include Heco, BSC, Polygon and Darwinia.
First, the relayer posts their quotes based on the reference price and the expected profit on the blockchain at any time. An off-chain pricing system maintains the reference price. Each relayer should lock a sufficient default margin on the chain to guarantee the faithful execution of the deal.
First, the relayers must register in the fee market system and post their quotes based on the reference price and the expected profit on the blockchain at any time. An off-chain pricing system maintains the reference price. Each relayer should lock a sufficient default margin on the chain to guarantee the faithful execution of the deal.

In this way, a series of ***Ask*** prices(price meanings fee per message) come into being in the ascending order on the blockchain. When the user initiates a request on the source chain, the lowest n offers **_P1, P2...Pn_** are filtered out and **Pn** is used as the billing price. Those who make these offers are called *Assigned Relayers*. The user can request a cross-chain message delivery after paying **_Pn_**. The reason that we select n relayers in the executed order is that we want to have redundancy for executing the message delivery. P1's relayer is R1, P2's relayer is R2, Pn's relayer is Rn.
In this way, a series of quoted prices (price meanings fee per message) come into being in the ascending order on the blockchain. When the user initiates a cross-chain request on the source chain, the lowest n quoted prices are filtered out and the last one is used as the billing price. Those who make these prices are called *Assigned Relayers*. User can send cross-chain messages after paying billing price on the source chain, then wait for message execution on the target chain. The assigned relayers are responsible for ensuring the success of cross-chain message delivery and need to monitor their running relayer clients closely. If a cross-chain message is not executed in the specified time on the target chain, all assigned relayers will be penalised. The reason that we select n relayers as assigned relayers is that we want to have redundancy for executing the message delivery. Note that if the count of relayers in current market are less than n when some users sends cross-chain message, it means the fee market system fails to provide a price for user sending cross-chain message, and the dispatch call user sent on the source chain will simply fail and exit.

In any time, the message relayer and confirm relayer can be anyone, do not have be the assigned relayer. But in priority time slots, assigned relayer will be rewarded with much more regardless wo relay the message and do the confirmation.
To give them different priority for the specific assigned relayer, each assigned relayer has a time slot. The relayer who is assigned with her own time slot will be rewarded with more percentage, and this reward is for the asked price and the commitment(delivery in time or slash). Relayer with lower price are assigned with earlier time slot.
In any time, the message delivery and confirmation relayer can be anyone, do not have be the assigned relayer. However, there is an additional bonus for being an assigned relayer as a reward for guarding the cross-chain messaging service. In order to better manage the responsibilities of the n assigned relayers, each assigned relayer is given a time slot (from the creation of the cross-chain message), meaning that the assigned relayer is obliged to deliver the cross-chain message in the allocated time slot. If a message is supposed to be delivered to the target chain in one of the assigned relayer's time slots, but it is not, the assigned relayer is considered to have acted badly and will be penalised for locked assets, or even removed from the set of assigned relayers.

For simplicity, if count of relayers in current market are less than MIN_ASSIGNED_RELAYERS_NUMBER(runtime config) when some user is sending bridge message, it means the relayer fee market fails to provide a price for user sending bridge message, and this dispatch call on source chain will simply fail and exit.
## Reward And Slash Rules

### Detailed Steps in Implementation
### Key Parameters

1. Enroll and lock collateral
1. `enroll_and_lock_collateral` dispatch call
2. `cancel_enrollment()` dispatch call, remember to check if the relayer is in priority time slots.
2. Ask price
We use simple constant price function for messages currently: fn(message) = const_price * 1 where const_price means fee per message. We might later improve this fn(message) with [relayer defined fee functions](https://github.com/darwinia-network/darwinia-common/issues/813).
1. Update, Cancel prices storage
2. If the collateral of any registered relayer is lower than required collateral threshold (e.g. slashed), the enrolment of this relayer will become inactive(will be removed from the ask list, and not able to put new ask).
3. Send message, user pay **_Pn_** for sending a cross-chain message.
1. Create a new order(with current block number), in the order lifecycle, relayer cannot cancel enrollment and take back collateral.
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.
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).
When calculating rewards and penalties, the following parameters are crucial.

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.
- DutyRelayersRewardRatio: `20% by default`
- MessageRelayersRewardRatio: `80% by default`
- ConfirmRelayersRewardRatio: `20% by default`
- AssignedRelayerSlashRatio: `20% by default`
- Slot: `300 blocks for each slot by default.`

### Basic Rules

## Another Proposal B-Oracle + On-chain Automatic Pricing
After a user sends a cross-chain transaction, the fee market system calculates the penalty or reward according to the time the cross-chain transaction is confirmed, with the following rules:

High gas fees in some networks, such as Ethereum, may prevent the relayer from quoting frequently, and the execution cost of message delivery on the target chain is predictable, such as (***Ethereum>Darwinia***). In this scenario, a second-best solution is to query the execution cost by the interface on the target chain, plus the estimated delivery cost. The disadvantage is that it is not adaptable, and it is possible that no relayer is willing to take the order, causing message delivery congestion and stability problems.
- The cross-chain transaction is confirmed before the last block of the n slot.

## Update to Darwinia > Ethereum Bridge: Grandpa Beefy Light Client + Three-tiered Quotation
As long as the order is confirmed before the last block of the nth slot, we consider it to be delivered on time, and the calculation of rewards and penalties varies depending on when the message is confirmed.

For BEEFY, the interaction is a multi-round process in which BridgedChain fee should be paid. The user needs to know in advance how much the handling fee is and whether the amount is sufficient. However, it can not be predicted. We can establish a market which implements a set of ***ask***/***bid*** system.
Suppose the cross-chain message has n slots, the message is confirmed at the m-th slot, and `Pm` denotes the quote price of m-th slot. At this point, the assigned relayers from 0 to m slots will be penalized, and the penalty will be calculated as `AssignedRelayerSlashRatio * collateral`, while the assigned relayers from m to n slots will receive a reward for ensuring the message is completed on time `(DutyRelayersRewardRatio * (fee - Pm)) / (n - m)`. `Pm` plus the penalties for the other assigned relayers mentioned above will be distributed as new rewards to the message delivery relayer and the message confirm relayer, where the message delivery relayer receive the `MessageRelayersRewardRatio` of this reward, the message confirm relayer gets the `ConfirmRelayersRewardRatio` of this reward. The rest of the fee will be given to treasury.

The relayer posts a quote for ***Header Relay*** during a specific period(***ask***) and the user may respond to it (***bid***) if they accept the quoted price. The relayer relays the **header** after the deal is closed. The relayer may lose the staking tokens if they fail to relay the message in time, whatever the reason is. More than one relayer can quote at the same time to compete for users.
- The cross-chain transaction is confirmed after the last block of the n slot.

We believe that this cross-chain transaction is severely delayed, in which case all assigned relayers will be heavily penalized by deducting the `AssignedRelayerSlashRatio` of the collateral and calculating an additional penalty amount based on the delay time. These penalty amounts, plus the cross-chain fees paid by users, will be distributed as new rewards to the message delivery relayer and the message confirm relayer, where the message delivery relayer receive the `MessageRelayersRewardRatio` of this reward, the message confirm relayer gets the `ConfirmRelayersRewardRatio` of this reward.


The following diagram shows how rewards are distributed:

```sh

assigned offensive relayers collateral
| |---> messaage delivery relayer
| |
|- slot price + slot offensive slash(may have) = message reward --> |
| |
message fee - |---> message confirm relayer
| ---> treasury
| |
|- message surplus -|
|
---> slot duty rewards -> assigned duty relayers

```

### An example

1. Assume that relayers `R1`, `R2`, `R3`, `R4` and `R5` have registered with the fee market and are all running relayer clients capable of delivering messages with quote prices of `P1=10`, `P2=20`, `P3=30`, `P4=4`0 and `P5=50` and are registered with a locked asset of `100`.
2. Assume that the total number of assigned relayers specified by the fee market system is `3` (default). In this case, the fee market will generate a cross-chain fee of `30` (10 < 20 < 30 < 40 < 50) and the set of assigned relayers is `R1, R2, R3`.
3. Assume that the slot value in the fee market runtime is equal to `50` blocks.

In this case, suppose the source chain receives a cross-chain message at height `100` and the user pays a cross-chain fee of `30`. After the source chain receives the message, the fee market assigns `R1, R2 and R3` as the assigned relayers for the message, respectively, and their corresponding time slots are `(100, 150)`, `(150, 200)`, `(200, 250)`

After that, all relayers clients will observe the message in the source chain and deliver it to the target chain first.

The slash, reward analysis is divided into two cases.

* *the message in time (confirmed before the end of the 3rd assigned relayer's slot)*

- Confirmed at block `110(the first slot)`

No assigned relayers will be slashed in this case.

Reward Summary:

* To assigned relayers (R1, R2, R3): `(DutyRelayersRewardRatio * (30 - 10)) / 3 = 1`
* To treasury: `30 - 10 - 1 * 3 = 17`
* To message delivery relayer: `10 * MessageRelayersRewardRatio = 8`
* To message confirm relayer: `10 * ConfirmRelayersRewardRatio = 2`

- Confirmed at block `160(the second slot)`

Since the message is confirmed at the second slot, the first assigned relayer will be slashed.

Slash Summary:

* R1: `100 * AssignedRelayerSlashRatio = 20`

Reward Summary:

* To assigned relayers (R2, R3) = `(DutyRelayersRewardRatio * (30 - 20)) / 2 = 1`
* To treasury: `30 - 20 - 1 * 2 = 8`
* To message delivery relayer: `(20 + 20) * MessageRelayersRewardRatio = 32`
* To message confirm relayer: `(20 + 20) * MessageRelayersRewardRatio = 8`


- Confirmed at block `210(the third slot)`

Since the message is confirmed at the third slot, the first two assigned relayer will be slashed.

Slash Summary:

* R1: `100 * AssignedRelayerSlashRatio = 20`
* R2: `100 * AssignedRelayerSlashRatio = 20`

Reward Summary:

* To assigned relayers (R3) = `(DutyRelayersRewardRatio * (30 - 30)) / 1 = 0`
* To treasury: `30 - 30 - 0 = 0`
* To message delivery relayer: `(10 + 20 * 2) * MessageRelayersRewardRatio = 56`
* To message confirm relayer: `(10 + 20 * 2) * MessageRelayersRewardRatio = 14`

* *the message times out (confirmed after the end of the 3rd assigned relayer's slot)*

- Confirmed at block `260(Out of slot)`

The message is confirmed out of slot 10 blocks, all the assigned relayer will be slashed.

Slash Summary:

* R1: `100 * AssignedRelayerSlashRatio + 10 * 2 = 40`
* R2: `100 * AssignedRelayerSlashRatio + 10 * 2 = 40`
* R3: `100 * AssignedRelayerSlashRatio + 10 * 2 = 40`

Reward Summary:

* To assigned relayers: `0`
* To treasury: `0`
* To message delivery relayer: `(30 + 40 * 3) * MessageRelayersRewardRatio = 120`
* To message confirm relayer: `(30 + 40 * 3) * MessageRelayersRewardRatio = 30`
2 changes: 1 addition & 1 deletion modules/fee-market/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub mod pallet {

/// Reward parameters
#[pallet::constant]
type GuardRelayersRewardRatio: Get<Permill>;
type DutyRelayersRewardRatio: Get<Permill>;
#[pallet::constant]
type MessageRelayersRewardRatio: Get<Permill>;
#[pallet::constant]
Expand Down
Loading

0 comments on commit e05d876

Please sign in to comment.