rippled
Loading...
Searching...
No Matches
RCLConsensus.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_APP_CONSENSUS_RCLCONSENSUS_H_INCLUDED
21#define RIPPLE_APP_CONSENSUS_RCLCONSENSUS_H_INCLUDED
22
23#include <xrpld/app/consensus/RCLCensorshipDetector.h>
24#include <xrpld/app/consensus/RCLCxLedger.h>
25#include <xrpld/app/consensus/RCLCxPeerPos.h>
26#include <xrpld/app/consensus/RCLCxTx.h>
27#include <xrpld/app/misc/FeeVote.h>
28#include <xrpld/app/misc/NegativeUNLVote.h>
29#include <xrpld/consensus/Consensus.h>
30#include <xrpld/core/JobQueue.h>
31#include <xrpld/overlay/Message.h>
32#include <xrpld/shamap/SHAMap.h>
33#include <xrpl/basics/CountedObject.h>
34#include <xrpl/basics/Log.h>
35#include <xrpl/beast/utility/Journal.h>
36#include <xrpl/protocol/RippleLedgerHash.h>
37#include <xrpl/protocol/STValidation.h>
38#include <atomic>
39#include <memory>
40#include <mutex>
41#include <set>
42#include <sstream>
43#include <string>
44
45namespace ripple {
46
47class InboundTransactions;
48class LocalTxs;
49class LedgerMaster;
50class ValidatorKeys;
51
55{
58 constexpr static unsigned int censorshipWarnInternal = 15;
59
60 // Implements the Adaptor template interface required by Consensus.
61 class Adaptor
62 {
69
70 // If the server is validating, the necessary keying information:
72
73 // A randomly selected non-zero value used to tag our validations
75
76 // Ledger we most recently needed to acquire
79
80 // The timestamp of the last validation we used
82
83 // These members are queried via public accesors and are atomic for
84 // thread safety.
90
93
94 public:
100
102
103 Adaptor(
104 Application& app,
105 std::unique_ptr<FeeVote>&& feeVote,
107 LocalTxs& localTxs,
108 InboundTransactions& inboundTransactions,
109 ValidatorKeys const& validatorKeys,
110 beast::Journal journal);
111
112 bool
114 {
115 return validating_;
116 }
117
120 {
121 return prevProposers_;
122 }
123
126 {
127 return prevRoundTime_;
128 }
129
131 mode() const
132 {
133 return mode_;
134 }
135
142 bool
144 RCLCxLedger const& prevLedger,
145 hash_set<NodeID> const& nowTrusted);
146
147 bool
148 haveValidated() const;
149
151 getValidLedgerIndex() const;
152
154 getQuorumKeys() const;
155
157 laggards(Ledger_t::Seq const seq, hash_set<NodeKey_t>& trustedKeys)
158 const;
159
164 bool
165 validator() const;
166
174 void
175 updateOperatingMode(std::size_t const positions) const;
176
179 ConsensusParms const&
180 parms() const
181 {
182 return parms_;
183 }
184
185 private:
186 //---------------------------------------------------------------------
187 // The following members implement the generic Consensus requirements
188 // and are marked private to indicate ONLY Consensus<Adaptor> will call
189 // them (via friendship). Since they are called only from
190 // Consensus<Adaptor> methods and since RCLConsensus::consensus_ should
191 // only be accessed under lock, these will only be called under lock.
192 //
193 // In general, the idea is that there is only ONE thread that is running
194 // consensus code at anytime. The only special case is the dispatched
195 // onAccept call, which does not take a lock and relies on Consensus not
196 // changing state until a future call to startRound.
197 friend class Consensus<Adaptor>;
198
207 acquireLedger(LedgerHash const& hash);
208
213 void
214 share(RCLCxPeerPos const& peerPos);
215
222 void
223 share(RCLCxTx const& tx);
224
234 acquireTxSet(RCLTxSet::ID const& setId);
235
238 bool
239 hasOpenTransactions() const;
240
247 proposersValidated(LedgerHash const& h) const;
248
258 proposersFinished(RCLCxLedger const& ledger, LedgerHash const& h) const;
259
264 void
266
271 void
272 share(RCLTxSet const& txns);
273
285 uint256
287 uint256 ledgerID,
288 RCLCxLedger const& ledger,
290
296 void
298
306 Result
307 onClose(
308 RCLCxLedger const& ledger,
309 NetClock::time_point const& closeTime,
311
325 void
326 onAccept(
327 Result const& result,
328 RCLCxLedger const& prevLedger,
329 NetClock::duration const& closeResolution,
330 ConsensusCloseTimes const& rawCloseTimes,
331 ConsensusMode const& mode,
332 Json::Value&& consensusJson,
333 const bool validating);
334
340 void
342 Result const& result,
343 RCLCxLedger const& prevLedger,
344 NetClock::duration const& closeResolution,
345 ConsensusCloseTimes const& rawCloseTimes,
346 ConsensusMode const& mode,
347 Json::Value&& consensusJson);
348
355 void
356 notify(
357 protocol::NodeEvent ne,
358 RCLCxLedger const& ledger,
359 bool haveCorrectLCL);
360
365 void
366 doAccept(
367 Result const& result,
368 RCLCxLedger const& prevLedger,
369 NetClock::duration closeResolution,
370 ConsensusCloseTimes const& rawCloseTimes,
371 ConsensusMode const& mode,
372 Json::Value&& consensusJson);
373
396 buildLCL(
397 RCLCxLedger const& previousLedger,
398 CanonicalTXSet& retriableTxs,
399 NetClock::time_point closeTime,
400 bool closeTimeCorrect,
401 NetClock::duration closeResolution,
403 std::set<TxID>& failedTxs);
404
415 void
416 validate(
417 RCLCxLedger const& ledger,
418 RCLTxSet const& txns,
419 bool proposing);
420 };
421
422public:
425 Application& app,
426 std::unique_ptr<FeeVote>&& feeVote,
428 LocalTxs& localTxs,
429 InboundTransactions& inboundTransactions,
431 ValidatorKeys const& validatorKeys,
432 beast::Journal journal);
433
434 RCLConsensus(RCLConsensus const&) = delete;
435
437 operator=(RCLConsensus const&) = delete;
438
440 bool
442 {
443 return adaptor_.validating();
444 }
445
450 {
451 return adaptor_.prevProposers();
452 }
453
463 {
464 return adaptor_.prevRoundTime();
465 }
466
469 mode() const
470 {
471 return adaptor_.mode();
472 }
473
475 phase() const
476 {
477 return consensus_.phase();
478 }
479
482 getJson(bool full) const;
483
487 void
489 NetClock::time_point const& now,
490 RCLCxLedger::ID const& prevLgrId,
491 RCLCxLedger const& prevLgr,
492 hash_set<NodeID> const& nowUntrusted,
493 hash_set<NodeID> const& nowTrusted,
495
497 void
499 NetClock::time_point const& now,
500 std::unique_ptr<std::stringstream> const& clog = {});
501
503 void
504 gotTxSet(NetClock::time_point const& now, RCLTxSet const& txSet);
505
506 // @see Consensus::prevLedgerID
509 {
511 return consensus_.prevLedgerID();
512 }
513
515 void
516 simulate(
517 NetClock::time_point const& now,
519
521 bool
523 NetClock::time_point const& now,
524 RCLCxPeerPos const& newProposal);
525
526 ConsensusParms const&
527 parms() const
528 {
529 return adaptor_.parms();
530 }
531
532private:
533 // Since Consensus does not provide intrinsic thread-safety, this mutex
534 // guards all calls to consensus_. adaptor_ uses atomics internally
535 // to allow concurrent access of its data members that have getters.
537
541};
542
553{
557 std::chrono::steady_clock::time_point start_;
558
559public:
560 explicit RclConsensusLogger(
561 const char* label,
562 bool validating,
565
568 {
569 return ss_;
570 }
571};
572} // namespace ripple
573
574#endif
Represents a JSON value.
Definition: json_value.h:147
A generic endpoint for log messages.
Definition: Journal.h:59
Holds transactions which were deferred to the next pass of consensus.
Generic implementation of consensus algorithm.
Definition: Consensus.h:292
Manages the acquisition and lifetime of transaction sets.
Manager to create NegativeUNL votes.
std::chrono::time_point< NetClock > time_point
Definition: chrono.h:70
A public key.
Definition: PublicKey.h:62
void propose(RCLCxPeerPos::Proposal const &proposal)
Propose the given position to my peers.
ValidatorKeys const & validatorKeys_
Definition: RCLConsensus.h:71
beast::Journal const j_
Definition: RCLConsensus.h:68
std::atomic< ConsensusMode > mode_
Definition: RCLConsensus.h:89
InboundTransactions & inboundTransactions_
Definition: RCLConsensus.h:67
std::atomic< std::size_t > prevProposers_
Definition: RCLConsensus.h:86
Result onClose(RCLCxLedger const &ledger, NetClock::time_point const &closeTime, ConsensusMode mode)
Close the open ledger and return initial consensus position.
void onAccept(Result const &result, RCLCxLedger const &prevLedger, NetClock::duration const &closeResolution, ConsensusCloseTimes const &rawCloseTimes, ConsensusMode const &mode, Json::Value &&consensusJson, const bool validating)
Process the accepted ledger.
void share(RCLCxPeerPos const &peerPos)
Share the given proposal with all peers.
void doAccept(Result const &result, RCLCxLedger const &prevLedger, NetClock::duration closeResolution, ConsensusCloseTimes const &rawCloseTimes, ConsensusMode const &mode, Json::Value &&consensusJson)
Accept a new ledger based on the given transactions.
ConsensusMode mode() const
Definition: RCLConsensus.h:131
std::chrono::milliseconds prevRoundTime() const
Definition: RCLConsensus.h:125
void onModeChange(ConsensusMode before, ConsensusMode after)
Notified of change in consensus mode.
std::size_t laggards(Ledger_t::Seq const seq, hash_set< NodeKey_t > &trustedKeys) const
RCLCensorshipDetector< TxID, LedgerIndex > censorshipDetector_
Definition: RCLConsensus.h:91
void onForceAccept(Result const &result, RCLCxLedger const &prevLedger, NetClock::duration const &closeResolution, ConsensusCloseTimes const &rawCloseTimes, ConsensusMode const &mode, Json::Value &&consensusJson)
Process the accepted ledger that was a result of simulation/force accept.
bool validator() const
Whether I am a validator.
RCLCxLedger buildLCL(RCLCxLedger const &previousLedger, CanonicalTXSet &retriableTxs, NetClock::time_point closeTime, bool closeTimeCorrect, NetClock::duration closeResolution, std::chrono::milliseconds roundTime, std::set< TxID > &failedTxs)
Build the new last closed ledger.
std::optional< RCLCxLedger > acquireLedger(LedgerHash const &hash)
Attempt to acquire a specific ledger.
std::unique_ptr< FeeVote > feeVote_
Definition: RCLConsensus.h:64
LedgerIndex getValidLedgerIndex() const
std::size_t proposersFinished(RCLCxLedger const &ledger, LedgerHash const &h) const
Number of proposers that have validated a ledger descended from requested ledger.
std::size_t prevProposers() const
Definition: RCLConsensus.h:119
ConsensusParms const & parms() const
Consensus simulation parameters.
Definition: RCLConsensus.h:180
NetClock::time_point lastValidationTime_
Definition: RCLConsensus.h:81
std::optional< RCLTxSet > acquireTxSet(RCLTxSet::ID const &setId)
Acquire the transaction set associated with a proposal.
bool hasOpenTransactions() const
Whether the open ledger has any transactions.
void validate(RCLCxLedger const &ledger, RCLTxSet const &txns, bool proposing)
Validate the given ledger and share with peers as necessary.
std::atomic< std::chrono::milliseconds > prevRoundTime_
Definition: RCLConsensus.h:87
std::uint64_t const valCookie_
Definition: RCLConsensus.h:74
bool preStartRound(RCLCxLedger const &prevLedger, hash_set< NodeID > const &nowTrusted)
Called before kicking off a new consensus round.
uint256 getPrevLedger(uint256 ledgerID, RCLCxLedger const &ledger, ConsensusMode mode)
Get the ID of the previous ledger/last closed ledger(LCL) on the network.
std::size_t proposersValidated(LedgerHash const &h) const
Number of proposers that have validated the given ledger.
std::atomic< bool > validating_
Definition: RCLConsensus.h:85
void notify(protocol::NodeEvent ne, RCLCxLedger const &ledger, bool haveCorrectLCL)
Notify peers of a consensus state change.
void updateOperatingMode(std::size_t const positions) const
Update operating mode based on current peer positions.
std::pair< std::size_t, hash_set< NodeKey_t > > getQuorumKeys() const
Manages the generic consensus algorithm for use by the RCL.
Definition: RCLConsensus.h:55
RCLConsensus(RCLConsensus const &)=delete
void gotTxSet(NetClock::time_point const &now, RCLTxSet const &txSet)
std::size_t prevProposers() const
Get the number of proposing peers that participated in the previous round.
Definition: RCLConsensus.h:449
void simulate(NetClock::time_point const &now, std::optional< std::chrono::milliseconds > consensusDelay)
ConsensusPhase phase() const
Definition: RCLConsensus.h:475
bool validating() const
Whether we are validating consensus ledgers.
Definition: RCLConsensus.h:441
RCLConsensus & operator=(RCLConsensus const &)=delete
std::chrono::milliseconds prevRoundTime() const
Get duration of the previous round.
Definition: RCLConsensus.h:462
ConsensusMode mode() const
Definition: RCLConsensus.h:469
static constexpr unsigned int censorshipWarnInternal
Warn for transactions that haven't been included every so many ledgers.
Definition: RCLConsensus.h:58
std::recursive_mutex mutex_
Definition: RCLConsensus.h:536
Consensus< Adaptor > consensus_
Definition: RCLConsensus.h:539
bool peerProposal(NetClock::time_point const &now, RCLCxPeerPos const &newProposal)
void startRound(NetClock::time_point const &now, RCLCxLedger::ID const &prevLgrId, RCLCxLedger const &prevLgr, hash_set< NodeID > const &nowUntrusted, hash_set< NodeID > const &nowTrusted, std::unique_ptr< std::stringstream > const &clog)
Adjust the set of trusted validators and kick-off the next round of consensus.
void timerEntry(NetClock::time_point const &now, std::unique_ptr< std::stringstream > const &clog={})
ConsensusParms const & parms() const
Definition: RCLConsensus.h:527
Json::Value getJson(bool full) const
RCLCxLedger::ID prevLedgerID() const
Definition: RCLConsensus.h:508
beast::Journal const j_
Definition: RCLConsensus.h:540
Represents a ledger in RCLConsensus.
Definition: RCLCxLedger.h:36
LedgerHash ID
Unique identifier of a ledger.
Definition: RCLCxLedger.h:39
LedgerIndex Seq
Sequence number of a ledger.
Definition: RCLCxLedger.h:41
A peer's signed, proposed position for use in RCLConsensus.
Definition: RCLCxPeerPos.h:44
Represents a transaction in RCLConsensus.
Definition: RCLCxTx.h:36
Represents a set of transactions in RCLConsensus.
Definition: RCLCxTx.h:66
Collects logging information.
Definition: RCLConsensus.h:553
std::unique_ptr< std::stringstream > const & ss()
Definition: RCLConsensus.h:567
std::chrono::steady_clock::time_point start_
Definition: RCLConsensus.h:557
std::unique_ptr< std::stringstream > ss_
Definition: RCLConsensus.h:556
Validator keys and manifest as set in configuration file.
Definition: ValidatorKeys.h:37
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
ConsensusMode
Represents how a node currently participates in Consensus.
@ proposing
We are normal participant in consensus and propose our position.
@ observing
We are observing peer positions, but not proposing our position.
base_uint< 160, detail::NodeIDTag > NodeID
NodeID is a 160-bit hash representing one node.
Definition: UintTypes.h:59
boost::outcome_v2::result< T, std::error_code > Result
Definition: b58_utils.h:38
ConsensusPhase
Phases of consensus for a single ledger round.
@ ledgerMaster
ledger master data for signing
@ proposal
proposal for signing
static bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition: Escrow.cpp:89
Stores the set of initial close times.
Consensus algorithm parameters.
Encapsulates the result of consensus.