rippled
Loading...
Searching...
No Matches
test/csf/Peer.h
1#ifndef XRPL_TEST_CSF_PEER_H_INCLUDED
2#define XRPL_TEST_CSF_PEER_H_INCLUDED
3
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>
11
12#include <xrpld/consensus/Consensus.h>
13#include <xrpld/consensus/Validations.h>
14
15#include <xrpl/beast/utility/WrappedSink.h>
16#include <xrpl/protocol/PublicKey.h>
17
18#include <boost/container/flat_map.hpp>
19#include <boost/container/flat_set.hpp>
20
21#include <algorithm>
22
23namespace ripple {
24namespace test {
25namespace csf {
26
27namespace bc = boost::container;
28
40struct Peer
41{
48 {
49 public:
51 {
52 }
53
54 Proposal const&
55 proposal() const
56 {
57 return proposal_;
58 }
59
61 getJson() const
62 {
63 return proposal_.getJson();
64 }
65
67 render() const
68 {
69 return "";
70 }
71
72 private:
74 };
75
79 {
84
87
88 // Return the receive delay for message type M, default is no delay
89 // Received delay is the time from receiving the message to actually
90 // handling it.
91 template <class M>
93 onReceive(M const&) const
94 {
95 return SimDuration{};
96 }
97
99 onReceive(Validation const&) const
100 {
101 return recvValidation;
102 }
103 };
104
106 {
107 };
108
113 {
115
116 public:
117 struct Mutex
118 {
119 void
121 {
122 }
123
124 void
126 {
127 }
128 };
129
132
134 {
135 }
136
138 now() const
139 {
140 return p_.now();
141 }
142
144 acquire(Ledger::ID const& lId)
145 {
146 if (Ledger const* ledger = p_.acquireLedger(lId))
147 return *ledger;
148 return std::nullopt;
149 }
150 };
151
156 using TxSet_t = TxSet;
160
164
167
170
173
176
179
182
185
188
191
194
197
201
202 //-------------------------------------------------------------------------
203 // Store most network messages; these could be purged if memory use ever
204 // becomes problematic
205
208 bc::flat_map<Ledger::ID, std::vector<Proposal>> peerPositions;
210 bc::flat_map<TxSet::ID, TxSet> txSets;
211
212 // Ledgers/TxSets we are acquiring and when that request times out
213 bc::flat_map<Ledger::ID, SimTime> acquiringLedgers;
214 bc::flat_map<TxSet::ID, SimTime> acquiringTxSets;
215
218
221
224
227
229 bool runAsValidator = true;
230
231 // TODO: Consider removing these two, they are only a convenience for tests
232 // Number of proposers in the prior round
234 // Duration of prior round
236
237 // Quorum of validations needed for a ledger to be fully validated
238 // TODO: Use the logic in ValidatorList to set this dynamically
240
242
243 // Simulation parameters
245
248
261 PeerID i,
262 Scheduler& s,
263 LedgerOracle& o,
266 CollectorRefs& c,
267 beast::Journal jIn)
268 : sink(jIn, "Peer " + to_string(i) + ": ")
269 , j(sink)
270 , consensus(s.clock(), *this, j)
271 , id{i}
272 , key{id, 0}
273 , oracle{o}
274 , scheduler{s}
275 , net{n}
276 , trustGraph(tg)
277 , lastClosedLedger{Ledger::MakeGenesis{}}
278 , validations{ValidationParms{}, s.clock(), *this}
279 , fullyValidatedLedger{Ledger::MakeGenesis{}}
280 , collectors{c}
281 {
282 // All peers start from the default constructed genesis ledger
284
285 // nodes always trust themselves . . SHOULD THEY?
286 trustGraph.trust(this, this);
287 }
288
292 template <class T>
293 void
295 {
296 using namespace std::chrono_literals;
297
298 if (when == 0ns)
299 what();
300 else
301 scheduler.in(when, std::forward<T>(what));
302 }
303
304 // Issue a new event to the collectors
305 template <class E>
306 void
307 issue(E const& event)
308 {
309 // Use the scheduler time and not the peer's (skewed) local time
310 collectors.on(id, scheduler.now(), event);
311 }
312
313 //--------------------------------------------------------------------------
314 // Trust and Network members
315 // Methods for modifying and querying the network and trust graphs from
316 // the perspective of this Peer
317
318 //< Extend trust to a peer
319 void
321 {
322 trustGraph.trust(this, &o);
323 }
324
325 //< Revoke trust from a peer
326 void
328 {
329 trustGraph.untrust(this, &o);
330 }
331
332 //< Check whether we trust a peer
333 bool
335 {
336 return trustGraph.trusts(this, &o);
337 }
338
339 //< Check whether we trust a peer based on its ID
340 bool
341 trusts(PeerID const& oId)
342 {
343 for (auto const p : trustGraph.trustedPeers(this))
344 if (p->id == oId)
345 return true;
346 return false;
347 }
348
358 bool
360 {
361 return net.connect(this, &o, dur);
362 }
363
371 bool
373 {
374 return net.disconnect(this, &o);
375 }
376
377 //--------------------------------------------------------------------------
378 // Generic Consensus members
379
380 // Attempt to acquire the Ledger associated with the given ID
381 Ledger const*
382 acquireLedger(Ledger::ID const& ledgerID)
383 {
384 if (auto it = ledgers.find(ledgerID); it != ledgers.end())
385 {
386 return &(it->second);
387 }
388
389 // No peers
390 if (net.links(this).empty())
391 return nullptr;
392
393 // Don't retry if we already are acquiring it and haven't timed out
394 auto aIt = acquiringLedgers.find(ledgerID);
395 if (aIt != acquiringLedgers.end())
396 {
397 if (scheduler.now() < aIt->second)
398 return nullptr;
399 }
400
401 using namespace std::chrono_literals;
402 SimDuration minDuration{10s};
403 for (auto const link : net.links(this))
404 {
405 minDuration = std::min(minDuration, link.data.delay);
406
407 // Send a messsage to neighbors to find the ledger
408 net.send(
409 this, link.target, [to = link.target, from = this, ledgerID]() {
410 if (auto it = to->ledgers.find(ledgerID);
411 it != to->ledgers.end())
412 {
413 // if the ledger is found, send it back to the original
414 // requesting peer where it is added to the available
415 // ledgers
416 to->net.send(to, from, [from, ledger = it->second]() {
417 from->acquiringLedgers.erase(ledger.id());
418 from->ledgers.emplace(ledger.id(), ledger);
419 });
420 }
421 });
422 }
423 acquiringLedgers[ledgerID] = scheduler.now() + 2 * minDuration;
424 return nullptr;
425 }
426
427 // Attempt to acquire the TxSet associated with the given ID
428 TxSet const*
430 {
431 if (auto it = txSets.find(setId); it != txSets.end())
432 {
433 return &(it->second);
434 }
435
436 // No peers
437 if (net.links(this).empty())
438 return nullptr;
439
440 // Don't retry if we already are acquiring it and haven't timed out
441 auto aIt = acquiringTxSets.find(setId);
442 if (aIt != acquiringTxSets.end())
443 {
444 if (scheduler.now() < aIt->second)
445 return nullptr;
446 }
447
448 using namespace std::chrono_literals;
449 SimDuration minDuration{10s};
450 for (auto const link : net.links(this))
451 {
452 minDuration = std::min(minDuration, link.data.delay);
453 // Send a message to neighbors to find the tx set
454 net.send(
455 this, link.target, [to = link.target, from = this, setId]() {
456 if (auto it = to->txSets.find(setId);
457 it != to->txSets.end())
458 {
459 // If the txSet is found, send it back to the original
460 // requesting peer, where it is handled like a TxSet
461 // that was broadcast over the network
462 to->net.send(to, from, [from, txSet = it->second]() {
463 from->acquiringTxSets.erase(txSet.id());
464 from->handle(txSet);
465 });
466 }
467 });
468 }
469 acquiringTxSets[setId] = scheduler.now() + 2 * minDuration;
470 return nullptr;
471 }
472
473 bool
475 {
476 return !openTxs.empty();
477 }
478
481 {
482 return validations.numTrustedForLedger(prevLedger);
483 }
484
486 proposersFinished(Ledger const& prevLedger, Ledger::ID const& prevLedgerID)
487 {
488 return validations.getNodesAfter(prevLedger, prevLedgerID);
489 }
490
491 Result
493 Ledger const& prevLedger,
494 NetClock::time_point closeTime,
495 ConsensusMode mode)
496 {
497 issue(CloseLedger{prevLedger, openTxs});
498
499 return Result(
500 TxSet{openTxs},
501 Proposal(
502 prevLedger.id(),
503 Proposal::seqJoin,
504 TxSet::calcID(openTxs),
505 closeTime,
506 now(),
507 id));
508 }
509
510 void
512 Result const& result,
513 Ledger const& prevLedger,
514 NetClock::duration const& closeResolution,
515 ConsensusCloseTimes const& rawCloseTimes,
516 ConsensusMode const& mode,
517 Json::Value&& consensusJson)
518 {
519 onAccept(
520 result,
521 prevLedger,
522 closeResolution,
523 rawCloseTimes,
524 mode,
525 std::move(consensusJson),
526 validating());
527 }
528
529 void
531 Result const& result,
532 Ledger const& prevLedger,
533 NetClock::duration const& closeResolution,
534 ConsensusCloseTimes const& rawCloseTimes,
535 ConsensusMode const& mode,
536 Json::Value&& consensusJson,
537 bool const validating)
538 {
539 schedule(delays.ledgerAccept, [=, this]() {
540 bool const proposing = mode == ConsensusMode::proposing;
541 bool const consensusFail = result.state == ConsensusState::MovedOn;
542
543 TxSet const acceptedTxs = injectTxs(prevLedger, result.txns);
544 Ledger const newLedger = oracle.accept(
545 prevLedger,
546 acceptedTxs.txs(),
547 closeResolution,
548 result.position.closeTime());
549 ledgers[newLedger.id()] = newLedger;
550
551 issue(AcceptLedger{newLedger, lastClosedLedger});
552 prevProposers = result.proposers;
553 prevRoundTime = result.roundTime.read();
554 lastClosedLedger = newLedger;
555
556 auto const it = std::remove_if(
557 openTxs.begin(), openTxs.end(), [&](Tx const& tx) {
558 return acceptedTxs.exists(tx.id());
559 });
560 openTxs.erase(it, openTxs.end());
561
562 // Only send validation if the new ledger is compatible with our
563 // fully validated ledger
564 bool const isCompatible =
565 newLedger.isAncestor(fullyValidatedLedger);
566
567 // Can only send one validated ledger per seq
568 if (runAsValidator && isCompatible && !consensusFail &&
569 validations.canValidateSeq(newLedger.seq()))
570 {
571 bool isFull = proposing;
572
573 Validation v{
574 newLedger.id(),
575 newLedger.seq(),
576 now(),
577 now(),
578 key,
579 id,
580 isFull};
581 // share the new validation; it is trusted by the receiver
582 share(v);
583 // we trust ourselves
584 addTrustedValidation(v);
585 }
586
587 checkFullyValidated(newLedger);
588
589 // kick off the next round...
590 // in the actual implementation, this passes back through
591 // network ops
592 ++completedLedgers;
593 // startRound sets the LCL state, so we need to call it once after
594 // the last requested round completes
595 if (completedLedgers <= targetLedgers)
596 {
597 startRound();
598 }
599 });
600 }
601
602 // Earliest allowed sequence number when checking for ledgers with more
603 // validations than our current ledger
604 Ledger::Seq
606 {
607 return fullyValidatedLedger.seq();
608 }
609
612 Ledger::ID const& ledgerID,
613 Ledger const& ledger,
614 ConsensusMode mode)
615 {
616 // only do if we are past the genesis ledger
617 if (ledger.seq() == Ledger::Seq{0})
618 return ledgerID;
619
620 Ledger::ID const netLgr =
621 validations.getPreferred(ledger, earliestAllowedSeq());
622
623 if (netLgr != ledgerID)
624 {
625 JLOG(j.trace()) << Json::Compact(validations.getJsonTrie());
626 issue(WrongPrevLedger{ledgerID, netLgr});
627 }
628
629 return netLgr;
630 }
631
632 void
633 propose(Proposal const& pos)
634 {
635 share(pos);
636 }
637
638 ConsensusParms const&
639 parms() const
640 {
641 return consensusParms;
642 }
643
644 // Not interested in tracking consensus mode changes for now
645 void
649
650 // Share a message by broadcasting to all connected peers
651 template <class M>
652 void
653 share(M const& m)
654 {
655 issue(Share<M>{m});
656 send(BroadcastMesg<M>{m, router.nextSeq++, this->id}, this->id);
657 }
658
659 // Unwrap the Position and share the raw proposal
660 void
661 share(Position const& p)
662 {
663 share(p.proposal());
664 }
665
666 //--------------------------------------------------------------------------
667 // Validation members
668
670 bool
672 {
673 v.setTrusted();
674 v.setSeen(now());
675 ValStatus const res = validations.add(v.nodeID(), v);
676
677 if (res == ValStatus::stale)
678 return false;
679
680 // Acquire will try to get from network if not already local
681 if (Ledger const* lgr = acquireLedger(v.ledgerID()))
682 checkFullyValidated(*lgr);
683 return true;
684 }
685
687 void
689 {
690 // Only consider ledgers newer than our last fully validated ledger
691 if (ledger.seq() <= fullyValidatedLedger.seq())
692 return;
693
694 std::size_t const count = validations.numTrustedForLedger(ledger.id());
695 std::size_t const numTrustedPeers = trustGraph.graph().outDegree(this);
696 quorum = static_cast<std::size_t>(std::ceil(numTrustedPeers * 0.8));
697 if (count >= quorum && ledger.isAncestor(fullyValidatedLedger))
698 {
699 issue(FullyValidateLedger{ledger, fullyValidatedLedger});
700 fullyValidatedLedger = ledger;
701 }
702 }
703
704 //-------------------------------------------------------------------------
705 // Peer messaging members
706
707 // Basic Sequence number router
708 // A message that will be flooded across the network is tagged with a
709 // sequence number by the origin node in a BroadcastMesg. Receivers will
710 // ignore a message as stale if they've already processed a newer sequence
711 // number, or will process and potentially relay the message along.
712 //
713 // The various bool handle(MessageType) members do the actual processing
714 // and should return true if the message should continue to be sent to
715 // peers.
716 //
717 // WARN: This assumes messages are received and processed in the order they
718 // are sent, so that a peer receives a message with seq 1 from node 0
719 // before seq 2 from node 0, etc.
720 // TODO: Break this out into a class and identify type interface to allow
721 // alternate routing strategies
722 template <class M>
729
730 struct Router
731 {
732 std::size_t nextSeq = 1;
733 bc::flat_map<PeerID, std::size_t> lastObservedSeq;
734 };
735
737
738 // Send a broadcast message to all peers
739 template <class M>
740 void
741 send(BroadcastMesg<M> const& bm, PeerID from)
742 {
743 for (auto const link : net.links(this))
744 {
745 if (link.target->id != from && link.target->id != bm.origin)
746 {
747 // cheat and don't bother sending if we know it has already been
748 // used on the other end
749 if (link.target->router.lastObservedSeq[bm.origin] < bm.seq)
750 {
751 issue(Relay<M>{link.target->id, bm.mesg});
752 net.send(
753 this,
754 link.target,
755 [to = link.target, bm, id = this->id] {
756 to->receive(bm, id);
757 });
758 }
759 }
760 }
761 }
762
763 // Receive a shared message, process it and consider continuing to relay it
764 template <class M>
765 void
767 {
768 issue(Receive<M>{from, bm.mesg});
769 if (router.lastObservedSeq[bm.origin] < bm.seq)
770 {
771 router.lastObservedSeq[bm.origin] = bm.seq;
772 schedule(delays.onReceive(bm.mesg), [this, bm, from] {
773 if (handle(bm.mesg))
774 send(bm, from);
775 });
776 }
777 }
778
779 // Type specific receive handlers, return true if the message should
780 // continue to be broadcast to peers
781 bool
782 handle(Proposal const& p)
783 {
784 // Only relay untrusted proposals on the same ledger
785 if (!trusts(p.nodeID()))
786 return p.prevLedger() == lastClosedLedger.id();
787
788 // TODO: This always suppresses relay of peer positions already seen
789 // Should it allow forwarding if for a recent ledger ?
790 auto& dest = peerPositions[p.prevLedger()];
791 if (std::find(dest.begin(), dest.end(), p) != dest.end())
792 return false;
793
794 dest.push_back(p);
795
796 // Rely on consensus to decide whether to relay
797 return consensus.peerProposal(now(), Position{p});
798 }
799
800 bool
801 handle(TxSet const& txs)
802 {
803 bool const inserted =
804 txSets.insert(std::make_pair(txs.id(), txs)).second;
805 if (inserted)
806 consensus.gotTxSet(now(), txs);
807 // relay only if new
808 return inserted;
809 }
810
811 bool
812 handle(Tx const& tx)
813 {
814 // Ignore and suppress relay of transactions already in last ledger
815 TxSetType const& lastClosedTxs = lastClosedLedger.txs();
816 if (lastClosedTxs.find(tx) != lastClosedTxs.end())
817 return false;
818
819 // only relay if it was new to our open ledger
820 return openTxs.insert(tx).second;
821 }
822
823 bool
825 {
826 // TODO: This is not relaying untrusted validations
827 if (!trusts(v.nodeID()))
828 return false;
829
830 // Will only relay if current
831 return addTrustedValidation(v);
832 }
833
834 bool
836 {
837 return fullyValidatedLedger.seq() > Ledger::Seq{0};
838 }
839
842 {
843 return earliestAllowedSeq();
844 }
845
848 {
850 for (auto const p : trustGraph.trustedPeers(this))
851 keys.insert(p->key);
852 return {quorum, keys};
853 }
854
857 {
858 return validations.laggards(seq, trusted);
859 }
860
861 bool
862 validator() const
863 {
864 return runAsValidator;
865 }
866
867 void
868 updateOperatingMode(std::size_t const positions) const
869 {
870 }
871
872 bool
874 {
875 // does not matter
876 return false;
877 }
878
879 //--------------------------------------------------------------------------
880 // A locally submitted transaction
881 void
882 submit(Tx const& tx)
883 {
884 issue(SubmitTx{tx});
885 if (handle(tx))
886 share(tx);
887 }
888
889 //--------------------------------------------------------------------------
890 // Simulation "driver" members
891
893 void
895 {
896 consensus.timerEntry(now());
897 // only reschedule if not completed
898 if (completedLedgers < targetLedgers)
899 scheduler.in(parms().ledgerGRANULARITY, [this]() { timerEntry(); });
900 }
901
902 // Called to begin the next round
903 void
905 {
906 // Between rounds, we take the majority ledger
907 // In the future, consider taking peer dominant ledger if no validations
908 // yet
909 Ledger::ID bestLCL =
910 validations.getPreferred(lastClosedLedger, earliestAllowedSeq());
911 if (bestLCL == Ledger::ID{0})
912 bestLCL = lastClosedLedger.id();
913
914 issue(StartRound{bestLCL, lastClosedLedger});
915
916 // Not yet modeling dynamic UNL.
917 hash_set<PeerID> nowUntrusted;
918 consensus.startRound(
919 now(), bestLCL, lastClosedLedger, nowUntrusted, runAsValidator, {});
920 }
921
922 // Start the consensus process assuming it is not yet running
923 // This runs forever unless targetLedgers is specified
924 void
926 {
927 // TODO: Expire validations less frequently?
928 validations.expire(j);
929 scheduler.in(parms().ledgerGRANULARITY, [&]() { timerEntry(); });
930 startRound();
931 }
932
934 now() const
935 {
936 // We don't care about the actual epochs, but do want the
937 // generated NetClock time to be well past its epoch to ensure
938 // any subtractions of two NetClock::time_point in the consensus
939 // code are positive. (e.g. proposeFRESHNESS)
940 using namespace std::chrono;
941 using namespace std::chrono_literals;
942 return NetClock::time_point(duration_cast<NetClock::duration>(
943 scheduler.now().time_since_epoch() + 86400s + clockSkew));
944 }
945
948 {
949 return consensus.prevLedgerID();
950 }
951
952 //-------------------------------------------------------------------------
953 // Injects a specific transaction when generating the ledger following
954 // the provided sequence. This allows simulating a byzantine failure in
955 // which a node generates the wrong ledger, even when consensus worked
956 // properly.
957 // TODO: Make this more robust
959
970 TxSet
971 injectTxs(Ledger prevLedger, TxSet const& src)
972 {
973 auto const it = txInjections.find(prevLedger.seq());
974
975 if (it == txInjections.end())
976 return src;
977 TxSetType res{src.txs()};
978 res.insert(it->second);
979
980 return TxSet{res};
981 }
982};
983
984} // namespace csf
985} // namespace test
986} // namespace ripple
987#endif
T ceil(T... args)
Decorator for streaming out compact json.
Represents a JSON value.
Definition json_value.h:130
A generic endpoint for log messages.
Definition Journal.h:41
Wraps a Journal::Sink to prefix its output with a string.
Definition WrappedSink.h:15
LedgerID_t const & prevLedger() const
Get the prior accepted ledger this position is based on.
NodeID_t const & nodeID() const
Identifying which peer took this position.
Json::Value getJson() const
Get JSON representation for debugging.
std::chrono::milliseconds read() const
Generic implementation of consensus algorithm.
Definition Consensus.h:279
std::chrono::time_point< NetClock > time_point
Definition chrono.h:50
Maintains current and recent ledger validations.
std::size_t numTrustedForLedger(ID const &ledgerID)
Count the number of trusted full validations for the given ledger.
std::size_t getNodesAfter(Ledger const &ledger, ID const &ledgerID)
Count the number of current trusted validators working on a ledger after the specified one.
bool canValidateSeq(Seq const s)
Return whether the local node can issue a validation for the given sequence number.
Peer to peer network simulator.
void send(Peer const &from, Peer const &to, Function &&f)
Send a message to a peer.
auto links(Peer const &from)
Return the range of active links.
A container of CollectorRefs.
void on(PeerID node, SimTime when, E const &e)
Oracle maintaining unique ledgers for a simulation.
Definition ledgers.h:231
A ledger is a set of observed transactions and a sequence number identifying the ledger.
Definition ledgers.h:45
bool isAncestor(Ledger const &ancestor) const
Determine whether ancestor is really an ancestor of this ledger.
Definition ledgers.cpp:21
Basic wrapper of a proposed position taken by a peer.
Proposal const & proposal() const
Generic Validations adaptor that simply ignores recently stale validations.
std::optional< Ledger > acquire(Ledger::ID const &lId)
NetClock::time_point now() const
Simulated discrete-event scheduler.
time_point now() const
Return the current network time.
cancel_token in(duration const &delay, Function &&f)
Schedule an event after a specified duration passes.
TxSet is a set of transactions to consider including in the ledger.
Definition Tx.h:64
TxSetType const & txs() const
Definition Tx.h:125
ID id() const
Definition Tx.h:131
beast::uhash<>::result_type ID
Definition Tx.h:66
Tx const * find(Tx::ID const &txId) const
Definition Tx.h:116
A single transaction.
Definition Tx.h:23
Validation of a specific ledger by a specific Peer.
Definition Validation.h:31
Ledger::Seq seq() const
Definition Validation.h:77
Ledger::ID ledgerID() const
Definition Validation.h:71
void setSeen(NetClock::time_point seen)
Definition Validation.h:178
PeerID const & nodeID() const
Definition Validation.h:101
T end(T... args)
T find(T... args)
T insert(T... args)
T is_same_v
T make_pair(T... args)
T max(T... args)
T min(T... args)
std::pair< PeerID, std::uint32_t > PeerKey
The current key of a peer.
Definition Validation.h:26
tagged_integer< std::uint32_t, PeerIDTag > PeerID
Definition Validation.h:18
typename SimClock::duration SimDuration
Definition SimTime.h:17
boost::container::flat_set< Tx > TxSetType
Definition Tx.h:60
std::string to_string(TxSetType const &txs)
Definition Tx.h:196
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
ConsensusMode
Represents how a node currently participates in Consensus.
@ proposing
We are normal participant in consensus and propose our position.
boost::outcome_v2::result< T, std::error_code > Result
Definition b58_utils.h:18
ValStatus
Status of validation we received.
@ stale
Not current or was older than current from this node.
T remove_if(T... args)
Stores the set of initial close times.
Consensus algorithm parameters.
Encapsulates the result of consensus.
Timing parameters to control validation staleness and expiration.
Definition Validations.h:28
Peer closed the open ledger.
Definition events.h:92
Peer fully validated a new ledger.
Definition events.h:121
Simulated delays in internal peer processing.
SimDuration onReceive(M const &) const
std::chrono::milliseconds ledgerAccept
Delay in consensus calling doAccept to accepting and issuing validation TODO: This should be a functi...
std::chrono::milliseconds recvValidation
Delay in processing validations from remote peers.
SimDuration onReceive(Validation const &) const
bc::flat_map< PeerID, std::size_t > lastObservedSeq
A single peer in the simulation.
bool handle(TxSet const &txs)
bc::flat_map< Ledger::ID, std::vector< Proposal > > peerPositions
Map from Ledger::ID to vector of Positions with that ledger as the prior ledger.
void propose(Proposal const &pos)
bool addTrustedValidation(Validation v)
Add a trusted validation and return true if it is worth forwarding.
bool hasOpenTransactions() const
bool handle(Validation const &v)
Ledger const * acquireLedger(Ledger::ID const &ledgerID)
Consensus< Peer > consensus
Generic consensus.
void receive(BroadcastMesg< M > const &bm, PeerID from)
BasicNetwork< Peer * > & net
Handle to network for sending messages.
void onAccept(Result const &result, Ledger const &prevLedger, NetClock::duration const &closeResolution, ConsensusCloseTimes const &rawCloseTimes, ConsensusMode const &mode, Json::Value &&consensusJson, bool const validating)
void checkFullyValidated(Ledger const &ledger)
Check if a new ledger can be deemed fully validated.
hash_set< NodeKey_t > trustedKeys
std::pair< std::size_t, hash_set< NodeKey_t > > getQuorumKeys()
hash_map< Ledger::ID, Ledger > ledgers
Ledgers this node has closed or loaded from the network.
Ledger::Seq earliestAllowedSeq() const
TrustGraph< Peer * > & trustGraph
Handle to Trust graph of network.
void send(BroadcastMesg< M > const &bm, PeerID from)
LedgerOracle & oracle
The oracle that manages unique ledgers.
TxSetType openTxs
openTxs that haven't been closed in a ledger yet
bool connect(Peer &o, SimDuration dur)
Create network connection.
void timerEntry()
Heartbeat timer call.
Ledger lastClosedLedger
The last ledger closed by this node.
std::size_t laggards(Ledger::Seq const seq, hash_set< NodeKey_t > &trusted)
PeerKey key
Current signing key.
hash_map< Ledger::Seq, Tx > txInjections
CollectorRefs & collectors
The collectors to report events to.
Result onClose(Ledger const &prevLedger, NetClock::time_point closeTime, ConsensusMode mode)
ConsensusParms const & parms() const
void issue(E const &event)
void updateOperatingMode(std::size_t const positions) const
bc::flat_map< Ledger::ID, SimTime > acquiringLedgers
void onForceAccept(Result const &result, Ledger const &prevLedger, NetClock::duration const &closeResolution, ConsensusCloseTimes const &rawCloseTimes, ConsensusMode const &mode, Json::Value &&consensusJson)
ProcessingDelays delays
Simulated delays to use for internal processing.
std::size_t proposersFinished(Ledger const &prevLedger, Ledger::ID const &prevLedgerID)
Ledger fullyValidatedLedger
The most recent ledger that has been fully validated by the network from the perspective of this Peer...
bc::flat_map< TxSet::ID, TxSet > txSets
TxSet associated with a TxSet::ID.
Peer(PeerID i, Scheduler &s, LedgerOracle &o, BasicNetwork< Peer * > &n, TrustGraph< Peer * > &tg, CollectorRefs &c, beast::Journal jIn)
Constructor.
TxSet const * acquireTxSet(TxSet::ID const &setId)
PeerID id
Our unique ID.
bc::flat_map< TxSet::ID, SimTime > acquiringTxSets
bool trusts(PeerID const &oId)
Ledger::ID prevLedgerID() const
Scheduler & scheduler
Scheduler of events.
int targetLedgers
The number of ledgers this peer should complete before stopping to run.
ConsensusParms consensusParms
beast::WrappedSink sink
Logging support that prefixes messages with the peer ID.
bool disconnect(Peer &o)
Remove a network connection.
std::chrono::seconds clockSkew
Skew of time relative to the common scheduler clock.
std::size_t proposersValidated(Ledger::ID const &prevLedger)
Ledger::ID getPrevLedger(Ledger::ID const &ledgerID, Ledger const &ledger, ConsensusMode mode)
bool handle(Proposal const &p)
void onModeChange(ConsensusMode, ConsensusMode)
int completedLedgers
The number of ledgers this peer has completed.
Validations< ValAdaptor > validations
Validations from trusted nodes.
TxSet injectTxs(Ledger prevLedger, TxSet const &src)
Inject non-consensus Tx.
bool runAsValidator
Whether to simulate running as validator or a tracking node.
bool handle(Tx const &tx)
void schedule(std::chrono::nanoseconds when, T &&what)
Schedule the provided callback in when duration, but if when is 0, call immediately.
void share(Position const &p)
std::chrono::milliseconds prevRoundTime
Ledger::Seq getValidLedgerIndex() const
void submit(Tx const &tx)
void share(M const &m)
NetClock::time_point now() const
A value received from another peer as part of flooding.
Definition events.h:63
A value relayed to another peer as part of flooding.
Definition events.h:51
A value to be flooded to all other peers starting from this peer.
Definition events.h:42
Peer starts a new consensus round.
Definition events.h:81
A transaction submitted to a peer.
Definition events.h:73
Peer detected a wrong prior ledger during consensus.
Definition events.h:112
Set the sequence number on a JTx.
Definition seq.h:15