diff --git a/modules/transaction-payment/src/mock.rs b/modules/transaction-payment/src/mock.rs index 066ec5e5fd..c745d8e682 100644 --- a/modules/transaction-payment/src/mock.rs +++ b/modules/transaction-payment/src/mock.rs @@ -111,7 +111,7 @@ impl orml_tokens::Config for Runtime { } parameter_types! { - pub const NativeTokenExistentialDeposit: Balance = 0; + pub const NativeTokenExistentialDeposit: Balance = 10; pub const MaxReserves: u32 = 50; } @@ -253,6 +253,7 @@ pub struct ExtBuilder { base_weight: u64, byte_fee: u128, weight_to_fee: u128, + native_balances: Vec<(AccountId, Balance)>, } impl Default for ExtBuilder { @@ -262,6 +263,7 @@ impl Default for ExtBuilder { base_weight: 0, byte_fee: 2, weight_to_fee: 1, + native_balances: vec![], } } } @@ -279,6 +281,10 @@ impl ExtBuilder { self.weight_to_fee = weight_to_fee; self } + pub fn one_hundred_thousand_for_alice_n_charlie(mut self) -> Self { + self.native_balances = vec![(ALICE, 100000), (CHARLIE, 100000)]; + self + } fn set_constants(&self) { EXTRINSIC_BASE_WEIGHT.with(|v| *v.borrow_mut() = self.base_weight); TRANSACTION_BYTE_FEE.with(|v| *v.borrow_mut() = self.byte_fee); @@ -291,7 +297,7 @@ impl ExtBuilder { .unwrap(); pallet_balances::GenesisConfig:: { - balances: vec![(ALICE, 100000), (CHARLIE, 100000)], + balances: self.native_balances, } .assimilate_storage(&mut t) .unwrap(); diff --git a/modules/transaction-payment/src/tests.rs b/modules/transaction-payment/src/tests.rs index 2d1cf5485e..7d838e6ffb 100644 --- a/modules/transaction-payment/src/tests.rs +++ b/modules/transaction-payment/src/tests.rs @@ -22,7 +22,7 @@ use super::*; use frame_support::{ - assert_ok, + assert_noop, assert_ok, weights::{DispatchClass, DispatchInfo, Pays}, }; use mock::{ @@ -50,131 +50,183 @@ const POST_INFO: PostDispatchInfo = PostDispatchInfo { }; #[test] -fn charges_fee() { +fn charges_fee_when_native_is_enough_but_cannot_keep_alive() { ExtBuilder::default().build().execute_with(|| { let fee = 23 * 2 + 1000; // len * byte + weight - assert_eq!( - ChargeTransactionPayment::::from(0) - .validate(&ALICE, CALL, &INFO, 23) - .unwrap() - .priority, - fee + assert_ok!(Currencies::update_balance( + Origin::root(), + ALICE, + ACA, + fee.unique_saturated_into(), + )); + assert_eq!(Currencies::free_balance(ACA, &ALICE), fee); + assert_noop!( + ChargeTransactionPayment::::from(0).validate(&ALICE, CALL, &INFO, 23), + TransactionValidityError::Invalid(InvalidTransaction::Payment) ); - assert_eq!(Currencies::free_balance(ACA, &ALICE), (100000 - fee).into()); - let fee2 = 18 * 2 + 1000; // len * byte + weight + let fee2 = 23 * 2 + 990; assert_eq!( ChargeTransactionPayment::::from(0) - .validate(&ALICE, CALL2, &INFO, 18) + .validate( + &ALICE, + CALL, + &DispatchInfo { + weight: 990, + class: DispatchClass::Normal, + pays_fee: Pays::Yes, + }, + 23 + ) .unwrap() .priority, - fee2 - ); - assert_eq!( - Currencies::free_balance(ACA, &ALICE), - (100000 - fee - fee2).unique_saturated_into() + fee2.saturated_into::() ); + assert_eq!(Currencies::free_balance(ACA, &ALICE), Currencies::minimum_balance(ACA)); }); } #[test] -fn signed_extension_transaction_payment_work() { - ExtBuilder::default().build().execute_with(|| { - 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); - assert_ok!(ChargeTransactionPayment::::post_dispatch( - pre, - &INFO, - &POST_INFO, - 23, - &Ok(()) - )); +fn charges_fee() { + ExtBuilder::default() + .one_hundred_thousand_for_alice_n_charlie() + .build() + .execute_with(|| { + let fee = 23 * 2 + 1000; // len * byte + weight + assert_eq!( + ChargeTransactionPayment::::from(0) + .validate(&ALICE, CALL, &INFO, 23) + .unwrap() + .priority, + fee + ); + assert_eq!(Currencies::free_balance(ACA, &ALICE), (100000 - fee).into()); - let refund = 200; // 1000 - 800 - assert_eq!(Currencies::free_balance(ACA, &ALICE), 100000 - fee + refund); - assert_eq!(FEE_UNBALANCED_AMOUNT.with(|a| a.borrow().clone()), fee - refund); - assert_eq!(TIP_UNBALANCED_AMOUNT.with(|a| a.borrow().clone()), 0); - - FEE_UNBALANCED_AMOUNT.with(|a| *a.borrow_mut() = 0); - - let pre = ChargeTransactionPayment::::from(5 /* tipped */) - .pre_dispatch(&CHARLIE, CALL, &INFO, 23) - .unwrap(); - assert_eq!(Currencies::free_balance(ACA, &CHARLIE), 100000 - fee - 5); - assert_ok!(ChargeTransactionPayment::::post_dispatch( - pre, - &INFO, - &POST_INFO, - 23, - &Ok(()) - )); - assert_eq!(Currencies::free_balance(ACA, &CHARLIE), 100000 - fee - 5 + refund); - assert_eq!(FEE_UNBALANCED_AMOUNT.with(|a| a.borrow().clone()), fee - refund); - assert_eq!(TIP_UNBALANCED_AMOUNT.with(|a| a.borrow().clone()), 5); - }); + let fee2 = 18 * 2 + 1000; // len * byte + weight + assert_eq!( + ChargeTransactionPayment::::from(0) + .validate(&ALICE, CALL2, &INFO, 18) + .unwrap() + .priority, + fee2 + ); + assert_eq!( + Currencies::free_balance(ACA, &ALICE), + (100000 - fee - fee2).unique_saturated_into() + ); + }); +} + +#[test] +fn signed_extension_transaction_payment_work() { + ExtBuilder::default() + .one_hundred_thousand_for_alice_n_charlie() + .build() + .execute_with(|| { + 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); + assert_ok!(ChargeTransactionPayment::::post_dispatch( + pre, + &INFO, + &POST_INFO, + 23, + &Ok(()) + )); + + let refund = 200; // 1000 - 800 + assert_eq!(Currencies::free_balance(ACA, &ALICE), 100000 - fee + refund); + assert_eq!(FEE_UNBALANCED_AMOUNT.with(|a| a.borrow().clone()), fee - refund); + assert_eq!(TIP_UNBALANCED_AMOUNT.with(|a| a.borrow().clone()), 0); + + FEE_UNBALANCED_AMOUNT.with(|a| *a.borrow_mut() = 0); + + let pre = ChargeTransactionPayment::::from(5 /* tipped */) + .pre_dispatch(&CHARLIE, CALL, &INFO, 23) + .unwrap(); + assert_eq!(Currencies::free_balance(ACA, &CHARLIE), 100000 - fee - 5); + assert_ok!(ChargeTransactionPayment::::post_dispatch( + pre, + &INFO, + &POST_INFO, + 23, + &Ok(()) + )); + assert_eq!(Currencies::free_balance(ACA, &CHARLIE), 100000 - fee - 5 + refund); + assert_eq!(FEE_UNBALANCED_AMOUNT.with(|a| a.borrow().clone()), fee - refund); + assert_eq!(TIP_UNBALANCED_AMOUNT.with(|a| a.borrow().clone()), 5); + }); } #[test] fn charges_fee_when_pre_dispatch_and_native_currency_is_enough() { - ExtBuilder::default().build().execute_with(|| { - let fee = 23 * 2 + 1000; // len * byte + weight - assert!(ChargeTransactionPayment::::from(0) - .pre_dispatch(&ALICE, CALL, &INFO, 23) - .is_ok()); - assert_eq!(Currencies::free_balance(ACA, &ALICE), 100000 - fee); - }); + ExtBuilder::default() + .one_hundred_thousand_for_alice_n_charlie() + .build() + .execute_with(|| { + let fee = 23 * 2 + 1000; // len * byte + weight + assert!(ChargeTransactionPayment::::from(0) + .pre_dispatch(&ALICE, CALL, &INFO, 23) + .is_ok()); + assert_eq!(Currencies::free_balance(ACA, &ALICE), 100000 - fee); + }); } #[test] fn refund_fee_according_to_actual_when_post_dispatch_and_native_currency_is_enough() { - ExtBuilder::default().build().execute_with(|| { - 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); - }); + ExtBuilder::default() + .one_hundred_thousand_for_alice_n_charlie() + .build() + .execute_with(|| { + 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); + }); } #[test] fn charges_fee_when_validate_and_native_is_not_enough() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(>::transfer(AUSD, &ALICE, &BOB, 1000)); - assert_eq!(>::free_balance(ACA, &BOB), 0); - assert_eq!(>::free_balance(AUSD, &BOB), 1000); - - // add liquidity to DEX - assert_ok!(DEXModule::add_liquidity( - Origin::signed(ALICE), - ACA, - AUSD, - 10000, - 1000, - 0, - false - )); - assert_eq!(DEXModule::get_liquidity_pool(ACA, AUSD), (10000, 1000)); - - let fee = 500 * 2 + 1000; // len * byte + weight - assert_eq!( - ChargeTransactionPayment::::from(0) - .validate(&BOB, CALL2, &INFO, 500) - .unwrap() - .priority, - fee - ); + ExtBuilder::default() + .one_hundred_thousand_for_alice_n_charlie() + .build() + .execute_with(|| { + assert_ok!(>::transfer(AUSD, &ALICE, &BOB, 1000)); + assert_eq!(>::free_balance(ACA, &BOB), 0); + assert_eq!(>::free_balance(AUSD, &BOB), 1000); + + // add liquidity to DEX + assert_ok!(DEXModule::add_liquidity( + Origin::signed(ALICE), + ACA, + AUSD, + 10000, + 1000, + 0, + false + )); + assert_eq!(DEXModule::get_liquidity_pool(ACA, AUSD), (10000, 1000)); + + let fee = 500 * 2 + 1000; // len * byte + weight + assert_eq!( + ChargeTransactionPayment::::from(0) + .validate(&BOB, CALL2, &INFO, 500) + .unwrap() + .priority, + fee + ); - assert_eq!(Currencies::free_balance(ACA, &BOB), 0); - assert_eq!(Currencies::free_balance(AUSD, &BOB), 749); - assert_eq!(DEXModule::get_liquidity_pool(ACA, AUSD), (10000 - 2000, 1251)); - }); + assert_eq!(Currencies::free_balance(ACA, &BOB), Currencies::minimum_balance(ACA)); + assert_eq!(Currencies::free_balance(AUSD, &BOB), 748); + assert_eq!(DEXModule::get_liquidity_pool(ACA, AUSD), (10000 - 2000 - 10, 1252)); + }); } #[test] @@ -193,53 +245,56 @@ fn set_default_fee_token_work() { #[test] fn charge_fee_by_default_fee_token() { - ExtBuilder::default().build().execute_with(|| { - // add liquidity to DEX - assert_ok!(DEXModule::add_liquidity( - Origin::signed(ALICE), - ACA, - AUSD, - 10000, - 1000, - 0, - false - )); - assert_ok!(DEXModule::add_liquidity( - Origin::signed(ALICE), - DOT, - AUSD, - 100, - 1000, - 0, - false - )); - assert_eq!(DEXModule::get_liquidity_pool(ACA, AUSD), (10000, 1000)); - assert_eq!(DEXModule::get_liquidity_pool(DOT, AUSD), (100, 1000)); - assert_ok!(TransactionPayment::set_default_fee_token( - Origin::signed(BOB), - Some(DOT) - )); - assert_eq!(TransactionPayment::default_fee_currency_id(&BOB), Some(DOT)); - assert_ok!(>::transfer(DOT, &ALICE, &BOB, 100)); - assert_eq!(>::free_balance(ACA, &BOB), 0); - assert_eq!(>::free_balance(AUSD, &BOB), 0); - assert_eq!(>::free_balance(DOT, &BOB), 100); - - let fee = 500 * 2 + 1000; // len * byte + weight - assert_eq!( - ChargeTransactionPayment::::from(0) - .validate(&BOB, CALL2, &INFO, 500) - .unwrap() - .priority, - fee - ); + ExtBuilder::default() + .one_hundred_thousand_for_alice_n_charlie() + .build() + .execute_with(|| { + // add liquidity to DEX + assert_ok!(DEXModule::add_liquidity( + Origin::signed(ALICE), + ACA, + AUSD, + 10000, + 1000, + 0, + false + )); + assert_ok!(DEXModule::add_liquidity( + Origin::signed(ALICE), + DOT, + AUSD, + 100, + 1000, + 0, + false + )); + assert_eq!(DEXModule::get_liquidity_pool(ACA, AUSD), (10000, 1000)); + assert_eq!(DEXModule::get_liquidity_pool(DOT, AUSD), (100, 1000)); + assert_ok!(TransactionPayment::set_default_fee_token( + Origin::signed(BOB), + Some(DOT) + )); + assert_eq!(TransactionPayment::default_fee_currency_id(&BOB), Some(DOT)); + assert_ok!(>::transfer(DOT, &ALICE, &BOB, 100)); + assert_eq!(>::free_balance(ACA, &BOB), 0); + assert_eq!(>::free_balance(AUSD, &BOB), 0); + assert_eq!(>::free_balance(DOT, &BOB), 100); + + let fee = 500 * 2 + 1000; // len * byte + weight + assert_eq!( + ChargeTransactionPayment::::from(0) + .validate(&BOB, CALL2, &INFO, 500) + .unwrap() + .priority, + fee + ); - assert_eq!(Currencies::free_balance(ACA, &BOB), 0); - assert_eq!(Currencies::free_balance(AUSD, &BOB), 0); - assert_eq!(Currencies::free_balance(DOT, &BOB), 100 - 34); - assert_eq!(DEXModule::get_liquidity_pool(ACA, AUSD), (10000 - 2000, 1251)); - assert_eq!(DEXModule::get_liquidity_pool(DOT, AUSD), (100 + 34, 1000 - 251)); - }); + assert_eq!(Currencies::free_balance(ACA, &BOB), Currencies::minimum_balance(ACA)); + assert_eq!(Currencies::free_balance(AUSD, &BOB), 0); + assert_eq!(Currencies::free_balance(DOT, &BOB), 100 - 34); + assert_eq!(DEXModule::get_liquidity_pool(ACA, AUSD), (10000 - 2000 - 10, 1252)); + assert_eq!(DEXModule::get_liquidity_pool(DOT, AUSD), (100 + 34, 1000 - 252)); + }); } #[test]