mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
Refactor consensus:
Classes implementing the consensus process on Ripple are cleaned up in preparation for modularizations and compartmentalization. Functions and state related to inter-round consensus are moved out of NetworkOPs and into Consensus, where they are more effectively isolated. Some member functions are changed to free functions and some free functions have their scope reduced to specific translation units. * Track inter-round consensus state using new Consensus object * Devirtualize interfaces * Reduce NetworkOPs, Consensus and LedgerConsensus interfaces * Add comments
This commit is contained in:
@@ -1357,12 +1357,20 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\BookListeners.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\Consensus.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\ConsensusTransSetSF.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\ConsensusTransSetSF.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\ConsensusImp.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\impl\ConsensusImp.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\DisputedTx.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
@@ -1383,10 +1391,12 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\impl\LedgerCleaner.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerConsensus.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerConsensusImp.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\impl\LedgerConsensusImp.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerFees.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
|
||||
@@ -2097,12 +2097,21 @@
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\BookListeners.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\Consensus.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\ConsensusTransSetSF.cpp">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\ConsensusTransSetSF.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\ConsensusImp.cpp">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\impl\ConsensusImp.h">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\DisputedTx.cpp">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
@@ -2121,9 +2130,12 @@
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\impl\LedgerCleaner.h">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerConsensus.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerConsensusImp.cpp">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\impl\LedgerConsensusImp.h">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerFees.cpp">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -41,9 +41,9 @@ void BookListeners::publish (Json::Value const& jvObj)
|
||||
std::string sObj = to_string (jvObj);
|
||||
|
||||
ScopedLockType sl (mLock);
|
||||
NetworkOPs::SubMapType::const_iterator it = mListeners.begin ();
|
||||
auto it = mListeners.cbegin ();
|
||||
|
||||
while (it != mListeners.end ())
|
||||
while (it != mListeners.cend ())
|
||||
{
|
||||
InfoSub::pointer p = it->second.lock ();
|
||||
|
||||
|
||||
89
src/ripple/app/ledger/Consensus.h
Normal file
89
src/ripple/app/ledger/Consensus.h
Normal file
@@ -0,0 +1,89 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_APP_LEDGER_CONSENSUS_H_INCLUDED
|
||||
#define RIPPLE_APP_LEDGER_CONSENSUS_H_INCLUDED
|
||||
|
||||
#include <ripple/app/ledger/LedgerConsensus.h>
|
||||
#include <ripple/app/ledger/LedgerMaster.h>
|
||||
#include <ripple/app/tx/InboundTransactions.h>
|
||||
#include <ripple/app/tx/LocalTxs.h>
|
||||
|
||||
#include <beast/cxx14/memory.h> // <memory>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Implements the consensus process and provides inter-round state. */
|
||||
class Consensus
|
||||
{
|
||||
public:
|
||||
using Proposals = hash_map <NodeID, std::deque<LedgerProposal::pointer>>;
|
||||
|
||||
virtual
|
||||
~Consensus () = default;
|
||||
|
||||
/** Returns whether we are issuing proposals currently. */
|
||||
virtual
|
||||
bool
|
||||
isProposing () const = 0;
|
||||
|
||||
/** Returns whether we are issuing validations currently. */
|
||||
virtual
|
||||
bool
|
||||
isValidating () const = 0;
|
||||
|
||||
/** Returns the number of unique proposers we observed for the LCL. */
|
||||
virtual
|
||||
int
|
||||
getLastCloseProposers () const = 0;
|
||||
|
||||
/** Returns the time (in milliseconds) that the last close took. */
|
||||
virtual
|
||||
int
|
||||
getLastCloseDuration () const = 0;
|
||||
|
||||
/** Called when a new round of consensus is about to begin */
|
||||
virtual
|
||||
std::shared_ptr<LedgerConsensus>
|
||||
startRound (
|
||||
InboundTransactions& inboundTransactions,
|
||||
LocalTxs& localtx,
|
||||
LedgerMaster& ledgerMaster,
|
||||
LedgerHash const &prevLCLHash,
|
||||
Ledger::ref previousLedger,
|
||||
std::uint32_t closeTime) = 0;
|
||||
|
||||
/** Specified the network time when the last ledger closed */
|
||||
virtual
|
||||
void
|
||||
setLastCloseTime (std::uint32_t t) = 0;
|
||||
|
||||
virtual
|
||||
void
|
||||
storeProposal (
|
||||
LedgerProposal::ref proposal,
|
||||
RippleAddress const& peerPublic) = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<Consensus>
|
||||
make_Consensus ();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -17,8 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_APP_CONSENSUS_LEDGERCONSENSUS_H_INCLUDED
|
||||
#define RIPPLE_APP_CONSENSUS_LEDGERCONSENSUS_H_INCLUDED
|
||||
#ifndef RIPPLE_APP_LEDGER_LEDGERCONSENSUS_H_INCLUDED
|
||||
#define RIPPLE_APP_LEDGER_LEDGERCONSENSUS_H_INCLUDED
|
||||
|
||||
#include <ripple/app/ledger/Ledger.h>
|
||||
#include <ripple/app/ledger/LedgerProposal.h>
|
||||
@@ -41,7 +41,7 @@ namespace ripple {
|
||||
class LedgerConsensus
|
||||
{
|
||||
public:
|
||||
virtual ~LedgerConsensus() = 0;
|
||||
virtual ~LedgerConsensus() = default;
|
||||
|
||||
virtual Json::Value getJson (bool full) = 0;
|
||||
|
||||
@@ -66,17 +66,25 @@ public:
|
||||
virtual void simulate () = 0;
|
||||
};
|
||||
|
||||
std::shared_ptr <LedgerConsensus>
|
||||
make_LedgerConsensus (
|
||||
int previousProposers, int previousConvergeTime,
|
||||
InboundTransactions& inboundTransactions, LocalTxs& localtx,
|
||||
LedgerHash const & prevLCLHash, Ledger::ref previousLedger,
|
||||
std::uint32_t closeTime, FeeVote& feeVote);
|
||||
//------------------------------------------------------------------------------
|
||||
/** Apply a set of transactions to a ledger
|
||||
|
||||
@param set The set of transactions to apply
|
||||
@param applyLedger The ledger to which the transactions should
|
||||
be applied.
|
||||
@param checkLedger A reference ledger for determining error
|
||||
messages (typically new last closed
|
||||
ledger).
|
||||
@param retriableTransactions collect failed transactions in this set
|
||||
@param openLgr true if applyLedger is open, else false.
|
||||
*/
|
||||
void
|
||||
applyTransactions(SHAMap const* set, Ledger::ref applyLedger,
|
||||
Ledger::ref checkLedger,
|
||||
CanonicalTXSet& retriableTransactions, bool openLgr);
|
||||
applyTransactions(
|
||||
SHAMap const* set,
|
||||
Ledger::ref applyLedger,
|
||||
Ledger::ref checkLedger,
|
||||
CanonicalTXSet& retriableTransactions,
|
||||
bool openLgr);
|
||||
|
||||
} // ripple
|
||||
|
||||
|
||||
@@ -120,7 +120,6 @@ public:
|
||||
virtual void addHeldTransaction (Transaction::ref trans) = 0;
|
||||
virtual void fixMismatch (Ledger::ref ledger) = 0;
|
||||
|
||||
virtual bool haveLedgerRange (std::uint32_t from, std::uint32_t to) = 0;
|
||||
virtual bool haveLedger (std::uint32_t seq) = 0;
|
||||
virtual void clearLedger (std::uint32_t seq) = 0;
|
||||
virtual bool getValidatedRange (std::uint32_t& minVal, std::uint32_t& maxVal) = 0;
|
||||
|
||||
@@ -24,57 +24,6 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Determines whether the current ledger should close at this time.
|
||||
|
||||
This function should be called when a ledger is open and there is no close
|
||||
in progress, or when a transaction is received and no close is in progress.
|
||||
|
||||
@param anyTransactions indicates whether any transactions have been received
|
||||
@param previousProposers proposers in the last closing
|
||||
@param proposersClosed proposers who have currently closed this ledger
|
||||
@param proposersValidated proposers who have validated the last closed ledger
|
||||
@param previousMSeconds time, in milliseconds, for the previous ledger to
|
||||
reach consensus (in milliseconds)
|
||||
@param currentMSeconds time, in milliseconds since the previous ledger closed
|
||||
@param openMSeconds time, in milliseconds, since the previous LCL was computed
|
||||
@param idleInterval the network's desired idle interval
|
||||
*/
|
||||
bool shouldCloseLedger (
|
||||
bool anyTransactions,
|
||||
int previousProposers,
|
||||
int proposersClosed,
|
||||
int proposersValidated,
|
||||
int previousMSeconds,
|
||||
int currentMSeconds,
|
||||
int openMSeconds,
|
||||
int idleInterval);
|
||||
|
||||
/** What state the consensus process is on. */
|
||||
enum class ConsensusState
|
||||
{
|
||||
No, // We do not have consensus
|
||||
MovedOn, // The network has consensus without us
|
||||
Yes // We have consensus along with the network
|
||||
};
|
||||
|
||||
/** Determine whether the network reached consensus and whether we joined.
|
||||
|
||||
@param previousProposers proposers in the last closing (not including us)
|
||||
@param currentProposers proposers in this closing so far (not including us)
|
||||
@param currentAgree proposers who agree with us
|
||||
@param currentFinished proposers who have validated a ledger after this one
|
||||
@param previousAgreeTime how long, in milliseconds, it took to agree on the
|
||||
last ledger
|
||||
@param currentAgreeTime how long, in milliseconds, we've been trying to agree
|
||||
*/
|
||||
ConsensusState checkConsensus (
|
||||
int previousProposers,
|
||||
int currentProposers,
|
||||
int currentAgree,
|
||||
int currentClosed,
|
||||
int previousAgreeTime,
|
||||
int currentAgreeTime);
|
||||
|
||||
/** Calculates the close time resolution for the specified ledger.
|
||||
|
||||
The Ripple protocol uses binning to represent time intervals using only one
|
||||
|
||||
181
src/ripple/app/ledger/impl/ConsensusImp.cpp
Normal file
181
src/ripple/app/ledger/impl/ConsensusImp.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/ledger/LedgerTiming.h>
|
||||
#include <ripple/app/ledger/impl/ConsensusImp.h>
|
||||
#include <ripple/app/ledger/impl/LedgerConsensusImp.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <beast/utility/Journal.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
ConsensusImp::ConsensusImp ()
|
||||
: journal_ (deprecatedLogs().journal("Consensus"))
|
||||
, feeVote_ (make_FeeVote (setup_FeeVote (getConfig().section ("voting")),
|
||||
deprecatedLogs().journal("FeeVote")))
|
||||
, proposing_ (false)
|
||||
, validating_ (false)
|
||||
, lastCloseProposers_ (0)
|
||||
, lastCloseConvergeTook_ (1000 * LEDGER_IDLE_INTERVAL)
|
||||
, lastValidationTimestamp_ (0)
|
||||
, lastCloseTime_ (0)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
ConsensusImp::isProposing () const
|
||||
{
|
||||
return proposing_;
|
||||
}
|
||||
|
||||
bool
|
||||
ConsensusImp::isValidating () const
|
||||
{
|
||||
return validating_;
|
||||
}
|
||||
|
||||
int
|
||||
ConsensusImp::getLastCloseProposers () const
|
||||
{
|
||||
return lastCloseProposers_;
|
||||
}
|
||||
|
||||
int
|
||||
ConsensusImp::getLastCloseDuration () const
|
||||
{
|
||||
return lastCloseConvergeTook_;
|
||||
}
|
||||
|
||||
std::shared_ptr<LedgerConsensus>
|
||||
ConsensusImp::startRound (
|
||||
InboundTransactions& inboundTransactions,
|
||||
LocalTxs& localtx,
|
||||
LedgerMaster& ledgerMaster,
|
||||
LedgerHash const &prevLCLHash,
|
||||
Ledger::ref previousLedger,
|
||||
std::uint32_t closeTime)
|
||||
{
|
||||
return make_LedgerConsensus (*this, lastCloseProposers_,
|
||||
lastCloseConvergeTook_, inboundTransactions, localtx, ledgerMaster,
|
||||
prevLCLHash, previousLedger, closeTime, *feeVote_);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConsensusImp::setProposing (bool p, bool v)
|
||||
{
|
||||
proposing_ = p;
|
||||
validating_ = v;
|
||||
}
|
||||
|
||||
STValidation::ref
|
||||
ConsensusImp::getLastValidation () const
|
||||
{
|
||||
return lastValidation_;
|
||||
}
|
||||
|
||||
void
|
||||
ConsensusImp::setLastValidation (STValidation::ref v)
|
||||
{
|
||||
lastValidation_ = v;
|
||||
}
|
||||
|
||||
void
|
||||
ConsensusImp::newLCL (
|
||||
int proposers,
|
||||
int convergeTime,
|
||||
uint256 const& ledgerHash)
|
||||
{
|
||||
lastCloseProposers_ = proposers;
|
||||
lastCloseConvergeTook_ = convergeTime;
|
||||
lastCloseHash_ = ledgerHash;
|
||||
}
|
||||
|
||||
std::uint32_t
|
||||
ConsensusImp::validationTimestamp (std::uint32_t vt)
|
||||
{
|
||||
if (vt <= lastValidationTimestamp_)
|
||||
vt = lastValidationTimestamp_ + 1;
|
||||
|
||||
lastValidationTimestamp_ = vt;
|
||||
return vt;
|
||||
}
|
||||
|
||||
std::uint32_t
|
||||
ConsensusImp::getLastCloseTime () const
|
||||
{
|
||||
return lastCloseTime_;
|
||||
}
|
||||
|
||||
void
|
||||
ConsensusImp::setLastCloseTime (std::uint32_t t)
|
||||
{
|
||||
lastCloseTime_ = t;
|
||||
}
|
||||
|
||||
void
|
||||
ConsensusImp::storeProposal (
|
||||
LedgerProposal::ref proposal,
|
||||
RippleAddress const& peerPublic)
|
||||
{
|
||||
auto& props = storedProposals_[peerPublic.getNodeID ()];
|
||||
|
||||
if (props.size () >= (unsigned) (getLastCloseProposers () + 10))
|
||||
props.pop_front ();
|
||||
|
||||
props.push_back (proposal);
|
||||
}
|
||||
|
||||
// Must be called while holding the master lock
|
||||
void
|
||||
ConsensusImp::takePosition (int seq, std::shared_ptr<SHAMap> const& position)
|
||||
{
|
||||
recentPositions_[position->getHash ()] = std::make_pair (seq, position);
|
||||
|
||||
if (recentPositions_.size () > 4)
|
||||
{
|
||||
for (auto i = recentPositions_.begin (); i != recentPositions_.end ();)
|
||||
{
|
||||
if (i->second.first < (seq - 2))
|
||||
{
|
||||
recentPositions_.erase (i);
|
||||
return;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Consensus::Proposals&
|
||||
ConsensusImp::peekStoredProposals ()
|
||||
{
|
||||
return storedProposals_;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
std::unique_ptr<Consensus>
|
||||
make_Consensus ()
|
||||
{
|
||||
return std::make_unique<ConsensusImp> ();
|
||||
}
|
||||
|
||||
}
|
||||
131
src/ripple/app/ledger/impl/ConsensusImp.h
Normal file
131
src/ripple/app/ledger/impl/ConsensusImp.h
Normal file
@@ -0,0 +1,131 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_APP_LEDGER_IMPL_CONSENSUSIMP_H_INCLUDED
|
||||
#define RIPPLE_APP_LEDGER_IMPL_CONSENSUSIMP_H_INCLUDED
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/ledger/Consensus.h>
|
||||
#include <ripple/app/ledger/LedgerConsensus.h>
|
||||
#include <ripple/app/misc/FeeVote.h>
|
||||
#include <ripple/protocol/STValidation.h>
|
||||
#include <ripple/shamap/SHAMap.h>
|
||||
#include <beast/utility/Journal.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Implements the consensus process and provides inter-round state. */
|
||||
class ConsensusImp
|
||||
: public Consensus
|
||||
{
|
||||
public:
|
||||
ConsensusImp ();
|
||||
|
||||
~ConsensusImp () = default;
|
||||
|
||||
bool
|
||||
isProposing () const override;
|
||||
|
||||
bool
|
||||
isValidating () const override;
|
||||
|
||||
int
|
||||
getLastCloseProposers () const override;
|
||||
|
||||
int
|
||||
getLastCloseDuration () const override;
|
||||
|
||||
std::shared_ptr<LedgerConsensus>
|
||||
startRound (
|
||||
InboundTransactions& inboundTransactions,
|
||||
LocalTxs& localtx,
|
||||
LedgerMaster& ledgerMaster,
|
||||
LedgerHash const &prevLCLHash,
|
||||
Ledger::ref previousLedger,
|
||||
std::uint32_t closeTime) override;
|
||||
|
||||
void
|
||||
setLastCloseTime (std::uint32_t t) override;
|
||||
|
||||
void
|
||||
storeProposal (
|
||||
LedgerProposal::ref proposal,
|
||||
RippleAddress const& peerPublic) override;
|
||||
|
||||
void
|
||||
setProposing (bool p, bool v);
|
||||
|
||||
STValidation::ref
|
||||
getLastValidation () const;
|
||||
|
||||
void
|
||||
setLastValidation (STValidation::ref v);
|
||||
|
||||
void
|
||||
newLCL (
|
||||
int proposers,
|
||||
int convergeTime,
|
||||
uint256 const& ledgerHash);
|
||||
|
||||
std::uint32_t
|
||||
validationTimestamp (std::uint32_t vt);
|
||||
|
||||
std::uint32_t
|
||||
getLastCloseTime () const;
|
||||
|
||||
void takePosition (int seq, std::shared_ptr<SHAMap> const& position);
|
||||
|
||||
Consensus::Proposals&
|
||||
peekStoredProposals ();
|
||||
|
||||
private:
|
||||
beast::Journal journal_;
|
||||
std::unique_ptr <FeeVote> feeVote_;
|
||||
|
||||
bool proposing_;
|
||||
bool validating_;
|
||||
|
||||
// A pointer to the last validation that we issued
|
||||
STValidation::pointer lastValidation_;
|
||||
|
||||
// The number of proposers who participated in the last ledger close
|
||||
int lastCloseProposers_;
|
||||
|
||||
// How long the last ledger close took, in milliseconds
|
||||
int lastCloseConvergeTook_;
|
||||
|
||||
// The hash of the last closed ledger
|
||||
uint256 lastCloseHash_;
|
||||
|
||||
// The timestamp of the last validation we used, in network time. This is
|
||||
// only used for our own validations.
|
||||
std::uint32_t lastValidationTimestamp_;
|
||||
|
||||
// The last close time
|
||||
std::uint32_t lastCloseTime_;
|
||||
|
||||
// Recent positions taken
|
||||
std::map<uint256, std::pair<int, std::shared_ptr<SHAMap>>> recentPositions_;
|
||||
|
||||
Consensus::Proposals storedProposals_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -38,8 +38,6 @@ namespace ripple {
|
||||
class DisputedTx
|
||||
{
|
||||
public:
|
||||
using pointer = std::shared_ptr <DisputedTx>;
|
||||
|
||||
// VFALCO `Blob` is a poor choice of parameter
|
||||
DisputedTx (uint256 const& txID,
|
||||
Blob const& tx, bool ourVote)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1875
src/ripple/app/ledger/impl/LedgerConsensusImp.cpp
Normal file
1875
src/ripple/app/ledger/impl/LedgerConsensusImp.cpp
Normal file
File diff suppressed because it is too large
Load Diff
351
src/ripple/app/ledger/impl/LedgerConsensusImp.h
Normal file
351
src/ripple/app/ledger/impl/LedgerConsensusImp.h
Normal file
@@ -0,0 +1,351 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_APP_LEDGER_IMPL_LEDGERCONSENSUSIMP_H_INCLUDED
|
||||
#define RIPPLE_APP_LEDGER_IMPL_LEDGERCONSENSUSIMP_H_INCLUDED
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/ledger/LedgerMaster.h>
|
||||
#include <ripple/app/ledger/impl/ConsensusImp.h>
|
||||
#include <ripple/app/ledger/impl/DisputedTx.h>
|
||||
#include <ripple/app/misc/CanonicalTXSet.h>
|
||||
#include <ripple/app/misc/FeeVote.h>
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/protocol/STValidation.h>
|
||||
#include <ripple/protocol/UintTypes.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/**
|
||||
Provides the implementation for LedgerConsensus.
|
||||
|
||||
Achieves consensus on the next ledger.
|
||||
This object is created when the consensus process starts, and
|
||||
is destroyed when the process is complete.
|
||||
|
||||
Nearly everything herein is invoked with the master lock.
|
||||
|
||||
Two things need consensus:
|
||||
1. The set of transactions.
|
||||
2. The close time for the ledger.
|
||||
*/
|
||||
class LedgerConsensusImp
|
||||
: public LedgerConsensus
|
||||
, public std::enable_shared_from_this <LedgerConsensusImp>
|
||||
, public CountedObject <LedgerConsensusImp>
|
||||
{
|
||||
private:
|
||||
enum class State
|
||||
{
|
||||
// We haven't closed our ledger yet, but others might have
|
||||
open,
|
||||
|
||||
// Establishing consensus
|
||||
establish,
|
||||
|
||||
// We have closed on a transaction set
|
||||
finished,
|
||||
|
||||
// We have accepted / validated a new last closed ledger
|
||||
accepted,
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* The result of applying a transaction to a ledger.
|
||||
*/
|
||||
enum {resultSuccess, resultFail, resultRetry};
|
||||
|
||||
static char const* getCountedObjectName () { return "LedgerConsensus"; }
|
||||
|
||||
LedgerConsensusImp(LedgerConsensusImp const&) = delete;
|
||||
LedgerConsensusImp& operator=(LedgerConsensusImp const&) = delete;
|
||||
|
||||
~LedgerConsensusImp () = default;
|
||||
|
||||
/**
|
||||
@param previousProposers the number of participants in the last round
|
||||
@param previousConvergeTime how long the last round took (ms)
|
||||
@param inboundTransactions
|
||||
@param localtx transactions issued by local clients
|
||||
@param inboundTransactions the set of
|
||||
@param localtx A set of local transactions to apply
|
||||
@param prevLCLHash The hash of the Last Closed Ledger (LCL).
|
||||
@param previousLedger Best guess of what the LCL was.
|
||||
@param closeTime Closing time point of the LCL.
|
||||
@param feeVote Our desired fee levels and voting logic.
|
||||
*/
|
||||
LedgerConsensusImp (
|
||||
ConsensusImp& consensus,
|
||||
int previousProposers,
|
||||
int previousConvergeTime,
|
||||
InboundTransactions& inboundTransactions,
|
||||
LocalTxs& localtx,
|
||||
LedgerMaster& ledgerMaster,
|
||||
LedgerHash const & prevLCLHash,
|
||||
Ledger::ref previousLedger,
|
||||
std::uint32_t closeTime,
|
||||
FeeVote& feeVote);
|
||||
|
||||
/**
|
||||
Get the Json state of the consensus process.
|
||||
Called by the consensus_info RPC.
|
||||
|
||||
@param full True if verbose response desired.
|
||||
@return The Json state.
|
||||
*/
|
||||
Json::Value getJson (bool full) override;
|
||||
|
||||
/* The hash of the last closed ledger */
|
||||
uint256 getLCL () override;
|
||||
|
||||
/**
|
||||
We have a complete transaction set, typically acquired from the network
|
||||
|
||||
@param hash hash of the transaction set.
|
||||
@param map the transaction set.
|
||||
@param acquired true if we have acquired the transaction set.
|
||||
*/
|
||||
void mapComplete (
|
||||
uint256 const& hash,
|
||||
std::shared_ptr<SHAMap> const& map,
|
||||
bool acquired) override;
|
||||
|
||||
/**
|
||||
Check if our last closed ledger matches the network's.
|
||||
This tells us if we are still in sync with the network.
|
||||
This also helps us if we enter the consensus round with
|
||||
the wrong ledger, to leave it with the correct ledger so
|
||||
that we can participate in the next round.
|
||||
*/
|
||||
void checkLCL ();
|
||||
|
||||
/**
|
||||
Change our view of the last closed ledger
|
||||
|
||||
@param lclHash Hash of the last closed ledger.
|
||||
*/
|
||||
void handleLCL (uint256 const& lclHash);
|
||||
|
||||
/**
|
||||
On timer call the correct handler for each state.
|
||||
*/
|
||||
void timerEntry () override;
|
||||
|
||||
/**
|
||||
Handle pre-close state.
|
||||
*/
|
||||
void statePreClose ();
|
||||
|
||||
/** We are establishing a consensus
|
||||
Update our position only on the timer, and in this state.
|
||||
If we have consensus, move to the finish state
|
||||
*/
|
||||
void stateEstablish ();
|
||||
|
||||
void stateFinished ();
|
||||
|
||||
void stateAccepted ();
|
||||
|
||||
/** Check if we've reached consensus */
|
||||
bool haveConsensus ();
|
||||
|
||||
std::shared_ptr<SHAMap> getTransactionTree (uint256 const& hash);
|
||||
|
||||
/**
|
||||
A server has taken a new position, adjust our tracking
|
||||
Called when a peer takes a new postion.
|
||||
|
||||
@param newPosition the new position
|
||||
@return true if we should do delayed relay of this position.
|
||||
*/
|
||||
bool peerPosition (LedgerProposal::ref newPosition) override;
|
||||
|
||||
void simulate () override;
|
||||
|
||||
private:
|
||||
/**
|
||||
We have a complete transaction set, typically acquired from the network
|
||||
|
||||
@param hash hash of the transaction set.
|
||||
@param map the transaction set.
|
||||
@param acquired true if we have acquired the transaction set.
|
||||
*/
|
||||
void mapCompleteInternal (
|
||||
uint256 const& hash,
|
||||
std::shared_ptr<SHAMap> const& map,
|
||||
bool acquired);
|
||||
|
||||
/** We have a new last closed ledger, process it. Final accept logic
|
||||
|
||||
@param set Our consensus set
|
||||
*/
|
||||
void accept (std::shared_ptr<SHAMap> set);
|
||||
|
||||
/**
|
||||
Compare two proposed transaction sets and create disputed
|
||||
transctions structures for any mismatches
|
||||
|
||||
@param m1 One transaction set
|
||||
@param m2 The other transaction set
|
||||
*/
|
||||
void createDisputes (std::shared_ptr<SHAMap> const& m1,
|
||||
std::shared_ptr<SHAMap> const& m2);
|
||||
|
||||
/**
|
||||
Add a disputed transaction (one that at least one node wants
|
||||
in the consensus set and at least one node does not) to our tracking
|
||||
|
||||
@param txID The ID of the disputed transaction
|
||||
@param tx The data of the disputed transaction
|
||||
*/
|
||||
void addDisputedTransaction (uint256 const& txID, Blob const& tx);
|
||||
|
||||
/**
|
||||
Adjust the votes on all disputed transactions based
|
||||
on the set of peers taking this position
|
||||
|
||||
@param map A disputed position
|
||||
@param peers peers which are taking the position map
|
||||
*/
|
||||
void adjustCount (std::shared_ptr<SHAMap> const& map,
|
||||
const std::vector<NodeID>& peers);
|
||||
|
||||
/**
|
||||
Revoke our outstanding proposal, if any, and
|
||||
cease proposing at least until this round ends
|
||||
*/
|
||||
void leaveConsensus ();
|
||||
|
||||
/** Make and send a proposal
|
||||
*/
|
||||
void propose ();
|
||||
|
||||
/** Let peers know that we a particular transactions set so they
|
||||
can fetch it from us.
|
||||
|
||||
@param hash The ID of the transaction.
|
||||
@param direct true if we have this transaction set locally, else a
|
||||
directly connected peer has it.
|
||||
*/
|
||||
void sendHaveTxSet (uint256 const& hash, bool direct);
|
||||
|
||||
/** Send a node status change message to our directly connected peers
|
||||
|
||||
@param event The event which caused the status change. This is
|
||||
typically neACCEPTED_LEDGER or neCLOSING_LEDGER.
|
||||
@param ledger The ledger associated with the event.
|
||||
*/
|
||||
void statusChange (protocol::NodeEvent event, Ledger& ledger);
|
||||
|
||||
/** Take an initial position on what we think the consensus should be
|
||||
based on the transactions that made it into our open ledger
|
||||
|
||||
@param initialLedger The ledger that contains our initial position.
|
||||
*/
|
||||
void takeInitialPosition (Ledger& initialLedger);
|
||||
|
||||
/**
|
||||
Called while trying to avalanche towards consensus.
|
||||
Adjusts our positions to try to agree with other validators.
|
||||
*/
|
||||
void updateOurPositions ();
|
||||
|
||||
/** If we radically changed our consensus context for some reason,
|
||||
we need to replay recent proposals so that they're not lost.
|
||||
*/
|
||||
void playbackProposals ();
|
||||
|
||||
/** We have just decided to close the ledger. Start the consensus timer,
|
||||
stash the close time, inform peers, and take a position
|
||||
*/
|
||||
void closeLedger ();
|
||||
|
||||
/**
|
||||
If we missed a consensus round, we may be missing a validation.
|
||||
This will send an older owed validation if we previously missed it.
|
||||
*/
|
||||
void checkOurValidation ();
|
||||
|
||||
/** We have a new LCL and must accept it */
|
||||
void beginAccept (bool synchronous);
|
||||
|
||||
void endConsensus ();
|
||||
|
||||
/** Add our load fee to our validation */
|
||||
void addLoad(STValidation::ref val);
|
||||
|
||||
private:
|
||||
ConsensusImp& consensus_;
|
||||
InboundTransactions& inboundTransactions_;
|
||||
LocalTxs& m_localTX;
|
||||
LedgerMaster& ledgerMaster_;
|
||||
FeeVote& m_feeVote;
|
||||
|
||||
State state_;
|
||||
std::uint32_t mCloseTime; // The wall time this ledger closed
|
||||
uint256 mPrevLedgerHash, mNewLedgerHash, mAcquiringLedger;
|
||||
Ledger::pointer mPreviousLedger;
|
||||
LedgerProposal::pointer mOurPosition;
|
||||
RippleAddress mValPublic, mValPrivate;
|
||||
bool mProposing, mValidating, mHaveCorrectLCL, mConsensusFail;
|
||||
|
||||
int mCurrentMSeconds;
|
||||
|
||||
// How long the close has taken, expressed as a percentage of the time that
|
||||
// we expected it to take.
|
||||
int mClosePercent;
|
||||
|
||||
int mCloseResolution;
|
||||
|
||||
bool mHaveCloseTimeConsensus;
|
||||
|
||||
std::chrono::steady_clock::time_point mConsensusStartTime;
|
||||
int mPreviousProposers;
|
||||
|
||||
// The time it took for the last consensus process to converge
|
||||
int mPreviousMSeconds;
|
||||
|
||||
// Convergence tracking, trusted peers indexed by hash of public key
|
||||
hash_map<NodeID, LedgerProposal::pointer> mPeerPositions;
|
||||
|
||||
// Transaction Sets, indexed by hash of transaction tree
|
||||
hash_map<uint256, std::shared_ptr<SHAMap>> mAcquired;
|
||||
|
||||
// Disputed transactions
|
||||
hash_map<uint256, std::shared_ptr <DisputedTx>> mDisputes;
|
||||
hash_set<uint256> mCompares;
|
||||
|
||||
// Close time estimates
|
||||
std::map<std::uint32_t, int> mCloseTimes;
|
||||
|
||||
// nodes that have bowed out of this consensus process
|
||||
hash_set<NodeID> mDeadNodes;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::shared_ptr <LedgerConsensus>
|
||||
make_LedgerConsensus (ConsensusImp& consensus, int previousProposers,
|
||||
int previousConvergeTime, InboundTransactions& inboundTransactions,
|
||||
LocalTxs& localtx, LedgerMaster& ledgerMaster, LedgerHash const &prevLCLHash,
|
||||
Ledger::ref previousLedger, std::uint32_t closeTime, FeeVote& feeVote);
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
@@ -397,13 +397,6 @@ public:
|
||||
mBuildingLedgerSeq.store (i);
|
||||
}
|
||||
|
||||
bool haveLedgerRange (std::uint32_t from, std::uint32_t to)
|
||||
{
|
||||
ScopedLockType sl (mCompleteLock);
|
||||
std::uint32_t prevMissing = mCompleteLedgers.prevMissing (to + 1);
|
||||
return (prevMissing == RangeSet::absent) || (prevMissing < from);
|
||||
}
|
||||
|
||||
bool haveLedger (std::uint32_t seq)
|
||||
{
|
||||
ScopedLockType sl (mCompleteLock);
|
||||
|
||||
@@ -25,125 +25,6 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
bool shouldCloseLedger (
|
||||
bool anyTransactions,
|
||||
int previousProposers,
|
||||
int proposersClosed,
|
||||
int proposersValidated,
|
||||
int previousMSeconds,
|
||||
int currentMSeconds,
|
||||
int openMSeconds,
|
||||
int idleInterval)
|
||||
{
|
||||
if ((previousMSeconds < -1000) || (previousMSeconds > 600000) ||
|
||||
(currentMSeconds < -1000) || (currentMSeconds > 600000))
|
||||
{
|
||||
WriteLog (lsWARNING, LedgerTiming) <<
|
||||
"shouldCloseLedger Trans=" << (anyTransactions ? "yes" : "no") <<
|
||||
" Prop: " << previousProposers << "/" << proposersClosed <<
|
||||
" Secs: " << currentMSeconds << " (last: " << previousMSeconds << ")";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!anyTransactions)
|
||||
{
|
||||
// did we miss a transaction?
|
||||
if (proposersClosed > (previousProposers / 4))
|
||||
{
|
||||
WriteLog (lsTRACE, LedgerTiming) <<
|
||||
"no transactions, many proposers: now (" << proposersClosed <<
|
||||
" closed, " << previousProposers << " before)";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Only close if we have idled for too long.
|
||||
return currentMSeconds >= (idleInterval * 1000); // normal idle
|
||||
}
|
||||
|
||||
// If we have any transactions, we don't want to close too frequently:
|
||||
if (openMSeconds < LEDGER_MIN_CLOSE)
|
||||
{
|
||||
if ((proposersClosed + proposersValidated) < (previousProposers / 2 ))
|
||||
{
|
||||
WriteLog (lsDEBUG, LedgerTiming) <<
|
||||
"Must wait minimum time before closing";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentMSeconds < previousMSeconds)
|
||||
{
|
||||
if ((proposersClosed + proposersValidated) < previousProposers)
|
||||
{
|
||||
WriteLog (lsDEBUG, LedgerTiming) <<
|
||||
"We are waiting for more closes/validations";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
checkConsensusReached (int agreeing, int proposing)
|
||||
{
|
||||
int currentPercentage = (agreeing * 100) / (proposing + 1);
|
||||
|
||||
return currentPercentage > minimumConsensusPercentage;
|
||||
}
|
||||
|
||||
ConsensusState checkConsensus (
|
||||
int previousProposers,
|
||||
int currentProposers,
|
||||
int currentAgree,
|
||||
int currentFinished,
|
||||
int previousAgreeTime,
|
||||
int currentAgreeTime)
|
||||
{
|
||||
WriteLog (lsTRACE, LedgerTiming) <<
|
||||
"checkConsensus: prop=" << currentProposers <<
|
||||
"/" << previousProposers <<
|
||||
" agree=" << currentAgree << " validated=" << currentFinished <<
|
||||
" time=" << currentAgreeTime << "/" << previousAgreeTime;
|
||||
|
||||
if (currentAgreeTime <= LEDGER_MIN_CONSENSUS)
|
||||
return ConsensusState::No;
|
||||
|
||||
if (currentProposers < (previousProposers * 3 / 4))
|
||||
{
|
||||
// Less than 3/4 of the last ledger's proposers are present; don't
|
||||
// rush: we may need more time.
|
||||
if (currentAgreeTime < (previousAgreeTime + LEDGER_MIN_CONSENSUS))
|
||||
{
|
||||
WriteLog (lsTRACE, LedgerTiming) <<
|
||||
"too fast, not enough proposers";
|
||||
return ConsensusState::No;
|
||||
}
|
||||
}
|
||||
|
||||
// Have we, together with the nodes on our UNL list, reached the treshold
|
||||
// to declare consensus?
|
||||
if (checkConsensusReached (currentAgree + 1, currentProposers))
|
||||
{
|
||||
WriteLog (lsDEBUG, LedgerTiming) << "normal consensus";
|
||||
return ConsensusState::Yes;
|
||||
}
|
||||
|
||||
// Have sufficient nodes on our UNL list moved on and reached the threshold
|
||||
// to declare consensus?
|
||||
if (checkConsensusReached (currentFinished, currentProposers))
|
||||
{
|
||||
WriteLog (lsWARNING, LedgerTiming) <<
|
||||
"We see no consensus, but 80% of nodes have moved on";
|
||||
return ConsensusState::MovedOn;
|
||||
}
|
||||
|
||||
// no consensus yet
|
||||
WriteLog (lsTRACE, LedgerTiming) << "no consensus";
|
||||
return ConsensusState::No;
|
||||
}
|
||||
|
||||
int getNextLedgerTimeResolution (
|
||||
int previousResolution,
|
||||
bool previousAgree,
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/protocol/Quality.h>
|
||||
#include <ripple/app/ledger/LedgerConsensus.h>
|
||||
#include <ripple/core/DatabaseCon.h>
|
||||
#include <ripple/app/main/Application.h>
|
||||
#include <ripple/app/misc/FeeVote.h>
|
||||
#include <ripple/app/ledger/Consensus.h>
|
||||
#include <ripple/app/ledger/LedgerConsensus.h>
|
||||
#include <ripple/app/ledger/AcceptedLedger.h>
|
||||
#include <ripple/ledger/CachedView.h>
|
||||
#include <ripple/app/ledger/InboundLedger.h>
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <ripple/app/misc/Validations.h>
|
||||
#include <ripple/app/misc/impl/AccountTxPaging.h>
|
||||
#include <ripple/app/misc/UniqueNodeList.h>
|
||||
#include <ripple/app/tx/TransactionEngine.h>
|
||||
#include <ripple/app/tx/TransactionMaster.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/basics/Time.h>
|
||||
@@ -119,22 +120,15 @@ public:
|
||||
: NetworkOPs (parent)
|
||||
, m_clock (clock)
|
||||
, m_journal (journal)
|
||||
, m_localTX (LocalTxs::New ())
|
||||
, m_feeVote (make_FeeVote (setup_FeeVote (getConfig().section ("voting")),
|
||||
deprecatedLogs().journal("FeeVote")))
|
||||
, m_localTX (make_LocalTxs ())
|
||||
, mMode (omDISCONNECTED)
|
||||
, mNeedNetworkLedger (false)
|
||||
, mProposing (false)
|
||||
, mValidating (false)
|
||||
, m_amendmentBlocked (false)
|
||||
, m_heartbeatTimer (this)
|
||||
, m_clusterTimer (this)
|
||||
, mConsensus (make_Consensus ())
|
||||
, m_ledgerMaster (ledgerMaster)
|
||||
, mCloseTimeOffset (0)
|
||||
, lastCloseProposers_ (0)
|
||||
, lastCloseConvergeTook_ (1000 * LEDGER_IDLE_INTERVAL)
|
||||
, mLastCloseTime (0)
|
||||
, mLastValidationTime (0)
|
||||
, mFetchPack ("FetchPack", 65536, 45, clock,
|
||||
deprecatedLogs().journal("TaggedCache"))
|
||||
, mFetchSeq (0)
|
||||
@@ -157,14 +151,14 @@ public:
|
||||
private:
|
||||
std::uint32_t getCloseTimeNC (int& offset) const;
|
||||
|
||||
bool isValidated (std::uint32_t seq, uint256 const& hash) /*override*/;
|
||||
|
||||
public:
|
||||
// Use *only* to timestamp our own validation.
|
||||
std::uint32_t getValidationTimeNC () override;
|
||||
void closeTimeOffset (int) override;
|
||||
|
||||
/** On return the offset param holds the System time offset in seconds.
|
||||
*/
|
||||
boost::posix_time::ptime getNetworkTimePT(int& offset) const override;
|
||||
boost::posix_time::ptime getNetworkTimePT(int& offset) const;
|
||||
std::uint32_t getLedgerID (uint256 const& hash) override;
|
||||
std::uint32_t getCurrentLedgerID () override;
|
||||
OperatingMode getOperatingMode () const override
|
||||
@@ -181,10 +175,6 @@ public:
|
||||
{
|
||||
return m_ledgerMaster.getValidatedLedger ();
|
||||
}
|
||||
Ledger::pointer getPublishedLedger () override
|
||||
{
|
||||
return m_ledgerMaster.getPublishedLedger ();
|
||||
}
|
||||
Ledger::pointer getCurrentLedger () override
|
||||
{
|
||||
return m_ledgerMaster.getCurrentLedger ();
|
||||
@@ -202,11 +192,9 @@ public:
|
||||
}
|
||||
|
||||
// Do we have this inclusive range of ledgers in our database
|
||||
bool haveLedgerRange (std::uint32_t from, std::uint32_t to) override;
|
||||
bool haveLedger (std::uint32_t seq) override;
|
||||
std::uint32_t getValidatedSeq () override;
|
||||
bool isValidated (std::uint32_t seq) override;
|
||||
bool isValidated (std::uint32_t seq, uint256 const& hash) override;
|
||||
|
||||
bool isValidated (Ledger::ref l) override
|
||||
{
|
||||
return isValidated (l->getLedgerSeq (), l->getHash ());
|
||||
@@ -216,20 +204,6 @@ public:
|
||||
{
|
||||
return m_ledgerMaster.getValidatedRange (minVal, maxVal);
|
||||
}
|
||||
bool getFullValidatedRange (
|
||||
std::uint32_t& minVal, std::uint32_t& maxVal) override
|
||||
{
|
||||
return m_ledgerMaster.getFullValidatedRange (minVal, maxVal);
|
||||
}
|
||||
|
||||
STValidation::ref getLastValidation () override
|
||||
{
|
||||
return mLastValidation;
|
||||
}
|
||||
void setLastValidation (STValidation::ref v) override
|
||||
{
|
||||
mLastValidation = v;
|
||||
}
|
||||
|
||||
//
|
||||
// Transaction operations.
|
||||
@@ -290,23 +264,6 @@ public:
|
||||
TransactionEngine& engine,
|
||||
std::vector<TransactionStatus>& transactions);
|
||||
|
||||
Transaction::pointer findTransactionByID (
|
||||
uint256 const& transactionID) override;
|
||||
|
||||
int findTransactionsByDestination (
|
||||
std::list<Transaction::pointer>&,
|
||||
RippleAddress const& destinationAccount,
|
||||
std::uint32_t startLedgerSeq, std::uint32_t endLedgerSeq,
|
||||
int maxTransactions) override;
|
||||
|
||||
//
|
||||
// Directory functions.
|
||||
//
|
||||
|
||||
STVector256 getDirNodeInfo (
|
||||
Ledger::ref lrLedger, uint256 const& uRootIndex,
|
||||
std::uint64_t& uNodePrevious, std::uint64_t& uNodeNext) override;
|
||||
|
||||
//
|
||||
// Owner functions.
|
||||
//
|
||||
@@ -330,8 +287,7 @@ public:
|
||||
|
||||
bool recvValidation (
|
||||
STValidation::ref val, std::string const& source) override;
|
||||
void takePosition (
|
||||
int seq, std::shared_ptr<SHAMap> const& position) override;
|
||||
|
||||
std::shared_ptr<SHAMap> getTXMap (uint256 const& hash);
|
||||
bool hasTXSet (
|
||||
const std::shared_ptr<Peer>& peer, uint256 const& set,
|
||||
@@ -378,8 +334,6 @@ public:
|
||||
*/
|
||||
void setStateTimer () override;
|
||||
|
||||
void newLCL (
|
||||
int proposers, int convergeTime, uint256 const& ledgerHash) override;
|
||||
void needNetworkLedger () override
|
||||
{
|
||||
mNeedNetworkLedger = true;
|
||||
@@ -396,44 +350,21 @@ public:
|
||||
{
|
||||
return !mNeedNetworkLedger && (mMode == omFULL);
|
||||
}
|
||||
void setProposing (bool p, bool v) override
|
||||
{
|
||||
mProposing = p;
|
||||
mValidating = v;
|
||||
}
|
||||
bool isProposing () override
|
||||
{
|
||||
return mProposing;
|
||||
}
|
||||
bool isValidating () override
|
||||
{
|
||||
return mValidating;
|
||||
}
|
||||
bool isAmendmentBlocked () override
|
||||
{
|
||||
return m_amendmentBlocked;
|
||||
}
|
||||
void setAmendmentBlocked () override;
|
||||
void consensusViewChange () override;
|
||||
std::uint32_t getLastCloseTime () override
|
||||
{
|
||||
return mLastCloseTime;
|
||||
}
|
||||
void setLastCloseTime (std::uint32_t t) override
|
||||
{
|
||||
mLastCloseTime = t;
|
||||
mConsensus->setLastCloseTime (t);
|
||||
}
|
||||
Json::Value getConsensusInfo () override;
|
||||
Json::Value getServerInfo (bool human, bool admin) override;
|
||||
void clearLedgerFetch () override;
|
||||
Json::Value getLedgerFetchInfo () override;
|
||||
std::uint32_t acceptLedger () override;
|
||||
Proposals & peekStoredProposals () override
|
||||
{
|
||||
return mStoredProposals;
|
||||
}
|
||||
void storeProposal (
|
||||
LedgerProposal::ref proposal, RippleAddress const& peerPublic) override;
|
||||
uint256 getConsensusLCL () override;
|
||||
void reportFeeChange () override;
|
||||
|
||||
@@ -441,11 +372,6 @@ public:
|
||||
{
|
||||
m_localTX->sweep (newValidLedger);
|
||||
}
|
||||
void addLocalTx (
|
||||
Ledger::ref openLedger, STTx::ref txn) override
|
||||
{
|
||||
m_localTX->push_back (openLedger->getLedgerSeq(), txn);
|
||||
}
|
||||
std::size_t getLocalTxCount () override
|
||||
{
|
||||
return m_localTX->size ();
|
||||
@@ -456,7 +382,7 @@ public:
|
||||
std::string selection, AccountID const& account,
|
||||
std::int32_t minLedger, std::int32_t maxLedger,
|
||||
bool descending, std::uint32_t offset, int limit,
|
||||
bool binary, bool count, bool bAdmin) override;
|
||||
bool binary, bool count, bool bAdmin);
|
||||
|
||||
// Client information retrieval functions.
|
||||
using NetworkOPs::AccountTxs;
|
||||
@@ -571,6 +497,7 @@ private:
|
||||
private:
|
||||
clock_type& m_clock;
|
||||
|
||||
using SubMapType = hash_map <std::uint64_t, InfoSub::wptr>;
|
||||
using SubInfoMapType = hash_map <AccountID, SubMapType>;
|
||||
using subRpcMapType = hash_map<std::string, InfoSub::pointer>;
|
||||
|
||||
@@ -581,44 +508,25 @@ private:
|
||||
beast::Journal m_journal;
|
||||
|
||||
std::unique_ptr <LocalTxs> m_localTX;
|
||||
std::unique_ptr <FeeVote> m_feeVote;
|
||||
|
||||
LockType mSubLock;
|
||||
|
||||
std::atomic<OperatingMode> mMode;
|
||||
|
||||
std::atomic <bool> mNeedNetworkLedger;
|
||||
bool mProposing;
|
||||
bool mValidating;
|
||||
bool m_amendmentBlocked;
|
||||
|
||||
beast::DeadlineTimer m_heartbeatTimer;
|
||||
beast::DeadlineTimer m_clusterTimer;
|
||||
|
||||
std::shared_ptr<LedgerConsensus> mConsensus;
|
||||
NetworkOPs::Proposals mStoredProposals;
|
||||
std::unique_ptr<Consensus> mConsensus;
|
||||
std::shared_ptr<LedgerConsensus> mLedgerConsensus;
|
||||
|
||||
LedgerMaster& m_ledgerMaster;
|
||||
InboundLedger::pointer mAcquiringLedger;
|
||||
|
||||
int mCloseTimeOffset;
|
||||
|
||||
// The number of proposers who participated in the last ledger close
|
||||
int lastCloseProposers_;
|
||||
|
||||
// How long the last ledger close took, in milliseconds
|
||||
int lastCloseConvergeTook_;
|
||||
|
||||
// The hash of the last closed ledger
|
||||
uint256 lastCloseHash_;
|
||||
|
||||
std::uint32_t mLastCloseTime;
|
||||
std::uint32_t mLastValidationTime;
|
||||
STValidation::pointer mLastValidation;
|
||||
|
||||
// Recent positions taken
|
||||
std::map<uint256, std::pair<int, std::shared_ptr<SHAMap>>> mRecentPositions;
|
||||
|
||||
SubInfoMapType mSubAccount;
|
||||
SubInfoMapType mSubRTAccount;
|
||||
|
||||
@@ -736,11 +644,11 @@ void NetworkOPsImp::processHeartbeatTimer ()
|
||||
else if (mMode == omCONNECTED)
|
||||
setMode (omCONNECTED);
|
||||
|
||||
if (!mConsensus)
|
||||
if (!mLedgerConsensus)
|
||||
tryStartConsensus ();
|
||||
|
||||
if (mConsensus)
|
||||
mConsensus->timerEntry ();
|
||||
if (mLedgerConsensus)
|
||||
mLedgerConsensus->timerEntry ();
|
||||
}
|
||||
|
||||
setHeartbeatTimer ();
|
||||
@@ -800,10 +708,10 @@ std::string NetworkOPsImp::strOperatingMode () const
|
||||
|
||||
if (mMode == omFULL)
|
||||
{
|
||||
if (mProposing)
|
||||
if (mConsensus->isProposing ())
|
||||
return "proposing";
|
||||
|
||||
if (mValidating)
|
||||
if (mConsensus->isValidating ())
|
||||
return "validating";
|
||||
}
|
||||
|
||||
@@ -832,8 +740,7 @@ std::uint32_t NetworkOPsImp::getNetworkTimeNC () const
|
||||
std::uint32_t NetworkOPsImp::getCloseTimeNC () const
|
||||
{
|
||||
int offset;
|
||||
return iToSeconds (getNetworkTimePT (offset) +
|
||||
boost::posix_time::seconds (mCloseTimeOffset));
|
||||
return getCloseTimeNC (offset);
|
||||
}
|
||||
|
||||
std::uint32_t NetworkOPsImp::getCloseTimeNC (int& offset) const
|
||||
@@ -842,17 +749,6 @@ std::uint32_t NetworkOPsImp::getCloseTimeNC (int& offset) const
|
||||
boost::posix_time::seconds (mCloseTimeOffset));
|
||||
}
|
||||
|
||||
std::uint32_t NetworkOPsImp::getValidationTimeNC ()
|
||||
{
|
||||
std::uint32_t vt = getNetworkTimeNC ();
|
||||
|
||||
if (vt <= mLastValidationTime)
|
||||
vt = mLastValidationTime + 1;
|
||||
|
||||
mLastValidationTime = vt;
|
||||
return vt;
|
||||
}
|
||||
|
||||
void NetworkOPsImp::closeTimeOffset (int offset)
|
||||
{
|
||||
// take large offsets, ignore small offsets, push towards our wall time
|
||||
@@ -889,11 +785,6 @@ std::uint32_t NetworkOPsImp::getCurrentLedgerID ()
|
||||
return m_ledgerMaster.getCurrentLedger ()->getLedgerSeq ();
|
||||
}
|
||||
|
||||
bool NetworkOPsImp::haveLedgerRange (std::uint32_t from, std::uint32_t to)
|
||||
{
|
||||
return m_ledgerMaster.haveLedgerRange (from, to);
|
||||
}
|
||||
|
||||
bool NetworkOPsImp::haveLedger (std::uint32_t seq)
|
||||
{
|
||||
return m_ledgerMaster.haveLedger (seq);
|
||||
@@ -906,19 +797,15 @@ std::uint32_t NetworkOPsImp::getValidatedSeq ()
|
||||
|
||||
bool NetworkOPsImp::isValidated (std::uint32_t seq, uint256 const& hash)
|
||||
{
|
||||
if (!isValidated (seq))
|
||||
if (!haveLedger (seq))
|
||||
return false;
|
||||
|
||||
if (seq > m_ledgerMaster.getValidatedLedger ()->getLedgerSeq ())
|
||||
return false;
|
||||
|
||||
return m_ledgerMaster.getHashBySeq (seq) == hash;
|
||||
}
|
||||
|
||||
bool NetworkOPsImp::isValidated (std::uint32_t seq)
|
||||
{
|
||||
// use when ledger was retrieved by seq
|
||||
return haveLedger (seq) &&
|
||||
seq <= m_ledgerMaster.getValidatedLedger ()->getLedgerSeq ();
|
||||
}
|
||||
|
||||
void NetworkOPsImp::submitTransaction (Job&, STTx::pointer iTrans)
|
||||
{
|
||||
if (isNeedNetworkLedger ())
|
||||
@@ -1175,8 +1062,9 @@ void NetworkOPsImp::apply (std::unique_lock<std::mutex>& batchLock)
|
||||
|
||||
if (addLocal)
|
||||
{
|
||||
addLocalTx (m_ledgerMaster.getCurrentLedger(),
|
||||
e.transaction->getSTransaction());
|
||||
m_localTX->push_back (
|
||||
m_ledgerMaster.getCurrentLedgerIndex(),
|
||||
e.transaction->getSTransaction());
|
||||
}
|
||||
|
||||
if (e.applied ||
|
||||
@@ -1235,70 +1123,6 @@ bool NetworkOPsImp::batchApply (Ledger::pointer& ledger,
|
||||
return applied;
|
||||
}
|
||||
|
||||
Transaction::pointer NetworkOPsImp::findTransactionByID (
|
||||
uint256 const& transactionID)
|
||||
{
|
||||
return Transaction::load (transactionID);
|
||||
}
|
||||
|
||||
int NetworkOPsImp::findTransactionsByDestination (
|
||||
std::list<Transaction::pointer>& txns,
|
||||
RippleAddress const& destinationAccount, std::uint32_t startLedgerSeq,
|
||||
std::uint32_t endLedgerSeq, int maxTransactions)
|
||||
{
|
||||
// WRITEME
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Directory functions
|
||||
//
|
||||
|
||||
// <-- false : no entrieS
|
||||
STVector256 NetworkOPsImp::getDirNodeInfo (
|
||||
Ledger::ref lrLedger,
|
||||
uint256 const& uNodeIndex,
|
||||
std::uint64_t& uNodePrevious,
|
||||
std::uint64_t& uNodeNext)
|
||||
{
|
||||
STVector256 svIndexes;
|
||||
auto const sleNode = cachedRead(*lrLedger, uNodeIndex,
|
||||
getApp().getSLECache(), ltDIR_NODE);
|
||||
|
||||
if (sleNode)
|
||||
{
|
||||
m_journal.debug
|
||||
<< "getDirNodeInfo: node index: " << to_string (uNodeIndex);
|
||||
|
||||
m_journal.trace
|
||||
<< "getDirNodeInfo: first: "
|
||||
<< strHex (sleNode->getFieldU64 (sfIndexPrevious));
|
||||
m_journal.trace
|
||||
<< "getDirNodeInfo: last: "
|
||||
<< strHex (sleNode->getFieldU64 (sfIndexNext));
|
||||
|
||||
uNodePrevious = sleNode->getFieldU64 (sfIndexPrevious);
|
||||
uNodeNext = sleNode->getFieldU64 (sfIndexNext);
|
||||
svIndexes = sleNode->getFieldV256 (sfIndexes);
|
||||
|
||||
m_journal.trace
|
||||
<< "getDirNodeInfo: first: " << strHex (uNodePrevious);
|
||||
m_journal.trace
|
||||
<< "getDirNodeInfo: last: " << strHex (uNodeNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_journal.info
|
||||
<< "getDirNodeInfo: node index: NOT FOUND: "
|
||||
<< to_string (uNodeIndex);
|
||||
|
||||
uNodePrevious = 0;
|
||||
uNodeNext = 0;
|
||||
}
|
||||
|
||||
return svIndexes;
|
||||
}
|
||||
|
||||
//
|
||||
// Owner functions
|
||||
//
|
||||
@@ -1443,7 +1267,7 @@ void NetworkOPsImp::tryStartConsensus ()
|
||||
}
|
||||
}
|
||||
|
||||
if ((!mConsensus) && (mMode != omDISCONNECTED))
|
||||
if ((!mLedgerConsensus) && (mMode != omDISCONNECTED))
|
||||
beginConsensus (networkClosed, m_ledgerMaster.getCurrentLedger ());
|
||||
}
|
||||
|
||||
@@ -1640,18 +1464,16 @@ bool NetworkOPsImp::beginConsensus (
|
||||
m_ledgerMaster.getClosedLedger ()->getHash ());
|
||||
|
||||
// Create a consensus object to get consensus on this ledger
|
||||
assert (!mConsensus);
|
||||
assert (!mLedgerConsensus);
|
||||
prevLedger->setImmutable ();
|
||||
|
||||
mConsensus = make_LedgerConsensus (
|
||||
lastCloseProposers_,
|
||||
lastCloseConvergeTook_,
|
||||
mLedgerConsensus = mConsensus->startRound (
|
||||
getApp().getInboundTransactions(),
|
||||
*m_localTX,
|
||||
m_ledgerMaster,
|
||||
networkClosed,
|
||||
prevLedger,
|
||||
m_ledgerMaster.getCurrentLedger ()->getCloseTimeNC (),
|
||||
*m_feeVote);
|
||||
m_ledgerMaster.getCurrentLedger ()->getCloseTimeNC ());
|
||||
|
||||
m_journal.debug << "Initiating consensus engine";
|
||||
return true;
|
||||
@@ -1659,7 +1481,7 @@ bool NetworkOPsImp::beginConsensus (
|
||||
|
||||
bool NetworkOPsImp::haveConsensusObject ()
|
||||
{
|
||||
if (mConsensus != nullptr)
|
||||
if (mLedgerConsensus != nullptr)
|
||||
return true;
|
||||
|
||||
if ((mMode == omFULL) || (mMode == omTRACKING))
|
||||
@@ -1677,13 +1499,13 @@ bool NetworkOPsImp::haveConsensusObject ()
|
||||
{
|
||||
m_journal.info << "Beginning consensus due to peer action";
|
||||
if ( ((mMode == omTRACKING) || (mMode == omSYNCING)) &&
|
||||
(lastCloseProposers_ >= m_ledgerMaster.getMinValidations()) )
|
||||
(mConsensus->getLastCloseProposers() >= m_ledgerMaster.getMinValidations()) )
|
||||
setMode (omFULL);
|
||||
beginConsensus (networkClosed, m_ledgerMaster.getCurrentLedger ());
|
||||
}
|
||||
}
|
||||
|
||||
return mConsensus != nullptr;
|
||||
return mLedgerConsensus != nullptr;
|
||||
}
|
||||
|
||||
uint256 NetworkOPsImp::getConsensusLCL ()
|
||||
@@ -1691,7 +1513,7 @@ uint256 NetworkOPsImp::getConsensusLCL ()
|
||||
if (!haveConsensusObject ())
|
||||
return uint256 ();
|
||||
|
||||
return mConsensus->getLCL ();
|
||||
return mLedgerConsensus->getLCL ();
|
||||
}
|
||||
|
||||
void NetworkOPsImp::processTrustedProposal (
|
||||
@@ -1712,45 +1534,23 @@ void NetworkOPsImp::processTrustedProposal (
|
||||
}
|
||||
else
|
||||
{
|
||||
storeProposal (proposal, nodePublic);
|
||||
mConsensus->storeProposal (proposal, nodePublic);
|
||||
|
||||
if (mConsensus->getLCL () == proposal->getPrevLedger ())
|
||||
if (mLedgerConsensus->getLCL () == proposal->getPrevLedger ())
|
||||
{
|
||||
relay = mConsensus->peerPosition (proposal);
|
||||
relay = mLedgerConsensus->peerPosition (proposal);
|
||||
m_journal.trace
|
||||
<< "Proposal processing finished, relay=" << relay;
|
||||
}
|
||||
}
|
||||
|
||||
if (relay)
|
||||
getApp().overlay().relay(*set,
|
||||
proposal->getSuppressionID());
|
||||
getApp().overlay().relay(*set, proposal->getSuppressionID());
|
||||
else
|
||||
m_journal.info << "Not relaying trusted proposal";
|
||||
}
|
||||
}
|
||||
|
||||
// Must be called while holding the master lock
|
||||
void
|
||||
NetworkOPsImp::takePosition (int seq, std::shared_ptr<SHAMap> const& position)
|
||||
{
|
||||
mRecentPositions[position->getHash ()] = std::make_pair (seq, position);
|
||||
|
||||
if (mRecentPositions.size () > 4)
|
||||
{
|
||||
for (auto i = mRecentPositions.begin (); i != mRecentPositions.end ();)
|
||||
{
|
||||
if (i->second.first < (seq - 2))
|
||||
{
|
||||
mRecentPositions.erase (i);
|
||||
return;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NetworkOPsImp::mapComplete (uint256 const& hash,
|
||||
std::shared_ptr<SHAMap> const& map)
|
||||
@@ -1758,7 +1558,7 @@ NetworkOPsImp::mapComplete (uint256 const& hash,
|
||||
std::lock_guard<Application::MutexType> lock(getApp().getMasterMutex());
|
||||
|
||||
if (haveConsensusObject ())
|
||||
mConsensus->mapComplete (hash, map, true);
|
||||
mLedgerConsensus->mapComplete (hash, map, true);
|
||||
}
|
||||
|
||||
void NetworkOPsImp::endConsensus (bool correctLCL)
|
||||
@@ -1777,7 +1577,7 @@ void NetworkOPsImp::endConsensus (bool correctLCL)
|
||||
}
|
||||
}
|
||||
|
||||
mConsensus = std::shared_ptr<LedgerConsensus> ();
|
||||
mLedgerConsensus = std::shared_ptr<LedgerConsensus> ();
|
||||
}
|
||||
|
||||
void NetworkOPsImp::consensusViewChange ()
|
||||
@@ -1946,7 +1746,7 @@ NetworkOPs::AccountTxs NetworkOPsImp::getAccountTxs (
|
||||
// can be called with no locks
|
||||
AccountTxs ret;
|
||||
|
||||
std::string sql = NetworkOPsImp::transactionsSQL (
|
||||
std::string sql = transactionsSQL (
|
||||
"AccountTransactions.LedgerSeq,Status,RawTxn,TxnMeta", account,
|
||||
minLedger, maxLedger, descending, offset, limit, false, false, bAdmin);
|
||||
|
||||
@@ -2009,7 +1809,7 @@ std::vector<NetworkOPsImp::txnMetaLedgerType> NetworkOPsImp::getAccountTxsB (
|
||||
// can be called with no locks
|
||||
std::vector<txnMetaLedgerType> ret;
|
||||
|
||||
std::string sql = NetworkOPsImp::transactionsSQL (
|
||||
std::string sql = transactionsSQL (
|
||||
"AccountTransactions.LedgerSeq,Status,RawTxn,TxnMeta", account,
|
||||
minLedger, maxLedger, descending, offset, limit, true/*binary*/, false,
|
||||
bAdmin);
|
||||
@@ -2109,8 +1909,8 @@ bool NetworkOPsImp::recvValidation (
|
||||
|
||||
Json::Value NetworkOPsImp::getConsensusInfo ()
|
||||
{
|
||||
if (mConsensus)
|
||||
return mConsensus->getJson (true);
|
||||
if (mLedgerConsensus)
|
||||
return mLedgerConsensus->getJson (true);
|
||||
|
||||
Json::Value info = Json::objectValue;
|
||||
info[jss::consensus] = "none";
|
||||
@@ -2169,23 +1969,23 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin)
|
||||
info[jss::peers] = Json::UInt (getApp ().overlay ().size ());
|
||||
|
||||
Json::Value lastClose = Json::objectValue;
|
||||
lastClose[jss::proposers] = lastCloseProposers_;
|
||||
lastClose[jss::proposers] = mConsensus->getLastCloseProposers();
|
||||
|
||||
if (human)
|
||||
{
|
||||
lastClose[jss::converge_time_s] = static_cast<double> (
|
||||
lastCloseConvergeTook_) / 1000.0;
|
||||
mConsensus->getLastCloseDuration()) / 1000.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastClose[jss::converge_time] =
|
||||
Json::Int (lastCloseConvergeTook_);
|
||||
Json::Int (mConsensus->getLastCloseDuration());
|
||||
}
|
||||
|
||||
info[jss::last_close] = lastClose;
|
||||
|
||||
// if (mConsensus)
|
||||
// info[jss::consensus] = mConsensus->getJson();
|
||||
// if (mLedgerConsensus)
|
||||
// info[jss::consensus] = mLedgerConsensus->getJson();
|
||||
|
||||
if (admin)
|
||||
info[jss::load] = m_job_queue.getJson ();
|
||||
@@ -2279,7 +2079,7 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin)
|
||||
else
|
||||
info[jss::closed_ledger] = l;
|
||||
|
||||
Ledger::pointer lpPublished = getPublishedLedger ();
|
||||
Ledger::pointer lpPublished = m_ledgerMaster.getPublishedLedger ();
|
||||
if (!lpPublished)
|
||||
info[jss::published_ledger] = "none";
|
||||
else if (lpPublished->getLedgerSeq() != lpClosed->getLedgerSeq())
|
||||
@@ -2679,15 +2479,6 @@ bool NetworkOPsImp::unsubBook (std::uint64_t uSeq, Book const& book)
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetworkOPsImp::newLCL (
|
||||
int proposers, int convergeTime, uint256 const& ledgerHash)
|
||||
{
|
||||
assert (convergeTime);
|
||||
lastCloseProposers_ = proposers;
|
||||
lastCloseConvergeTook_ = convergeTime;
|
||||
lastCloseHash_ = ledgerHash;
|
||||
}
|
||||
|
||||
std::uint32_t NetworkOPsImp::acceptLedger ()
|
||||
{
|
||||
// This code-path is exclusively used when the server is in standalone
|
||||
@@ -2702,21 +2493,10 @@ std::uint32_t NetworkOPsImp::acceptLedger ()
|
||||
beginConsensus (
|
||||
m_ledgerMaster.getClosedLedger ()->getHash (),
|
||||
m_ledgerMaster.getCurrentLedger ());
|
||||
mConsensus->simulate ();
|
||||
mLedgerConsensus->simulate ();
|
||||
return m_ledgerMaster.getCurrentLedger ()->getLedgerSeq ();
|
||||
}
|
||||
|
||||
void NetworkOPsImp::storeProposal (
|
||||
LedgerProposal::ref proposal, RippleAddress const& peerPublic)
|
||||
{
|
||||
auto& props = mStoredProposals[peerPublic.getNodeID ()];
|
||||
|
||||
if (props.size () >= (unsigned) (lastCloseProposers_ + 10))
|
||||
props.pop_front ();
|
||||
|
||||
props.push_back (proposal);
|
||||
}
|
||||
|
||||
// <-- bool: true=added, false=already there
|
||||
bool NetworkOPsImp::subLedger (InfoSub::ref isrListener, Json::Value& jvResult)
|
||||
{
|
||||
|
||||
@@ -39,7 +39,6 @@ namespace ripple {
|
||||
// Master operational handler, server sequencer, network tracker
|
||||
|
||||
class Peer;
|
||||
class LedgerConsensus;
|
||||
class LedgerMaster;
|
||||
|
||||
// This is the primary interface into the "client" portion of the program.
|
||||
@@ -74,13 +73,6 @@ protected:
|
||||
public:
|
||||
using clock_type = beast::abstract_clock <std::chrono::steady_clock>;
|
||||
|
||||
enum Fault
|
||||
{
|
||||
// exceptions these functions can throw
|
||||
IO_ERROR = 1,
|
||||
NO_NETWORK = 2,
|
||||
};
|
||||
|
||||
enum OperatingMode
|
||||
{
|
||||
// how we process transactions or account balance requests
|
||||
@@ -101,10 +93,6 @@ public:
|
||||
return noMeansDont ? FailHard::yes : FailHard::no;
|
||||
}
|
||||
|
||||
// VFALCO TODO Fix OrderBookDB to not need this unrelated type.
|
||||
//
|
||||
using SubMapType = hash_map <std::uint64_t, InfoSub::wptr>;
|
||||
|
||||
public:
|
||||
virtual ~NetworkOPs () = 0;
|
||||
|
||||
@@ -117,10 +105,7 @@ public:
|
||||
virtual std::uint32_t getNetworkTimeNC () const = 0;
|
||||
// Our best estimate of current ledger close time
|
||||
virtual std::uint32_t getCloseTimeNC () const = 0;
|
||||
// Use *only* to timestamp our own validation
|
||||
virtual std::uint32_t getValidationTimeNC () = 0;
|
||||
virtual void closeTimeOffset (int) = 0;
|
||||
virtual boost::posix_time::ptime getNetworkTimePT (int& offset) const = 0;
|
||||
virtual std::uint32_t getLedgerID (uint256 const& hash) = 0;
|
||||
virtual std::uint32_t getCurrentLedgerID () = 0;
|
||||
|
||||
@@ -128,7 +113,6 @@ public:
|
||||
virtual std::string strOperatingMode () const = 0;
|
||||
virtual Ledger::pointer getClosedLedger () = 0;
|
||||
virtual Ledger::pointer getValidatedLedger () = 0;
|
||||
virtual Ledger::pointer getPublishedLedger () = 0;
|
||||
virtual Ledger::pointer getCurrentLedger () = 0;
|
||||
virtual Ledger::pointer getLedgerByHash (uint256 const& hash) = 0;
|
||||
virtual Ledger::pointer getLedgerBySeq (const std::uint32_t seq) = 0;
|
||||
@@ -137,17 +121,10 @@ public:
|
||||
virtual uint256 getClosedLedgerHash () = 0;
|
||||
|
||||
// Do we have this inclusive range of ledgers in our database
|
||||
virtual bool haveLedgerRange (std::uint32_t from, std::uint32_t to) = 0;
|
||||
virtual bool haveLedger (std::uint32_t seq) = 0;
|
||||
virtual std::uint32_t getValidatedSeq () = 0;
|
||||
virtual bool isValidated (std::uint32_t seq) = 0;
|
||||
virtual bool isValidated (std::uint32_t seq, uint256 const& hash) = 0;
|
||||
virtual bool isValidated (Ledger::ref l) = 0;
|
||||
virtual bool getValidatedRange (std::uint32_t& minVal, std::uint32_t& maxVal) = 0;
|
||||
virtual bool getFullValidatedRange (std::uint32_t& minVal, std::uint32_t& maxVal) = 0;
|
||||
|
||||
virtual STValidation::ref getLastValidation () = 0;
|
||||
virtual void setLastValidation (STValidation::ref v) = 0;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
@@ -155,8 +132,6 @@ public:
|
||||
//
|
||||
|
||||
// must complete immediately
|
||||
// VFALCO TODO Make this a TxCallback structure
|
||||
using stCallback = std::function<void (Transaction::pointer, TER)>;
|
||||
virtual void submitTransaction (Job&, STTx::pointer) = 0;
|
||||
|
||||
/**
|
||||
@@ -170,19 +145,6 @@ public:
|
||||
*/
|
||||
virtual void processTransaction (Transaction::pointer transaction,
|
||||
bool bAdmin, bool bLocal, FailHard failType) = 0;
|
||||
virtual Transaction::pointer findTransactionByID (uint256 const& transactionID) = 0;
|
||||
virtual int findTransactionsByDestination (std::list<Transaction::pointer>&,
|
||||
RippleAddress const& destinationAccount, std::uint32_t startLedgerSeq,
|
||||
std::uint32_t endLedgerSeq, int maxTransactions) = 0;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Directory functions
|
||||
//
|
||||
|
||||
virtual STVector256 getDirNodeInfo (Ledger::ref lrLedger,
|
||||
uint256 const& uRootIndex, std::uint64_t& uNodePrevious,
|
||||
std::uint64_t& uNodeNext) = 0;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
@@ -217,9 +179,6 @@ public:
|
||||
virtual bool recvValidation (STValidation::ref val,
|
||||
std::string const& source) = 0;
|
||||
|
||||
virtual void takePosition (int seq,
|
||||
std::shared_ptr<SHAMap> const& position) = 0;
|
||||
|
||||
virtual void mapComplete (uint256 const& hash,
|
||||
std::shared_ptr<SHAMap> const& map) = 0;
|
||||
|
||||
@@ -241,20 +200,16 @@ public:
|
||||
virtual void setStandAlone () = 0;
|
||||
virtual void setStateTimer () = 0;
|
||||
|
||||
virtual void newLCL (
|
||||
int proposers, int convergeTime, uint256 const& ledgerHash) = 0;
|
||||
// VFALCO TODO rename to setNeedNetworkLedger
|
||||
virtual void needNetworkLedger () = 0;
|
||||
virtual void clearNeedNetworkLedger () = 0;
|
||||
virtual bool isNeedNetworkLedger () = 0;
|
||||
virtual bool isFull () = 0;
|
||||
virtual void setProposing (bool isProposing, bool isValidating) = 0;
|
||||
virtual bool isProposing () = 0;
|
||||
virtual bool isValidating () = 0;
|
||||
virtual bool isAmendmentBlocked () = 0;
|
||||
virtual void setAmendmentBlocked () = 0;
|
||||
virtual void consensusViewChange () = 0;
|
||||
virtual std::uint32_t getLastCloseTime () = 0;
|
||||
|
||||
// FIXME(NIKB): Remove the need for this function
|
||||
virtual void setLastCloseTime (std::uint32_t t) = 0;
|
||||
|
||||
virtual Json::Value getConsensusInfo () = 0;
|
||||
@@ -270,26 +225,13 @@ public:
|
||||
*/
|
||||
virtual std::uint32_t acceptLedger () = 0;
|
||||
|
||||
using Proposals = hash_map <NodeID, std::deque<LedgerProposal::pointer>>;
|
||||
virtual Proposals& peekStoredProposals () = 0;
|
||||
|
||||
virtual void storeProposal (LedgerProposal::ref proposal,
|
||||
RippleAddress const& peerPublic) = 0;
|
||||
|
||||
virtual uint256 getConsensusLCL () = 0;
|
||||
|
||||
virtual void reportFeeChange () = 0;
|
||||
|
||||
virtual void updateLocalTx (Ledger::ref newValidLedger) = 0;
|
||||
virtual void addLocalTx (Ledger::ref openLedger, STTx::ref txn) = 0;
|
||||
virtual std::size_t getLocalTxCount () = 0;
|
||||
|
||||
//Helper function to generate SQL query to get transactions
|
||||
virtual std::string transactionsSQL (std::string selection,
|
||||
AccountID const& account, std::int32_t minLedger, std::int32_t maxLedger,
|
||||
bool descending, std::uint32_t offset, int limit, bool binary,
|
||||
bool count, bool bAdmin) = 0;
|
||||
|
||||
// client information retrieval functions
|
||||
using AccountTx = std::pair<Transaction::pointer, TransactionMetaSet::pointer>;
|
||||
using AccountTxs = std::vector<AccountTx>;
|
||||
|
||||
@@ -20,8 +20,9 @@
|
||||
#ifndef RIPPLE_APP_TX_LOCALTXS_H_INCLUDED
|
||||
#define RIPPLE_APP_TX_LOCALTXS_H_INCLUDED
|
||||
|
||||
#include <ripple/app/tx/TransactionEngine.h>
|
||||
#include <ripple/app/ledger/Ledger.h>
|
||||
#include <ripple/app/misc/CanonicalTXSet.h>
|
||||
#include <beast/cxx14/memory.h> // <memory>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -32,16 +33,13 @@ namespace ripple {
|
||||
class LocalTxs
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~LocalTxs () = default;
|
||||
|
||||
static std::unique_ptr<LocalTxs> New ();
|
||||
|
||||
// Add a new local transaction
|
||||
virtual void push_back (LedgerIndex index, STTx::ref txn) = 0;
|
||||
|
||||
// Apply local transactions to a new open ledger
|
||||
virtual void apply (TransactionEngine&) = 0;
|
||||
// Return the set of local transactions to a new open ledger
|
||||
virtual CanonicalTXSet getTxSet () = 0;
|
||||
|
||||
// Remove obsolete transactions based on a new fully-valid ledger
|
||||
virtual void sweep (Ledger::ref validLedger) = 0;
|
||||
@@ -49,6 +47,9 @@ public:
|
||||
virtual std::size_t size () = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<LocalTxs>
|
||||
make_LocalTxs ();
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/tx/LocalTxs.h>
|
||||
#include <ripple/app/main/Application.h>
|
||||
#include <ripple/app/misc/CanonicalTXSet.h>
|
||||
#include <ripple/protocol/Indexes.h>
|
||||
|
||||
/*
|
||||
@@ -107,12 +106,11 @@ private:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class LocalTxsImp : public LocalTxs
|
||||
class LocalTxsImp
|
||||
: public LocalTxs
|
||||
{
|
||||
public:
|
||||
|
||||
LocalTxsImp()
|
||||
{ }
|
||||
LocalTxsImp() = default;
|
||||
|
||||
// Add a new transaction to the set of local transactions
|
||||
void push_back (LedgerIndex index, STTx::ref txn) override
|
||||
@@ -138,9 +136,9 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
void apply (TransactionEngine& engine) override
|
||||
CanonicalTXSet
|
||||
getTxSet () override
|
||||
{
|
||||
|
||||
CanonicalTXSet tset (uint256 {});
|
||||
|
||||
// Get the set of local transactions as a canonical
|
||||
@@ -148,24 +146,11 @@ public:
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (m_lock);
|
||||
|
||||
for (auto& it : m_txns)
|
||||
for (auto const& it : m_txns)
|
||||
tset.push_back (it.getTX());
|
||||
}
|
||||
|
||||
for (auto it : tset)
|
||||
{
|
||||
try
|
||||
{
|
||||
engine.applyTransaction (*it.second, tapOPEN_LEDGER);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Nothing special we need to do.
|
||||
// It's possible a cleverly malformed transaction or
|
||||
// corrupt back end database could cause an exception
|
||||
// during transaction processing.
|
||||
}
|
||||
}
|
||||
return tset;
|
||||
}
|
||||
|
||||
// Remove transactions that have either been accepted into a fully-validated
|
||||
@@ -191,14 +176,14 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::mutex m_lock;
|
||||
std::list <LocalTx> m_txns;
|
||||
};
|
||||
|
||||
std::unique_ptr <LocalTxs> LocalTxs::New()
|
||||
std::unique_ptr<LocalTxs>
|
||||
make_LocalTxs ()
|
||||
{
|
||||
return std::make_unique <LocalTxsImp> ();
|
||||
return std::make_unique<LocalTxsImp> ();
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -30,11 +30,12 @@
|
||||
#include <ripple/app/ledger/OrderBookDB.cpp>
|
||||
#include <ripple/app/ledger/TransactionStateSF.cpp>
|
||||
|
||||
#include <ripple/app/ledger/impl/ConsensusImp.cpp>
|
||||
#include <ripple/app/ledger/impl/DisputedTx.cpp>
|
||||
#include <ripple/app/ledger/impl/InboundLedger.cpp>
|
||||
#include <ripple/app/ledger/impl/InboundLedgers.cpp>
|
||||
#include <ripple/app/ledger/impl/LedgerCleaner.cpp>
|
||||
#include <ripple/app/ledger/impl/LedgerConsensus.cpp>
|
||||
#include <ripple/app/ledger/impl/LedgerConsensusImp.cpp>
|
||||
#include <ripple/app/ledger/impl/LedgerFees.cpp>
|
||||
#include <ripple/app/ledger/impl/LedgerMaster.cpp>
|
||||
#include <ripple/app/ledger/impl/LedgerTiming.cpp>
|
||||
|
||||
Reference in New Issue
Block a user