Comprehensive compute fees (#20531)

* Comprehensive fees proposal

* Updated
This commit is contained in:
Jack May 2021-10-11 17:14:21 -07:00 committed by GitHub
parent b0ee5d6cfa
commit 94ca5063de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 132 additions and 0 deletions

View File

@ -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.