As I've checked the pallet-tx-payment, I've figured it out the fee is withdrawn twice

pub fn validate() {
    let (final_fee, _) = self.withdraw_fee(who, call, info, len)?;

pub fn pre_dispatch() {
    let (_fee, imbalance) = self.withdraw_fee(who, call, info, len)?;

As far as I understand transaction life cycle

  1. Validate transaction and put into tx pool if valid (withdraw_fee)
pub fn validate_transaction {
  1. Block author fetch the valid transaction and dispatch tx(withdraw_fee)
fn apply_extrinsic() {

Question: Is tx fee withdrawn twice for 'who' account? Once for during validating tx and once for pre-dispatching tx?

Thank you

2 Answers 2


validate() and pre_dispatch() both call the same withdraw_fee function, but only pre_dispatch() actually reflects fee changes of the account in the node state. validate() doesn't execute any side-effects; it merely checks whether the transaction would panic if it were included or not.

refer these links:

Transactions lifecycle



I'll post an answer from Joshy Orndorff

Nothing that happens in the transaction pool API is committed to storage. 
Nodes call the transaction pool API when they first hear about a transaction to do some pre-checks. 
One of those pre-checks is making sure the transaction can pay its own fees. 
Only when the transaction is included in a block are the storage changes committed to state. 
So the fee amount is indeed checked twice, but only once is it deducted and written to storage. 
Ultimately the transactor only pays the fee once.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.