Comprehensive compute fees (#20531)
* Comprehensive fees proposal * Updated
This commit is contained in:
parent
b0ee5d6cfa
commit
94ca5063de
|
@ -0,0 +1,132 @@
|
|||
---
|
||||
title: Comprehensive Compute Fees
|
||||
---
|
||||
|
||||
## Motivation
|
||||
|
||||
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.
|
||||
|
||||
## Proposed Solution
|
||||
|
||||
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.
|
||||
|
||||
### Fee
|
||||
|
||||
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 will be calculated based on:
|
||||
|
||||
1. Number of signatures
|
||||
- Fixed rate per signature
|
||||
2. Number of write locks
|
||||
- Fixed rate per writable account
|
||||
3. Data byte cost
|
||||
- Fixed rate per byte of the sum of the length all a transactions instruction
|
||||
datas
|
||||
4. Account sizes
|
||||
- Account sizes can't be known up-front but can account for a considerable
|
||||
amount of the load the transaction incurs on the network. The payer will
|
||||
be charged for a maximum account size (10m) upfront and refunded the
|
||||
difference after the actual account sizes are known.
|
||||
5. Compute budget
|
||||
- Each transaction will be given a default transaction-wide compute budget of
|
||||
200k units with the option of requesting a larger budget via a compute
|
||||
budget instruction up to a maximum of 1m units. This budget is used to
|
||||
limit the time it takes to process a transaction. The compute budget
|
||||
portion of the fee will be charged up-front based on the default or
|
||||
requested amount. After processing, the actual number of units consumed
|
||||
will be known, and the payer will be refunded the difference, so the payer
|
||||
only pays for what they used. Builtin programs will have a fixed cost
|
||||
while BPF program's cost will be measured at runtime.
|
||||
6. Precompiled programs
|
||||
- Precompiled programs are performing compute-intensive operations. The work
|
||||
incurred by a precompiled program is predictable based on the instruction's
|
||||
data array. Therefore a cost will be assigned per precompiled program
|
||||
based on the parsing of instruction data. Because precompiled programs are
|
||||
processed outside of the bank, their compute cost will not be reflected in
|
||||
the compute budget and will not be used in transaction scheduling
|
||||
decisions. The methods used to determine the fixed cost of the components
|
||||
above are described in
|
||||
[#19627](https://github.com/solana-labs/solana/issues/19627)
|
||||
|
||||
### Cost model
|
||||
|
||||
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.
|
||||
|
||||
### Cache account sizes and use them instead of the max
|
||||
|
||||
https://github.com/solana-labs/solana/issues/20511
|
||||
|
||||
### Transaction-wide compute caps
|
||||
|
||||
The current compute budget caps are independently applied to each instruction
|
||||
within a transaction. This means the overall transaction cap varies depending on
|
||||
how many instructions are in the transaction. To more accurately schedule a
|
||||
transaction, the compute budget will be applied transaction-wide. One challenge
|
||||
of the transaction-wide cap is that each instruction (program) can no longer
|
||||
expect to be given an equal amount of compute units. Each instruction will be
|
||||
given the remaining units left over after processing earlier instructions. This
|
||||
will provide some additional tuning and composability challenges for developers.
|
||||
|
||||
### Requestable compute budget caps and heap sizes
|
||||
|
||||
The precompiled
|
||||
[ComputeBudget](https://github.com/solana-labs/solana/blob/00929f836348d76cb3503d0ba5f76f0d275bcc66/sdk/src/compute_budget.rs#L34)
|
||||
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.
|
||||
|
||||
### Fees for precompiled program failures
|
||||
|
||||
https://github.com/solana-labs/solana/issues/20481
|
||||
|
||||
### Rate governing
|
||||
|
||||
Current rate governing needs to be re-assessed. Current 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.
|
||||
|
||||
### How do clients calculate a transaction's fee
|
||||
|
||||
Transaction fees are currently calculated based on a fixed cost per signature
|
||||
and implemented via an object in the SDK that took a transaction and returned a
|
||||
cost. This object is looked up via a blockhash and returned via RPC to
|
||||
calculate the fee offline.
|
||||
|
||||
The comprehensive fee calculations are more sophisticated and depend on a
|
||||
greater amount of information (recent program compute meter measurements). To
|
||||
move to the new fee structure the RPC APIs that return a FeeCalculator object
|
||||
will be deprecated, and clients will send their transactions over RPC and be
|
||||
returned the calculated fee.
|
||||
|
||||
Fees will no longer be calculated based on a blockhash since it is
|
||||
cost-prohibitive to retain the fee cost inputs for each bank (program units,
|
||||
account sizes). And mainly, the governed fee is based on network load now, not
|
||||
at some time in the past. This will mean that during offline-signing the actual
|
||||
fee charged will not be known until the transaction is submitted.
|
Loading…
Reference in New Issue