intermediate 90 min

Consensus fundamentals

The XRP Ledger Consensus Protocol — what it agrees on and the generic consensus engine.

Prerequisites

Complete these before starting this module:

What you'll learn

  • Explain what consensus decides (set membership) and why.
  • Map the generic `Consensus` engine and RCLConsensus.
  • Understand validators, proposals and quorum.
Complete this module by self-assessment and a quiz. Jump to assessment

Introduction

≈90 min · Intermediate · builds on Ledger architecture & data structures

How do thousands of independent nodes agree on one history, without a central authority, and without proof-of-work? In this module you'll learn what XRPL consensus actually decides, why it relies on trusted validators and a UNL instead of mining, and the roles of proposals and quorum. This is the idea at the very core of the ledger.


Consensus Protocol Overview

In brief: what consensus decides (the transaction set), and why it is not proof-of-work.

What is Consensus?

Consensus is the process by which a distributed network of nodes agrees on a single shared state. In the context of the XRP Ledger, this means agreeing on:

  1. Which transactions to include in the next ledger
  2. The order of those transactions (deterministic ordering)
  3. The resulting ledger state after applying all transactions

Without consensus, different nodes might have different views of the ledger, leading to double-spending and inconsistencies.

Why Not Proof-of-Work?

Traditional blockchains like Bitcoin use proof-of-work (PoW):

  • Miners compete to solve cryptographic puzzles
  • Winner proposes the next block
  • Requires massive computational resources
  • Block confirmation takes ~10 minutes (Bitcoin) or ~15 seconds (Ethereum)

XRP Ledger's approach is different:

  • No mining or computational puzzles
  • Validators vote on transaction sets
  • Consensus achieved in rounds lasting 3-5 seconds
  • Energy efficient (no wasted computation)
  • Fast finality (transactions confirmed quickly)

Byzantine Fault Tolerance

The XRP Ledger consensus protocol is Byzantine Fault Tolerant (BFT), meaning it can tolerate some validators being:

  • Offline or unreachable
  • Malicious (trying to disrupt consensus)
  • Byzantine (behaving arbitrarily or incorrectly)

Key Property: As long as >80% of trusted validators are honest and online, consensus will be reached correctly.

Security Model:

Network can tolerate up to 20% faulty validators
Examples:
- 100 validators → Can handle 20 failures
- 50 validators → Can handle 10 failures
- 35 validators (XRP Ledger mainnet) → Can handle 7 failures

Validators and UNL

In brief: each node trusts a list of validators (its UNL) to agree with.

Validators are nodes that participate in the XRP Ledger consensus process, validating transactions and agreeing on the state of the ledger. Each validator proposes and votes on ledger updates during consensus rounds.

A Unique Node List (UNL) is a trusted set of validators chosen by a participant. By relying on their UNL, a node can efficiently reach consensus while protecting against faulty or malicious validators. Proper UNL selection is crucial for network security, decentralization, and ledger reliability.

{% embed url="https://www.youtube.com/watch?v=4b58RtqO-oU" %}

What is a Validator?

A validator is a rippled server configured to participate in consensus by:

  • Proposing transaction sets
  • Voting on other validators' proposals
  • Signing validated ledgers

Not all rippled servers are validators. Most servers are:

  • Tracking servers: Follow the network and process transactions but don't participate in consensus
  • Stock servers: Serve API requests but don't store full history

To become a validator, a server needs:

  1. A validator key pair (generated with validator-keys tool)
  2. Configuration in xrpld.cfg to enable validation
  3. To be trusted by other validators (added to their UNLs)

Unique Node List (UNL)

Each validator maintains a Unique Node List (UNL), a list of validators it trusts to be honest and not collude.

Key Concepts:

Personal Choice: Each validator operator chooses their own UNL based on their trust relationships.

Overlap Required: For the network to reach consensus, there must be sufficient overlap between validators' UNLs. The protocol requires >90% overlap to ensure agreement.

Default UNL: Most operators use the default UNL provided by the XRP Ledger Foundation, which is regularly updated and reviewed.

