docs/src/proposals/comprehensive-compute-fees.md
The current fee structure lacks a comprehensive account of the work required by a validator to process a transaction. The fee structure is only based on the number of signatures in a transaction but is meant to account for the work that the validator must perform to validate each transaction. The validator performs a lot more user-defined work than just signature verification. Processing a transaction typically includes signature verifications, account locking, account loading, and instruction processing.
The following solution does not specify what native token costs are to be associated with the new fee structure. Instead, it sets the criteria and provides the knobs that a cost model can use to determine those costs.
The goal of the fees is to cover the computation cost of processing a transaction. Each of the fee categories below will be represented as a compute unit cost that, when added together, encompasses the entire cost of processing the transaction. By calculating the total cost of the transaction, the runtime can charge a more representative fee and make better transaction scheduling decisions.
A fee could be calculated based on:
The cost model is used to assess what load a transaction will incur during in-slot processing and then make decisions on how to best schedule transaction into batches.
The cost model's criteria are identical to the fee's criteria except for signatures and precompiled programs. These two costs are incurred before a transaction is scheduled and therefore do not affect how long a transaction takes within a slot to process.
https://github.com/solana-labs/solana/issues/20511
The precompiled ComputeBudget program can be used to request higher transaction-wide compute budget caps and program heap sizes. The requested increases will be reflected in the transaction's fee.
https://github.com/solana-labs/solana/issues/20481
Current rate governing needs to be re-assessed. Fees are being rate governed down to their minimums because the number of signatures in each slot is far lower than the "target" signatures per slot.
Instead of using the number of signatures to rate govern, the cost model will feed back information based on the batch/queue load it is seeing. The fees will sit at a target rate and only increase if the load goes above a specified but to be determined threshold. The governing will be applied across all the fee criteria.
Solana's fees are currently deterministic based on a given blockhash. This determinism is a nice feature that simplifies client interactions. An example is when draining an account that is also the payer, the transaction issuer can pre-compute the fee and then set the entire remaining balance to be transferred out without worrying that the fee will change leaving a very small amount remaining in the account. Another example is for offline signing, the payer signer can guarantee what fee that will be charged for the transaction based on the nonce's blockhash.
Determinism is achieved in two ways:
lamports_per_signature value. The blockhash queue is one of the snapshot's
serialized members and thus bank hash depends on it.lamports_per_signature
value in its account dataIn both cases, when a transaction is assessed a fee, the
lamports_per_signature to use is looked up (either in the queue or in the
nonce account's data) using the transaction's blockhash.
This currently comes with the following challenges:
FeeCalculator object to the clients (holds the
lamports_per_signature) makes it hard to evolve the fee criteria due to
backward-compatibility. This issue is being solved by deprecating the
FeeCalculator object and instead the new apis take a message and return a
fee.Two solutions to the latter two challenges