mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 10:31:04 +00:00
Split fees and tips between author and treasury independently (#5207)
* Split fees and tips between author and treasury independently * Docs and cleanup * Fix test
This commit is contained in:
@@ -24,7 +24,7 @@ use sp_std::prelude::*;
|
|||||||
use frame_support::{
|
use frame_support::{
|
||||||
construct_runtime, parameter_types, debug,
|
construct_runtime, parameter_types, debug,
|
||||||
weights::Weight,
|
weights::Weight,
|
||||||
traits::{SplitTwoWays, Currency, Randomness},
|
traits::{Currency, Randomness, OnUnbalanced, Imbalance},
|
||||||
};
|
};
|
||||||
use sp_core::u32_trait::{_1, _2, _3, _4};
|
use sp_core::u32_trait::{_1, _2, _3, _4};
|
||||||
pub use node_primitives::{AccountId, Signature};
|
pub use node_primitives::{AccountId, Signature};
|
||||||
@@ -98,12 +98,21 @@ pub fn native_version() -> NativeVersion {
|
|||||||
|
|
||||||
type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
|
type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
|
||||||
|
|
||||||
pub type DealWithFees = SplitTwoWays<
|
pub struct DealWithFees;
|
||||||
Balance,
|
impl OnUnbalanced<NegativeImbalance> for DealWithFees {
|
||||||
NegativeImbalance,
|
fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item=NegativeImbalance>) {
|
||||||
_4, Treasury, // 4 parts (80%) goes to the treasury.
|
if let Some(fees) = fees_then_tips.next() {
|
||||||
_1, Author, // 1 part (20%) goes to the block author.
|
// for fees, 80% to treasury, 20% to author
|
||||||
>;
|
let mut split = fees.ration(80, 20);
|
||||||
|
if let Some(tips) = fees_then_tips.next() {
|
||||||
|
// for tips, if any, 80% to treasury, 20% to author (though this can be anything)
|
||||||
|
tips.ration_merge_into(80, 20, &mut split);
|
||||||
|
}
|
||||||
|
Treasury::on_unbalanced(split.0);
|
||||||
|
Author::on_unbalanced(split.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const BlockHashCount: BlockNumber = 250;
|
pub const BlockHashCount: BlockNumber = 250;
|
||||||
|
|||||||
@@ -256,6 +256,13 @@ pub trait KeyOwnerProofSystem<Key> {
|
|||||||
/// - Someone got slashed.
|
/// - Someone got slashed.
|
||||||
/// - Someone paid for a transaction to be included.
|
/// - Someone paid for a transaction to be included.
|
||||||
pub trait OnUnbalanced<Imbalance: TryDrop> {
|
pub trait OnUnbalanced<Imbalance: TryDrop> {
|
||||||
|
/// Handler for some imbalances. The different imbalances might have different origins or
|
||||||
|
/// meanings, dependent on the context. Will default to simply calling on_unbalanced for all
|
||||||
|
/// of them. Infallible.
|
||||||
|
fn on_unbalanceds<B>(amounts: impl Iterator<Item=Imbalance>) where Imbalance: crate::traits::Imbalance<B> {
|
||||||
|
Self::on_unbalanced(amounts.fold(Imbalance::zero(), |i, x| x.merge(i)))
|
||||||
|
}
|
||||||
|
|
||||||
/// Handler for some imbalance. Infallible.
|
/// Handler for some imbalance. Infallible.
|
||||||
fn on_unbalanced(amount: Imbalance) {
|
fn on_unbalanced(amount: Imbalance) {
|
||||||
amount.try_drop().unwrap_or_else(Self::on_nonzero_unbalanced)
|
amount.try_drop().unwrap_or_else(Self::on_nonzero_unbalanced)
|
||||||
@@ -263,13 +270,11 @@ pub trait OnUnbalanced<Imbalance: TryDrop> {
|
|||||||
|
|
||||||
/// Actually handle a non-zero imbalance. You probably want to implement this rather than
|
/// Actually handle a non-zero imbalance. You probably want to implement this rather than
|
||||||
/// `on_unbalanced`.
|
/// `on_unbalanced`.
|
||||||
fn on_nonzero_unbalanced(amount: Imbalance);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Imbalance: TryDrop> OnUnbalanced<Imbalance> for () {
|
|
||||||
fn on_nonzero_unbalanced(amount: Imbalance) { drop(amount); }
|
fn on_nonzero_unbalanced(amount: Imbalance) { drop(amount); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Imbalance: TryDrop> OnUnbalanced<Imbalance> for () {}
|
||||||
|
|
||||||
/// Simple boolean for whether an account needs to be kept in existence.
|
/// Simple boolean for whether an account needs to be kept in existence.
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||||
pub enum ExistenceRequirement {
|
pub enum ExistenceRequirement {
|
||||||
@@ -331,10 +336,71 @@ pub trait Imbalance<Balance>: Sized + TryDrop {
|
|||||||
/// is guaranteed to be at most `amount` and the second will be the remainder.
|
/// is guaranteed to be at most `amount` and the second will be the remainder.
|
||||||
fn split(self, amount: Balance) -> (Self, Self);
|
fn split(self, amount: Balance) -> (Self, Self);
|
||||||
|
|
||||||
|
/// Consume `self` and return two independent instances; the amounts returned will be in
|
||||||
|
/// approximately the same ratio as `first`:`second`.
|
||||||
|
///
|
||||||
|
/// NOTE: This requires up to `first + second` room for a multiply, and `first + second` should
|
||||||
|
/// fit into a `u32`. Overflow will safely saturate in both cases.
|
||||||
|
fn ration(self, first: u32, second: u32) -> (Self, Self)
|
||||||
|
where Balance: From<u32> + Saturating + Div<Output=Balance>
|
||||||
|
{
|
||||||
|
let total: u32 = first.saturating_add(second);
|
||||||
|
let amount1 = self.peek().saturating_mul(first.into()) / total.into();
|
||||||
|
self.split(amount1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consume self and add its two components, defined by the first component's balance,
|
||||||
|
/// element-wise to two pre-existing Imbalances.
|
||||||
|
///
|
||||||
|
/// A convenient replacement for `split` and `merge`.
|
||||||
|
fn split_merge(self, amount: Balance, others: (Self, Self)) -> (Self, Self) {
|
||||||
|
let (a, b) = self.split(amount);
|
||||||
|
(a.merge(others.0), b.merge(others.1))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consume self and add its two components, defined by the ratio `first`:`second`,
|
||||||
|
/// element-wise to two pre-existing Imbalances.
|
||||||
|
///
|
||||||
|
/// A convenient replacement for `split` and `merge`.
|
||||||
|
fn ration_merge(self, first: u32, second: u32, others: (Self, Self)) -> (Self, Self)
|
||||||
|
where Balance: From<u32> + Saturating + Div<Output=Balance>
|
||||||
|
{
|
||||||
|
let (a, b) = self.ration(first, second);
|
||||||
|
(a.merge(others.0), b.merge(others.1))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consume self and add its two components, defined by the first component's balance,
|
||||||
|
/// element-wise into two pre-existing Imbalance refs.
|
||||||
|
///
|
||||||
|
/// A convenient replacement for `split` and `subsume`.
|
||||||
|
fn split_merge_into(self, amount: Balance, others: &mut (Self, Self)) {
|
||||||
|
let (a, b) = self.split(amount);
|
||||||
|
others.0.subsume(a);
|
||||||
|
others.1.subsume(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consume self and add its two components, defined by the ratio `first`:`second`,
|
||||||
|
/// element-wise to two pre-existing Imbalances.
|
||||||
|
///
|
||||||
|
/// A convenient replacement for `split` and `merge`.
|
||||||
|
fn ration_merge_into(self, first: u32, second: u32, others: &mut (Self, Self))
|
||||||
|
where Balance: From<u32> + Saturating + Div<Output=Balance>
|
||||||
|
{
|
||||||
|
let (a, b) = self.ration(first, second);
|
||||||
|
others.0.subsume(a);
|
||||||
|
others.1.subsume(b);
|
||||||
|
}
|
||||||
|
|
||||||
/// Consume `self` and an `other` to return a new instance that combines
|
/// Consume `self` and an `other` to return a new instance that combines
|
||||||
/// both.
|
/// both.
|
||||||
fn merge(self, other: Self) -> Self;
|
fn merge(self, other: Self) -> Self;
|
||||||
|
|
||||||
|
/// Consume self to mutate `other` so that it combines both. Just like `subsume`, only with
|
||||||
|
/// reversed arguments.
|
||||||
|
fn merge_into(self, other: &mut Self) {
|
||||||
|
other.subsume(self)
|
||||||
|
}
|
||||||
|
|
||||||
/// Consume `self` and maybe an `other` to return a new instance that combines
|
/// Consume `self` and maybe an `other` to return a new instance that combines
|
||||||
/// both.
|
/// both.
|
||||||
fn maybe_merge(self, other: Option<Self>) -> Self {
|
fn maybe_merge(self, other: Option<Self>) -> Self {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ use sp_std::prelude::*;
|
|||||||
use codec::{Encode, Decode};
|
use codec::{Encode, Decode};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
decl_storage, decl_module,
|
decl_storage, decl_module,
|
||||||
traits::{Currency, Get, OnUnbalanced, ExistenceRequirement, WithdrawReason},
|
traits::{Currency, Get, OnUnbalanced, ExistenceRequirement, WithdrawReason, Imbalance},
|
||||||
weights::{Weight, DispatchInfo, GetDispatchInfo},
|
weights::{Weight, DispatchInfo, GetDispatchInfo},
|
||||||
};
|
};
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
@@ -58,7 +58,9 @@ pub trait Trait: frame_system::Trait {
|
|||||||
/// The currency type in which fees will be paid.
|
/// The currency type in which fees will be paid.
|
||||||
type Currency: Currency<Self::AccountId> + Send + Sync;
|
type Currency: Currency<Self::AccountId> + Send + Sync;
|
||||||
|
|
||||||
/// Handler for the unbalanced reduction when taking transaction fees.
|
/// Handler for the unbalanced reduction when taking transaction fees. This is either one or
|
||||||
|
/// two separate imbalances, the first is the transaction fee paid, the second is the tip paid,
|
||||||
|
/// if any.
|
||||||
type OnTransactionPayment: OnUnbalanced<NegativeImbalanceOf<Self>>;
|
type OnTransactionPayment: OnUnbalanced<NegativeImbalanceOf<Self>>;
|
||||||
|
|
||||||
/// The fee to be paid for making a transaction; the base.
|
/// The fee to be paid for making a transaction; the base.
|
||||||
@@ -234,7 +236,9 @@ impl<T: Trait + Send + Sync> SignedExtension for ChargeTransactionPayment<T>
|
|||||||
Ok(imbalance) => imbalance,
|
Ok(imbalance) => imbalance,
|
||||||
Err(_) => return InvalidTransaction::Payment.into(),
|
Err(_) => return InvalidTransaction::Payment.into(),
|
||||||
};
|
};
|
||||||
T::OnTransactionPayment::on_unbalanced(imbalance);
|
let imbalances = imbalance.split(tip);
|
||||||
|
T::OnTransactionPayment::on_unbalanceds(Some(imbalances.0).into_iter()
|
||||||
|
.chain(Some(imbalances.1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut r = ValidTransaction::default();
|
let mut r = ValidTransaction::default();
|
||||||
|
|||||||
Reference in New Issue
Block a user