Skip to content

Commit

Permalink
Merge pull request #788 from galacticcouncil/set_currency_in_batch_tx
Browse files Browse the repository at this point in the history
feat: allow set_currency in batch TX
  • Loading branch information
Roznovjak authored Mar 19, 2024
2 parents a0c524a + ea0482d commit 857fe8c
Show file tree
Hide file tree
Showing 9 changed files with 433 additions and 16 deletions.
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "runtime-integration-tests"
version = "1.19.10"
version = "1.19.11"
description = "Integration tests"
authors = ["GalacticCouncil"]
edition = "2021"
Expand Down
192 changes: 192 additions & 0 deletions integration-tests/src/non_native_fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,198 @@ fn non_native_fee_payment_works_with_oracle_price_based_on_onchain_route() {
});
}

#[test]
fn set_currency_should_work_in_batch_transaction_when_first_tx() {
TestNet::reset();

// batch
Hydra::execute_with(|| {
let first_inner_call = hydradx_runtime::RuntimeCall::MultiTransactionPayment(
pallet_transaction_multi_payment::Call::set_currency { currency: BTC },
);
let second_inner_call = hydradx_runtime::RuntimeCall::System(frame_system::Call::remark { remark: vec![] });
let call = hydradx_runtime::RuntimeCall::Utility(pallet_utility::Call::batch {
calls: vec![first_inner_call, second_inner_call],
});

let info = DispatchInfo {
weight: Weight::from_parts(106_957_000, 0),
..Default::default()
};
let len: usize = 10;

assert_ok!(
pallet_transaction_payment::ChargeTransactionPayment::<hydradx_runtime::Runtime>::from(0).pre_dispatch(
&AccountId::from(BOB),
&call,
&info,
len,
)
);
let bob_balance = hydradx_runtime::Tokens::free_balance(BTC, &AccountId::from(BOB));
assert_eq!(bob_balance, 999991);
});

TestNet::reset();

// batch_all
Hydra::execute_with(|| {
let first_inner_call = hydradx_runtime::RuntimeCall::MultiTransactionPayment(
pallet_transaction_multi_payment::Call::set_currency { currency: BTC },
);
let second_inner_call = hydradx_runtime::RuntimeCall::System(frame_system::Call::remark { remark: vec![] });
let call = hydradx_runtime::RuntimeCall::Utility(pallet_utility::Call::batch_all {
calls: vec![first_inner_call, second_inner_call],
});

let info = DispatchInfo {
weight: Weight::from_parts(106_957_000, 0),
..Default::default()
};
let len: usize = 10;

assert_ok!(
pallet_transaction_payment::ChargeTransactionPayment::<hydradx_runtime::Runtime>::from(0).pre_dispatch(
&AccountId::from(BOB),
&call,
&info,
len,
)
);
let bob_balance = hydradx_runtime::Tokens::free_balance(BTC, &AccountId::from(BOB));
assert_eq!(bob_balance, 999991);
});

TestNet::reset();

// batch_all
Hydra::execute_with(|| {
let first_inner_call = hydradx_runtime::RuntimeCall::MultiTransactionPayment(
pallet_transaction_multi_payment::Call::set_currency { currency: BTC },
);
let second_inner_call = hydradx_runtime::RuntimeCall::System(frame_system::Call::remark { remark: vec![] });
let call = hydradx_runtime::RuntimeCall::Utility(pallet_utility::Call::force_batch {
calls: vec![first_inner_call, second_inner_call],
});

let info = DispatchInfo {
weight: Weight::from_parts(106_957_000, 0),
..Default::default()
};
let len: usize = 10;

assert_ok!(
pallet_transaction_payment::ChargeTransactionPayment::<hydradx_runtime::Runtime>::from(0).pre_dispatch(
&AccountId::from(BOB),
&call,
&info,
len,
)
);
let bob_balance = hydradx_runtime::Tokens::free_balance(BTC, &AccountId::from(BOB));
assert_eq!(bob_balance, 999991);
});
}

