mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 12:11:02 +00:00
22d5b80d44
Bridging fees are calculated using a static ETH/DOT exchange rate that can deviate significantly from the real-world exchange rate. We therefore need to add a safety margin to the fee so that users almost aways cover the cost of relaying. # FAQ > Why introduce a `multiplier` parameter instead of configuring an exchange rate which already has a safety factor applied? When converting from ETH to DOT, we need to _divide_ the multiplier by the exchange rate, and to convert from DOT to ETH we need to _multiply_ the multiplier by the exchange rate. > Other input parameters to the fee calculation can also deviate from real-world values. These include substrate weights, gas prices, and so on. Why does the multiplier introduced here not adjust those? A single scalar multiplier won't be able to accommodate the different volatilities efficiently. For example, gas prices are much more volatile than exchange rates, and substrate weights hardly ever change. So the pricing config relating to weights and gas prices should already have some appropriate safety margin pre-applied. # Detailed Changes: * Added `multiplier` field to `PricingParameters` * Outbound-queue fee is multiplied by `multiplier` * This `multiplier` is synced to the Ethereum side * Improved Runtime API for calculating outbound-queue fees. This API makes it much easier to for configure parts of the system in preparation for launch. * Improve and clarify code documentation Upstreamed from https://github.com/Snowfork/polkadot-sdk/pull/127 --------- Co-authored-by: Clara van Staden <claravanstaden64@gmail.com> Co-authored-by: Adrian Catangiu <adrian@parity.io>
73 lines
1.9 KiB
Rust
73 lines
1.9 KiB
Rust
use codec::{Decode, Encode, MaxEncodedLen};
|
|
use scale_info::TypeInfo;
|
|
use sp_arithmetic::traits::{BaseArithmetic, Unsigned, Zero};
|
|
use sp_core::U256;
|
|
use sp_runtime::{FixedU128, RuntimeDebug};
|
|
use sp_std::prelude::*;
|
|
|
|
#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)]
|
|
pub struct PricingParameters<Balance> {
|
|
/// ETH/DOT exchange rate
|
|
pub exchange_rate: FixedU128,
|
|
/// Relayer rewards
|
|
pub rewards: Rewards<Balance>,
|
|
/// Ether (wei) fee per gas unit
|
|
pub fee_per_gas: U256,
|
|
/// Fee multiplier
|
|
pub multiplier: FixedU128,
|
|
}
|
|
|
|
#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)]
|
|
pub struct Rewards<Balance> {
|
|
/// Local reward in DOT
|
|
pub local: Balance,
|
|
/// Remote reward in ETH (wei)
|
|
pub remote: U256,
|
|
}
|
|
|
|
#[derive(RuntimeDebug)]
|
|
pub struct InvalidPricingParameters;
|
|
|
|
impl<Balance> PricingParameters<Balance>
|
|
where
|
|
Balance: BaseArithmetic + Unsigned + Copy,
|
|
{
|
|
pub fn validate(&self) -> Result<(), InvalidPricingParameters> {
|
|
if self.exchange_rate == FixedU128::zero() {
|
|
return Err(InvalidPricingParameters)
|
|
}
|
|
if self.fee_per_gas == U256::zero() {
|
|
return Err(InvalidPricingParameters)
|
|
}
|
|
if self.rewards.local.is_zero() {
|
|
return Err(InvalidPricingParameters)
|
|
}
|
|
if self.rewards.remote.is_zero() {
|
|
return Err(InvalidPricingParameters)
|
|
}
|
|
if self.multiplier == FixedU128::zero() {
|
|
return Err(InvalidPricingParameters)
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
/// Holder for fixed point number implemented in <https://github.com/PaulRBerg/prb-math>
|
|
#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
|
|
#[cfg_attr(feature = "std", derive(PartialEq))]
|
|
pub struct UD60x18(U256);
|
|
|
|
impl From<FixedU128> for UD60x18 {
|
|
fn from(value: FixedU128) -> Self {
|
|
// Both FixedU128 and UD60x18 have 18 decimal places
|
|
let inner: u128 = value.into_inner();
|
|
UD60x18(inner.into())
|
|
}
|
|
}
|
|
|
|
impl UD60x18 {
|
|
pub fn into_inner(self) -> U256 {
|
|
self.0
|
|
}
|
|
}
|