Generic implementation of consensus algorithm.

    class Derived,
    class Traits>
class Consensus




Clock type for measuring time within the consensus code.

Member Functions






Get the last closed ledger ID.


Get the Json state of the consensus process.


Get the number of proposing peers that participated in the previous round.


Get duration of the previous round.


Process a transaction set, typically acquired from the network.


Whether we have the correct last closed ledger.



A peer has proposed a new position, adjust our tracking.


Whether we are sending proposals during consensus.


Simulate the consensus process without any network traffic.


Kick-off the next round of consensus.


Call periodically to drive consensus forward.


Whether we are validating consensus ledgers.

Protected Member Functions




Accept a new last closed ledger.


Achieves consensus on the next ledger.

Two things need consensus:

  1. The set of transactions included in the ledger.
  2. The close time for the ledger.

The general consensus stages:

  1. Consensus finishes, we build a new last closed ledger and a new open ledger based on it.
  2. The open ledger interval starts. This gives servers time to finish building the new last closed ledger and fill the new ledger with transactions.
  3. The ledger closes. Servers send their initial proposal.
  4. We do not change our position or declare a consensus for at least LEDGER_MIN_CONSENSUS to ensure servers have a chance to make an initial proposal.
  5. On a frequent timer event, we change our position if needed based on received peer positions.
  6. When we have a consensus, go to step 1.

This class uses CRTP to allow adapting Consensus for specific applications.

The Derived template argument is used to embed consensus within the larger application framework. The Traits template identifies types that play important roles in Consensus (transactions, ledgers, etc.) and which must conform to the generic interface outlined below. The Traits typesmust be copy constructible and assignable.


The interface below is in flux as this code is refactored.

// A single transaction
struct Tx
  // Unique identifier of transaction
  using ID = ...;

  ID id() const;


// A set of transactions
struct TxSet
  // Unique ID of TxSet (not of Tx)
  using ID = ...;
  // Type of individual transaction comprising the TxSet
  using Tx = Tx;

  bool exists(Tx::ID const &) const;
  // Return value should have semantics like Tx const *
  Tx const * find(Tx::ID const &) const ;
  ID const & id() const;

  // Return set of transactions that are not common to this set or other
  // boolean indicates which set it was in
  std::map<Tx::ID, bool> compare(TxSet const & other) const;

  // A mutable view of transactions
  struct MutableTxSet
  bool insert(Tx const &);
  bool erase(Tx::ID const &);
  // get a mutable view of the transactions
  MutablTxSet mutableSet() const;
  // Construct from a mutable view.
  TxSet(MutableTxSet const &);

  // Alternatively, if the TxSet is itself mutable
  // just alias MutableTxSet = TxSet


// Agreed upon state that consensus transactions will modify
struct Ledger
  using ID = ...;

  // Unique identifier of ledgerr
  ID const & id() const;
  auto seq() const;
  auto closeTimeResolution() const;
  auto closeAgree() const;
  auto closeTime() const;
  auto parentCloseTime() const;
  auto const & parentID() const;
  Json::Value getJson() const;

struct Traits
  using Ledger_t = Ledger;
  using NodeID_t = std::uint32_t;
  using TxSet_t = TxSet;
  // To be removed; currently needed to handle missing SHAMap node exception
  using MissingTxException_t = MissingTx;

class ConsensusImp : public Consensus<ConsensusImp, Traits>
    // Whether consensus should (proposing,validating).
    std::pair<bool, bool> getMode();

    // Attempt to acquire a specific ledger.
    Ledger const * acquireLedger(Ledger::ID const & ledgerID);

    // Get peers' proposed positions. Returns an iterable
    // with value_type convertable to ConsensusPosition<...>
    auto const & proposals(Ledger::ID const & ledgerID);

    // Acquire the transaction set associated with a proposed position.
    TxSet const * acquireTxSet(TxSet::ID const & setID);

    // Whether the open ledger has any transactions
    bool hasOpenTransactions() const;

    // Number of proposers that have vallidated the given ledger
    std::size_t proposersValidated(Ledger::ID const & prevLedger) const;

    // Number of proposers that have validated a ledger descended from requested ledger.
    std::size_t proposersFinished(LedgerHash const & h) const;re

    // Called when a new round of consensus has started
    void onStartRound(Ledger const &);

    // Called when ledger is closes
    void onClose(Ledger const &, bool haveCorrectLCL);

    // Setup later call to Consensus::accept which will call Derived::accept
    // Can call Consensus::accept immediately if no interest in offloading
    void dispatchAccept(TxSet const & );

    // Share given transaction set with peers
    void share(TxSet const &s);

    // Return the ID of the last closed (and validated) ledger
    Ledger::ID getLCL(Ledger::ID const & currLedger,
                    Ledger::ID const & priorLedger,
                    bool haveCorrectLCL);

    // Propose the position to peers.
    void propose(ConsensusProposal<...> const & pos);

    // Relay a received peer proposal on to other peer's.
    // The argument type should be convertible to ConsensusProposal<...>
    // but may be a different type.
    void relay(implementation_defined const & pos);

    // Relay disputed transaction to peers
    void relay(DisputedTx<Txn, NodeID> const & dispute);

    // Create initial position for current consensus round
    std::pair <TxSet, Proposal>
          Ledger const & prevLedger,
          bool isProposing,
          bool isCorrectLCL,
          NetClock::time_point closeTime,
          NetClock::time_point now)

    // Process the accepted transaction set, generating the newly closed ledger
    // and clearing out the openTxs that were included.
    bool accept(TxSet const& set, ... )

    // Called when time to end current round of consensus.  Client code
    // determines when to call startRound again.
    void endConsensus(bool correct);
Template Parameters




The deriving class which adapts the Consensus algorithm.


Provides definitions of types used in Consensus.


#include <ripple/consensus/Consensus.h>