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
33#include <xrpl/beast/utility/Journal.h>
34#include <xrpl/protocol/RippleLedgerHash.h>
35
36#include <atomic>
37#include <memory>
38#include <mutex>
39#include <set>
40#include <sstream>
41#include <string>
42
43namespace ripple {
44
45class InboundTransactions;
46class LocalTxs;
47class LedgerMaster;
48class ValidatorKeys;
49
53{
56 constexpr static unsigned int censorshipWarnInternal = 15;
57
58 // Implements the Adaptor template interface required by Consensus.
59 class Adaptor
60 {
67
68 // If the server is validating, the necessary keying information:
70
71 // A randomly selected non-zero value used to tag our validations
73
74 // Ledger we most recently needed to acquire
77
78 // The timestamp of the last validation we used
80
81 // These members are queried via public accesors and are atomic for
82 // thread safety.
88
91
92 public:
98
100
101 Adaptor(
102 Application& app,
103 std::unique_ptr<FeeVote>&& feeVote,
105 LocalTxs& localTxs,
106 InboundTransactions& inboundTransactions,
107 ValidatorKeys const& validatorKeys,
108 beast::Journal journal);
109
110 bool
112 {
113 return validating_;
114 }
115
118 {
119 return prevProposers_;
120 }
121
124 {
125 return prevRoundTime_;
126 }
127
129 mode() const
130 {
131 return mode_;
132 }
133
140 bool
142 RCLCxLedger const& prevLedger,
143 hash_set<NodeID> const& nowTrusted);
144
145 bool
146 haveValidated() const;
147
149 getValidLedgerIndex() const;
150
152 getQuorumKeys() const;
153
155 laggards(Ledger_t::Seq const seq, hash_set<NodeKey_t>& trustedKeys)
156 const;
157
162 bool
163 validator() const;
164
172 void
173 updateOperatingMode(std::size_t const positions) const;
174
177 ConsensusParms const&
178 parms() const
179 {
180 return parms_;
181 }
182
183 private:
184 //---------------------------------------------------------------------
185 // The following members implement the generic Consensus requirements
186 // and are marked private to indicate ONLY Consensus<Adaptor> will call
187 // them (via friendship). Since they are called only from
188 // Consensus<Adaptor> methods and since RCLConsensus::consensus_ should
189 // only be accessed under lock, these will only be called under lock.
190 //
191 // In general, the idea is that there is only ONE thread that is running
192 // consensus code at anytime. The only special case is the dispatched
193 // onAccept call, which does not take a lock and relies on Consensus not
194 // changing state until a future call to startRound.
195 friend class Consensus<Adaptor>;
196
205 acquireLedger(LedgerHash const& hash);
206
211 void
212 share(RCLCxPeerPos const& peerPos);
213
220 void
221 share(RCLCxTx const& tx);
222
232 acquireTxSet(RCLTxSet::ID const& setId);
233
236 bool
237 hasOpenTransactions() const;
238
245 proposersValidated(LedgerHash const& h) const;
246
256 proposersFinished(RCLCxLedger const& ledger, LedgerHash const& h) const;
257
262 void
264
269 void
270 share(RCLTxSet const& txns);
271
283 uint256
285 uint256 ledgerID,
286 RCLCxLedger const& ledger,
288
294 void
296
304 Result
305 onClose(
306 RCLCxLedger const& ledger,
307 NetClock::time_point const& closeTime,
309
323 void
324 onAccept(
325 Result const& result,
326 RCLCxLedger const& prevLedger,
327 NetClock::duration const& closeResolution,
328 ConsensusCloseTimes const& rawCloseTimes,
329 ConsensusMode const& mode,
330 Json::Value&& consensusJson,
331 bool const validating);
332
338 void
340 Result const& result,
341 RCLCxLedger const& prevLedger,
342 NetClock::duration const& closeResolution,
343 ConsensusCloseTimes const& rawCloseTimes,
344 ConsensusMode const& mode,
345 Json::Value&& consensusJson);
346
353 void
354 notify(
355 protocol::NodeEvent ne,
356 RCLCxLedger const& ledger,
357 bool haveCorrectLCL);
358
363 void
364 doAccept(
365 Result const& result,
366 RCLCxLedger const& prevLedger,
367 NetClock::duration closeResolution,
368 ConsensusCloseTimes const& rawCloseTimes,
369 ConsensusMode const& mode,
370 Json::Value&& consensusJson);
371
394 buildLCL(
395 RCLCxLedger const& previousLedger,
396 CanonicalTXSet& retriableTxs,
397 NetClock::time_point closeTime,
398 bool closeTimeCorrect,
399 NetClock::duration closeResolution,
401 std::set<TxID>& failedTxs);
402
413 void
414 validate(
415 RCLCxLedger const& ledger,
416 RCLTxSet const& txns,
417 bool proposing);
418 };
419
420public:
423 Application& app,
424 std::unique_ptr<FeeVote>&& feeVote,
426 LocalTxs& localTxs,
427 InboundTransactions& inboundTransactions,
429 ValidatorKeys const& validatorKeys,
430 beast::Journal journal);
431
432 RCLConsensus(RCLConsensus const&) = delete;
433
435 operator=(RCLConsensus const&) = delete;
436
438 bool
440 {
441 return adaptor_.validating();
442 }
443
448 {
449 return adaptor_.prevProposers();
450 }
451
461 {
462 return adaptor_.prevRoundTime();
463 }
464
467 mode() const
468 {
469 return adaptor_.mode();
470 }
471
473 phase() const
474 {
475 return consensus_.phase();
476 }
477
480 getJson(bool full) const;
481
485 void
487 NetClock::time_point const& now,
488 RCLCxLedger::ID const& prevLgrId,
489 RCLCxLedger const& prevLgr,
490 hash_set<NodeID> const& nowUntrusted,
491 hash_set<NodeID> const& nowTrusted,
493
495 void
497 NetClock::time_point const& now,
498 std::unique_ptr<std::stringstream> const& clog = {});
499
501 void
502 gotTxSet(NetClock::time_point const& now, RCLTxSet const& txSet);
503
504 // @see Consensus::prevLedgerID
507 {
509 return consensus_.prevLedgerID();
510 }
511
513 void
514 simulate(
515 NetClock::time_point const& now,
517
519 bool
521 NetClock::time_point const& now,
522 RCLCxPeerPos const& newProposal);
523
524 ConsensusParms const&
525 parms() const
526 {
527 return adaptor_.parms();
528 }
529
530private:
531 // Since Consensus does not provide intrinsic thread-safety, this mutex
532 // guards all calls to consensus_. adaptor_ uses atomics internally
533 // to allow concurrent access of its data members that have getters.
535
539};
540
551{
555 std::chrono::steady_clock::time_point start_;
556
557public:
558 explicit RclConsensusLogger(
559 char const* label,
560 bool validating,
563
566 {
567 return ss_;
568 }
569};
570} // namespace ripple
571
572#endif
Represents a JSON value.
Definition json_value.h:149
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:298
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:61
void propose(RCLCxPeerPos::Proposal const &proposal)
Propose the given position to my peers.
ValidatorKeys const & validatorKeys_
beast::Journal const j_
std::atomic< ConsensusMode > mode_
InboundTransactions & inboundTransactions_
std::atomic< std::size_t > prevProposers_
Result onClose(RCLCxLedger const &ledger, NetClock::time_point const &closeTime, ConsensusMode mode)
Close the open ledger and return initial consensus position.
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
std::chrono::milliseconds prevRoundTime() const
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_
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_
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
ConsensusParms const & parms() const
Consensus simulation parameters.
NetClock::time_point lastValidationTime_
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 onAccept(Result const &result, RCLCxLedger const &prevLedger, NetClock::duration const &closeResolution, ConsensusCloseTimes const &rawCloseTimes, ConsensusMode const &mode, Json::Value &&consensusJson, bool const validating)
Process the accepted ledger.
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_
std::uint64_t const valCookie_
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_
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.
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.
void simulate(NetClock::time_point const &now, std::optional< std::chrono::milliseconds > consensusDelay)
ConsensusPhase phase() const
bool validating() const
Whether we are validating consensus ledgers.
RCLConsensus & operator=(RCLConsensus const &)=delete
std::chrono::milliseconds prevRoundTime() const
Get duration of the previous round.
ConsensusMode mode() const
static constexpr unsigned int censorshipWarnInternal
Warn for transactions that haven't been included every so many ledgers.
std::recursive_mutex mutex_
Consensus< Adaptor > consensus_
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
Json::Value getJson(bool full) const
RCLCxLedger::ID prevLedgerID() const
beast::Journal const j_
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.
Represents a transaction in RCLConsensus.
Definition RCLCxTx.h:33
Represents a set of transactions in RCLConsensus.
Definition RCLCxTx.h:63
Collects logging information.
std::unique_ptr< std::stringstream > const & ss()
std::chrono::steady_clock::time_point start_
std::unique_ptr< std::stringstream > ss_
Validator keys and manifest as set in configuration file.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
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:37
ConsensusPhase
Phases of consensus for a single ledger round.
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:3239
@ ledgerMaster
ledger master data for signing
@ proposal
proposal for signing
Stores the set of initial close times.
Consensus algorithm parameters.
Encapsulates the result of consensus.