docs: updated "transaction fees" page (#26861)

* docs: transaction fees, compute units, compute budget

* docs: added messages definition

* Revert "docs: added messages definition"

This reverts commit 3c56156dfaaf17158c5eafbc5877080a83607a06.

* docs: added messages definition

* Update docs/src/transaction_fees.md

Co-authored-by: Jacob Creech <82475023+jacobcreech@users.noreply.github.com>

* fix: updates from feedback

Co-authored-by: Jacob Creech <82475023+jacobcreech@users.noreply.github.com>
This commit is contained in:
Nick Frostbutter 2022-08-17 22:07:40 -04:00 committed by GitHub
parent a2e7bdf50a
commit 0d6a223e63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 101 additions and 33 deletions

View File

@ -49,7 +49,9 @@ To prevent abuse of computational resources, each transaction is allocated a
compute budget. The budget specifies a maximum number of compute units that a
transaction can consume, the costs associated with different types of operations
the transaction may perform, and operational bounds the transaction must adhere
to. As the transaction is processed compute units are consumed by its
to.
As the transaction is processed compute units are consumed by its
instruction's programs performing operations such as executing BPF instructions,
calling syscalls, etc... When the transaction consumes its entire budget, or
exceeds a bound such as attempting a call stack that is too deep, the runtime
@ -71,11 +73,11 @@ budget, or exceeds a bound, the entire invocation chain and the top level
transaction processing are halted.
The current [compute
budget](https://github.com/solana-labs/solana/blob/090e11210aa7222d8295610a6ccac4acda711bb9/program-runtime/src/compute_budget.rs#L26-L87)
budget](https://github.com/solana-labs/solana/blob/090e11210aa7222d8295610a6ccac4acda711bb9/program-runtime/src/compute_budget.rs#L26-L87) can be found in the Solana Program Runtime.
can be found in the Solana Program Runtime.
#### Example Compute Budget
For example, if the current budget is:
For example, if the compute budget set in the Solana runtime is:
```rust
max_units: 1,400,000,
@ -89,21 +91,23 @@ log_pubkey_units: 100,
...
```
Then the transaction
Then any transaction:
- Could execute 1,400,000 BPF instructions, if it did nothing else.
- Cannot exceed 4k of stack usage.
- Cannot exceed a BPF call depth of 64.
- Cannot exceed 4 levels of cross-program invocations.
Since the compute budget is consumed incrementally as the transaction executes,
the total budget consumption will be a combination of the various costs of the
operations it performs.
> **NOTE:** Since the compute budget is consumed incrementally as the transaction executes,
> the total budget consumption will be a combination of the various costs of the
> operations it performs.
At runtime a program may log how much of the compute budget remains. See
[debugging](developing/on-chain-programs/debugging.md#monitoring-compute-budget-consumption)
for more information.
### Prioritization fees
A transaction may set the maximum number of compute units it is allowed to
consume and the compute unit price by including a `SetComputeUnitLimit` and a
`SetComputeUnitPrice`
@ -112,20 +116,19 @@ respectively.
If no `SetComputeUnitLimit` is provided the limit will be calculated as the
product of the number of instructions in the transaction (excluding the [Compute
budget
instructions](https://github.com/solana-labs/solana/blob/db32549c00a1b5370fcaf128981ad3323bbd9570/sdk/src/compute_budget.rs#L22))
and the default per-instruction units, which is currently 200k.
budget instructions](https://github.com/solana-labs/solana/blob/db32549c00a1b5370fcaf128981ad3323bbd9570/sdk/src/compute_budget.rs#L22)) and the default per-instruction units, which is currently 200k.
Note that a transaction's prioritization fee is calculated by multiplying the
number of compute units by the compute unit price (measured in micro-lamports)
set by the transaction via compute budget instructions. So transactions should
request the minimum amount of compute units required for execution to minimize
> **NOTE:** A transaction's [prioritization fee](./../../terminology.md#prioritization-fee) is calculated by multiplying the
> number of _compute units_ by the _compute unit price_ (measured in micro-lamports)
> set by the transaction via compute budget instructions.
Transactions should request the minimum amount of compute units required for execution to minimize
fees. Also note that fees are not adjusted when the number of requested compute
units exceeds the number of compute units actually consumed by an executed
transaction.
Compute Budget instructions don't require any accounts and don't consume any
compute units to process. Transactions can only contain one of each type of
compute units to process. Transactions can only contain one of each type of
compute budget instruction, duplicate types will result in an error.
The `ComputeBudgetInstruction::set_compute_unit_limit` and

View File

@ -1,8 +1,10 @@
---
title: Terminology
description: "Learn the essential terminology used thoughtout the Solana blockchain and development models."
keywords: "terms, dictionary, definitions, define, programming models"
---
The following terms are used throughout the documentation.
The following terms are used throughout the Solana documentation and development ecosystem.
## account
@ -12,9 +14,9 @@ Like an account at a traditional bank, a Solana account may hold funds called [l
The key may be one of:
* an ed25519 public key
* a program-derived account address (32byte value forced off the ed25519 curve)
* a hash of an ed25519 public key with a 32 character string
- an ed25519 public key
- a program-derived account address (32byte value forced off the ed25519 curve)
- a hash of an ed25519 public key with a 32 character string
## account owner
@ -34,7 +36,7 @@ A contiguous set of [entries](#entry) on the ledger covered by a [vote](#ledger-
## blockhash
A unique value ([hash](#hash)) that identifies a record (block). Solana computes a blockhash from the last [entry id](#entry-id) of the block.
A unique value ([hash](#hash)) that identifies a record (block). Solana computes a blockhash from the last [entry id](#entry-id) of the block.
## block height
@ -56,6 +58,14 @@ A computer program that accesses the Solana server network [cluster](#cluster).
A set of [validators](#validator) maintaining a single [ledger](#ledger).
## compute budget
The maximum number of [compute units](#compute-units) consumed per transaction.
## compute units
The smallest unit of measure for consumption of computational resources of the blockchain.
## confirmation time
The wallclock duration between a [leader](#leader) creating a [tick entry](#tick) and creating a [confirmed block](#confirmed-block).
@ -179,6 +189,12 @@ A [program](#program) with the ability to interpret the binary encoding of other
The duration of time for which a [validator](#validator) is unable to [vote](#ledger-vote) on another [fork](#fork).
## message
The structured contents of a [transaction](#transaction). Generally containing a header, array of account addresses, recent [blockhash](#blockhash), and an array of [instructions](#instruction).
Learn more about the [message formatting inside of transactions](./developing/programming-model/transactions.md#message-format) here.
## native token
The [token](#token) used to track work done by [nodes](#node) in a cluster.
@ -221,7 +237,7 @@ A stack of proofs, each of which proves that some data existed before the proof
## prioritization fee
An additional fee user can specify in compute budget [instruction](#instruction) to prioritize their [transactions](#transaction).
An additional fee user can specify in the compute budget [instruction](#instruction) to prioritize their [transactions](#transaction).
The prioritization fee is calculated by multiplying the requested maximum compute units by the compute-unit price (specified in increments of 0.000001 lamports per compute unit) rounded up to the nearest lamport.
@ -287,7 +303,7 @@ Tokens forfeit to the [cluster](#cluster) if malicious [validator](#validator) b
## sysvar
A system [account](#account). [Sysvars](developing/runtime-facilities/sysvars.md) provide cluster state information such as current tick height, rewards [points](#point) values, etc. Programs can access Sysvars via a Sysvar account (pubkey) or by querying via a syscall.
A system [account](#account). [Sysvars](developing/runtime-facilities/sysvars.md) provide cluster state information such as current tick height, rewards [points](#point) values, etc. Programs can access Sysvars via a Sysvar account (pubkey) or by querying via a syscall.
## thin client
@ -327,7 +343,7 @@ A set of [transactions](#transaction) that may be executed in parallel.
## validator
A full participant in a Solana network [cluster](#cluster) that produces new [blocks](#block). A validator validates the transactions added to the [ledger](#ledger)
A full participant in a Solana network [cluster](#cluster) that produces new [blocks](#block). A validator validates the transactions added to the [ledger](#ledger)
## VDF

View File

@ -1,21 +1,70 @@
---
title: Transaction Fees
description: "Transaction fees are the small fees paid to process instructions on the network. These fees are based on computation and an optional prioritization fee."
keywords: "instruction fee, processing fee, storage fee, low fee blockchain, gas, gwei, cheap network, affordable blockchain"
---
**Subject to change.**
The small fees paid to process [instructions](./terminology.md#instruction) on the Solana blockchain are known as "_transaction fees_".
Each transaction sent through the network, to be processed by the current leader validation-client and confirmed as a global state transaction, contains a transaction fee. Transaction fees offer many benefits in the Solana economic design, for example they:
As each transaction (which contains one or more instructions) is sent through the network, it gets processed by the current leader validation-client. Once confirmed as a global state transaction, this _transaction fee_ is paid to the network to help support the [economic design](#economic-design) of the Solana blockchain.
- provide unit compensation to the validator network for the CPU/GPU resources necessary to process the state transaction,
> **NOTE:** Transaction fees are different from [account rent](./terminology.md#rent)!
> While transaction fees are paid to process instructions on the Solana network, rent is paid to store data on the blockchain.
<!-- > You can learn more about rent here: [What is rent?](./developing/intro/rent.md) -->
## Why pay transaction fees?
Transaction fees offer many benefits in the Solana [economic design](#basic-economic-design) described below. Mainly:
- they provide compensation to the validator network for the CPU/GPU resources necessary to process transactions,
- reduce network spam by introducing real cost to transactions,
- and provide potential long-term economic stability of the network through a protocol-captured minimum fee amount per transaction, as described below.
- and provide potential long-term economic stability of the network through a protocol-captured minimum fee amount per transaction
Network consensus votes are sent as normal system transfers, which means that validators pay transaction fees to participate in consensus.
> **NOTE:** Network consensus votes are sent as normal system transfers, which means that validators pay transaction fees to participate in consensus.
Many current blockchain economies \(e.g. Bitcoin, Ethereum\), rely on protocol-based rewards to support the economy in the short term, with the assumption that the revenue generated through transaction fees will support the economy in the long term, when the protocol derived rewards expire. In an attempt to create a sustainable economy through protocol-based rewards and transaction fees, a fixed portion (initially 50%) of each transaction fee is destroyed, with the remaining fee going to the current leader processing the transaction. A scheduled global inflation rate provides a source for rewards distributed to validation-clients, through the process described above.
## Basic economic design
Transaction fees are set by the network cluster based on recent historical throughput, see [Congestion Driven Fees](implemented-proposals/transaction-fees.md#congestion-driven-fees). This minimum portion of each transaction fee can be dynamically adjusted depending on historical _signatures-per-slot_. In this way, the protocol can use the minimum fee to target a desired hardware utilization. By monitoring a protocol specified _signatures-per-slot_ with respect to a desired, target usage amount, the minimum fee can be raised/lowered which should, in turn, lower/raise the actual _signature-per-slot_ per block until it reaches the target amount. This adjustment process can be thought of as similar to the difficulty adjustment algorithm in the Bitcoin protocol, however in this case it is adjusting the minimum transaction fee to guide the transaction processing hardware usage to a desired level.
Many current blockchain economies \(e.g. Bitcoin, Ethereum\), rely on _protocol-based rewards_ to support the economy in the short term. And when the protocol derived rewards expire, predict that the revenue generated through _transaction fees_ will support the economy in the long term.
As mentioned, a fixed-proportion of each transaction fee is to be destroyed. The intent of this design is to retain leader incentive to include as many transactions as possible within the leader-slot time, while providing an inflation limiting mechanism that protects against "tax evasion" attacks \(i.e. side-channel fee payments\).
In an attempt to create a sustainable economy on Solana through _protocol-based rewards_ and _transaction fees_:
Additionally, the burnt fees can be a consideration in fork selection. In the case of a PoH fork with a malicious, censoring leader, we would expect the total fees destroyed to be less than a comparable honest fork, due to the fees lost from censoring. If the censoring leader is to compensate for these lost protocol fees, they would have to replace the burnt fees on their fork themselves, thus potentially reducing the incentive to censor in the first place.
- a fixed portion (initially 50%) of each transaction fee is _burned_ (aka destroyed),
- with the remaining fee going to the current [leader](./terminology.md#leader) processing the transaction.
A scheduled global inflation rate provides a source for [rewards](./implemented-proposals/staking-rewards.md) distributed to [Solana Validators](../src/running-validator.md).
### Why burn some fees?
As mentioned above, a fixed proportion of each transaction fee is _burned_ (aka destroyed). The intent of this design is to retain leader incentive to include as many transactions as possible within the leader-slot time. While still providing an inflation limiting mechanism that protects against "tax evasion" attacks \(i.e. side-channel fee payments\).
Burnt fees can also help prevent malicious validators from censoring transactions by being considered in [fork](./terminology.md#fork) selection.
#### Example of an attack:
In the case of a [Proof of History (PoH)](./terminology.md#proof-of-history-poh) fork with a malicious, censoring leader:
- due to the fees lost from censoring, we would expect the total fees destroyed to be **_less than_** a comparable honest fork
- if the censoring leader is to compensate for these lost protocol fees, they would have to replace the burnt fees on their fork themselves
- thus potentially reducing the incentive to censor in the first place
## Calculating transaction fees
Transactions fees are calculated based on two main parts:
- a statically set base fee per signature, and
- the computational resources used during the transaction, measured in "[_compute units_](./terminology.md#compute-units)"
Since each transaction may require a different amount of computational resources, they are alloted a maximum number of _compute units_ per transaction known as the "[_compute budget_](./terminology.md#compute-budget)".
The execution of each instruction within a transactions consumes a different number of _compute units_. After the maximum number of _computer units_ has been consumed (aka compute budget exhaustion), the runtime will halt the transaction and return an error. Resulting in a failed transaction.
> **Learn more:** compute units and the [Compute Budget](./developing/programming-model/runtime#compute-budget) in the Runtime and [requesting a fee estimate](./developing/clients/jsonrpc-api.md#getfeeformessage) from the RPC.
## Prioritization fee
Recently, Solana has introduced an optional fee called the "_[prioritization fee](./terminology.md#prioritization-fee)_". This additional fee can be paid to help boost how a transaction is prioritized against others, resulting in faster transaction execution times.
The prioritization fee is calculated by multiplying the requested maximum _compute units_ by the compute-unit price (specified in increments of 0.000001 lamports per compute unit) rounded up to the nearest lamport.
You can read more about the [compute budget instruction](./developing/programming-model/runtime.md#compute-budget) here.