The Ripple Ledger Consensus Process
The Ripple Ledger Consensus Process
Written by: Dave Cohen, David Schwartz and Arthur Britto.
This article provides a high level overview of the Ripple ledger, the information it stores, and how transactions result in changes to the ledger.
When building applications on Ripple, it is important to understand this process, so as not to be surprised by the behavior of Ripple APIs and their effect on the ledger.
Important: Transactions are not applied to the Ripple ledger instantaneously; it takes some time for the effects of transactions to be applied. During this process, Ripple APIs may return provisional results that should not be mistaken for the final, immutable results of a transaction. Immutable results can only be determined by looking at validated ledgers.
The Ripple network provides a worldwide, shared ledger, which gives applications authoritative information about the state of account balances and offers. This state information includes:
- settings for each account
- balances between accounts
- offers to buy and sell currencies
- network settings, such as fees and reserve amounts
- a time stamp
Figure 1: Ripple Ledger Elements
The Ripple network produces a new ledger instance every several seconds. The ledgers that preceded it comprise the ledger history. Even the most recent validated ledger is part of history, as it represents the state of the network as of a short time ago. In the present, the network is evaluating transactions which may be applied and finalized in the next ledger instance.
Figure 2: Ledger Sequence Timeline
A ledger instance is uniquely identified by its sequence number . Ledgers are numbered incrementally. If the last validated ledger is N, the previous was N-1 and the next will be N+1. The N+1 ledger is produced by applying a set of transactions to ledger N.
User level changes to the ledger are the results of transactions. Examples of transactions include payments, changes to account settings or trust lines, and offers to trade. Each transaction authorizes changes to the ledger and is cryptographically signed by an account owner. Transactions are the only way to authorize changes to an account.
A ledger instance also contains a set of transactions and metadata about those transactions. The transactions are those that have been applied to the prior ledger in order to create the new instance. The metadata records precisely the effects of the transaction on the ledger.
Figure 3: Transactions Applied to Ledger Sequence
The set of transactions included in a ledger instance are recorded in that ledger and allow auditability of the Ripple ledger history. If an account balance is different in ledger N+1 than it was in ledger N, then ledger N+1 contains the transaction(s) responsible for the change.
Transactions that appear in a validated ledger may have succeeded in changing the ledger, or may have been processed without doing the requested action. Successful transactions will have the tesSUCCESS result code which indicates the requested changes are applied to the ledger and a fee was claimed. Other transactions in the ledger have tec class result codes, which indicate transactions that only claim a fee and perform no other changes .
Transactions of the tec class are included with the ledger because they change an account balance when claiming a fee.
In addition to the tes and tec class result codes, there are ter, tef and tem class codes. The latter three indicate provisional failures returned by API calls. These three classes of errors do not appear in validated ledgers.
When working with Ripple APIs, applications must distinguish between candidate transactions proposed for inclusion in a ledger versus validated transactions which are included in a validated ledger. Only transaction results found in a validated ledger are immutable. A candidate transaction may or may not ever be included in a validated ledger.
Important: Some Ripple APIs provide provisional results, based on candidate transactions . Applications should never rely on provisional results to determine the final outcome of a transaction. The only way to know with certainty that a transaction finally succeeded is to check the status of the transaction until it is both in a validated ledger and has result code tesSUCCESS. If the transaction is in a validated ledger with any other result code, it has failed. If the ledger specified in a transaction’s LastLedgerSequence has been validated, yet the transaction does not appear in that ledger or any before it, then that transaction has failed and will never appear in any ledger. An outcome is final only for transactions that appear in a validated ledger or can never appear because of LastLedgerSequence restrictions as explained later in this document.
The Ripple Protocol – Consensus and Validation
The Ripple network consists of many distributed servers, called nodes, that accept and process transactions. Client applications sign and send transactions to nodes, which relay these candidate transactions throughout the network for processing. Examples of client applications include mobile and web wallets, gateways to financial institutions, and electronic trading platforms.
Figure 4: Participants in the Ripple Protocol
The nodes that receive, relay and process transactions may be either tracking nodes or validating nodes. Tracking nodes’ primary functions include distributing transactions from clients and responding to queries about the ledger. Validating nodes perform the same functions as tracking nodes and additionally contribute to advancing the ledger sequence .
While accepting transactions submitted by client applications, each tracking node uses the last validated ledger as a starting point. The accepted transactions are candidates. The nodes relay their candidate transactions to their peers, allowing the candidate transactions to propagate throughout the network. Ideally, each candidate transaction would be known to all nodes, allowing each to consider an identical set of transactions to apply to the last validated ledger. As transactions take time to propagate however, the nodes do not work with an identical set of candidate transactions at all times. To account for this, the Ripple network uses a process called consensus to ensure that identical transactions are processed and validated ledgers are consistent across the network.
The nodes on the network share information about candidate transactions. Through the consensus process, validating nodes agree on a specific subset of the candidate transactions to be considered for the next ledger. Consensus is an iterative process in which nodes relay proposals, or sets of candidate transactions. Nodes communicate and update proposals until a supermajority  of peers agree on the same set of candidate transactions.
During consensus, each node evaluates proposals from a specific set of peers, called chosen validators . Chosen validators represent a subset of the network which, when taken collectively, is “trusted” not to collude in an attempt to defraud the node evaluating the proposals. This definition of “trust” does not require that each individual chosen validator is trusted. Rather, validators are chosen based on the expectation they will not collude in a coordinated effort to falsify data relayed to the network .
Figure 5: Validators Propose Transaction Sets — At the start of consensus, nodes work with different sets of transactions. Rounds of proposals determine which transactions will be applied to the ledger, and which must wait for a subsequent round of consensus.
Candidate transactions which fail to be included in the agreed-upon proposal remain candidate transactions. They may be considered again in the next round of consensus.
Figure 6: Through Consensus, Nodes Agree On Transaction Set — Nodes will apply the agreed-upon set of transactions (shown in green) to the last validated ledger. Transactions not in the set (in red) may be agreed upon in the next round.
Typically, a transaction which does not pass one round of consensus will succeed in the following round. However, in some circumstances, a transaction could fail to pass consensus indefinitely. One such circumstance is if the network increases the base fee to a value higher than the transaction provides. The transaction could potentially succeed if the fees are lowered at some point in the future.
Ripple provides a mechanism to prevent such a transaction from being viable indefinitely and ensure transaction processing occurs in a timely fashion. Applications should include a LastLedgerSequence parameter with each transaction. This ensures a transaction will either succeed or fail on or before the specified ledger sequence number, thus limiting the amount of time an application must wait before obtaining a definitive transaction result.
When a round of consensus completes, each node computes a new ledger by applying the candidate transactions in the consensus transaction set to the last validated ledger.
Figure 7: A Network Node Calculates a Ledger Validation — Each tracking node applies agreed-upon transactions to the last validated ledger. Validating nodes will transmit their results to the entire network.
The validating nodes calculate a new version of the ledger and relay their results to the network, each transmitting a signed hash of the ledger it calculated based on the candidate transactions proposed during consensus. These signed hashes, called validations, allow each node to compare the ledger it computed with those of its peers.
Figure 8: Ledger is Validated When Supermajority of Peers Calculate an Identical Result — Nodes compare their calculated ledger with the hashes received from chosen validators. If not in agreement, the node must re-calculate or retrieve the correct ledger.
Nodes of the network recognize a ledger instance as validated when a supermajority of the peers have signed and broadcast an identical validation hash . Going forward, transactions will be applied to this updated and now validated ledger with sequence number N+1.
In cases where a node is in the minority, having computed a ledger that differs from its peers, the node will disregard the ledger it computed . It will recompute the correct ledger, or retrieve the correct ledger as needed.
If the network fails to achieve supermajority agreement on validations, this implies that transaction volume was too high or network latency too great for the consensus process to produce consistent proposals. In this case, the nodes repeat the consensus process. As time passes since consensus began, it becomes increasingly likely that a majority of the nodes have received the same set of candidate transactions, as each consensus round reduces disagreement. The Ripple network dynamically adjusts its fees and the time to wait for consensus in response to these conditions.
Figure 9: Network Recognises the New Validated Ledger — At the end of a round of the consensus process, nodes have an updated validated ledger.
Once they reach supermajority agreement on validations, the nodes work with the new validated ledger, sequence number N+1. The consensus and validation process repeats , considering candidate transactions that were not included in the last round along with new transactions submitted in the meantime.
Transactions submitted to the Ripple network are not processed instantaneously. For a period of time, each transaction remains a candidate.
The lifecycle of a single transaction is as follows:
- A transaction is created and signed by an account owner.
- The transaction is submitted to the network.
- Badly formed transactions may be rejected immediately.
- Well formed transactions may provisionally succeed, then later fail.
- Well formed transactions may provisionally fail, then later succeed.
- During consensus, the transaction is included in the ledger.
- The result of a successful consensus round is a validated ledger.
- If a consensus round fails, the consensus process repeats until it succeeds.
- The validated ledger includes the transaction and its effects on the ledger state.
Applications should only rely on information in validated ledgers, not on the provisional results of candidate transactions. Some ripple APIs initially return provisional results for transactions. The results of a transaction become immutable only when that transaction is included in a validated ledger, or the transaction includes LastLedgerSequence and does not appear in any validated ledger with that sequence number or lower.
Best practices for applications submitting transactions include:
- Use the LastLedgerSequence parameter to ensure that transactions validate or fail in a deterministic and timely fashion.
- Check the results of transactions in validated ledgers.
- Until a ledger containing the transaction is validated, or LastLedgerSequence has passed, results are provisional.
- Transactions with result code tesSUCCESS and “validated”: “true” have immutably succeeded.
- Transactions with other result codes and “validated”: “true” have immutably failed.
- Transactions that fail to appear in any validated ledger up to and including the validated ledger identified by the transaction’s LastLedgerSequence have immutably failed.
- Take care to use a node with a continuous ledger history to detect this case .
- It may be necessary to check the status of a transaction repeatedly until the ledger identified by LastLedgerSequence is validated.
- Consensus White Paper
- Ripple Consensus Video
- Reliable Transaction Submission (Developer support material)
 – A ledger instance can also be uniquely identified by its hash, which is a digital fingerprint of its contents.
 – Transactions with tec result codes are included in ledgers and not do the requested action. The rationale for this is that multiple transactions may be submitted in sequence, with the order of processing determined by a sequence number associated with an account (not to be confused with the ledger sequence number). To prevent a hold on account sequence numbers which would block subsequent transactions, the transaction is processed to consume the sequence number. Additionally, transactions which are distributed to the network must claim a fee to prevent network abuse.
 – For example, consider a scenario where Alice has $100, and sends all of it to Bob. If an application first submits that payment transaction, then immediately after checks Alice’s balance, the API will return $0. This value is based on the provisional result of a candidate transaction. There are circumstances in which the payment will fail and Alice’s balance will remain $100 (or, due to other transactions, become some other amount). The only way to know with certainty that Alice’s payment to Bob succeeded is to check the status of the transaction until it is both in a validated ledger and has result code tesSUCCESS. If the transaction is in a validated ledger with any other result code, the payment has failed.
 – Strictly speaking, validating nodes are a subset of tracking nodes. They provide the same features and additionally create “validations.” Tracking nodes may be further categorized by whether they maintain full vs. partial ledger history.
 – Transactions fail to pass a round of consensus when the percentage of peers recognizing the transaction falls below a threshold. Each round is an iterative process. At the start of the first round, at least 50% of peers must agree. The final threshold for a consensus round is 80% agreement. These specific values are subject to change
 – Sometimes referred to as a Unique Node List (UNL).
 – If proposals from all validators were evaluated, instead of exclusively from the validators chosen not to collude, a malicious attacker could spin up enough validating nodes to comprise a colluding supermajority to introduce invalid transactions or omit valid transactions from proposals. The chosen validator list defends against Sybil attacks.
 – The supermajority threshold, as of November 2014, requires that at least 80% of peers must agree for a ledger to be validated. This happens to be the same percentage required by a round of consensus. Both thresholds are subject to change and need not be equal.
 – In practice, the node detects that it is in the minority before receiving validations from all peers. It knows when it receives non-matching validations from over 20% of peers that its validation will not meet the 80% threshold. At that point, it can begin to recalculate a ledger.
 – In practice, the Ripple network runs more efficiently by starting a new round of consensus concurrently, before validation has completed.
 – A ripple node can respond to API requests even without a complete ledger history. Interruptions in service or network connectivity can lead to missing ledgers, or gaps, in the node’s ledger history. Over time, if configured to, rippled will fill in gaps in its history. When testing for missing transactions, it is important to verify against a node with continuous complete ledgers from the time the transaction was submitted until its LastLedgerSequence. Use the RPC server_state to determine which complete_ledgers are available to a particular node.