Substrate: Transaction Fee module

Created on 22 Jan 2019  路  6Comments  路  Source: paritytech/substrate

It will be useful to create a transaction fee module

  • It provide a centralized location for all transaction fee handling

    • This makes it possible for client easy to query transaction fee charged in a given transaction, currently client side have to do the math themself

  • It can be a start point to implement transaction fee reward to validators

    • tx fee for all txs in a single block can be tracked in the storage, and on_finalize method can distribute them to validators

  • It helps reduce coupling between various modules and balances module #1514

Some requirements

  • It should be generalized and not coupled with balances module

    • This makes it possible to work with other kinds of token models such multi token assets or UTXO

  • It should support dynamic fee module (gas amount & gas price for contract) as well as static fee module (fixed fee per call)

I am keen to start working on this if this is the right direction

Z1-question

Most helpful comment

It will replace MakePayment as I feel the current MakePayment is too specific.
I also thinking about have the gas meter code moved from contract module to here as it is general enough to be useful by other modules with dynamic tx fee. Any runtime method with computational complexity that is not near O(1) should use GasMeter to ensure the upper bound of the computation.

A draft API:

Generic parameters:

  • FeeAmount: SimpleArithmetic

    • Balance for simple implementation

    • struct FeeAmount(Vec<(AssetId, Balance)>) for multi token implementation

Storage & Config

  • BaseFee: FeeAmount

    • base tx fee

  • ByteFee: FeeAmount

    • tx fee per byte

  • Fees: mapping u32 => FeeAmount

    • total tx fee for each tx index in the current block

Internal methods (public to other modules):

  • charge_base_bytes_fee(who: &AccountId, len: usize) -> Result
  • charge_fee(who: &AccountId, fee: FeeAmount) -> Result
  • refund_fee(who: &AccountId, fee: FeeAmount)

Events

  • ChargeFee(u32, FeeAmount)

    • tx index and fee amount

Other method

  • on_finalise()

    • deposit tx fee events

    • optionally distribute the tx fees to validators

    • kill storage

One tricky part is make this works with contracts overlay storage, which I need to spend some time to understand the details first.


Edit: Removed the gas fee related part

All 6 comments

This would replace MakePayment? Or it would implement MakePayment? Could you sketch the API you see it having?

It will replace MakePayment as I feel the current MakePayment is too specific.
I also thinking about have the gas meter code moved from contract module to here as it is general enough to be useful by other modules with dynamic tx fee. Any runtime method with computational complexity that is not near O(1) should use GasMeter to ensure the upper bound of the computation.

A draft API:

Generic parameters:

  • FeeAmount: SimpleArithmetic

    • Balance for simple implementation

    • struct FeeAmount(Vec<(AssetId, Balance)>) for multi token implementation

Storage & Config

  • BaseFee: FeeAmount

    • base tx fee

  • ByteFee: FeeAmount

    • tx fee per byte

  • Fees: mapping u32 => FeeAmount

    • total tx fee for each tx index in the current block

Internal methods (public to other modules):

  • charge_base_bytes_fee(who: &AccountId, len: usize) -> Result
  • charge_fee(who: &AccountId, fee: FeeAmount) -> Result
  • refund_fee(who: &AccountId, fee: FeeAmount)

Events

  • ChargeFee(u32, FeeAmount)

    • tx index and fee amount

Other method

  • on_finalise()

    • deposit tx fee events

    • optionally distribute the tx fees to validators

    • kill storage

One tricky part is make this works with contracts overlay storage, which I need to spend some time to understand the details first.


Edit: Removed the gas fee related part

(AccountId is alreeady in system::Trait, so no need for that.)

If MakePayment is replaced by this, then we'd be introducing a dependency to executive which includes the concept of gas which is a no-go.

@gavofyork What is the reason to avoid introduce concept of gas to be dependent of executive? Just keep it simple because contract module won't be included in many chains including polkadot chain?
Anyhow I can remove the gas part and only do the static tx fee part.

Correct. Neither Gas nor Balance are first-class concepts on Substrate and I want to keep it that way. This also means that Executive should not know about fee structures and balances in general.

Understood. I have updated the proposal above and planning start working on this next.

On the other hand, I still think a reusable gas meter is a useful module. But I don't have a concrete requirement for it so I will leave it alone.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JoshOrndorff picture JoshOrndorff  路  4Comments

Mischi picture Mischi  路  5Comments

gavofyork picture gavofyork  路  4Comments

AurevoirXavier picture AurevoirXavier  路  3Comments

expenses picture expenses  路  5Comments