polkascan / substrate-interface-api

Substrate Interface API Application
https://documenter.getpostman.com/view/9969999/SWT5iLXH?version=latest
GNU General Public License v3.0
4 stars 13 forks source link

getting extrinsic fee in advance #2

Closed roccomuso closed 3 years ago

roccomuso commented 4 years ago

Is there any RPC call available that helps getting fee estimation in advance?

arjanz commented 4 years ago

Fees in Substrate based chains like Polkadot work a bit different than you're used to in Ethereum. There is no gas-like calculation, but it works with 'weight'. There is a base weight and then depending on what happens inside the call (like state-writes) there is weight added and in the end converted to a fee.

You can see the base weight in the documentation (e.g. https://polkascan.io/polkadot/runtime-call/24-balances-transfer_keep_alive) to get an idea. There is also some more information about the benchmarks (but a bit technical): https://www.shawntabrizi.com/substrate-graph-benchmarks/docs/#/results?id=runtime-extrinsic-weight

roccomuso commented 4 years ago

Is there a way through rpc to know the exact fee for an extrinsic before broadcasting it? Because otherwise when sending a tx you don't know what's the exact max amount you can send (because you don't know what the fee would be).

Can transfer_keep_alive be used to get the fee? Is there a way to define the fee when using runtime_createSignaturePayload?

I saw there should be this rpc call: https://polkadot.js.org/docs/substrate/rpc#queryinfoextrinsic-bytes-at-blockhash-runtimedispatchinfo . But how can this be used in the tx "creation" flow? aren't fee defined in the extrinsic already?

thanks!

arjanz commented 4 years ago

As far as I know there is no way to determine on-chain in advance what the exact fee will be, only the indication of the weight according to the documentation that will give a possible range of fees (although something like a balance will be pretty predictable if successful). transfer_keep_alive is basically a transfer call but with extra checks so you will never transfer more than the existential deposit and unsuspectedly reap your account.

The RPC call you mentioned is able to extract the applied fee for already executed extrinsics on the chain, so this is like the receipt, but this will not work when creating an extrinsic. You can define a 'tip' though, which will be an incentive for a validator to prioritize your extrinsic when there is high traffic.

But you can really assume the fee for a simple extrinsic like a balance transfer will be always the same, for example:

https://polkascan.io/polkadot/transaction/2204645-3

If you open and add up the amounts stated in the triggered events treasury.Deposit (treasury fee) and balances.Deposit (validator fee) you will see it is 0.0154 DOT for every successful balance transfer. I saw a balances.transfer_keep_alive is slightly higher (0.0156 DOT) because probably the extra lookup of the current balance to prevent reaping.

arjanz commented 3 years ago

I saw there should be this rpc call: https://polkadot.js.org/docs/substrate/rpc#queryinfoextrinsic-bytes-at-blockhash-runtimedispatchinfo . But how can this be used in the tx "creation" flow? aren't fee defined in the extrinsic already?

thanks!

I stand corrected, they RPC call you described gives indeed the predicted fee information according to given encoded extrinsic intended to send to the network. It's already possible to manually do the RPC call, but I will implement this feature in a more developer-friendly way: https://github.com/polkascan/py-substrate-interface/issues/45

Afterwards I will add this feature to Substrate API as well

arjanz commented 3 years ago

I have pushed an update, you can use runtime_getPaymentInfo in the GUI and API now to retrieve fee estimates