Dynamic Updates: UNLs can be updated over time as validators join or leave the network.

UNL Configuration

In validators.txt:

# Validator List (maintained by XRP Ledger Foundation)
# Format: validator_public_key [optional_comment]

nHUon2tpyJEHHYGmxqeGu37cvPYHzrMtUNQFVdCgGNvYkr4k
nHBidG3pZK11zQD6kpNDoAhDxH6WLGui6ZxSbUx7LSqLHsgzMPe
nHUcNC5ni7XjVYfCMe38Rm3KQaq27jw7wJpcUYdo4miWwpNePRTw
nHU95JxeaHJoSdpE7R49Mxp4611Yk5yL9SGEc12UDJLr4oEUN
# ... more validators

# Optional: Add custom validators
# nH... My Custom Validator

Validator List Management

The validator list can be automatically fetched from trusted sources:

[validators_file]
validators.txt

[validator_list_sites]
https://vl.ripple.com
https://vl.xrplf.org

[validator_list_keys]
ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734

This allows dynamic updates without manual configuration changes.

Key idea. Consensus is trust-based, not work-based. Your node only counts proposals from validators on its UNL, and roughly 80% of them must agree.


Consensus Rounds

In brief: the repeating round that closes one ledger after another.

Round Structure

Consensus operates in discrete rounds, each typically lasting 3-5 seconds. Each round attempts to agree on the next ledger.

Round Phases:

The four phases of a round with their durations: Open (2 to 5 seconds, collecting transactions), Establish (2 to 4 seconds, exchanging proposals), Accepted (instant agreement), Validated (1 to 2 seconds, confirming the ledger)

Phase 1: Open Phase

Duration: Variable (typically 2 to 5 seconds; it can stretch toward ~15 seconds when the network is idle and there is nothing to close)

Purpose: Collect transactions for the next ledger

What Happens:

  • Transactions arrive from clients and peers
  • Transactions are validated and added to the open ledger
  • Each validator builds its own transaction set
  • Open ledger is tentatively applied (provides immediate feedback)

Key Point: The open ledger is not final, it shows what might be in the next ledger, but consensus hasn't been reached yet.

Phase 2: Establish Phase (Consensus Rounds)

Duration: 2-4 seconds (multiple sub-rounds with 50% increase each time)

Purpose: Validators exchange proposals and converge on a common transaction set

Process:

Initial Proposal

Each validator creates a proposal containing:

  • Hash of their proposed transaction set
  • Their validator signature
  • Previous ledger hash
  • Proposed close time
// Simplified proposal structure
struct ConsensusProposal
{
    uint256 previousLedger;     // Hash of previous ledger
    uint256 position;           // Hash of proposed transaction set
    NetClock::time_point closeTime;  // Proposed close time
    PublicKey publicKey;        // Validator's public key
    Signature signature;        // Proposal signature
};

Proposal Exchange

Validators broadcast proposals to the network using tmPROPOSE_LEDGER messages.

Agreement Threshold

Validators track which transactions appear in proposals from their UNL:

  • 80% agreement: Transaction is considered "likely to be included"
  • 50% agreement: Transaction is "disputed"
  • <50% agreement: Transaction is "unlikely to be included"

Iterative Refinement

Multiple rounds of proposals:

Round 1 (Initial): Each validator proposes their transaction set

Round 2 (50% threshold): Validators update proposals, including only transactions with >50% support

Round 3+ (Increasing threshold): Threshold increases each round, converging toward agreement

Round 1: 50% threshold, 2 second timer
Round 2: 65% threshold, 3 second timer (50% increase)
Round 3: 80% threshold, 4.5 second timer
Round 4: 95% threshold, 6.75 second timer
...

Avalanche Effect

Once enough validators converge on the same set, others quickly follow (avalanche effect), achieving rapid consensus.

Phase 3: Accepted Phase

Duration: Instant (threshold is reached)

Purpose: Consensus is reached, transaction set is accepted

Trigger: When a validator sees >80% of its UNL agreeing on the same transaction set