#[test]
fn set_currency_should_not_work_in_batch_transaction_when_not_first_tx() {
TestNet::reset();

// batch
Hydra::execute_with(|| {
let first_inner_call = hydradx_runtime::RuntimeCall::System(frame_system::Call::remark { remark: vec![] });
let second_inner_call = hydradx_runtime::RuntimeCall::MultiTransactionPayment(
pallet_transaction_multi_payment::Call::set_currency { currency: BTC },
);
let call = hydradx_runtime::RuntimeCall::Utility(pallet_utility::Call::batch {
calls: vec![first_inner_call, second_inner_call],
});

let info = DispatchInfo {
weight: Weight::from_parts(106_957_000, 0),
..Default::default()
};
let len: usize = 10;

let bob_initial_balance = hydradx_runtime::Tokens::free_balance(BTC, &AccountId::from(BOB));

assert_ok!(
pallet_transaction_payment::ChargeTransactionPayment::<hydradx_runtime::Runtime>::from(0).pre_dispatch(
&AccountId::from(BOB),
&call,
&info,
len,
)
);
let bob_balance = hydradx_runtime::Tokens::free_balance(BTC, &AccountId::from(BOB));
assert_eq!(bob_balance, bob_initial_balance);
});

TestNet::reset();

// batch_all
Hydra::execute_with(|| {
let first_inner_call = hydradx_runtime::RuntimeCall::System(frame_system::Call::remark { remark: vec![] });
let second_inner_call = hydradx_runtime::RuntimeCall::MultiTransactionPayment(
pallet_transaction_multi_payment::Call::set_currency { currency: BTC },
);
let call = hydradx_runtime::RuntimeCall::Utility(pallet_utility::Call::batch_all {
calls: vec![first_inner_call, second_inner_call],
});

let info = DispatchInfo {
weight: Weight::from_parts(106_957_000, 0),
..Default::default()
};
let len: usize = 10;

let bob_initial_balance = hydradx_runtime::Tokens::free_balance(BTC, &AccountId::from(BOB));

assert_ok!(
pallet_transaction_payment::ChargeTransactionPayment::<hydradx_runtime::Runtime>::from(0).pre_dispatch(
&AccountId::from(BOB),
&call,
&info,
len,
)
);
let bob_balance = hydradx_runtime::Tokens::free_balance(BTC, &AccountId::from(BOB));
assert_eq!(bob_balance, bob_initial_balance);
});

TestNet::reset();

// batch_all
Hydra::execute_with(|| {
let first_inner_call = hydradx_runtime::RuntimeCall::System(frame_system::Call::remark { remark: vec![] });
let second_inner_call = hydradx_runtime::RuntimeCall::MultiTransactionPayment(
pallet_transaction_multi_payment::Call::set_currency { currency: BTC },
);
let call = hydradx_runtime::RuntimeCall::Utility(pallet_utility::Call::force_batch {
calls: vec![first_inner_call, second_inner_call],
});

let info = DispatchInfo {
weight: Weight::from_parts(106_957_000, 0),
..Default::default()
};
let len: usize = 10;

let bob_initial_balance = hydradx_runtime::Tokens::free_balance(BTC, &AccountId::from(BOB));

assert_ok!(
pallet_transaction_payment::ChargeTransactionPayment::<hydradx_runtime::Runtime>::from(0).pre_dispatch(
&AccountId::from(BOB),
&call,
&info,
len,
)
);
let bob_balance = hydradx_runtime::Tokens::free_balance(BTC, &AccountId::from(BOB));
assert_eq!(bob_balance, bob_initial_balance);
});
}

const HITCHHIKER: [u8; 32] = [42u8; 32];

#[test]
Expand Down
3 changes: 2 additions & 1 deletion pallets/transaction-multi-payment/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pallet-transaction-multi-payment"
version = "9.4.0"
version = "9.5.0"
description = "Transaction multi currency payment support module"
authors = ["GalacticCoucil"]
edition = "2021"
Expand Down Expand Up @@ -30,6 +30,7 @@ sp-core = { workspace = true }
sp-std = { workspace = true }
sp-runtime = { workspace = true }
pallet-transaction-payment = { workspace = true }
pallet-utility = { workspace = true }

