diff --git a/Cargo.lock b/Cargo.lock index fdcd450454629..815254376e6cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4664,6 +4664,7 @@ dependencies = [ "pallet-contracts", "pallet-im-online", "pallet-timestamp", + "pallet-transaction-payment", "pallet-treasury", "parity-scale-codec", "sc-executor", diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 0145cacef8f7d..c514cdf6c25fd 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -249,6 +249,7 @@ impl pallet_balances::Config for Runtime { } impl pallet_transaction_payment::Config for Runtime { + type Event = Event; type OnChargeTransaction = CurrencyAdapter; type OperationalFeeMultiplier = ConstU8<5>; type WeightToFee = IdentityFee; diff --git a/bin/node/bench/src/import.rs b/bin/node/bench/src/import.rs index faba85468b1fa..b9229fbd5331d 100644 --- a/bin/node/bench/src/import.rs +++ b/bin/node/bench/src/import.rs @@ -135,9 +135,10 @@ impl core::Benchmark for ImportBenchmark { .inspect_state(|| { match self.block_type { BlockType::RandomTransfersKeepAlive => { - // should be 7 per signed extrinsic + 1 per unsigned + // should be 8 per signed extrinsic + 1 per unsigned // we have 1 unsigned and the rest are signed in the block - // those 7 events per signed are: + // those 8 events per signed are: + // - transaction paid for the transaction payment // - withdraw (Balances::Withdraw) for charging the transaction fee // - new account (System::NewAccount) as we always transfer fund to // non-existent account @@ -148,7 +149,7 @@ impl core::Benchmark for ImportBenchmark { // - extrinsic success assert_eq!( node_runtime::System::events().len(), - (self.block.extrinsics.len() - 1) * 7 + 1, + (self.block.extrinsics.len() - 1) * 8 + 1, ); }, BlockType::Noop => { diff --git a/bin/node/executor/Cargo.toml b/bin/node/executor/Cargo.toml index 6b6a1709d5aa0..5fbf59a74fdcd 100644 --- a/bin/node/executor/Cargo.toml +++ b/bin/node/executor/Cargo.toml @@ -36,6 +36,7 @@ pallet-contracts = { version = "4.0.0-dev", path = "../../../frame/contracts" } pallet-im-online = { version = "4.0.0-dev", path = "../../../frame/im-online" } pallet-timestamp = { version = "4.0.0-dev", path = "../../../frame/timestamp" } pallet-treasury = { version = "4.0.0-dev", path = "../../../frame/treasury" } +pallet-transaction-payment = { version = "4.0.0-dev", path = "../../../frame/transaction-payment" } sp-application-crypto = { version = "6.0.0", path = "../../../primitives/application-crypto" } sp-consensus-babe = { version = "0.10.0-dev", path = "../../../primitives/consensus/babe" } sp-externalities = { version = "0.12.0", path = "../../../primitives/externalities" } diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index da0f4e6afb319..de2aa6c18369d 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -417,6 +417,17 @@ fn full_native_block_import_works() { event: Event::Treasury(pallet_treasury::Event::Deposit { value: fees * 8 / 10 }), topics: vec![], }, + EventRecord { + phase: Phase::ApplyExtrinsic(1), + event: Event::TransactionPayment( + pallet_transaction_payment::Event::TransactionFeePaid { + who: alice().into(), + actual_fee: fees, + tip: 0, + }, + ), + topics: vec![], + }, EventRecord { phase: Phase::ApplyExtrinsic(1), event: Event::System(frame_system::Event::ExtrinsicSuccess { @@ -488,6 +499,17 @@ fn full_native_block_import_works() { event: Event::Treasury(pallet_treasury::Event::Deposit { value: fees * 8 / 10 }), topics: vec![], }, + EventRecord { + phase: Phase::ApplyExtrinsic(1), + event: Event::TransactionPayment( + pallet_transaction_payment::Event::TransactionFeePaid { + who: bob().into(), + actual_fee: fees, + tip: 0, + }, + ), + topics: vec![], + }, EventRecord { phase: Phase::ApplyExtrinsic(1), event: Event::System(frame_system::Event::ExtrinsicSuccess { @@ -525,6 +547,17 @@ fn full_native_block_import_works() { event: Event::Treasury(pallet_treasury::Event::Deposit { value: fees * 8 / 10 }), topics: vec![], }, + EventRecord { + phase: Phase::ApplyExtrinsic(2), + event: Event::TransactionPayment( + pallet_transaction_payment::Event::TransactionFeePaid { + who: alice().into(), + actual_fee: fees, + tip: 0, + }, + ), + topics: vec![], + }, EventRecord { phase: Phase::ApplyExtrinsic(2), event: Event::System(frame_system::Event::ExtrinsicSuccess { diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index bc889e002bf4f..addcd0b35a9d9 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -447,6 +447,7 @@ parameter_types! { } impl pallet_transaction_payment::Config for Runtime { + type Event = Event; type OnChargeTransaction = CurrencyAdapter; type OperationalFeeMultiplier = OperationalFeeMultiplier; type WeightToFee = IdentityFee; diff --git a/client/db/src/parity_db.rs b/client/db/src/parity_db.rs index 7ce1d6a683401..4adacbf6f041c 100644 --- a/client/db/src/parity_db.rs +++ b/client/db/src/parity_db.rs @@ -106,7 +106,7 @@ impl> Database for DbAdapter { } return None }, - Change::Reference(col, key) => + Change::Reference(col, key) => { if ref_counted_column(col) { // FIXME accessing value is not strictly needed, optimize this in parity-db. let value = >::get(self, col, key.as_ref()); @@ -116,7 +116,8 @@ impl> Database for DbAdapter { not_ref_counted_column.push(col); } return None - }, + } + }, Change::Release(col, key) => if ref_counted_column(col) { (col as u8, key.as_ref().to_vec(), None) diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 298c2a6963880..683ebce2b1693 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -158,6 +158,7 @@ mod tests; mod benchmarking; mod tests_composite; mod tests_local; +#[cfg(test)] mod tests_reentrancy; pub mod weights; diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index 4a2cc1d91936d..4ab913cf1411a 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -40,7 +40,7 @@ frame_support::construct_runtime!( { System: frame_system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage}, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, } ); @@ -77,6 +77,7 @@ impl frame_system::Config for Test { } impl pallet_transaction_payment::Config for Test { + type Event = Event; type OnChargeTransaction = CurrencyAdapter, ()>; type OperationalFeeMultiplier = ConstU8<5>; type WeightToFee = IdentityFee; diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index cfc7f84ab3a38..6f4c50d90153a 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -41,7 +41,7 @@ frame_support::construct_runtime!( { System: frame_system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage}, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, } ); @@ -78,6 +78,7 @@ impl frame_system::Config for Test { } impl pallet_transaction_payment::Config for Test { + type Event = Event; type OnChargeTransaction = CurrencyAdapter, ()>; type OperationalFeeMultiplier = ConstU8<5>; type WeightToFee = IdentityFee; diff --git a/frame/balances/src/tests_reentrancy.rs b/frame/balances/src/tests_reentrancy.rs index 7037e9615afd8..4c028840d553c 100644 --- a/frame/balances/src/tests_reentrancy.rs +++ b/frame/balances/src/tests_reentrancy.rs @@ -19,13 +19,11 @@ #![cfg(test)] -use crate::{self as pallet_balances, Config, Pallet}; +use crate::{self as pallet_balances, Config}; use frame_support::{ parameter_types, - traits::{ConstU32, ConstU64, ConstU8, StorageMapShim}, - weights::IdentityFee, + traits::{ConstU32, ConstU64, StorageMapShim}, }; -use pallet_transaction_payment::CurrencyAdapter; use sp_core::H256; use sp_io; use sp_runtime::{testing::Header, traits::IdentityLookup}; @@ -83,14 +81,6 @@ impl frame_system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; } -impl pallet_transaction_payment::Config for Test { - type OnChargeTransaction = CurrencyAdapter, ()>; - type OperationalFeeMultiplier = ConstU8<5>; - type WeightToFee = IdentityFee; - type LengthToFee = IdentityFee; - type FeeMultiplierUpdate = (); -} - pub struct OnDustRemoval; impl OnUnbalanced> for OnDustRemoval { fn on_nonzero_unbalanced(amount: NegativeImbalance) { diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 55b7e926a0fad..60bf0a47ca120 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -722,7 +722,7 @@ mod tests { { System: frame_system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage}, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, Custom: custom::{Pallet, Call, ValidateUnsigned, Inherent}, } ); @@ -783,6 +783,7 @@ mod tests { pub const TransactionByteFee: Balance = 0; } impl pallet_transaction_payment::Config for Runtime { + type Event = Event; type OnChargeTransaction = CurrencyAdapter; type OperationalFeeMultiplier = ConstU8<5>; type WeightToFee = IdentityFee; diff --git a/frame/transaction-payment/asset-tx-payment/src/tests.rs b/frame/transaction-payment/asset-tx-payment/src/tests.rs index 5b1fa157c3f10..ad5bc3f22e57f 100644 --- a/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -48,7 +48,7 @@ frame_support::construct_runtime!( { System: system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage}, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, Assets: pallet_assets::{Pallet, Call, Storage, Event}, Authorship: pallet_authorship::{Pallet, Call, Storage}, AssetTxPayment: pallet_asset_tx_payment::{Pallet}, @@ -143,6 +143,7 @@ impl WeightToFeeT for TransactionByteFee { } impl pallet_transaction_payment::Config for Runtime { + type Event = Event; type OnChargeTransaction = CurrencyAdapter; type WeightToFee = WeightToFee; type LengthToFee = TransactionByteFee; diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index d44f8b1b894e1..0f5c0321130be 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -249,6 +249,9 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { + /// The overarching event type. + type Event: From> + IsType<::Event>; + /// Handler for withdrawing, refunding and depositing the transaction fee. /// Transaction fees are withdrawn before the transaction is executed. /// After the transaction was executed the transaction weight can be @@ -321,6 +324,14 @@ pub mod pallet { } } + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// A transaction fee `actual_fee`, of which `tip` was added to the minimum inclusion fee, + /// has been paid by `who`. + TransactionFeePaid { who: T::AccountId, actual_fee: BalanceOf, tip: BalanceOf }, + } + #[pallet::hooks] impl Hooks> for Pallet { fn on_finalize(_: T::BlockNumber) { @@ -734,6 +745,7 @@ where T::OnChargeTransaction::correct_and_deposit_fee( &who, info, post_info, actual_fee, tip, imbalance, )?; + Pallet::::deposit_event(Event::::TransactionFeePaid { who, actual_fee, tip }); } Ok(()) } @@ -790,7 +802,7 @@ mod tests { { System: system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage}, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, } ); @@ -899,6 +911,7 @@ mod tests { } impl Config for Runtime { + type Event = Event; type OnChargeTransaction = CurrencyAdapter; type OperationalFeeMultiplier = OperationalFeeMultiplier; type WeightToFee = WeightToFee; @@ -1407,8 +1420,14 @@ mod tests { &Ok(()) )); assert_eq!(Balances::total_balance(&user), 0); - // No events for such a scenario - assert_eq!(System::events().len(), 0); + // TransactionFeePaid Event + System::assert_has_event(Event::TransactionPayment( + pallet_transaction_payment::Event::TransactionFeePaid { + who: user, + actual_fee: 0, + tip: 0, + }, + )); }); }