What Happens:

  • The agreed-upon transaction set becomes the "accepted" set
  • Ledger is closed with this transaction set
  • Validators compute the resulting ledger hash
  • Consensus round ends
// Simplified consensus acceptance check
bool hasConsensus(ConsensusMode mode, int validations)
{
    if (mode == ConsensusMode::Proposing)
    {
        // Need 80% of UNL to agree
        return validations >= (unlSize_ * 4 / 5);
    }
    return false;
}

Phase 4: Validated Phase

Duration: 1-2 seconds

Purpose: Validators sign and broadcast validations

What Happens:

  • Each validator applies the agreed transaction set
  • Computes the resulting ledger hash
  • Creates a validation message
  • Signs and broadcasts the validation

Validation Message (tmVALIDATION):

struct STValidation
{
    uint256 ledgerHash;          // Hash of validated ledger
    uint32 ledgerSequence;       // Ledger sequence number
    NetClock::time_point signTime;    // When validation was signed
    PublicKey publicKey;         // Validator's public key
    Signature signature;         // Validation signature
    bool full;                   // Full validation vs partial
};

Validation Collection:

  • Nodes collect validations from validators
  • When >80% of trusted validators validate the same ledger hash, it's considered fully validated
  • The ledger becomes immutable and part of the permanent ledger history

Consensus Round Timeline

One round on the clock: the open phase fills with transactions for 2 to 5 seconds, consensus triggers, three proposal rounds converge to the 80% threshold at about 9.5 seconds, validators apply transactions and create validations, and by about 11.5 seconds the ledger is fully validated and the next open phase begins

Total time from consensus start to validation: ~3-5 seconds. Total time from transaction submission to confirmation: typically ~4-10 seconds (depending on when in the open phase you submit; Mainnet closes a ledger every 3-5 seconds)


Transaction Ordering and Determinism

Why Ordering Matters

For all validators to reach the same ledger state, they must apply transactions in exactly the same order. Different orders can produce different results:

Example:

Why order matters: with 100 XRP and two 60-XRP payments, order TX1-then-TX2 leaves B paid and C empty-handed, while TX2-then-TX1 does the opposite; the results differ, so the order must be part of the agreement

Canonical Ordering

The XRP Ledger uses canonical ordering to ensure determinism:

Primary Sort: By account (lexicographic order of account IDs)

Secondary Sort: By transaction sequence number (nonce)

// Canonical transaction ordering
bool txOrderCompare(STTx const& tx1, STTx const& tx2)
{
    // First, sort by account
    if (tx1.getAccountID(sfAccount) < tx2.getAccountID(sfAccount))
        return true;
    if (tx1.getAccountID(sfAccount) > tx2.getAccountID(sfAccount))
        return false;
    
    // Same account, sort by sequence number
    return tx1.getSequence() < tx2.getSequence();
}

This ensures:

  • All transactions from the same account are processed in sequence order
  • Transactions from different accounts are processed in a deterministic order
  • All validators apply transactions identically

Transaction Set Hash

The transaction set is represented by a hash:

Simplified. The real canonical order is salted: CanonicalTXSet XORs each account key with a salt derived from the previous ledger's hash, so the order is deterministic for everyone but unpredictable in advance (nobody can buy a better position). The sort shown here keeps the idea readable; see the Transaction ordering module for the real mechanics.

This hash is what validators include in their proposals, a compact representation of the entire transaction set.


Dispute Resolution

What is a Dispute?

A dispute occurs when validators initially disagree about which transactions should be included in the next ledger. This is normal and expected, validators may have different views due to:

  • Network latency (different arrival times)
  • Transaction validity questions
  • Different open ledger states

Resolution Process

Disputes are resolved through the iterative consensus rounds:

Round 1: Initial Disagreement

Round 2: Converge on High-Agreement TXs

Validators drop transactions with <50% support:

Validator A proposes: {TX1, TX2, TX3, TX4, TX5}  (drops nothing, all >50%)
Validator B proposes: {TX1, TX2, TX3}            (drops TX6, TX7)
Validator C proposes: {TX1, TX2, TX4, TX5}       (drops TX8)