pallet-evm = { workspace = true, optional = true }

Expand Down
32 changes: 23 additions & 9 deletions pallets/transaction-multi-payment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,13 +405,14 @@ pub struct TransferFees<MC, DF, FR>(PhantomData<(MC, DF, FR)>);

impl<T, MC, DF, FR> OnChargeTransaction<T> for TransferFees<MC, DF, FR>
where
T: Config,
T: Config + pallet_utility::Config,
MC: MultiCurrency<<T as frame_system::Config>::AccountId>,
AssetIdOf<T>: Into<MC::CurrencyId>,
MC::Balance: FixedPointOperand,
FR: Get<T::AccountId>,
DF: DepositFee<T::AccountId, MC::CurrencyId, MC::Balance>,
<T as frame_system::Config>::RuntimeCall: IsSubType<Call<T>>,
<T as frame_system::Config>::RuntimeCall: IsSubType<Call<T>> + IsSubType<pallet_utility::pallet::Call<T>>,
<T as pallet_utility::Config>::RuntimeCall: IsSubType<Call<T>>,
BalanceOf<T>: FixedPointOperand,
{
type LiquidityInfo = Option<PaymentInfo<Self::Balance, AssetIdOf<T>, Price>>;
Expand All @@ -422,18 +423,31 @@ where
/// Note: The `fee` already includes the `tip`.
fn withdraw_fee(
who: &T::AccountId,
call: &T::RuntimeCall,
_info: &DispatchInfoOf<T::RuntimeCall>,
call: &<T as frame_system::Config>::RuntimeCall,
_info: &DispatchInfoOf<<T as frame_system::Config>::RuntimeCall>,
fee: Self::Balance,
_tip: Self::Balance,
) -> Result<Self::LiquidityInfo, TransactionValidityError> {
if fee.is_zero() {
return Ok(None);
}

let currency = match call.is_sub_type() {
Some(Call::set_currency { currency }) => *currency,
_ => Pallet::<T>::account_currency(who),
let currency = if let Some(Call::set_currency { currency }) = call.is_sub_type() {
*currency
} else if let Some(pallet_utility::pallet::Call::batch { calls })
| Some(pallet_utility::pallet::Call::batch_all { calls })
| Some(pallet_utility::pallet::Call::force_batch { calls }) = call.is_sub_type()
{
// `calls` can be empty Vec
match calls.first() {
Some(first_call) => match first_call.is_sub_type() {
Some(Call::set_currency { currency }) => *currency,
_ => Pallet::<T>::account_currency(who),
},
_ => Pallet::<T>::account_currency(who),
}
} else {
Pallet::<T>::account_currency(who)
};

let price = Pallet::<T>::get_currency_price(currency)
Expand All @@ -460,8 +474,8 @@ where
/// Note: The `fee` already includes the `tip`.
fn correct_and_deposit_fee(
who: &T::AccountId,
_dispatch_info: &DispatchInfoOf<T::RuntimeCall>,
_post_info: &PostDispatchInfoOf<T::RuntimeCall>,
_dispatch_info: &DispatchInfoOf<<T as frame_system::Config>::RuntimeCall>,
_post_info: &PostDispatchInfoOf<<T as frame_system::Config>::RuntimeCall>,
corrected_fee: Self::Balance,
tip: Self::Balance,
already_withdrawn: Self::LiquidityInfo,
Expand Down
8 changes: 8 additions & 0 deletions pallets/transaction-multi-payment/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ frame_support::construct_runtime!(
Currencies: pallet_currencies,
Tokens: orml_tokens,
EVMAccounts: pallet_evm_accounts,
Utility: pallet_utility,
}

);
Expand Down Expand Up @@ -287,6 +288,13 @@ impl pallet_evm_accounts::Config for Test {
type WeightInfo = ();
}

impl pallet_utility::Config for Test {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type PalletsOrigin = OriginCaller;
type WeightInfo = ();
}

pub struct ExtBuilder {
base_weight: Weight,
native_balances: Vec<(AccountId, Balance)>,
Expand Down
Loading

0 comments on commit 857fe8c

Please sign in to comment.