mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-11-20 03:35:51 +00:00
Queue, Consensus: separate out queue mechanics, clarify how ledgers are calculated
This commit is contained in:
@@ -79,7 +79,7 @@
|
||||
<div class="card-body">
|
||||
<img src="img/consensus-w-q-6.png" alt="Adding to the Queue" width="250" height="180" />
|
||||
<div class="description">
|
||||
<p>Each validator prepares its proposal for the next ledger version, starting with queued transactions.</p>
|
||||
<p>If the next proposed ledger is already full, incoming transactions are queued for a later ledger version.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /.card -->
|
||||
|
||||
@@ -81,13 +81,43 @@ In some circumstances, a transaction could fail to achieve consensus indefinitel
|
||||
|
||||
### Validation
|
||||
|
||||
When the consensus process completes, each server computes a new ledger by applying the agreed-upon set of transactions to the previous validated ledger.
|
||||
Validation is the second stage of the overall consensus process, which verifies that the servers got the same results and declares a ledger version final. In rare cases, the first stage of [consensus can fail](consensus-principles-and-rules.html#consensus-can-fail); validation provides a confirmation afterward so that servers can recognize this and act accordingly.
|
||||
|
||||
Validation can be broken up into roughly two parts:
|
||||
|
||||
- Calculating the resulting ledger version from an agreed-upon transaction set.
|
||||
- Comparing results and declaring the ledger version validated if enough trusted validators agree.
|
||||
|
||||
#### Calculate and Share Validations
|
||||
|
||||
When the consensus process completes, each server independently computes a new ledger from the agreed-upon set of transactions. Each server calculates the results by following the same rules, which can be summarized as follows:
|
||||
|
||||
1. Start with the previous validated ledger.
|
||||
|
||||
2. Place the agreed-upon transaction set in _canonical order_ so that every server processes them the same way.
|
||||
|
||||
[Canonical order](https://github.com/ripple/rippled/blob/8429dd67e60ba360da591bfa905b58a35638fda1/src/ripple/app/misc/CanonicalTXSet.cpp#L25-L36) is not the order the transactions were received, because servers may receive the same transactions in different order. To prevent participants from competing over transaction ordering, canonical order is hard to manipulate.
|
||||
|
||||
3. Process each transaction according to its instructions, in order. Update the ledger's state data accordingly.
|
||||
|
||||
If the transaction cannot be successfully executed, destroy the XRP transaction cost only. Include the transaction with a [`tec`-class result code](tec-codes.html).
|
||||
|
||||
For certain "retriable" transaction failures, instead move the transaction to the end of the canonical order to be retried after other transactions in the same ledger version have executed.
|
||||
|
||||
4. Update the ledger header with the appropriate metadata.
|
||||
|
||||
This includes data such as the ledger index, the identifying hash of the previous validated ledger (this one's "parent"), this ledger version's approximate close time, and the cryptographic hashes of this ledger's contents.
|
||||
|
||||
5. Calculate the identifying hash of the new ledger version.
|
||||
|
||||
|
||||
[](img/consensus-calculate-validation.png)
|
||||
|
||||
_Figure 7: An XRP Ledger Server Calculates a Ledger Validation — Each server applies agreed-upon transactions to the previous validated ledger. Validators send their results to the entire network._
|
||||
|
||||
The validators calculate a new version of the ledger and relay their results to the network, each sending a signed hash of the ledger it calculated based on the candidate transactions proposed during consensus. These signed hashes, called validations, allow each server to compare the ledger it computed with those of its peers.
|
||||
#### Compare Results
|
||||
|
||||
Validators each relay their results in the form of a signed message containing the hash of the ledger version they calculated. These messages, called _validations_, allow each server to compare the ledger it computed with those of its peers.
|
||||
|
||||
[](img/consensus-declare-validation.png)
|
||||
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
|
||||
The `rippled` server uses a transaction queue to help enforce the [open ledger cost](transaction-cost.html#open-ledger-cost). The open ledger cost sets a target number of transactions in a given ledger, and escalates the required transaction cost very quickly when the open ledger surpasses this size. Rather than discarding transactions that cannot pay the escalated transaction cost, `rippled` tries to put them in a transaction queue, which it uses to build the next ledger.
|
||||
|
||||
## Order Within the Queue
|
||||
|
||||
Within the transaction queue, transactions are ranked so that transactions paying a higher transaction cost come first. This ranking is not by the transactions' _absolute_ XRP cost, but by their _[fee levels](transaction-cost.html#fee-levels)_ which are relative to the [minimum cost for that type of transaction](transaction-cost.html#special-transaction-costs). Other factors may also affect the order of transactions in the queue; for example, transactions from the same sender are sorted by their `Sequence` numbers so that they are submitted in order.
|
||||
|
||||
## Transaction Queue and Consensus
|
||||
|
||||
The transaction queue plays an important role in selecting the transactions that are included or excluded from a given ledger version in the consensus process. The following steps describe how the transaction queue relates to the [consensus process](consensus.html).
|
||||
@@ -15,8 +11,46 @@ The transaction queue plays an important role in selecting the transactions that
|
||||
|
||||
**Note:** Technically, several of the steps described in the above process occur in parallel, because each server is always listening for new transactions, and starts preparing its next ledger proposal while the consensus process for the previous ledger version is ongoing.
|
||||
|
||||
## Queuing Restrictions
|
||||
|
||||
The `rippled` server uses a variety of heuristics to estimate which transactions are "likely to be included in a ledger." The current implementation uses the following rules to decide which transactions to queue:
|
||||
|
||||
* Transactions must be properly-formed and [authorized](transaction-basics.html#authorizing-transactions) with valid signatures.
|
||||
* Transactions with an `AccountTxnID` field cannot be queued.
|
||||
* A single sending address can have at most 10 transactions queued at the same time. In order for a transaction to be queued, the sender must have enough XRP to pay all the XRP costs of all the sender's queued transactions including both the `Fee` fields and the sum of the XRP that each transaction could send. [New in: rippled 0.32.0][]
|
||||
* If a transaction affects how the sending address authorizes transactions, no other transactions from the same address can be queued behind it. [New in: rippled 0.32.0][]
|
||||
* If the transaction includes a `LastLedgerSequence` field, the value of that field must be at least **the current ledger index + 2**.
|
||||
|
||||
### Fee Averaging
|
||||
|
||||
[New in: rippled 0.33.0][]
|
||||
|
||||
If a sending address has one or more transactions queued, that sender can "push" the existing queued transactions into the open ledger by submitting a new transaction with a high enough transaction cost to pay for all of them. Specifically, the new transaction must increase the total transaction cost of the queued transactions from the same sending address, including the new transaction, to cover the [open ledger cost](transaction-cost.html#open-ledger-cost) of each transaction as it gets added to the ledger. The total must include the increased open ledger cost for each new transaction. The transactions must still follow the other [queuing restrictions](#queuing-restrictions) and the sending address must have enough XRP to pay the transaction costs of all the queued transactions.
|
||||
|
||||
This feature helps you work around a particular situation. If you submitted one or more transactions with a low cost, which got queued, you cannot send new transactions from the same address unless you do one of the following:
|
||||
|
||||
* Wait for the queued transactions to be included in a validated ledger, _or_
|
||||
* Wait for the queued transactions to be permanently invalidated if the transactions have the [`LastLedgerSequence` field](reliable-transaction-submission.html#lastledgersequence) set, _or_
|
||||
* [Cancel the queued transactions](cancel-or-skip-a-transaction.html) by submitting a new transaction with the same sequence number.
|
||||
|
||||
If none of the above occur, transactions can stay in the queue for a theoretically unlimited amount of time, while other senders can "cut in line" by submitting transactions with higher transaction costs. Since signed transactions are immutable, you cannot increase the transaction cost of the queued transactions to increase their priority. If you do not want to invalidate the previously submitted transactions, fee averaging provides a workaround. If you increase the transaction cost of your new transaction to compensate, you can ensure the queued transactions are included in an open ledger right away.
|
||||
|
||||
## Order Within the Queue
|
||||
|
||||
Within the transaction queue, transactions are ranked so that transactions paying a higher transaction cost come first. This ranking is not by the transactions' _absolute_ XRP cost, but by costs _relative to the [minimum cost for that type of transaction](transaction-cost.html#special-transaction-costs)_. Transactions that pay the same transaction cost are ranked in the order the server received them. Other factors may also affect the order of transactions in the queue; for example, transactions from the same sender are sorted by their `Sequence` numbers so that they are submitted in order.
|
||||
|
||||
The precise order of transactions in the queue decides which transactions get added to the next in-progress ledger version in cases where there are more transactions in the queue than the expected size of the next ledger version. The order of the transactions **does not affect the order the transactions are executed within a validated ledger**. In each validated ledger version, the transaction set for that version executes in [canonical order](consensus.html#calculate-and-share-validations).
|
||||
|
||||
**Note:** When `rippled` queues a transaction, the provisional [transaction response code](transaction-results.html) is `terQUEUED`. This means that the transaction is likely to succeed in a future ledger version. As with all provisional response codes, the outcome of the transaction is not final until the transaction is either included in a validated ledger, or [rendered permanently invalid](finality-of-results.html).
|
||||
|
||||
|
||||
## See Also
|
||||
|
||||
- [Transaction Cost](transaction-cost.html)
|
||||
- [Queued Transactions](transaction-cost.html#queued-transactions)
|
||||
- [Transaction Cost](transaction-cost.html) for information on why the transaction cost exists and how the XRP Ledger enforces it.
|
||||
- [Consensus](consensus.html) for a detailed description of how the consensus process approves transactions.
|
||||
|
||||
|
||||
<!--{# common link defs #}-->
|
||||
{% include '_snippets/rippled-api-links.md' %}
|
||||
{% include '_snippets/tx-type-links.md' %}
|
||||
{% include '_snippets/rippled_versions.md' %}
|
||||
|
||||
@@ -60,34 +60,7 @@ See also: [Fee Escalation explanation in `rippled` repository](https://github.co
|
||||
|
||||
When `rippled` receives a transaction that meets the server's local load cost but not the [open ledger cost](#open-ledger-cost), the server estimates whether the transaction is "likely to be included" in a later ledger. If so, the server adds the transaction to the transaction queue and relays the transaction to other members of the network. Otherwise, the server discards the transaction. The server tries to minimize the amount of network load caused by transactions that would not pay a transaction cost, since [the transaction cost only applies when a transaction is included in a validated ledger](#transaction-costs-and-failed-transactions).
|
||||
|
||||
When the current open ledger closes and the server starts a new open ledger, the server starts taking transactions from the queue to include in the new open ledger. The transaction queue is sorted with the transactions that would pay the highest transaction cost first, proportional to the [reference cost](#reference-transaction-cost) of those transactions. Transactions that pay the same transaction cost are queued in the order the server receives them.
|
||||
|
||||
**Note:** When `rippled` queues a transaction, the provisional [transaction response code](transaction-results.html) is `terQUEUED`. This means that the transaction is likely to succeed in a future ledger version. As with all provisional response codes, the outcome of the transaction is not final until the transaction is either included in a validated ledger, or [rendered permanently invalid](finality-of-results.html).
|
||||
|
||||
#### Queuing Restrictions
|
||||
|
||||
The `rippled` server uses a variety of heuristics to estimate which transactions are "likely to be included in a ledger." The current implementation uses the following rules to decide which transactions to queue:
|
||||
|
||||
* Transactions must be properly-formed and [authorized](transaction-basics.html#authorizing-transactions) with valid signatures.
|
||||
* Transactions with an `AccountTxnID` field cannot be queued.
|
||||
* A single sending address can have at most 10 transactions queued at the same time. In order for a transaction to be queued, the sender must have enough XRP to pay all the XRP costs of all the sender's queued transactions including both the `Fee` fields and the sum of the XRP that each transaction could send. [New in: rippled 0.32.0][]
|
||||
* If a transaction affects how the sending address authorizes transactions, no other transactions from the same address can be queued behind it. [New in: rippled 0.32.0][]
|
||||
* If the transaction includes a `LastLedgerSequence` field, the value of that field must be at least **the current ledger index + 2**.
|
||||
|
||||
#### Fee Averaging
|
||||
|
||||
[New in: rippled 0.33.0][]
|
||||
|
||||
If a sending address has one or more transactions queued, that sender can "push" the existing queued transactions into the open ledger by submitting a new transaction with a high enough transaction cost to pay for all of them. Specifically, the new transaction must increase the total transaction cost of the queued transactions from the same sending address, including the new transaction, to cover the [open ledger cost](#open-ledger-cost) of each transaction as it gets added to the ledger. The total must include the increased open ledger cost for each new transaction. The transactions must still follow the other [queuing restrictions](#queuing-restrictions) and the sending address must have enough XRP to pay the transaction costs of all the queued transactions.
|
||||
|
||||
This feature helps you work around a particular situation. If you submitted one or more transactions with a low cost, which got queued, you cannot send new transactions from the same address unless you do one of the following:
|
||||
|
||||
* Wait for the queued transactions to be included in a validated ledger, _or_
|
||||
* Wait for the queued transactions to be permanently invalidated if the transactions have the [`LastLedgerSequence` field](reliable-transaction-submission.html#lastledgersequence) set, _or_
|
||||
* [Cancel the queued transactions](cancel-or-skip-a-transaction.html) by submitting a new transaction with the same sequence number.
|
||||
|
||||
If none of the above occur, transactions can stay in the queue for a theoretically unlimited amount of time, while other senders can "cut in line" by submitting transactions with higher transaction costs. Since signed transactions are immutable, you cannot increase the transaction cost of the queued transactions to increase their priority. If you do not want to invalidate the previously submitted transactions, fee averaging provides a workaround. If you increase the transaction cost of your new transaction to compensate, you can ensure the queued transactions are included in an open ledger right away.
|
||||
|
||||
For more information on queued transactions, see [Transaction Queue](transaction-queue.html).
|
||||
|
||||
## Reference Transaction Cost
|
||||
|
||||
|
||||
Reference in New Issue
Block a user