pallet-transaction-payment
has ChargeTransactionPayment
that implements SignedExtension
. In its code, both validate()
and pre_dispatch()
call withdraw_fee()
internally.
Why doesn't this cause multiple withdrawals?
Also, validate()
could be called many times.
https://github.com/paritytech/substrate/blob/v2.0.0/frame/transaction-payment/src/lib.rs#L511-L534
During validation phase, all state changes are discarded. Validation phase in used while the transaction lives in the pool. While being authored and imported, it only goes through
pre_dispatch
.Indeed, the pool (or generally any component outside of the runtime) might want to re-validate the transaction multiple times. Key is to remember that the state changes are discarded in validation.
See more here: https://github.com/paritytech/substrate/blob/a200cdb93c6af5763b9c7bf313fa708764ac88ca/primitives/runtime/src/traits.rs#L711-L728