From 70ef6a6e12ca3c45d9e04f9a59ef745d035255fb Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi <shawntabrizi@gmail.com> Date: Thu, 29 Oct 2020 11:12:39 +0100 Subject: [PATCH] Update Tips to go 100% to Author (#1836) * 100% of tip goes to Author * refactor dealwithfees into common * add fee and tip test * fix --- polkadot/runtime/common/Cargo.toml | 1 + polkadot/runtime/common/src/impls.rs | 183 ++++++++++++++++++++++++++- polkadot/runtime/kusama/src/lib.rs | 18 +-- polkadot/runtime/polkadot/src/lib.rs | 16 +-- 4 files changed, 192 insertions(+), 26 deletions(-) diff --git a/polkadot/runtime/common/Cargo.toml b/polkadot/runtime/common/Cargo.toml index cfdf76ee884..b3ac78e9040 100644 --- a/polkadot/runtime/common/Cargo.toml +++ b/polkadot/runtime/common/Cargo.toml @@ -32,6 +32,7 @@ pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = " pallet-vesting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } pallet-offences = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +pallet-treasury = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false } diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index f371972ccae..72d4f6ce895 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -21,7 +21,6 @@ use crate::NegativeImbalance; /// Logic for the author to get a portion of fees. pub struct ToAuthor<R>(sp_std::marker::PhantomData<R>); - impl<R> OnUnbalanced<NegativeImbalance<R>> for ToAuthor<R> where R: pallet_balances::Trait + pallet_authorship::Trait, @@ -40,3 +39,185 @@ where <frame_system::Module<R>>::deposit_event(pallet_balances::RawEvent::Deposit(author, numeric_amount)); } } + +pub struct DealWithFees<R>(sp_std::marker::PhantomData<R>); +impl<R> OnUnbalanced<NegativeImbalance<R>> for DealWithFees<R> +where + R: pallet_balances::Trait + pallet_treasury::Trait + pallet_authorship::Trait, + pallet_treasury::Module<R>: OnUnbalanced<NegativeImbalance<R>>, + <R as frame_system::Trait>::AccountId: From<primitives::v1::AccountId>, + <R as frame_system::Trait>::AccountId: Into<primitives::v1::AccountId>, + <R as frame_system::Trait>::Event: From<pallet_balances::RawEvent< + <R as frame_system::Trait>::AccountId, + <R as pallet_balances::Trait>::Balance, + pallet_balances::DefaultInstance> + >, +{ + fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item=NegativeImbalance<R>>) { + if let Some(fees) = fees_then_tips.next() { + // 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, 100% to author + tips.merge_into(&mut split.1); + } + use pallet_treasury::Module as Treasury; + <Treasury<R> as OnUnbalanced<_>>::on_unbalanced(split.0); + <ToAuthor<R> as OnUnbalanced<_>>::on_unbalanced(split.1); + } + } +} + + +#[cfg(test)] +mod tests { + use super::*; + use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; + use frame_support::traits::FindAuthor; + use sp_core::H256; + use sp_runtime::{ + testing::Header, ModuleId, + traits::{BlakeTwo256, IdentityLookup}, + Perbill, + }; + use primitives::v1::AccountId; + + #[derive(Clone, PartialEq, Eq, Debug)] + pub struct Test; + + impl_outer_origin!{ + pub enum Origin for Test {} + } + + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const ExtrinsicBaseWeight: u64 = 100; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + } + + impl frame_system::Trait for Test { + type BaseCallFilter = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup<Self::AccountId>; + type Header = Header; + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = ExtrinsicBaseWeight; + type MaximumExtrinsicWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + type PalletInfo = (); + type AccountData = pallet_balances::AccountData<u64>; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + } + + impl pallet_balances::Trait for Test { + type Balance = u64; + type Event = (); + type DustRemoval = (); + type ExistentialDeposit = (); + type AccountStore = System; + type MaxLocks = (); + type WeightInfo = (); + } + + pub struct Nobody; + impl frame_support::traits::Contains<AccountId> for Nobody { + fn contains(_: &AccountId) -> bool { false } + fn sorted_members() -> Vec<AccountId> { vec![] } + #[cfg(feature = "runtime-benchmarks")] + fn add(_: &AccountId) { unimplemented!() } + } + impl frame_support::traits::ContainsLengthBound for Nobody { + fn min_len() -> usize { 0 } + fn max_len() -> usize { 0 } + } + + parameter_types! { + pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry"); + } + + impl pallet_treasury::Trait for Test { + type Currency = pallet_balances::Module<Test>; + type ApproveOrigin = frame_system::EnsureRoot<AccountId>; + type RejectOrigin = frame_system::EnsureRoot<AccountId>; + type Event = (); + type OnSlash = (); + type ProposalBond = (); + type ProposalBondMinimum = (); + type SpendPeriod = (); + type Burn = (); + type BurnDestination = (); + type Tippers = Nobody; + type TipCountdown = (); + type TipFindersFee = (); + type TipReportDepositBase = (); + type DataDepositPerByte = (); + type BountyDepositBase = (); + type BountyDepositPayoutDelay = (); + type BountyUpdatePeriod = (); + type MaximumReasonLength = (); + type BountyCuratorDeposit = (); + type BountyValueMinimum = (); + type ModuleId = TreasuryModuleId; + type WeightInfo = (); + } + + pub struct OneAuthor; + impl FindAuthor<AccountId> for OneAuthor { + fn find_author<'a, I>(_: I) -> Option<AccountId> + where I: 'a, + { + Some(Default::default()) + } + } + impl pallet_authorship::Trait for Test { + type FindAuthor = OneAuthor; + type UncleGenerations = (); + type FilterUncle = (); + type EventHandler = (); + } + + type Treasury = pallet_treasury::Module<Test>; + type Balances = pallet_balances::Module<Test>; + type System = frame_system::Module<Test>; + + pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap(); + // We use default for brevity, but you can configure as desired if needed. + pallet_balances::GenesisConfig::<Test>::default().assimilate_storage(&mut t).unwrap(); + t.into() + } + + #[test] + fn test_fees_and_tip_split() { + new_test_ext().execute_with(|| { + let fee = Balances::issue(10); + let tip = Balances::issue(20); + + assert_eq!(Balances::free_balance(Treasury::account_id()), 0); + assert_eq!(Balances::free_balance(AccountId::default()), 0); + + DealWithFees::on_unbalanceds(vec![fee, tip].into_iter()); + + // Author gets 100% of tip and 20% of fee = 22 + assert_eq!(Balances::free_balance(AccountId::default()), 22); + // Treasury gets 80% of fee + assert_eq!(Balances::free_balance(Treasury::account_id()), 8); + }); + } +} diff --git a/polkadot/runtime/kusama/src/lib.rs b/polkadot/runtime/kusama/src/lib.rs index 54ae7a16250..aac964802cc 100644 --- a/polkadot/runtime/kusama/src/lib.rs +++ b/polkadot/runtime/kusama/src/lib.rs @@ -21,7 +21,7 @@ #![recursion_limit = "256"] use sp_std::prelude::*; -use sp_core::u32_trait::{_1, _2, _3, _4, _5}; +use sp_core::u32_trait::{_1, _2, _3, _5}; use codec::{Encode, Decode}; use primitives::v1::{ AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt, @@ -30,8 +30,8 @@ use primitives::v1::{ }; use runtime_common::{ claims, SlowAdjustingFeeUpdate, CurrencyToVote, - impls::ToAuthor, - NegativeImbalance, BlockHashCount, MaximumBlockWeight, AvailableBlockRatio, + impls::DealWithFees, + BlockHashCount, MaximumBlockWeight, AvailableBlockRatio, MaximumBlockLength, BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, MaximumExtrinsicWeight, ParachainSessionKeyPlaceholder, }; @@ -55,7 +55,7 @@ use sp_core::OpaqueMetadata; use sp_staking::SessionIndex; use frame_support::{ parameter_types, construct_runtime, debug, RuntimeDebug, - traits::{KeyOwnerProofSystem, SplitTwoWays, Randomness, LockIdentifier, Filter, InstanceFilter}, + traits::{KeyOwnerProofSystem, Randomness, LockIdentifier, Filter, InstanceFilter}, weights::Weight, }; use frame_system::{EnsureRoot, EnsureOneOf}; @@ -214,14 +214,6 @@ parameter_types! { pub const MaxLocks: u32 = 50; } -/// Splits fees 80/20 between treasury and block author. -pub type DealWithFees = SplitTwoWays< - Balance, - NegativeImbalance<Runtime>, - _4, Treasury, // 4 parts (80%) goes to the treasury. - _1, ToAuthor<Runtime>, // 1 part (20%) goes to the block author. ->; - impl pallet_balances::Trait for Runtime { type Balance = Balance; type DustRemoval = (); @@ -238,7 +230,7 @@ parameter_types! { impl pallet_transaction_payment::Trait for Runtime { type Currency = Balances; - type OnTransactionPayment = DealWithFees; + type OnTransactionPayment = DealWithFees<Self>; type TransactionByteFee = TransactionByteFee; type WeightToFee = WeightToFee; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>; diff --git a/polkadot/runtime/polkadot/src/lib.rs b/polkadot/runtime/polkadot/src/lib.rs index e2e0b1780ec..b14771b8e77 100644 --- a/polkadot/runtime/polkadot/src/lib.rs +++ b/polkadot/runtime/polkadot/src/lib.rs @@ -22,8 +22,8 @@ use runtime_common::{ claims, SlowAdjustingFeeUpdate, CurrencyToVote, - impls::ToAuthor, - NegativeImbalance, BlockHashCount, MaximumBlockWeight, AvailableBlockRatio, + impls::DealWithFees, + BlockHashCount, MaximumBlockWeight, AvailableBlockRatio, MaximumBlockLength, BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, MaximumExtrinsicWeight, ParachainSessionKeyPlaceholder, }; @@ -55,7 +55,7 @@ use sp_core::OpaqueMetadata; use sp_staking::SessionIndex; use frame_support::{ parameter_types, construct_runtime, debug, RuntimeDebug, - traits::{KeyOwnerProofSystem, SplitTwoWays, Randomness, LockIdentifier, Filter}, + traits::{KeyOwnerProofSystem, Randomness, LockIdentifier, Filter}, weights::Weight, }; use frame_system::{EnsureRoot, EnsureOneOf}; @@ -227,14 +227,6 @@ parameter_types! { pub const MaxLocks: u32 = 50; } -/// Splits fees 80/20 between treasury and block author. -pub type DealWithFees = SplitTwoWays< - Balance, - NegativeImbalance<Runtime>, - _4, Treasury, // 4 parts (80%) goes to the treasury. - _1, ToAuthor<Runtime>, // 1 part (20%) goes to the block author. ->; - impl pallet_balances::Trait for Runtime { type Balance = Balance; type DustRemoval = (); @@ -251,7 +243,7 @@ parameter_types! { impl pallet_transaction_payment::Trait for Runtime { type Currency = Balances; - type OnTransactionPayment = DealWithFees; + type OnTransactionPayment = DealWithFees<Runtime>; type TransactionByteFee = TransactionByteFee; type WeightToFee = WeightToFee; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>; -- GitLab