Agreement:
- TX1: 100%
- TX2: 100%
- TX3: 67% (A, B)
- TX4: 67% (A, C)
- TX5: 67% (A, C)

Round 3: Further Convergence

As threshold increases to 80%, validators must drop disputed transactions:

All validators propose: {TX1, TX2}

Agreement:
- TX1: 100% ✓ (exceeds 80%)
- TX2: 100% ✓ (exceeds 80%)

Consensus reached on {TX1, TX2}
TX3, TX4, TX5 deferred to next ledger

Deferred Transactions

Transactions that don't reach consensus are not lost:

  • They remain in the open ledger
  • They'll be included in the next consensus round
  • They're only dropped if they become invalid

Byzantine Validators

If a validator behaves maliciously:

  • Their proposals are signed, so misbehavior is detectable
  • Other validators ignore proposals that don't follow protocol rules
  • Byzantine validators cannot force consensus on invalid states (requires >80% support)
  • Operators can remove misbehaving validators from their UNL

Ledger Close Process

Close Triggers

A ledger close is triggered when:

Timer-based: Minimum time has elapsed (typically 2-10 seconds)

Transaction threshold: Sufficient transactions have accumulated

Consensus readiness: Validators are ready to reach agreement

Close Time Agreement

Validators must also agree on the close time of the ledger:

Why it matters: Some transactions are time-dependent (escrows, offers with expiration)

Process:

  • Each validator proposes a close time
  • Consensus includes the close time in proposals
  • Final close time is the median of proposed times (Byzantine fault tolerant)

Close Time Resolution:

  • Rounded to nearest 10 seconds for efficiency
  • Prevents clock skew from causing issues

Post-Consensus Application

After consensus is reached:

Step 1: Apply agreed transaction set

// Apply transactions in canonical order
for (auto const& tx : canonicalOrder(agreedTxSet))
{
    auto const result = applyTransaction(tx, view);
    // Record metadata
}

Step 2: Compute ledger hash

// Hash includes:
// - Parent ledger hash
// - Transaction set hash
// - Account state hash
// - Close time
// - Ledger sequence
auto ledgerHash = computeLedgerHash(
    parentHash,
    txSetHash,
    stateHash,
    closeTime,
    ledgerSeq);

Step 3: Create and broadcast validation

STValidation validation;
validation.setLedgerHash(ledgerHash);
validation.setLedgerSequence(ledgerSeq);
validation.setSignTime(now);
validation.sign(validatorKey);

overlay().broadcast(validation);

Step 4: Collect validations

// Wait for validations from UNL
while (validationCount < unlSize_ * 4 / 5)
{
    // Process incoming validations
    auto val = receiveValidation();
    
    if (val.getLedgerHash() == ledgerHash)
        validationCount++;
}

// Ledger is now fully validated
ledgerMaster_.setFullyValidated(ledger);

Codebase Deep Dive

Key Files and Directories

Consensus Core:

Consensus Implementation:

Network Messages:

Configuration:

  • validators.txt - UNL configuration
  • xrpld.cfg - Validator key configuration

Key Classes

Consensus Class

RCLConsensus (Ripple Consensus Ledger)

XRP Ledger-specific consensus implementation:

Code Navigation Tips

Finding Consensus Start

Search for ledger close triggers:

// In NetworkOPs or LedgerMaster
void beginConsensus(LedgerHash const& prevHash)
{
    // Build initial transaction set
    auto initialSet = buildTxSet();
    
    // Start consensus round
    consensus_.startRound(
        prevHash,
        prevLedger,
        suggestCloseTime());
}

Tracing Proposal Handling

Follow proposal processing:

// Overlay receives tmPROPOSE_LEDGER message
void onProposal(std::shared_ptr<protocol::TMProposeSet> const& proposal)
{
    // Validate proposal signature
    if (!verifyProposal(proposal))
        return;
    
    // Pass to consensus engine
    consensus_.peerProposal(
        now(),
        parseProposal(proposal));
}

