From 94ca5063de18ddbbf2d821d2a4fcf19430ea9fd4 Mon Sep 17 00:00:00 2001 From: Jack May Date: Mon, 11 Oct 2021 17:14:21 -0700 Subject: [PATCH] Comprehensive compute fees (#20531) * Comprehensive fees proposal * Updated --- .../proposals/comprehensive-compute-fees.md | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 docs/src/proposals/comprehensive-compute-fees.md diff --git a/docs/src/proposals/comprehensive-compute-fees.md b/docs/src/proposals/comprehensive-compute-fees.md new file mode 100644 index 0000000000..a47460dec1 --- /dev/null +++ b/docs/src/proposals/comprehensive-compute-fees.md @@ -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.