advanced 75 min

Ledger acquisition & the tx lifecycle

How a node acquires and validates ledgers, and the end-to-end path of a transaction across RPC, peers and consensus.

Prerequisites

Complete these before starting this module:

What you'll learn

  • Explain ledger acquisition and validation.
  • Trace a transaction from RPC through peers to a validated ledger.
  • Connect acquisition to catch-up / sync.
Complete this module by mentor review and a quiz. Jump to assessment

Introduction

≈75 min · Advanced · builds on Consensus lifecycle & phases

A node doesn't just build ledgers, it also has to catch up on the ones it missed. In this module you'll learn how LedgerMaster and InboundLedgers acquire and validate ledgers and fill gaps, then trace a transaction end to end, from RPC or peer relay all the way to a validated ledger. Two threads of the story, tied together.

LedgerMaster Overview

In brief: the component that tracks known ledgers and spots gaps.

The LedgerMaster is the central coordinator for ledger state management:

LedgerMaster's core state tracks the published, validated, closed, and current ledgers plus a history cache, and its key functions doAdvance, fetchForHistory, checkAccept, tryAdvance, and storeLedger drive the ledger timeline.

Ledger Types in LedgerMaster

One ledger is four different things depending on how sure the network is about it. The same ledger starts current (still accepting transactions), becomes closed when consensus fixes its content, validated once enough validators sign it, and published when the node has streamed it to subscribers. LedgerMaster tracks where each ledger sits on that scale:

The four ledger types on one timeline: published, validated, closed, and current, ordered so that published never passes validated, validated never passes closed, and closed never passes current.

Ledger Type Description Mutability
Current Open ledger accepting transactions Mutable
Closed Just closed, awaiting validation Immutable
Validated Network consensus achieved Immutable
Published Streamed to subscribers Immutable

Gap Detection and Filling

When the node detects missing ledgers, it initiates acquisition:

Gap detection: doAdvance finds the hole between ledgers 600 and 603, then fills it backwards, 602 first and then 601, so every fetched ledger's parent hash can be verified immediately.

InboundLedgers System

Knowing a ledger is missing is one thing; fetching it is another. That work belongs to the InboundLedgers subsystem, which runs one acquisition state machine per missing ledger and knows exactly which tree nodes each one still lacks.

In brief: fetches missing ledgers from peers.

The InboundLedgers class manages ledger acquisition from peers:

Acquisition Architecture:

The InboundLedgers system: InboundLedgersImp tracks all acquisitions in flight plus recent failures, and each InboundLedger knows its target hash, sequence, peers, and the state and transaction nodes it still needs.

Key idea. A node that falls behind does not give up: LedgerMaster detects the gap and InboundLedgers fetches the missing history from peers until it catches up.

Acquisition Process

An acquisition always follows the same four steps, whether it was triggered by gap filling, by consensus needing a ledger, or by an operator request:

In brief: how a missing ledger is requested, received, and verified.

Step-by-Step Flow:

The ledger acquisition flow in four steps: doAdvance triggers fetchForHistory, acquire initializes an InboundLedger, gotData and processBatch gather and validate nodes, and done stores the ledger and schedules checkAccept and tryAdvance.

Validation Process

Validation Quorum:

Illustrative structure (conceptual, not a real rippled type) showing what quorum tracking involves:

// Validation requirements (illustrative)
struct ValidationQuorum {
    std::size_t minVal;           // Minimum validations needed
    std::set<NodeID> trustedValidators;  // UNL validators
    std::set<NodeID> negativeUNL;        // Excluded validators
};

checkAccept Flow:

checkAccept promotes a ledger to validated: it checks the sequence, counts trusted validations against the UNL, and once the minimum is reached marks the ledger validated, handles fee voting and amendment warnings, and calls tryAdvance.

Validation Checks:

Check Purpose
Sequence check Ensure forward progress
Trusted count Verify UNL agreement
Minimum threshold Require sufficient validations
Negative UNL Exclude untrusted validators

tryAdvance State Machine

In brief: how the node advances to the newest validated ledger.

tryAdvance drives the state machine from gap detected through acquiring and validating to publishing, and failures restart the cycle.

Ledger Storage

When a ledger is complete and validated:

Publication Stream

Validation makes a ledger true; publication makes it visible. The publication stream walks every validated ledger, in order and without gaps, out to WebSocket subscribers and internal consumers:

Validated ledgers are published to clients:

Ledger publication: findNewLedgersToPublish walks the queue between last published and last validated, checks the sequence is consecutive, and publishes each ledger to WebSocket clients, streaming APIs, and internal consumers.

Error Handling and Recovery

Acquisition Failures:

Error handling in acquisition: each failure type maps to a recovery action, and logFailure records failures so retries follow a backoff strategy.

Validation Mismatches:

// When built ledger doesn't match validated
if (builtHash != validatedHash) {
    JLOG(journal_.warn())
        << "Built ledger " << builtHash
        << " doesn't match validated " << validatedHash;

    // Trigger reacquisition
    acquireLedger(validatedHash, validatedSeq);
}

Ledger Cleaning

Disks corrupt, downloads abort, bugs happen. The LedgerCleaner is the low-priority background repairman that re-verifies stored history and re-acquires whatever fails the check:

The LedgerCleaner component maintains ledger integrity:

The LedgerCleaner re-verifies state and transaction nodes for a configured ledger range, fixes or reacquires broken data, and runs at low priority to avoid load spikes.

RPC and Peer Transaction Lifecycle


Introduction

Transactions enter the XRP Ledger network through two primary channels: direct RPC submission from clients and relay from peer nodes. Understanding how transactions flow through these paths is essential for debugging submission issues, optimizing transaction throughput, and implementing client applications.

This chapter traces the complete journey of a transaction from submission to inclusion in a validated ledger.

Transaction Entry Points

The two transaction entry points: RPC clients arrive through doSubmit and peer nodes through PeerImp::onMessage, and both converge on NetworkOPs::processTransaction.

Path 1: RPC Submission

Client submits via submit RPC:

The RPC submission path: a submit request's tx_blob is deserialized and validated by doSubmit, forwarded to NetworkOPs::processTransaction, and processed in a batch.

Path 2: Peer Relay

Transaction received from peer:

The peer relay path: PeerImp::onMessage deduplicates and checks structure, checkTransaction validates the signature and flags, then the transaction joins the common processing path.

Common Processing Path

After entry (RPC or Peer):

The common processing path: processTransaction leads through doTransactionSync and doTransactionSyncBatch to NetworkOPs::apply, where the TxQ decides between queueing and direct application.

Transaction Application

The apply process (preflight → preclaim → doApply):

Transaction application in three gates: preflight does stateless validation, preclaim checks against ledger state without modifying it, and doApply finally executes and writes.

Transaction Queue (TxQ)

Queue management:

The TxQ decision flow: an incoming transaction is rejected if the fee is too low, held if its sequence is in the future, and applied to the open ledger if both checks pass.

Network Relay

After successful application:

Network relay: the receiving node forwards the transaction to its peers, who relay it onward; tracking seen transactions and never echoing to the source keeps the flood bounded.

Complete Transaction Journey

The complete transaction journey in eleven steps, from submission and entry through validation, queueing, application, relay, consensus, and inclusion, to finality.

Result Codes

Transaction result categories:

Prefix Category Description
tes Success Transaction succeeded
tec Claim Fee claimed but transaction failed
tef Failure Transaction failed, fee not claimed
tel Local Local error, not submitted
tem Malformed Transaction malformed
ter Retry Temporary failure, retry possible

Common Results:

The six result code families: tes success, tec claimed fee, tef failure without fee, tel local rejection, tem malformed, and ter retry, each with representative codes.

processClosedLedger

When a ledger closes:

processClosedLedger updates the queue after every close: applied transactions are removed, fee metrics recalculated, expired transactions dropped, held ones retried, and deferred ones queued for the next round.

Open Ledger Accept

Preparing for next round:

Open ledger accept: the new open ledger is seeded with local transactions and retries, its state is updated for new submissions, and temporary state is reset for the next round.


Summary

This module tied two threads together. You saw how LedgerMaster tracks ledgers and detects gaps and how InboundLedgers fetches the missing ones from peers so a node can catch up, and you traced a transaction end to end, from RPC or peer relay, through consensus, to a validated ledger. A node that falls behind does not give up; it acquires the history it needs and advances.

To remember:

  • LedgerMaster tracks the validated chain and detects gaps (tryAdvance)
  • InboundLedgers fetches missing ledgers by hash from peers
  • Transactions enter via RPC submit or peer relay, then the open ledger, then consensus
  • The TxQ holds the overflow, ordered by fee level (fee escalation)
  • Validated ledgers are announced on the publication stream (what subscribe ledger taps)
  • server_info complete_ledgers tells you which ledgers you actually hold
  • Code: src/xrpld/app/ledger (LedgerMaster; InboundLedgers under detail/)
  • Watch out: complete_ledgers: empty right after startup is normal acquisition, not a fault; do not panic-restart

Next up. A ledger everyone built still is not final. Next: consensus validations, the signed votes that turn agreement into finality.

Assignments

0 of 3 complete

Unlocks

Finishing this module opens up:

XRPL Academy © 2026