Understanding Validation

Follow validation creation and verification:


Common Misconceptions

In brief: clearing up what consensus does and does not guarantee.

Misconception 1: "Validators mine like Bitcoin"

False: Validators don't perform computational work. They simply vote on which transactions to include.

Misconception 2: "Ripple controls consensus"

False: Any organization can run validators, and each validator operator independently chooses their UNL. While many operators use the recommended UNL from the XRP Ledger Foundation, they're free to customize it.

Misconception 3: "All servers participate in consensus"

False: Most rippled servers are tracking servers that follow consensus but don't vote. Only configured validators participate.

Misconception 4: "Consensus can be blocked by one entity"

False: As long as >80% of a validator's UNL is operational and honest, consensus proceeds normally.

Misconception 5: "XRP Ledger has forked"

False: The XRP Ledger has never had a fork (competing chains). The consensus protocol prevents this by design.


Additional Resources

Official Documentation

Academic Papers

  • Original Consensus Whitepaper: David Schwartz, Noah Youngs, Arthur Britto
  • Analysis of the XRP Ledger Consensus Protocol: Brad Chase, Ethan MacBrough
  • Cobalt: BFT Governance in Open Networks: Ethan MacBrough

Codebase References

  • Protocols - How consensus messages are propagated
  • Application Layer - How consensus integrates with other components
  • Transaction Lifecycle - How transactions flow through consensus

Consensus Fundamentals


Introduction

The XRP Ledger consensus mechanism is the heart of how distributed nodes agree on a single, canonical view of the network state. Unlike proof-of-work systems that rely on computational puzzles, or proof-of-stake systems that rely on economic incentives, XRPL uses a unique consensus protocol based on trusted validators reaching agreement through iterative voting.

This chapter introduces the fundamental concepts that underpin the consensus process, providing the foundation for understanding how thousands of independent nodes create identical ledgers without central coordination.

The Consensus Problem

The Challenge:

In a distributed system with no central authority, how do nodes agree on:

  • Which transactions are valid?
  • What order should transactions be processed?
  • What is the resulting state of all accounts?

Traditional Solutions and Their Trade-offs:

Approach Mechanism Trade-off
Proof of Work Computational puzzles High energy cost, slow finality
Proof of Stake Economic staking Wealth concentration, nothing-at-stake
PBFT Voting rounds Limited scalability
XRPL Consensus Trusted validators + iterative agreement Requires UNL overlap

XRPL's Approach: Federated Consensus

The XRPL consensus protocol achieves agreement through a federated model:

Federated consensus: validators broadcast proposals, iterate during the establish phase (share positions, adjust to peers, continue until supermajority), 80% agree on the same set, consensus is reached, and the new ledger is created

Key Principles:

  1. Trust is configurable: Each node chooses which validators to trust (Unique Node List - UNL)
  2. Iterative convergence: Validators adjust positions based on peer input
  3. Avalanche voting: Dynamic thresholds (50% → 65% → 70% → 95%) help validators converge on which transactions to include
  4. Final consensus: 80% of validators must agree on the complete transaction set (same hash) to declare consensus
  5. Fast finality: Ledgers close in 3-5 seconds on average

The Consensus State Machine

The consensus process is implemented as a template-based state machine in the codebase:

Design Properties:

  • Generic Architecture: Template-based design allows flexibility
  • Adaptor Pattern: Integrates with different ledger and transaction types
  • State Isolation: Each round maintains independent state
  • Event-Driven: Timer events drive phase transitions

Unique Node List (UNL)

The UNL is the set of validators a node trusts for consensus:

A node's perspective: its trusted UNL lists the validators whose proposals count (Ripple, exchanges, universities, companies); everyone else is relayed but ignored for consensus

UNL Requirements:

  • Overlap: For network-wide agreement, UNLs must overlap sufficiently
  • Diversity: Mix of organizations prevents single points of failure
  • Threshold: Minimum ~80% overlap between any two UNLs recommended

Consensus vs. Validation

Important Distinction:

