In this past week, we have been researching and discussing a lot about blockchain transaction fees, their support and implementation in Substrate, and how exactly we want to implement them in our Radicle Registry project.
After some good discussions and feature polishing on both our Notion issue and on the GitHub issue, we reached a sweet spot where I’d like to share with you the requirements and flow for the first iteration of this feature.
We want our users to bid an amount they are truly willing to pay, using a simplistic fee setup.
That means that every issued transaction must be accompanied by a positive balance that should cover the single base_fee. The remainder is used as a tip, used to gain priority accordingly.
For the sake of clarity, requirements are conditions that need to be met to implement this feature the way we envision it.
R0: Transactions must be validated pre-dispatch, where the transaction author is verified to have enough funds to cover the respective transaction fees.
R1: Allow tx authors to specify the total fee they are willing to pay.
This bid should cover all internal fees and the remainder be used as a tip to get the tx priority.
R2: Be able to control who pays the tx fee
For org-related transactions, we want the org’s account to be the one paying for the transaction.
R3: Only charge base_fee and tip
In the future, we might include other sub fees, such as weights, but for now, we go-ahead with a
base_fee and tip.
R4: From the withdrawn amount from the transaction payee, burn only a small percentage.
R5: Transactions must only run if the fee can be withdrawn successfully
Consider having tx author, TA , and the registry, R.
TA will issue a transaction, T , to R . In this transaction, TA will indicate a fee amount F that they are willing to pay.
Pre-dispatch, R will validate that TA has enough funds to cover the transaction fees.
R will deduct base_fee from F, and use the remainder as a tip, used to prioritize T accordingly.
R will withdraw F from the end account (see R2).
In case of success, T will run (see 4.), otherwise, an error will be returned and T is dismissed.
R will burn a small percentage of the withdrawn balance and transfer the rest to an account.
(I need more information about what account that should be but it’s non-blocking).
Given R3 and especially R2, I am considering implementing a simple fee-charging system of our own.
Especially R2 since Substrate only runs a transaction if it succeeds to charge the fee beforehand, while
to meet this requirement we need much more control, to be able to figure whether the tx author is a member of the org in question (for org-related transactions, that is).
I will quickly get in touch with Substrate to make sure that’s not supported at the moment, since using their own system also has its advantages, such as being able to add more levels of fees almost for free.
Since org-related transactions should be withdrawn from the involved org’s account, we must authorize the tx author as a member of that org. Otherwise, it’d be an open door to destroy an org’s funds.
Doing so also means that there’s still an open door to issue transactions that will cause stress on the runtime (checking if the tx author belongs to the involved org). Note that a bad actor could - following the design we have at this point - issue as many transactions involving an org they do not belong to and pay nothing for it.
A solution could be to charge the base_fee as early as possible and only later the tip when these authorizations steps can take place.
Let me have your thoughts!