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/shamap/SHAMap.h>
32#include <xrpl/beast/utility/Journal.h>
33#include <xrpl/protocol/RippleLedgerHash.h>
34
35#include <atomic>
36#include <memory>
37#include <mutex>
38#include <set>
39#include <sstream>
40#include <string>
41
42namespace ripple {
43
44class InboundTransactions;
45class LocalTxs;
46class LedgerMaster;
47class ValidatorKeys;
48
52{
55 constexpr static unsigned int censorshipWarnInternal = 15;
56
57 // Implements the Adaptor template interface required by Consensus.
58 class Adaptor
59 {
66
67 // If the server is validating, the necessary keying information:
69
70 // A randomly selected non-zero value used to tag our validations
72
73 // Ledger we most recently needed to acquire
76
77 // The timestamp of the last validation we used
79
80 // These members are queried via public accesors and are atomic for
81 // thread safety.
87
90
91 public:
97
99
100 Adaptor(
101 Application& app,
102 std::unique_ptr<FeeVote>&& feeVote,
104 LocalTxs& localTxs,
105 InboundTransactions& inboundTransactions,
106 ValidatorKeys const& validatorKeys,
107 beast::Journal journal);
108
109 bool
111 {
112 return validating_;
113 }
114
117 {
118 return prevProposers_;
119 }
120
123 {
124 return prevRoundTime_;
125 }
126
128 mode() const
129 {
130 return mode_;
131 }
132
139 bool
141 RCLCxLedger const& prevLedger,
142 hash_set<NodeID> const& nowTrusted);
143
144 bool
145 haveValidated() const;
146
148 getValidLedgerIndex() const;
149
151 getQuorumKeys() const;
152
154 laggards(Ledger_t::Seq const seq, hash_set<NodeKey_t>& trustedKeys)
155 const;
156
161 bool
162 validator() const;
163
171 void
172 updateOperatingMode(std::size_t const positions) const;
173
176 ConsensusParms const&
177 parms() const
178 {
179 return parms_;
180 }
181
182 private:
183 //---------------------------------------------------------------------
184 // The following members implement the generic Consensus requirements
185 // and are marked private to indicate ONLY Consensus<Adaptor> will call
186 // them (via friendship). Since they are called only from
187 // Consensus<Adaptor> methods and since RCLConsensus::consensus_ should
188 // only be accessed under lock, these will only be called under lock.
189 //
190 // In general, the idea is that there is only ONE thread that is running
191 // consensus code at anytime. The only special case is the dispatched
192 // onAccept call, which does not take a lock and relies on Consensus not
193 // changing state until a future call to startRound.
194 friend class Consensus<Adaptor>;
195
204 acquireLedger(LedgerHash const& hash);
205
210 void
211 share(RCLCxPeerPos const& peerPos);
212
219 void
220 share(RCLCxTx const& tx);
221
231 acquireTxSet(RCLTxSet::ID const& setId);
232
235 bool
236 hasOpenTransactions() const;
237
244 proposersValidated(LedgerHash const& h) const;
245
255 proposersFinished(RCLCxLedger const& ledger, LedgerHash const& h) const;
256
261 void
263
268 void
269 share(RCLTxSet const& txns);
270
282 uint256
284 uint256 ledgerID,
285 RCLCxLedger const& ledger,
287
293 void
295
303 Result
304 onClose(
305 RCLCxLedger const& ledger,
306 NetClock::time_point const& closeTime,
308
322 void
323 onAccept(
324 Result const& result,
325 RCLCxLedger const& prevLedger,
326 NetClock::duration const& closeResolution,
327 ConsensusCloseTimes const& rawCloseTimes,
328 ConsensusMode const& mode,
329 Json::Value&& consensusJson,
330 const bool validating);
331
337 void
339 Result const& result,
340 RCLCxLedger const& prevLedger,
341 NetClock::duration const& closeResolution,
342 ConsensusCloseTimes const& rawCloseTimes,
343 ConsensusMode const& mode,
344 Json::Value&& consensusJson);
345
352 void
353 notify(
354 protocol::NodeEvent ne,
355 RCLCxLedger const& ledger,
356 bool haveCorrectLCL);
357
362 void
363 doAccept(
364 Result const& result,
365 RCLCxLedger const& prevLedger,
366 NetClock::duration closeResolution,
367 ConsensusCloseTimes const& rawCloseTimes,
368 ConsensusMode const& mode,
369 Json::Value&& consensusJson);
370
393 buildLCL(
394 RCLCxLedger const& previousLedger,
395 CanonicalTXSet& retriableTxs,
396 NetClock::time_point closeTime,
397 bool closeTimeCorrect,
398 NetClock::duration closeResolution,
400 std::set<TxID>& failedTxs);
401
412 void
413 validate(
414 RCLCxLedger const& ledger,
415 RCLTxSet const& txns,
416 bool proposing);
417 };
418
419public:
422 Application& app,
423 std::unique_ptr<FeeVote>&& feeVote,
425 LocalTxs& localTxs,
426 InboundTransactions& inboundTransactions,
428 ValidatorKeys const& validatorKeys,
429 beast::Journal journal);
430
431 RCLConsensus(RCLConsensus const&) = delete;
432
434 operator=(RCLConsensus const&) = delete;
435
437 bool
439 {
440 return adaptor_.validating();
441 }
442
447 {
448 return adaptor_.prevProposers();
449 }
450
460 {
461 return adaptor_.prevRoundTime();
462 }
463
466 mode() const
467 {
468 return adaptor_.mode();
469 }
470
472 phase() const
473 {
474 return consensus_.phase();
475 }
476
479 getJson(bool full) const;
480
484 void
486 NetClock::time_point const& now,
487 RCLCxLedger::ID const& prevLgrId,
488 RCLCxLedger const& prevLgr,
489 hash_set<NodeID> const& nowUntrusted,
490 hash_set<NodeID> const& nowTrusted,
492
494 void
496 NetClock::time_point const& now,
497 std::unique_ptr<std::stringstream> const& clog = {});
498
500 void
501 gotTxSet(NetClock::time_point const& now, RCLTxSet const& txSet);
502
503 // @see Consensus::prevLedgerID
506 {
508 return consensus_.prevLedgerID();
509 }
510
512 void
513 simulate(
514 NetClock::time_point const& now,
516
518 bool
520 NetClock::time_point const& now,
521 RCLCxPeerPos const& newProposal);
522
523 ConsensusParms const&
524 parms() const
525 {
526 return adaptor_.parms();
527 }
528
529private:
530 // Since Consensus does not provide intrinsic thread-safety, this mutex
531 // guards all calls to consensus_. adaptor_ uses atomics internally
532 // to allow concurrent access of its data members that have getters.
534
538};
539
550{
554 std::chrono::steady_clock::time_point start_;
555
556public:
557 explicit RclConsensusLogger(
558 const char* label,
559 bool validating,
562
565 {
566 return ss_;
567 }
568};
569} // namespace ripple
570
571#endif
Represents a JSON value.
Definition: json_value.h:148
A generic endpoint for log messages.
Definition: Journal.h:60
Holds transactions which were deferred to the next pass of consensus.
Generic implementation of consensus algorithm.
Definition: Consensus.h:291
Manages the acquisition and lifetime of transaction sets.
Manager to create NegativeUNL votes.
std::chrono::time_point< NetClock > time_point
Definition: chrono.h:69
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:68
beast::Journal const j_
Definition: RCLConsensus.h:65
std::atomic< ConsensusMode > mode_
Definition: RCLConsensus.h:86
InboundTransactions & inboundTransactions_
Definition: RCLConsensus.h:64
std::atomic< std::size_t > prevProposers_
Definition: RCLConsensus.h:83
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:128
std::chrono::milliseconds prevRoundTime() const
Definition: RCLConsensus.h:122
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:88
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:61
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:116
ConsensusParms const & parms() const
Consensus simulation parameters.
Definition: RCLConsensus.h:177
NetClock::time_point lastValidationTime_
Definition: RCLConsensus.h:78
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:84
std::uint64_t const valCookie_
Definition: RCLConsensus.h:71
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:82
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:52
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:446
void simulate(NetClock::time_point const &now, std::optional< std::chrono::milliseconds > consensusDelay)
ConsensusPhase phase() const
Definition: RCLConsensus.h:472
bool validating() const
Whether we are validating consensus ledgers.
Definition: RCLConsensus.h:438
RCLConsensus & operator=(RCLConsensus const &)=delete
std::chrono::milliseconds prevRoundTime() const
Get duration of the previous round.
Definition: RCLConsensus.h:459
ConsensusMode mode() const
Definition: RCLConsensus.h:466
static constexpr unsigned int censorshipWarnInternal
Warn for transactions that haven't been included every so many ledgers.
Definition: RCLConsensus.h:55
std::recursive_mutex mutex_
Definition: RCLConsensus.h:533
Consensus< Adaptor > consensus_
Definition: RCLConsensus.h:536
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:524
Json::Value getJson(bool full) const
RCLCxLedger::ID prevLedgerID() const
Definition: RCLConsensus.h:505
beast::Journal const j_
Definition: RCLConsensus.h:537
Represents a ledger in RCLConsensus.
Definition: RCLCxLedger.h:35
LedgerHash ID
Unique identifier of a ledger.
Definition: RCLCxLedger.h:38
LedgerIndex Seq
Sequence number of a ledger.
Definition: RCLCxLedger.h:40
A peer's signed, proposed position for use in RCLConsensus.
Definition: RCLCxPeerPos.h:43
Represents a transaction in RCLConsensus.
Definition: RCLCxTx.h:33
Represents a set of transactions in RCLConsensus.
Definition: RCLCxTx.h:63
Collects logging information.
Definition: RCLConsensus.h:550
std::unique_ptr< std::stringstream > const & ss()
Definition: RCLConsensus.h:564
std::chrono::steady_clock::time_point start_
Definition: RCLConsensus.h:554
std::unique_ptr< std::stringstream > ss_
Definition: RCLConsensus.h:553
Validator keys and manifest as set in configuration file.
Definition: ValidatorKeys.h:38
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:85
Stores the set of initial close times.
Consensus algorithm parameters.
Encapsulates the result of consensus.