Consensus Validation
Agreement on transaction set Cryptographic endorsement of ledger
Happens during ledger close Happens after ledger is built
Determines what's in the ledger Confirms ledger is correct
Internal process Published to network

Flow:

The pipeline: transactions go through consensus to an agreed set, the ledger is built, validation confirms it, and the result is the validated ledger

Byzantine Fault Tolerance

XRPL consensus tolerates Byzantine (malicious or faulty) validators:

Tolerance Threshold:

For UNL of size n:
  - Can tolerate up to ⌊n/5⌋ Byzantine validators (less than 20%)
  - Requires 80% honest agreement
  - Safety guaranteed with <20% Byzantine

Attack Resistance:

  • Sybil Attacks: UNL selection limits attacker influence
  • Denial of Service: Multiple validators ensure availability
  • Equivocation: Proposals are signed and tracked
  • Censorship: Requires controlling >20% of UNL

Consensus Parameters

Key parameters that control consensus behavior:

Parameter Impact:

Parameter Low Value High Value
minCONSENSUS_PCT Faster but less secure Slower but more secure
ledgerMinConsensus Faster finality More time for propagation
ledgerMaxConsensus Potential stalls Eventual termination

The Avalanche Mechanism

XRPL's avalanche mechanism uses increasing thresholds to force convergence on disputed transactions:

Threshold Progression:

The avalanche threshold progression: agreement required rises from 50 percent in the init state through 65 and 70 percent in mid and late, up to 95 percent once the round is stuck.

How It Works:

  • Early (50% threshold): Easy to include transactions → rapid exploration
  • Mid (65% threshold): Harder to change votes → stabilization begins
  • Late (70% threshold): Very hard to change → forced convergence
  • Stuck (95% threshold): Near-impossible to change → lock-in

Key Point: Thresholds rise over time, making it progressively harder to dissent from the majority. This creates an "avalanche effect" - once a majority position emerges, validators are forced to converge to it.

Purpose:

  1. Prevent endless flip-flopping of votes
  2. Force commitment to majority view
  3. Resist Byzantine manipulation
  4. Guarantee convergence in finite time

Analogy: Like a real avalanche, once momentum builds (majority emerges), the increasing thresholds make it impossible to stop the convergence toward that position.

Integration with the Ledger

Consensus doesn't operate in isolation, it's tightly integrated with ledger management:

The consensus stack: the application layer drives NetworkOPs (coordination), which drives RCLConsensus (the XRPL-specific adapter), which drives the generic Consensus template state machine, with LedgerMaster managing ledger state and history

Why This Design Matters

Understanding consensus fundamentals is essential because:

  1. Transaction Finality: Consensus determines when transactions are final
  2. Network Security: The mechanism protects against attacks
  3. Performance: Parameters affect throughput and latency
  4. Debugging: Many issues trace back to consensus behavior
  5. Protocol Evolution: Changes require deep understanding

Summary

This module explained what XRPL consensus is. It decides which transactions enter the next ledger and in what order, and it does so without proof-of-work: each node trusts a list of validators (its UNL), and a ledger is agreed once roughly 80% of them concur, round after round. That trust-based design is what keeps thousands of independent nodes on one shared history.

To remember:

  • Consensus decides WHICH transactions enter the next ledger (and their canonical order); applying them is deterministic afterwards
  • No proof-of-work: agreement is trust-based, through validators
  • Your UNL = the validators your node listens to; quorum is about 80% of it
  • A round: propose, converge (establish), accept, then validate
  • Most servers are trackers; only configured validators propose and vote
  • Generic engine: src/xrpld/consensus; XRPL glue: src/xrpld/app/consensus (RCLConsensus)
  • The UNL comes from validators.txt / published validator lists (e.g. vl.ripple.com)
  • Watch out: heavily overlapping UNLs across the network are what prevents forks; a divergent UNL isolates your node

Next up. You have the theory of agreement; next you watch a round actually run: the consensus lifecycle, phase by phase, timer tick by timer tick.

Assignments

0 of 2 complete

Unlocks

Finishing this module opens up:

XRPL Academy © 2026