3#include <test/csf/BasicNetwork.h>
4#include <test/csf/CollectorRef.h>
5#include <test/csf/Scheduler.h>
6#include <test/csf/TrustGraph.h>
7#include <test/csf/Tx.h>
8#include <test/csf/Validation.h>
9#include <test/csf/events.h>
10#include <test/csf/ledgers.h>
12#include <xrpld/consensus/Consensus.h>
13#include <xrpld/consensus/Validations.h>
15#include <xrpl/beast/utility/WrappedSink.h>
16#include <xrpl/protocol/PublicKey.h>
18#include <boost/container/flat_map.hpp>
19#include <boost/container/flat_set.hpp>
25namespace bc = boost::container;
144 if (
Ledger const* ledger =
p_.acquireLedger(lId))
294 using namespace std::chrono_literals;
345 for (
auto const p :
trustGraph.trustedPeers(
this))
365 return net.connect(
this, &o, dur);
378 return net.disconnect(
this, &o);
390 return &(it->second);
394 if (
net.links(
this).empty())
405 using namespace std::chrono_literals;
407 for (
auto const link :
net.links(
this))
409 minDuration =
std::min(minDuration, link.data.delay);
412 net.send(
this, link.target, [to = link.target, from =
this, ledgerID]() {
413 if (auto it = to->ledgers.find(ledgerID); it != to->ledgers.end())
418 to->net.send(to, from, [from, ledger = it->second]() {
419 from->acquiringLedgers.erase(ledger.id());
420 from->ledgers.emplace(ledger.id(), ledger);
435 return &(it->second);
439 if (
net.links(
this).empty())
450 using namespace std::chrono_literals;
452 for (
auto const link :
net.links(
this))
454 minDuration =
std::min(minDuration, link.data.delay);
456 net.send(
this, link.target, [to = link.target, from =
this, setId]() {
457 if (auto it = to->txSets.find(setId); it != to->txSets.end())
462 to->net.send(to, from, [from, txSet = it->second]() {
463 from->acquiringTxSets.erase(txSet.id());
469 acquiringTxSets[setId] = scheduler.
now() + 2 * minDuration;
482 return validations.numTrustedForLedger(prevLedger);
512 result, prevLedger, closeResolution, rawCloseTimes, mode, consensusJson,
validating());
525 schedule(
delays.ledgerAccept, [mode, result, prevLedger, closeResolution,
this]() {
526 bool const proposing = mode == ConsensusMode::Proposing;
527 bool const consensusFail = result.state == ConsensusState::MovedOn;
529 TxSet const acceptedTxs = injectTxs(prevLedger, result.txns);
530 Ledger const newLedger = oracle.accept(
531 prevLedger, acceptedTxs.txs(), closeResolution, result.position.closeTime());
532 ledgers[newLedger.id()] = newLedger;
534 issue(AcceptLedger{.ledger = newLedger, .prior = lastClosedLedger});
540 openTxs, [&](
Tx const& tx) {
return acceptedTxs.exists(tx.
id()); });
541 openTxs.erase(removed.begin(), removed.end());
551 bool const isFull = proposing;
592 if (netLgr != ledgerID)
712 for (
auto const link :
net.links(
this))
714 if (link.target->id != from && link.target->id != bm.
origin)
718 if (link.target->router.lastObservedSeq[bm.
origin] < bm.
seq)
721 net.send(
this, link.target, [to = link.target, bm,
id = this->id] {
781 if (lastClosedTxs.contains(tx))
785 return openTxs.insert(tx).second;
815 for (
auto const p :
trustGraph.trustedPeers(
this))
904 using namespace std::chrono_literals;
942 res.insert(it->second);
A generic endpoint for log messages.
Wraps a Journal::Sink to prefix its output with a string.
Decorator for streaming out compact json.
static std::uint32_t const kSeqJoin
LedgerId const & prevLedger() const
Get the prior accepted ledger this position is based on.
NodeId const & nodeID() const
Identifying which peer took this position.
std::chrono::milliseconds read() const
Generic implementation of consensus algorithm.
std::chrono::time_point< NetClock > time_point
std::chrono::duration< rep, period > duration
Maintains current and recent ledger validations.
Peer to peer network simulator.
A container of CollectorRefs.
Oracle maintaining unique ledgers for a simulation.
A ledger is a set of observed transactions and a sequence number identifying the ledger.
TaggedInteger< std::uint32_t, IdTag > ID
TaggedInteger< std::uint32_t, SeqTag > Seq
bool isAncestor(Ledger const &ancestor) const
Determine whether ancestor is really an ancestor of this ledger.
TxSetType const & txs() const
Basic wrapper of a proposed position taken by a peer.
static std::string render()
json::Value getJson() const
Position(Proposal const &p)
Proposal const & proposal() const
csf::Validation Validation
NetClock::time_point now() const
std::optional< Ledger > acquire(Ledger::ID const &lId)
Simulated discrete-event scheduler.
time_point now() const
Return the current network time.
TxSet is a set of transactions to consider including in the ledger.
beast::Uhash<>::result_type ID
static ID calcID(TxSetType const &txs)
TxSetType const & txs() const
Validation of a specific ledger by a specific Peer.
void setSeen(NetClock::time_point seen)
PeerID const & nodeID() const
Ledger::ID ledgerID() const
T duration_cast(T... args)
SimClock::duration SimDuration
std::string to_string(TxSetType const &txs)
boost::container::flat_set< Tx > TxSetType
TaggedInteger< std::uint32_t, PeerIDTag > PeerID
ConsensusProposal< PeerID, Ledger::ID, TxSet::ID > Proposal
Proposal is a position taken in the consensus process and is represented directly from the generic ty...
std::pair< PeerID, std::uint32_t > PeerKey
The current key of a peer.
ConsensusMode
Represents how a node currently participates in Consensus.
std::unordered_set< Value, Hash, Pred, Allocator > hash_set
boost::outcome_v2::result< T, std::error_code > Result
ValStatus
Status of validation we received.
@ Stale
Not current or was older than current from this node.
std::unordered_map< Key, Value, Hash, Pred, Allocator > hash_map
Stores the set of initial close times.
Consensus algorithm parameters.
Encapsulates the result of consensus.
Timing parameters to control validation staleness and expiration.
Peer closed the open ledger.
Peer fully validated a new ledger.
Simulated delays in internal peer processing.
std::chrono::milliseconds recvValidation
Delay in processing validations from remote peers.
SimDuration onReceive(Validation const &) const
std::chrono::milliseconds ledgerAccept
SimDuration onReceive(M const &) const
bc::flat_map< PeerID, std::size_t > lastObservedSeq
ConsensusResult< Peer > Result
Result onClose(Ledger const &prevLedger, NetClock::time_point closeTime, ConsensusMode mode)
std::chrono::seconds clockSkew
Skew of time relative to the common scheduler clock.
void propose(Proposal const &pos)
Ledger::ID prevLedgerID() const
TxSetType openTxs
openTxs that haven't been closed in a ledger yet
void updateOperatingMode(std::size_t const positions) const
void receive(BroadcastMesg< M > const &bm, PeerID from)
ConsensusParms const & parms() const
Ledger::Seq getValidLedgerIndex() const
bc::flat_map< TxSet::ID, TxSet > txSets
TxSet associated with a TxSet::ID.
BasicNetwork< Peer * > & net
Handle to network for sending messages.
std::size_t prevProposers
int completedLedgers
The number of ledgers this peer has completed.
hash_set< NodeKey_t > trustedKeys
hash_map< Ledger::ID, Ledger > ledgers
Ledgers this node has closed or loaded from the network.
bool haveValidated() const
Peer(PeerID i, Scheduler &s, LedgerOracle &o, BasicNetwork< Peer * > &n, TrustGraph< Peer * > &tg, CollectorRefs &c, beast::Journal jIn)
Constructor.
bool runAsValidator
Whether to simulate running as validator or a tracking node.
hash_map< Ledger::Seq, Tx > txInjections
TxSet const * acquireTxSet(TxSet::ID const &setId)
ConsensusParms consensusParms
CollectorRefs & collectors
The collectors to report events to.
bool trusts(PeerID const &oId)
TxSet injectTxs(Ledger prevLedger, TxSet const &src)
Inject non-consensus Tx.
Ledger lastClosedLedger
The last ledger closed by this node.
LedgerOracle & oracle
The oracle that manages unique ledgers.
std::pair< std::size_t, hash_set< NodeKey_t > > getQuorumKeys()
Ledger const * acquireLedger(Ledger::ID const &ledgerID)
Ledger Ledger_t
Type definitions for generic consensus.
bc::flat_map< TxSet::ID, SimTime > acquiringTxSets
Ledger::ID getPrevLedger(Ledger::ID const &ledgerID, Ledger const &ledger, ConsensusMode mode)
Consensus< Peer > consensus
Generic consensus.
bool connect(Peer &o, SimDuration dur)
Create network connection.
void onForceAccept(Result const &result, Ledger const &prevLedger, NetClock::duration const &closeResolution, ConsensusCloseTimes const &rawCloseTimes, ConsensusMode const &mode, json::Value const &consensusJson)
bool handle(Validation const &v)
void send(BroadcastMesg< M > const &bm, PeerID from)
void issue(E const &event)
bool handle(TxSet const &txs)
void checkFullyValidated(Ledger const &ledger)
Check if a new ledger can be deemed fully validated.
bc::flat_map< Ledger::ID, SimTime > acquiringLedgers
void onModeChange(ConsensusMode, ConsensusMode)
NetClock::time_point now() const
TrustGraph< Peer * > & trustGraph
Handle to Trust graph of network.
std::size_t laggards(Ledger::Seq const seq, hash_set< NodeKey_t > &trusted)
bool handle(Proposal const &p)
void timerEntry()
Heartbeat timer call.
void onAccept(Result const &result, Ledger const &prevLedger, NetClock::duration const &closeResolution, ConsensusCloseTimes const &rawCloseTimes, ConsensusMode const &mode, json::Value const &consensusJson, bool const validating)
bc::flat_map< Ledger::ID, std::vector< Proposal > > peerPositions
Validations< ValAdaptor > validations
Validations from trusted nodes.
bool addTrustedValidation(Validation v)
Add a trusted validation and return true if it is worth forwarding.
bool handle(Tx const &tx)
PeerKey key
Current signing key.
void schedule(std::chrono::nanoseconds when, T &&what)
Schedule the provided callback in when duration, but if when is 0, call immediately.
Scheduler & scheduler
Scheduler of events.
ProcessingDelays delays
Simulated delays to use for internal processing.
void share(Position const &p)
Ledger fullyValidatedLedger
bool hasOpenTransactions() const
beast::WrappedSink sink
Logging support that prefixes messages with the peer ID.
int targetLedgers
The number of ledgers this peer should complete before stopping to run.
Validation::NodeKey NodeKey
std::size_t proposersFinished(Ledger const &prevLedger, Ledger::ID const &prevLedgerID)
std::size_t proposersValidated(Ledger::ID const &prevLedger)
bool disconnect(Peer &o)
Remove a network connection.
Ledger::Seq earliestAllowedSeq() const
std::chrono::milliseconds prevRoundTime
void submit(Tx const &tx)
A value received from another peer as part of flooding.
A value relayed to another peer as part of flooding.
A value to be flooded to all other peers starting from this peer.
Peer starts a new consensus round.
A transaction submitted to a peer.
Peer detected a wrong prior ledger during consensus.