From c39a4643ab00bdb210aacdd89be3e66d98f4a033 Mon Sep 17 00:00:00 2001 From: zjb0807 Date: Fri, 17 Dec 2021 08:18:27 +0800 Subject: [PATCH] Refund extra tip (#1706) * refund extra tip * add more tests --- modules/transaction-payment/src/lib.rs | 16 ++++++- modules/transaction-payment/src/tests.rs | 59 ++++++++++++++++++++++++ runtime/acala/src/constants.rs | 23 +++++++-- runtime/karura/src/constants.rs | 21 +++++++-- runtime/mandala/src/constants.rs | 28 +++++++---- runtime/mandala/src/lib.rs | 2 +- 6 files changed, 129 insertions(+), 20 deletions(-) diff --git a/modules/transaction-payment/src/lib.rs b/modules/transaction-payment/src/lib.rs index 723140ba50..27b1f3e511 100644 --- a/modules/transaction-payment/src/lib.rs +++ b/modules/transaction-payment/src/lib.rs @@ -884,7 +884,19 @@ where let (tip, who, imbalance, fee) = pre; if let Some(payed) = imbalance { let actual_fee = Pallet::::compute_actual_fee(len as u32, info, post_info, tip); - let refund = fee.saturating_sub(actual_fee); + let refund_fee = fee.saturating_sub(actual_fee); + let mut refund = refund_fee; + let mut actual_tip = tip; + + if !tip.is_zero() && !info.weight.is_zero() { + // tip_pre_weight * unspent_weight + let refund_tip = tip + .checked_div(&info.weight.saturated_into::>()) + .expect("checked is non-zero; qed") + .saturating_mul(post_info.calc_unspent(info).saturated_into::>()); + refund = refund_fee.saturating_add(refund_tip); + actual_tip = tip.saturating_sub(refund_tip); + } let actual_payment = match ::Currency::deposit_into_existing(&who, refund) { Ok(refund_imbalance) => { // The refund cannot be larger than the up front payed max weight. @@ -899,7 +911,7 @@ where // is gone in that case. Err(_) => payed, }; - let (tip, fee) = actual_payment.split(tip); + let (tip, fee) = actual_payment.split(actual_tip); // distribute fee ::OnTransactionPayment::on_unbalanceds(Some(fee).into_iter().chain(Some(tip))); diff --git a/modules/transaction-payment/src/tests.rs b/modules/transaction-payment/src/tests.rs index 046c2e9a5a..71b024bd18 100644 --- a/modules/transaction-payment/src/tests.rs +++ b/modules/transaction-payment/src/tests.rs @@ -192,6 +192,65 @@ fn refund_fee_according_to_actual_when_post_dispatch_and_native_currency_is_enou }); } +#[test] +fn refund_tip_according_to_actual_when_post_dispatch_and_native_currency_is_enough() { + ExtBuilder::default() + .one_hundred_thousand_for_alice_n_charlie() + .build() + .execute_with(|| { + // tip = 0 + let fee = 23 * 2 + 1000; // len * byte + weight + let pre = ChargeTransactionPayment::::from(0) + .pre_dispatch(&ALICE, CALL, &INFO, 23) + .unwrap(); + assert_eq!(Currencies::free_balance(ACA, &ALICE), 100000 - fee); + + let refund = 200; // 1000 - 800 + assert!(ChargeTransactionPayment::::post_dispatch(pre, &INFO, &POST_INFO, 23, &Ok(())).is_ok()); + assert_eq!(Currencies::free_balance(ACA, &ALICE), 100000 - fee + refund); + + // tip = 1000 + let fee = 23 * 2 + 1000; // len * byte + weight + let tip = 1000; + let pre = ChargeTransactionPayment::::from(tip) + .pre_dispatch(&CHARLIE, CALL, &INFO, 23) + .unwrap(); + assert_eq!(Currencies::free_balance(ACA, &CHARLIE), 100000 - fee - tip); + + let refund_fee = 200; // 1000 - 800 + let refund_tip = 200; // 1000 - 800 + assert!(ChargeTransactionPayment::::post_dispatch(pre, &INFO, &POST_INFO, 23, &Ok(())).is_ok()); + assert_eq!( + Currencies::free_balance(ACA, &CHARLIE), + 100000 - fee - tip + refund_fee + refund_tip + ); + }); +} + +#[test] +fn refund_should_not_works() { + ExtBuilder::default() + .one_hundred_thousand_for_alice_n_charlie() + .build() + .execute_with(|| { + let tip = 1000; + let fee = 23 * 2 + 1000; // len * byte + weight + let pre = ChargeTransactionPayment::::from(tip) + .pre_dispatch(&ALICE, CALL, &INFO, 23) + .unwrap(); + assert_eq!(Currencies::free_balance(ACA, &ALICE), 100000 - fee - tip); + + // actual_weight > weight + const POST_INFO: PostDispatchInfo = PostDispatchInfo { + actual_weight: Some(INFO.weight + 1), + pays_fee: Pays::Yes, + }; + + assert!(ChargeTransactionPayment::::post_dispatch(pre, &INFO, &POST_INFO, 23, &Ok(())).is_ok()); + assert_eq!(Currencies::free_balance(ACA, &ALICE), 100000 - fee - tip); + }); +} + #[test] fn charges_fee_when_validate_and_native_is_not_enough() { ExtBuilder::default() diff --git a/runtime/acala/src/constants.rs b/runtime/acala/src/constants.rs index df5373b209..cfe463bc71 100644 --- a/runtime/acala/src/constants.rs +++ b/runtime/acala/src/constants.rs @@ -49,10 +49,7 @@ pub mod fee { use smallvec::smallvec; use sp_runtime::Perbill; - /// The block saturation level. Fees will be updates based on this value. - pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); - - fn base_tx_in_aca() -> Balance { + pub fn base_tx_in_aca() -> Balance { cent(ACA) / 10 } @@ -71,7 +68,7 @@ pub mod fee { impl WeightToFeePolynomial for WeightToFee { type Balance = Balance; fn polynomial() -> WeightToFeeCoefficients { - // in Karura, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: + // in Acala, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: let p = base_tx_in_aca(); let q = Balance::from(ExtrinsicBaseWeight::get()); smallvec![WeightToFeeCoefficient { @@ -94,3 +91,19 @@ pub mod fee { aca_per_second() / 50 * dollar(DOT) / dollar(ACA) } } + +#[cfg(test)] +mod tests { + use crate::{constants::fee::base_tx_in_aca, Balance}; + use frame_support::weights::constants::ExtrinsicBaseWeight; + + #[test] + fn check_weight() { + let p = base_tx_in_aca(); + let q = Balance::from(ExtrinsicBaseWeight::get()); + + assert_eq!(p, 1_000_000_000); + assert_eq!(q, 125_000_000); + assert_eq!(p / q, 8); + } +} diff --git a/runtime/karura/src/constants.rs b/runtime/karura/src/constants.rs index 0206b7fa62..b6b6be6de1 100644 --- a/runtime/karura/src/constants.rs +++ b/runtime/karura/src/constants.rs @@ -49,10 +49,7 @@ pub mod fee { use smallvec::smallvec; use sp_runtime::Perbill; - /// The block saturation level. Fees will be updates based on this value. - pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); - - fn base_tx_in_kar() -> Balance { + pub fn base_tx_in_kar() -> Balance { cent(KAR) / 10 } @@ -111,3 +108,19 @@ pub mod parachains { pub const KINT_KEY: &[u8] = &[5]; } } + +#[cfg(test)] +mod tests { + use crate::{constants::fee::base_tx_in_kar, Balance}; + use frame_support::weights::constants::ExtrinsicBaseWeight; + + #[test] + fn check_weight() { + let p = base_tx_in_kar(); + let q = Balance::from(ExtrinsicBaseWeight::get()); + + assert_eq!(p, 1_000_000_000); + assert_eq!(q, 125_000_000); + assert_eq!(p / q, 8); + } +} diff --git a/runtime/mandala/src/constants.rs b/runtime/mandala/src/constants.rs index dc31d4e858..87af591e94 100644 --- a/runtime/mandala/src/constants.rs +++ b/runtime/mandala/src/constants.rs @@ -49,10 +49,7 @@ pub mod fee { use smallvec::smallvec; use sp_runtime::Perbill; - /// The block saturation level. Fees will be updates based on this value. - pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); - - fn base_tx_in_aca() -> Balance { + pub fn base_tx_in_aca() -> Balance { cent(ACA) / 10 } @@ -71,15 +68,14 @@ pub mod fee { impl WeightToFeePolynomial for WeightToFee { type Balance = Balance; fn polynomial() -> WeightToFeeCoefficients { - // in Acala, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 - // CENT: - let p = base_tx_in_aca(); // 10_000_000_000; + // in Acala, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: + let p = base_tx_in_aca(); // 1_000_000_000; let q = Balance::from(ExtrinsicBaseWeight::get()); // 125_000_000 smallvec![WeightToFeeCoefficient { degree: 1, negative: false, coeff_frac: Perbill::from_rational(p % q, q), // zero - coeff_integer: p / q, // 80 + coeff_integer: p / q, // 8 }] } } @@ -94,3 +90,19 @@ pub mod fee { aca_per_second() / 100 } } + +#[cfg(test)] +mod tests { + use crate::{constants::fee::base_tx_in_aca, Balance}; + use frame_support::weights::constants::ExtrinsicBaseWeight; + + #[test] + fn check_weight() { + let p = base_tx_in_aca(); + let q = Balance::from(ExtrinsicBaseWeight::get()); + + assert_eq!(p, 1_000_000_000); + assert_eq!(q, 125_000_000); + assert_eq!(p / q, 8); + } +} diff --git a/runtime/mandala/src/lib.rs b/runtime/mandala/src/lib.rs index ddc8ce3be7..21de2aa7f5 100644 --- a/runtime/mandala/src/lib.rs +++ b/runtime/mandala/src/lib.rs @@ -40,7 +40,7 @@ pub use frame_support::{ Randomness, SortedMembers, U128CurrencyToVote, WithdrawReasons, }, weights::{ - constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, + constants::{BlockExecutionWeight, RocksDbWeight, WEIGHT_PER_SECOND}, DispatchClass, IdentityFee, Weight, }, PalletId, RuntimeDebug, StorageValue,