mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-26 14:05:51 +00:00
Consensus cleanup:
* Inject dependencies, make functions free and levelize * Add comments to document the intent behind the code * Reduce class public interfaces * Remove support for proposals without ledger hashes
This commit is contained in:
committed by
Tom Ritchford
parent
1b4e0f5f48
commit
dd902292ed
@@ -1394,26 +1394,44 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\DirectoryEntryIterator.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\DisputedTx.cpp">
|
||||
<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>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\DisputedTx.h">
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\impl\DisputedTx.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\InboundLedger.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\InboundLedgers.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerCleaner.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\LedgerCleaner.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerConsensus.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<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>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\InboundLedger.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerMaster.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerTiming.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\InboundLedger.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\InboundLedgers.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\InboundLedgers.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\Ledger.cpp">
|
||||
@@ -1422,16 +1440,6 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\Ledger.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\LedgerCleaner.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerCleaner.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\LedgerConsensus.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerConsensus.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\LedgerEntrySet.cpp">
|
||||
@@ -1450,10 +1458,6 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerHolder.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\LedgerMaster.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerMaster.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\LedgerProposal.cpp">
|
||||
@@ -1462,10 +1466,6 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerProposal.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\LedgerTiming.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerTiming.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerToJson.h">
|
||||
|
||||
@@ -2115,24 +2115,39 @@
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\DirectoryEntryIterator.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\DisputedTx.cpp">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\DisputedTx.cpp">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\DisputedTx.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\impl\DisputedTx.h">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\InboundLedger.cpp">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\InboundLedgers.cpp">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerCleaner.cpp">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
<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">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerFees.cpp">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\InboundLedger.cpp">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerMaster.cpp">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\impl\LedgerTiming.cpp">
|
||||
<Filter>ripple\app\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\InboundLedger.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\InboundLedgers.cpp">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\InboundLedgers.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
@@ -2142,15 +2157,6 @@
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\Ledger.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\LedgerCleaner.cpp">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerCleaner.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\LedgerConsensus.cpp">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerConsensus.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
@@ -2172,9 +2178,6 @@
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerHolder.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\LedgerMaster.cpp">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerMaster.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
@@ -2184,9 +2187,6 @@
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerProposal.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\LedgerTiming.cpp">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\LedgerTiming.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// VFALCO TODO Rename to InboundLedger
|
||||
// A ledger we are trying to acquire
|
||||
class InboundLedger
|
||||
: public PeerSet
|
||||
|
||||
@@ -1592,16 +1592,6 @@ void Ledger::updateSkipList ()
|
||||
}
|
||||
}
|
||||
|
||||
std::uint32_t Ledger::roundCloseTime (
|
||||
std::uint32_t closeTime, std::uint32_t closeResolution)
|
||||
{
|
||||
if (closeTime == 0)
|
||||
return 0;
|
||||
|
||||
closeTime += (closeResolution / 2);
|
||||
return closeTime - (closeTime % closeResolution);
|
||||
}
|
||||
|
||||
/** Save, or arrange to save, a fully-validated ledger
|
||||
Returns false on error
|
||||
*/
|
||||
|
||||
@@ -139,8 +139,6 @@ public:
|
||||
~Ledger ();
|
||||
|
||||
static Ledger::pointer getLastFullLedger ();
|
||||
static std::uint32_t roundCloseTime (
|
||||
std::uint32_t closeTime, std::uint32_t closeResolution);
|
||||
|
||||
void updateHash ();
|
||||
void setClosed ()
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <ripple/app/ledger/LedgerProposal.h>
|
||||
#include <ripple/app/misc/CanonicalTXSet.h>
|
||||
#include <ripple/app/misc/FeeVote.h>
|
||||
#include <ripple/app/tx/InboundTransactions.h>
|
||||
#include <ripple/app/tx/LocalTxs.h>
|
||||
#include <ripple/json/json_value.h>
|
||||
#include <ripple/overlay/Peer.h>
|
||||
@@ -42,8 +43,6 @@ class LedgerConsensus
|
||||
public:
|
||||
virtual ~LedgerConsensus() = 0;
|
||||
|
||||
virtual int startup () = 0;
|
||||
|
||||
virtual Json::Value getJson (bool full) = 0;
|
||||
|
||||
virtual uint256 getLCL () = 0;
|
||||
@@ -55,12 +54,22 @@ public:
|
||||
|
||||
virtual bool peerPosition (LedgerProposal::ref) = 0;
|
||||
|
||||
// test/debug
|
||||
/** Simulate the consensus process without any network traffic.
|
||||
|
||||
The end result, is that consensus begins and completes as if everyone
|
||||
had agreed with whatever we propose.
|
||||
|
||||
This function is only called from the rpc "ledger_accept" path with the
|
||||
server in standalone mode and SHOULD NOT be used during the normal
|
||||
consensus process.
|
||||
*/
|
||||
virtual void simulate () = 0;
|
||||
};
|
||||
|
||||
std::shared_ptr <LedgerConsensus>
|
||||
make_LedgerConsensus (LocalTxs& localtx,
|
||||
make_LedgerConsensus (
|
||||
int previousProposers, int previousConvergeTime,
|
||||
InboundTransactions& inboundTransactions, LocalTxs& localtx,
|
||||
LedgerHash const & prevLCLHash, Ledger::ref previousLedger,
|
||||
std::uint32_t closeTime, FeeVote& feeVote);
|
||||
|
||||
|
||||
@@ -26,34 +26,38 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
LedgerProposal::LedgerProposal (uint256 const& pLgr, std::uint32_t seq,
|
||||
uint256 const& tx, std::uint32_t closeTime,
|
||||
RippleAddress const& naPeerPublic, uint256 const& suppression) :
|
||||
mPreviousLedger (pLgr), mCurrentHash (tx), mSuppression (suppression), mCloseTime (closeTime),
|
||||
mProposeSeq (seq), mPublicKey (naPeerPublic)
|
||||
{
|
||||
// XXX Validate key.
|
||||
// if (!mKey->SetPubKey(pubKey))
|
||||
// throw std::runtime_error("Invalid public key in proposal");
|
||||
|
||||
mPeerID = mPublicKey.getNodeID ();
|
||||
mTime = std::chrono::steady_clock::now ();
|
||||
}
|
||||
|
||||
LedgerProposal::LedgerProposal (RippleAddress const& naPub, RippleAddress const& naPriv,
|
||||
uint256 const& prevLgr, uint256 const& position,
|
||||
std::uint32_t closeTime) :
|
||||
mPreviousLedger (prevLgr), mCurrentHash (position), mCloseTime (closeTime), mProposeSeq (0),
|
||||
mPublicKey (naPub), mPrivateKey (naPriv)
|
||||
LedgerProposal::LedgerProposal (
|
||||
uint256 const& pLgr,
|
||||
std::uint32_t seq,
|
||||
uint256 const& tx,
|
||||
std::uint32_t closeTime,
|
||||
RippleAddress const& publicKey,
|
||||
uint256 const& suppression)
|
||||
: mPreviousLedger (pLgr)
|
||||
, mCurrentHash (tx)
|
||||
, mSuppression (suppression)
|
||||
, mCloseTime (closeTime)
|
||||
, mProposeSeq (seq)
|
||||
, mPublicKey (publicKey)
|
||||
{
|
||||
mPeerID = mPublicKey.getNodeID ();
|
||||
mTime = std::chrono::steady_clock::now ();
|
||||
}
|
||||
|
||||
LedgerProposal::LedgerProposal (uint256 const& prevLgr, uint256 const& position,
|
||||
std::uint32_t closeTime) :
|
||||
mPreviousLedger (prevLgr), mCurrentHash (position), mCloseTime (closeTime), mProposeSeq (0)
|
||||
LedgerProposal::LedgerProposal (
|
||||
RippleAddress const& publicKey,
|
||||
uint256 const& prevLgr,
|
||||
uint256 const& position,
|
||||
std::uint32_t closeTime)
|
||||
: mPreviousLedger (prevLgr)
|
||||
, mCurrentHash (position)
|
||||
, mCloseTime (closeTime)
|
||||
, mProposeSeq (seqJoin)
|
||||
, mPublicKey (publicKey)
|
||||
{
|
||||
if (mPublicKey.isValid ())
|
||||
mPeerID = mPublicKey.getNodeID ();
|
||||
|
||||
mTime = std::chrono::steady_clock::now ();
|
||||
}
|
||||
|
||||
@@ -70,42 +74,17 @@ uint256 LedgerProposal::getSigningHash () const
|
||||
return s.getSHA512Half ();
|
||||
}
|
||||
|
||||
/*
|
||||
The "id" is a unique value computed on all fields that contribute to
|
||||
the signature, and including the signature. There is one caveat, the
|
||||
"last closed ledger" field may be omitted. However, the signer still
|
||||
computes the signature as if this field was present. Recipients of
|
||||
the proposal need to inject the last closed ledger in order to
|
||||
validate the signature. If the last closed ledger is left out, then
|
||||
it is considered as all zeroes for the purposes of signing.
|
||||
*/
|
||||
// Compute a unique identifier for this signed proposal
|
||||
uint256 LedgerProposal::computeSuppressionID (
|
||||
uint256 const& proposeHash,
|
||||
uint256 const& previousLedger,
|
||||
std::uint32_t proposeSeq,
|
||||
std::uint32_t closeTime,
|
||||
Blob const& pubKey,
|
||||
Blob const& signature)
|
||||
bool LedgerProposal::checkSign (std::string const& signature) const
|
||||
{
|
||||
|
||||
Serializer s (512);
|
||||
s.add256 (proposeHash);
|
||||
s.add256 (previousLedger);
|
||||
s.add32 (proposeSeq);
|
||||
s.add32 (closeTime);
|
||||
s.addVL (pubKey);
|
||||
s.addVL (signature);
|
||||
|
||||
return s.getSHA512Half ();
|
||||
return mPublicKey.verifyNodePublic (
|
||||
getSigningHash (),
|
||||
signature,
|
||||
ECDSA::not_strict);
|
||||
}
|
||||
|
||||
bool LedgerProposal::checkSign (std::string const& signature, uint256 const& signingHash)
|
||||
{
|
||||
return mPublicKey.verifyNodePublic (signingHash, signature, ECDSA::not_strict);
|
||||
}
|
||||
|
||||
bool LedgerProposal::changePosition (uint256 const& newPosition, std::uint32_t closeTime)
|
||||
bool LedgerProposal::changePosition (
|
||||
uint256 const& newPosition,
|
||||
std::uint32_t closeTime)
|
||||
{
|
||||
if (mProposeSeq == seqLeave)
|
||||
return false;
|
||||
@@ -123,18 +102,12 @@ void LedgerProposal::bowOut ()
|
||||
mProposeSeq = seqLeave;
|
||||
}
|
||||
|
||||
Blob LedgerProposal::sign (void)
|
||||
Blob LedgerProposal::sign (RippleAddress const& privateKey)
|
||||
{
|
||||
Blob ret;
|
||||
|
||||
mPrivateKey.signNodePrivate (getSigningHash (), ret);
|
||||
// XXX If this can fail, find out sooner.
|
||||
// if (!mPrivateKey.signNodePrivate(getSigningHash(), ret))
|
||||
// throw std::runtime_error("unable to sign proposal");
|
||||
|
||||
mSuppression = computeSuppressionID (mCurrentHash, mPreviousLedger, mProposeSeq,
|
||||
privateKey.signNodePrivate (getSigningHash (), ret);
|
||||
mSuppression = proposalUniqueId (mCurrentHash, mPreviousLedger, mProposeSeq,
|
||||
mCloseTime, mPublicKey.getNodePublic (), ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -157,4 +130,24 @@ Json::Value LedgerProposal::getJson () const
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint256 proposalUniqueId (
|
||||
uint256 const& proposeHash,
|
||||
uint256 const& previousLedger,
|
||||
std::uint32_t proposeSeq,
|
||||
std::uint32_t closeTime,
|
||||
Blob const& pubKey,
|
||||
Blob const& signature)
|
||||
{
|
||||
|
||||
Serializer s (512);
|
||||
s.add256 (proposeHash);
|
||||
s.add256 (previousLedger);
|
||||
s.add32 (proposeSeq);
|
||||
s.add32 (closeTime);
|
||||
s.addVL (pubKey);
|
||||
s.addVL (signature);
|
||||
|
||||
return s.getSHA512Half ();
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/json/json_value.h>
|
||||
#include <ripple/protocol/RippleAddress.h>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
@@ -33,35 +33,38 @@ namespace ripple {
|
||||
class LedgerProposal
|
||||
: public CountedObject <LedgerProposal>
|
||||
{
|
||||
private:
|
||||
// A peer initial joins the consensus process
|
||||
static std::uint32_t const seqJoin = 0;
|
||||
|
||||
// A peer wants to bow out and leave the consensus process
|
||||
static std::uint32_t const seqLeave = 0xffffffff;
|
||||
|
||||
public:
|
||||
static char const* getCountedObjectName () { return "LedgerProposal"; }
|
||||
|
||||
static const std::uint32_t seqLeave = 0xffffffff; // leaving the consensus process
|
||||
|
||||
using pointer = std::shared_ptr<LedgerProposal>;
|
||||
using ref = const pointer&;
|
||||
|
||||
// proposal from peer
|
||||
LedgerProposal (uint256 const& prevLgr, std::uint32_t proposeSeq, uint256 const& propose,
|
||||
std::uint32_t closeTime, const RippleAddress & naPeerPublic, uint256 const& suppress);
|
||||
LedgerProposal (
|
||||
uint256 const& prevLgr,
|
||||
std::uint32_t proposeSeq,
|
||||
uint256 const& propose,
|
||||
std::uint32_t closeTime,
|
||||
RippleAddress const& publicKey,
|
||||
uint256 const& suppress);
|
||||
|
||||
// our first proposal
|
||||
LedgerProposal (const RippleAddress & pubKey, const RippleAddress & privKey,
|
||||
uint256 const& prevLedger, uint256 const& position, std::uint32_t closeTime);
|
||||
|
||||
// an unsigned "dummy" proposal for nodes not validating
|
||||
LedgerProposal (uint256 const& prevLedger, uint256 const& position, std::uint32_t closeTime);
|
||||
// Our own proposal: the publicKey, if set, indicates we are a validating
|
||||
// node but does not indicate if we're validating in this consensus round.
|
||||
LedgerProposal (
|
||||
RippleAddress const& publicKey,
|
||||
uint256 const& prevLedger,
|
||||
uint256 const& position,
|
||||
std::uint32_t closeTime);
|
||||
|
||||
uint256 getSigningHash () const;
|
||||
bool checkSign (std::string const& signature, uint256 const& signingHash);
|
||||
bool checkSign (std::string const& signature)
|
||||
{
|
||||
return checkSign (signature, getSigningHash ());
|
||||
}
|
||||
bool checkSign ()
|
||||
{
|
||||
return checkSign (mSignature, getSigningHash ());
|
||||
}
|
||||
bool checkSign (std::string const& signature) const;
|
||||
|
||||
NodeID const& getPeerID () const
|
||||
{
|
||||
@@ -87,42 +90,23 @@ public:
|
||||
{
|
||||
return mCloseTime;
|
||||
}
|
||||
RippleAddress const& peekPublic () const
|
||||
{
|
||||
return mPublicKey;
|
||||
}
|
||||
Blob getPubKey () const
|
||||
{
|
||||
return mPublicKey.getNodePublic ();
|
||||
}
|
||||
Blob sign ();
|
||||
|
||||
void setPrevLedger (uint256 const& prevLedger)
|
||||
{
|
||||
mPreviousLedger = prevLedger;
|
||||
}
|
||||
void setSignature (std::string const& signature)
|
||||
{
|
||||
mSignature = signature;
|
||||
}
|
||||
bool hasSignature ()
|
||||
{
|
||||
return !mSignature.empty ();
|
||||
}
|
||||
bool isPrevLedger (uint256 const& pl)
|
||||
Blob sign (RippleAddress const& privateKey);
|
||||
|
||||
bool isPrevLedger (uint256 const& pl) const
|
||||
{
|
||||
return mPreviousLedger == pl;
|
||||
}
|
||||
bool isBowOut ()
|
||||
bool isInitial () const
|
||||
{
|
||||
return mProposeSeq == seqJoin;
|
||||
}
|
||||
bool isBowOut () const
|
||||
{
|
||||
return mProposeSeq == seqLeave;
|
||||
}
|
||||
|
||||
std::chrono::steady_clock::time_point getCreateTime ()
|
||||
{
|
||||
return mTime;
|
||||
}
|
||||
bool isStale (std::chrono::steady_clock::time_point cutoff)
|
||||
bool isStale (std::chrono::steady_clock::time_point cutoff) const
|
||||
{
|
||||
return mTime <= cutoff;
|
||||
}
|
||||
@@ -131,7 +115,26 @@ public:
|
||||
void bowOut ();
|
||||
Json::Value getJson () const;
|
||||
|
||||
static uint256 computeSuppressionID (
|
||||
private:
|
||||
uint256 mPreviousLedger, mCurrentHash, mSuppression;
|
||||
std::uint32_t mCloseTime, mProposeSeq;
|
||||
|
||||
NodeID mPeerID;
|
||||
RippleAddress mPublicKey;
|
||||
|
||||
std::chrono::steady_clock::time_point mTime;
|
||||
};
|
||||
|
||||
/** Calculate a unique identifier for a signed proposal.
|
||||
|
||||
The identifier is based on all the fields that contribute to the signature,
|
||||
as well as the signature itself. The "last closed ledger" field may be
|
||||
omitted, but the signer will compute the signature as if this
|
||||
field was present. Recipients of the proposal will inject the last closed
|
||||
ledger in order to validate the signature. If the last closed ledger is left
|
||||
out, then it is considered as all zeroes for the purposes of signing.
|
||||
*/
|
||||
uint256 proposalUniqueId (
|
||||
uint256 const& proposeHash,
|
||||
uint256 const& previousLedger,
|
||||
std::uint32_t proposeSeq,
|
||||
@@ -139,18 +142,6 @@ public:
|
||||
Blob const& pubKey,
|
||||
Blob const& signature);
|
||||
|
||||
private:
|
||||
uint256 mPreviousLedger, mCurrentHash, mSuppression;
|
||||
std::uint32_t mCloseTime, mProposeSeq;
|
||||
|
||||
NodeID mPeerID;
|
||||
RippleAddress mPublicKey;
|
||||
RippleAddress mPrivateKey; // If ours
|
||||
|
||||
std::string mSignature; // set only if needed
|
||||
std::chrono::steady_clock::time_point mTime;
|
||||
};
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
|
||||
@@ -88,6 +88,15 @@ int getNextLedgerTimeResolution (
|
||||
bool previousAgree,
|
||||
std::uint32_t ledgerSeq);
|
||||
|
||||
/** Calculates the close time for a ledger, given a close time resolution.
|
||||
|
||||
@param closeTime The time to be rouned.
|
||||
@param closeResolution The resolution
|
||||
*/
|
||||
std::uint32_t roundCloseTime (
|
||||
std::uint32_t closeTime,
|
||||
std::uint32_t closeResolution);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// These are protocol parameters used to control the behavior of the system and
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/ledger/DisputedTx.h>
|
||||
#include <ripple/app/ledger/impl/DisputedTx.h>
|
||||
#include <ripple/app/ledger/LedgerTiming.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/json/to_string.h>
|
||||
@@ -18,10 +18,10 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/ledger/LedgerCleaner.h>
|
||||
#include <ripple/app/ledger/InboundLedgers.h>
|
||||
#include <ripple/app/ledger/Ledger.h>
|
||||
#include <ripple/app/ledger/LedgerMaster.h>
|
||||
#include <ripple/app/ledger/impl/LedgerCleaner.h>
|
||||
#include <ripple/app/main/Application.h>
|
||||
#include <ripple/core/LoadFeeTrack.h>
|
||||
#include <ripple/protocol/JsonFields.h>
|
||||
@@ -18,12 +18,12 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/ledger/DisputedTx.h>
|
||||
#include <ripple/app/ledger/LedgerConsensus.h>
|
||||
#include <ripple/app/ledger/InboundLedgers.h>
|
||||
#include <ripple/app/ledger/LedgerMaster.h>
|
||||
#include <ripple/app/ledger/LedgerTiming.h>
|
||||
#include <ripple/app/ledger/LedgerToJson.h>
|
||||
#include <ripple/app/ledger/impl/DisputedTx.h>
|
||||
#include <ripple/app/main/Application.h>
|
||||
#include <ripple/app/misc/AmendmentTable.h>
|
||||
#include <ripple/app/misc/CanonicalTXSet.h>
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <ripple/app/misc/NetworkOPs.h>
|
||||
#include <ripple/app/misc/Validations.h>
|
||||
#include <ripple/app/tx/TransactionAcquire.h>
|
||||
#include <ripple/app/tx/InboundTransactions.h>
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/core/Config.h>
|
||||
@@ -66,6 +65,22 @@ class LedgerConsensusImp
|
||||
, 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.
|
||||
@@ -78,21 +93,30 @@ public:
|
||||
LedgerConsensusImp& operator=(LedgerConsensusImp const&) = delete;
|
||||
|
||||
/**
|
||||
The result of applying a transaction to a ledger.
|
||||
|
||||
@param localtx A set of local transactions to apply.
|
||||
@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 Last Closed Ledger (LCL)
|
||||
was.
|
||||
@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 (LocalTxs& localtx,
|
||||
LedgerHash const & prevLCLHash, Ledger::ref previousLedger,
|
||||
std::uint32_t closeTime, FeeVote& feeVote)
|
||||
: m_localTX (localtx)
|
||||
LedgerConsensusImp (
|
||||
int previousProposers,
|
||||
int previousConvergeTime,
|
||||
InboundTransactions& inboundTransactions,
|
||||
LocalTxs& localtx,
|
||||
LedgerHash const & prevLCLHash,
|
||||
Ledger::ref previousLedger,
|
||||
std::uint32_t closeTime,
|
||||
FeeVote& feeVote)
|
||||
: inboundTransactions_ (inboundTransactions)
|
||||
, m_localTX (localtx)
|
||||
, m_feeVote (feeVote)
|
||||
, mState (lcsPRE_CLOSE)
|
||||
, state_ (State::open)
|
||||
, mCloseTime (closeTime)
|
||||
, mPrevLedgerHash (prevLCLHash)
|
||||
, mPreviousLedger (previousLedger)
|
||||
@@ -102,23 +126,23 @@ public:
|
||||
, mCurrentMSeconds (0)
|
||||
, mClosePercent (0)
|
||||
, mHaveCloseTimeConsensus (false)
|
||||
, mConsensusStartTime
|
||||
(std::chrono::steady_clock::now ())
|
||||
, mConsensusStartTime (std::chrono::steady_clock::now ())
|
||||
, mPreviousProposers (previousProposers)
|
||||
, mPreviousMSeconds (previousConvergeTime)
|
||||
{
|
||||
WriteLog (lsDEBUG, LedgerConsensus) << "Creating consensus object";
|
||||
WriteLog (lsTRACE, LedgerConsensus)
|
||||
<< "LCL:" << previousLedger->getHash () << ", ct=" << closeTime;
|
||||
mPreviousProposers = getApp().getOPs ().getPreviousProposers ();
|
||||
mPreviousMSeconds = getApp().getOPs ().getPreviousConvergeTime ();
|
||||
|
||||
assert (mPreviousMSeconds);
|
||||
|
||||
getApp().getInboundTransactions().newRound (mPreviousLedger->getLedgerSeq());
|
||||
inboundTransactions_.newRound (mPreviousLedger->getLedgerSeq());
|
||||
|
||||
// Adapt close time resolution to recent network conditions
|
||||
mCloseResolution = getNextLedgerTimeResolution (
|
||||
mPreviousLedger->getCloseResolution (),
|
||||
mPreviousLedger->getCloseAgree (),
|
||||
previousLedger->getLedgerSeq () + 1);
|
||||
mPreviousLedger->getLedgerSeq () + 1);
|
||||
|
||||
if (mValPublic.isSet () && mValPrivate.isSet ()
|
||||
&& !getApp().getOPs ().isNeedNetworkLedger ())
|
||||
@@ -163,16 +187,6 @@ public:
|
||||
getApp().getOPs ().setProposing (mProposing, mValidating);
|
||||
}
|
||||
|
||||
/**
|
||||
This function is called, but its return value is always ignored.
|
||||
|
||||
@return 1.
|
||||
*/
|
||||
int startup ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the Json state of the consensus process.
|
||||
Called by the consensus_info RPC.
|
||||
@@ -196,21 +210,21 @@ public:
|
||||
else
|
||||
ret["synched"] = false;
|
||||
|
||||
switch (mState)
|
||||
switch (state_)
|
||||
{
|
||||
case lcsPRE_CLOSE:
|
||||
case State::open:
|
||||
ret[jss::state] = "open";
|
||||
break;
|
||||
|
||||
case lcsESTABLISH:
|
||||
case State::establish:
|
||||
ret[jss::state] = "consensus";
|
||||
break;
|
||||
|
||||
case lcsFINISHED:
|
||||
case State::finished:
|
||||
ret[jss::state] = "finished";
|
||||
break;
|
||||
|
||||
case lcsACCEPTED:
|
||||
case State::accepted:
|
||||
ret[jss::state] = "accepted";
|
||||
break;
|
||||
}
|
||||
@@ -356,7 +370,7 @@ public:
|
||||
if (!acquired)
|
||||
{
|
||||
// Put the map where others can get it
|
||||
getApp().getInboundTransactions().giveSet (hash, map, false);
|
||||
inboundTransactions_.giveSet (hash, map, false);
|
||||
}
|
||||
|
||||
// Inform directly-connected peers that we have this transaction set
|
||||
@@ -445,22 +459,22 @@ public:
|
||||
// LCL change
|
||||
const char* status;
|
||||
|
||||
switch (mState)
|
||||
switch (state_)
|
||||
{
|
||||
case lcsPRE_CLOSE:
|
||||
status = "PreClose";
|
||||
case State::open:
|
||||
status = "open";
|
||||
break;
|
||||
|
||||
case lcsESTABLISH:
|
||||
status = "Establish";
|
||||
case State::establish:
|
||||
status = "establish";
|
||||
break;
|
||||
|
||||
case lcsFINISHED:
|
||||
status = "Finished";
|
||||
case State::finished:
|
||||
status = "finished";
|
||||
break;
|
||||
|
||||
case lcsACCEPTED:
|
||||
status = "Accepted";
|
||||
case State::accepted:
|
||||
status = "accepted";
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -531,13 +545,14 @@ public:
|
||||
return;
|
||||
|
||||
// we need to switch the ledger we're working from
|
||||
Ledger::pointer newLCL = getApp().getLedgerMaster ().getLedgerByHash (mPrevLedgerHash);
|
||||
auto newLCL = getApp().getLedgerMaster ().getLedgerByHash (mPrevLedgerHash);
|
||||
if (!newLCL)
|
||||
{
|
||||
if (mAcquiringLedger != lclHash)
|
||||
{
|
||||
// need to start acquiring the correct consensus LCL
|
||||
WriteLog (lsWARNING, LedgerConsensus) << "Need consensus ledger " << mPrevLedgerHash;
|
||||
WriteLog (lsWARNING, LedgerConsensus) <<
|
||||
"Need consensus ledger " << mPrevLedgerHash;
|
||||
|
||||
// Tell the ledger acquire system that we need the consensus ledger
|
||||
mAcquiringLedger = mPrevLedgerHash;
|
||||
@@ -556,7 +571,8 @@ public:
|
||||
mPreviousLedger = newLCL;
|
||||
mPrevLedgerHash = lclHash;
|
||||
|
||||
WriteLog (lsINFO, LedgerConsensus) << "Have the consensus ledger " << mPrevLedgerHash;
|
||||
WriteLog (lsINFO, LedgerConsensus) <<
|
||||
"Have the consensus ledger " << mPrevLedgerHash;
|
||||
mHaveCorrectLCL = true;
|
||||
|
||||
mCloseResolution = getNextLedgerTimeResolution (
|
||||
@@ -587,34 +603,34 @@ public:
|
||||
|
||||
void doTimer ()
|
||||
{
|
||||
if ((mState != lcsFINISHED) && (mState != lcsACCEPTED))
|
||||
if ((state_ != State::finished) && (state_ != State::accepted))
|
||||
checkLCL ();
|
||||
|
||||
mCurrentMSeconds = std::chrono::duration_cast <std::chrono::milliseconds>
|
||||
(std::chrono::steady_clock::now() - mConsensusStartTime).count ();
|
||||
mClosePercent = mCurrentMSeconds * 100 / mPreviousMSeconds;
|
||||
|
||||
switch (mState)
|
||||
switch (state_)
|
||||
{
|
||||
case lcsPRE_CLOSE:
|
||||
case State::open:
|
||||
statePreClose ();
|
||||
return;
|
||||
|
||||
case lcsESTABLISH:
|
||||
case State::establish:
|
||||
stateEstablish ();
|
||||
|
||||
if (mState != lcsFINISHED) return;
|
||||
if (state_ != State::finished) return;
|
||||
|
||||
// Fall through
|
||||
|
||||
case lcsFINISHED:
|
||||
case State::finished:
|
||||
stateFinished ();
|
||||
|
||||
if (mState != lcsACCEPTED) return;
|
||||
if (state_ != State::accepted) return;
|
||||
|
||||
// Fall through
|
||||
|
||||
case lcsACCEPTED:
|
||||
case State::accepted:
|
||||
stateAccepted ();
|
||||
return;
|
||||
}
|
||||
@@ -696,7 +712,7 @@ public:
|
||||
|
||||
WriteLog (lsINFO, LedgerConsensus) <<
|
||||
"Converge cutoff (" << mPeerPositions.size () << " participants)";
|
||||
mState = lcsFINISHED;
|
||||
state_ = State::finished;
|
||||
beginAccept (false);
|
||||
}
|
||||
|
||||
@@ -781,7 +797,7 @@ public:
|
||||
if (it != mAcquired.end() && it->second)
|
||||
return it->second;
|
||||
|
||||
auto set = getApp().getInboundTransactions().getSet (hash, true);
|
||||
auto set = inboundTransactions_.getSet (hash, true);
|
||||
|
||||
if (set)
|
||||
mAcquired[hash] = set;
|
||||
@@ -798,7 +814,7 @@ public:
|
||||
*/
|
||||
bool peerPosition (LedgerProposal::ref newPosition)
|
||||
{
|
||||
auto peerID = newPosition->getPeerID ();
|
||||
auto const peerID = newPosition->getPeerID ();
|
||||
|
||||
if (mDeadNodes.find (peerID) != mDeadNodes.end ())
|
||||
{
|
||||
@@ -820,17 +836,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (newPosition->getProposeSeq () == 0)
|
||||
if (newPosition->isBowOut ())
|
||||
{
|
||||
// new initial close time estimate
|
||||
WriteLog (lsTRACE, LedgerConsensus)
|
||||
<< "Peer reports close time as "
|
||||
<< newPosition->getCloseTime ();
|
||||
++mCloseTimes[newPosition->getCloseTime ()];
|
||||
}
|
||||
else if (newPosition->getProposeSeq () == LedgerProposal::seqLeave)
|
||||
{
|
||||
// peer bows out
|
||||
WriteLog (lsINFO, LedgerConsensus)
|
||||
<< "Peer bows out: " << to_string (peerID);
|
||||
for (auto& it : mDisputes)
|
||||
@@ -840,6 +847,14 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
if (newPosition->isInitial ())
|
||||
{
|
||||
// Record the close time estimate
|
||||
WriteLog (lsTRACE, LedgerConsensus)
|
||||
<< "Peer reports close time as "
|
||||
<< newPosition->getCloseTime ();
|
||||
++mCloseTimes[newPosition->getCloseTime ()];
|
||||
}
|
||||
|
||||
WriteLog (lsTRACE, LedgerConsensus) << "Processing peer proposal "
|
||||
<< newPosition->getProposeSeq () << "/"
|
||||
@@ -863,8 +878,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Simulate a consensus round without any network traffic
|
||||
*/
|
||||
void simulate ()
|
||||
{
|
||||
WriteLog (lsINFO, LedgerConsensus) << "Simulating consensus";
|
||||
@@ -874,6 +887,7 @@ public:
|
||||
endConsensus ();
|
||||
WriteLog (lsINFO, LedgerConsensus) << "Simulation complete";
|
||||
}
|
||||
|
||||
private:
|
||||
/** We have a new last closed ledger, process it. Final accept logic
|
||||
|
||||
@@ -881,9 +895,8 @@ private:
|
||||
*/
|
||||
void accept (std::shared_ptr<SHAMap> set)
|
||||
{
|
||||
|
||||
{
|
||||
std::lock_guard<Application::MutexType> lock(getApp().getMasterMutex());
|
||||
auto lock = beast::make_lock(getApp().getMasterMutex());
|
||||
|
||||
// put our set where others can get it later
|
||||
if (set->getHash ().isNonZero ())
|
||||
@@ -895,7 +908,8 @@ private:
|
||||
getApp().getOPs ().peekStoredProposals ().clear ();
|
||||
}
|
||||
|
||||
std::uint32_t closeTime = roundCloseTime (mOurPosition->getCloseTime ());
|
||||
std::uint32_t closeTime = roundCloseTime (
|
||||
mOurPosition->getCloseTime (), mCloseResolution);
|
||||
bool closeTimeCorrect = true;
|
||||
|
||||
if (closeTime == 0)
|
||||
@@ -921,9 +935,7 @@ private:
|
||||
CanonicalTXSet retriableTransactions (set->getHash ());
|
||||
|
||||
// Build the new last closed ledger
|
||||
Ledger::pointer newLCL
|
||||
= std::make_shared<Ledger> (false
|
||||
, *mPreviousLedger);
|
||||
auto newLCL = std::make_shared<Ledger> (false, *mPreviousLedger);
|
||||
|
||||
// Set up to write SHAMap changes to our database,
|
||||
// perform updates, extract changes
|
||||
@@ -981,7 +993,7 @@ private:
|
||||
getApp().getAmendmentTable ().doValidation (newLCL, *v);
|
||||
}
|
||||
|
||||
v->sign (signingHash, mValPrivate);
|
||||
signingHash = v->sign (mValPrivate);
|
||||
v->setTrusted ();
|
||||
// suppress it if we receive it - FIXME: wrong suppression
|
||||
getApp().getHashRouter ().addSuppression (signingHash);
|
||||
@@ -1003,8 +1015,7 @@ private:
|
||||
getApp().getLedgerMaster().consensusBuilt (newLCL);
|
||||
|
||||
// Build new open ledger
|
||||
Ledger::pointer newOL = std::make_shared<Ledger>
|
||||
(true, *newLCL);
|
||||
auto newOL = std::make_shared<Ledger> (true, *newLCL);
|
||||
|
||||
// Apply disputed transactions that didn't get in
|
||||
TransactionEngine engine (newOL);
|
||||
@@ -1065,15 +1076,14 @@ private:
|
||||
}
|
||||
|
||||
mNewLedgerHash = newLCL->getHash ();
|
||||
mState = lcsACCEPTED;
|
||||
state_ = State::accepted;
|
||||
|
||||
if (mValidating)
|
||||
{
|
||||
// see how close our close time is to other node's
|
||||
// close time reports, and update our clock.
|
||||
WriteLog (lsINFO, LedgerConsensus)
|
||||
<< "We closed at "
|
||||
<< beast::lexicalCastThrow <std::string> (mCloseTime);
|
||||
<< "We closed at " << mCloseTime;
|
||||
std::uint64_t closeTotal = mCloseTime;
|
||||
int closeCount = 1;
|
||||
|
||||
@@ -1253,10 +1263,12 @@ private:
|
||||
prop.set_proposeseq (mOurPosition->getProposeSeq ());
|
||||
prop.set_closetime (mOurPosition->getCloseTime ());
|
||||
|
||||
Blob pubKey = mOurPosition->getPubKey ();
|
||||
Blob sig = mOurPosition->sign ();
|
||||
Blob const pubKey = mValPublic.getNodePublic ();
|
||||
prop.set_nodepubkey (&pubKey[0], pubKey.size ());
|
||||
|
||||
Blob const sig = mOurPosition->sign (mValPrivate);
|
||||
prop.set_signature (&sig[0], sig.size ());
|
||||
|
||||
getApp().overlay().send(prop);
|
||||
}
|
||||
|
||||
@@ -1277,17 +1289,6 @@ private:
|
||||
msg, protocol::mtHAVE_SET)));
|
||||
}
|
||||
|
||||
/**
|
||||
Round the close time to the close time resolution.
|
||||
|
||||
@param closeTime The time to be rouned.
|
||||
@return The rounded close time.
|
||||
*/
|
||||
std::uint32_t roundCloseTime (std::uint32_t closeTime)
|
||||
{
|
||||
return Ledger::roundCloseTime (closeTime, mCloseResolution);
|
||||
}
|
||||
|
||||
/** Send a node status change message to our directly connected peers
|
||||
|
||||
@param event The event which caused the status change. This is
|
||||
@@ -1360,19 +1361,8 @@ private:
|
||||
WriteLog (lsINFO, LedgerConsensus) << "initial position " << txSet;
|
||||
mapCompleteInternal (txSet, initialSet, false);
|
||||
|
||||
if (mValidating)
|
||||
{
|
||||
mOurPosition = std::make_shared<LedgerProposal>
|
||||
(mValPublic, mValPrivate
|
||||
, initialLedger.getParentHash ()
|
||||
, txSet, mCloseTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
mOurPosition
|
||||
= std::make_shared<LedgerProposal>
|
||||
(initialLedger.getParentHash (), txSet, mCloseTime);
|
||||
}
|
||||
(mValPublic, initialLedger.getParentHash (), txSet, mCloseTime);
|
||||
|
||||
for (auto& it : mDisputes)
|
||||
{
|
||||
@@ -1402,17 +1392,22 @@ private:
|
||||
propose ();
|
||||
}
|
||||
|
||||
/**
|
||||
For a given number of participants and required percent
|
||||
for consensus, how many participants must agree?
|
||||
/** How many of the participants must agree to reach a given threshold?
|
||||
|
||||
@param size number of validators
|
||||
@param percent desired percent for consensus
|
||||
@return number of participates which must agree
|
||||
Note that the number may not precisely yield the requested percentage.
|
||||
For example, with with size = 5 and percent = 70, we return 3, but
|
||||
3 out of 5 works out to 60%. There are no security implications to
|
||||
this.
|
||||
|
||||
@param participants the number of participants (i.e. validators)
|
||||
@param the percent that we want to reach
|
||||
|
||||
@return the number of participants which must agree
|
||||
*/
|
||||
static int computePercent (int size, int percent)
|
||||
static int participantsNeeded (int participants, int percent)
|
||||
{
|
||||
int result = ((size * percent) + (percent / 2)) / 100;
|
||||
int result = ((participants * percent) + (percent / 2)) / 100;
|
||||
|
||||
return (result == 0) ? 1 : result;
|
||||
}
|
||||
|
||||
@@ -1452,7 +1447,7 @@ private:
|
||||
else
|
||||
{
|
||||
// proposal is still fresh
|
||||
++closeTimes[roundCloseTime (it->second->getCloseTime ())];
|
||||
++closeTimes[roundCloseTime (it->second->getCloseTime (), mCloseResolution)];
|
||||
++it;
|
||||
}
|
||||
}
|
||||
@@ -1504,22 +1499,24 @@ private:
|
||||
{
|
||||
// no other times
|
||||
mHaveCloseTimeConsensus = true;
|
||||
closeTime = roundCloseTime (mOurPosition->getCloseTime ());
|
||||
closeTime = roundCloseTime (mOurPosition->getCloseTime (), mCloseResolution);
|
||||
}
|
||||
else
|
||||
{
|
||||
int participants = mPeerPositions.size ();
|
||||
if (mProposing)
|
||||
{
|
||||
++closeTimes[roundCloseTime (mOurPosition->getCloseTime ())];
|
||||
++closeTimes[roundCloseTime (mOurPosition->getCloseTime (), mCloseResolution)];
|
||||
++participants;
|
||||
}
|
||||
|
||||
// Threshold for non-zero vote
|
||||
int threshVote = computePercent (participants, neededWeight);
|
||||
int threshVote = participantsNeeded (participants,
|
||||
neededWeight);
|
||||
|
||||
// Threshold to declare consensus
|
||||
int threshConsensus = computePercent (participants, AV_CT_CONSENSUS_PCT);
|
||||
int const threshConsensus = participantsNeeded (
|
||||
participants, AV_CT_CONSENSUS_PCT);
|
||||
|
||||
WriteLog (lsINFO, LedgerConsensus) << "Proposers:"
|
||||
<< mPeerPositions.size () << " nw:" << neededWeight
|
||||
@@ -1559,7 +1556,7 @@ private:
|
||||
}
|
||||
|
||||
if (!changes &&
|
||||
((closeTime != roundCloseTime (mOurPosition->getCloseTime ()))
|
||||
((closeTime != roundCloseTime (mOurPosition->getCloseTime (), mCloseResolution))
|
||||
|| mOurPosition->isStale (ourCutoff)))
|
||||
{
|
||||
// close time changed or our position is stale
|
||||
@@ -1596,20 +1593,7 @@ private:
|
||||
bool relay = false;
|
||||
for (auto const& proposal : it.second)
|
||||
{
|
||||
if (proposal->hasSignature ())
|
||||
{
|
||||
// we have the signature but don't know the
|
||||
// ledger so couldn't verify
|
||||
proposal->setPrevLedger (mPrevLedgerHash);
|
||||
|
||||
if (proposal->checkSign ())
|
||||
{
|
||||
WriteLog (lsINFO, LedgerConsensus)
|
||||
<< "Applying stored proposal";
|
||||
relay = peerPosition (proposal);
|
||||
}
|
||||
}
|
||||
else if (proposal->isPrevLedger (mPrevLedgerHash))
|
||||
if (proposal->isPrevLedger (mPrevLedgerHash))
|
||||
relay = peerPosition (proposal);
|
||||
|
||||
if (relay)
|
||||
@@ -1628,7 +1612,7 @@ private:
|
||||
void closeLedger ()
|
||||
{
|
||||
checkOurValidation ();
|
||||
mState = lcsESTABLISH;
|
||||
state_ = State::establish;
|
||||
mConsensusStartTime
|
||||
= std::chrono::steady_clock::now ();
|
||||
mCloseTime = getApp().getOPs ().getCloseTimeNC ();
|
||||
@@ -1644,7 +1628,8 @@ private:
|
||||
*/
|
||||
void checkOurValidation ()
|
||||
{
|
||||
// This only covers some cases - Fix for the case where we can't ever acquire the consensus ledger
|
||||
// This only covers some cases - Fix for the case where we can't ever
|
||||
// acquire the consensus ledger
|
||||
if (!mHaveCorrectLCL || !mValPublic.isSet ()
|
||||
|| !mValPrivate.isSet ()
|
||||
|| getApp().getOPs ().isNeedNetworkLedger ())
|
||||
@@ -1673,7 +1658,7 @@ private:
|
||||
, getApp().getOPs ().getValidationTimeNC (), mValPublic, false);
|
||||
addLoad(v);
|
||||
v->setTrusted ();
|
||||
v->sign (signingHash, mValPrivate);
|
||||
signingHash = v->sign (mValPrivate);
|
||||
// FIXME: wrong supression
|
||||
getApp().getHashRouter ().addSuppression (signingHash);
|
||||
getApp().getValidations ().addValidation (v, "localMissing");
|
||||
@@ -1716,8 +1701,7 @@ private:
|
||||
getApp().getOPs ().endConsensus (mHaveCorrectLCL);
|
||||
}
|
||||
|
||||
/** Add our load fee to our validation
|
||||
*/
|
||||
/** Add our load fee to our validation */
|
||||
void addLoad(STValidation::ref val)
|
||||
{
|
||||
std::uint32_t fee = std::max(
|
||||
@@ -1727,22 +1711,13 @@ private:
|
||||
if (fee > ref)
|
||||
val->setFieldU32(sfLoadFee, fee);
|
||||
}
|
||||
|
||||
private:
|
||||
InboundTransactions& inboundTransactions_;
|
||||
LocalTxs& m_localTX;
|
||||
FeeVote& m_feeVote;
|
||||
|
||||
// VFALCO TODO Rename these to look pretty
|
||||
enum LCState
|
||||
{
|
||||
lcsPRE_CLOSE, // We haven't closed our ledger yet,
|
||||
// but others might have
|
||||
lcsESTABLISH, // Establishing consensus
|
||||
lcsFINISHED, // We have closed on a transaction set
|
||||
lcsACCEPTED, // We have accepted/validated
|
||||
// a new last closed ledger
|
||||
};
|
||||
|
||||
LCState mState;
|
||||
State state_;
|
||||
std::uint32_t mCloseTime; // The wall time this ledger closed
|
||||
uint256 mPrevLedgerHash, mNewLedgerHash, mAcquiringLedger;
|
||||
Ledger::pointer mPreviousLedger;
|
||||
@@ -1750,11 +1725,20 @@ private:
|
||||
RippleAddress mValPublic, mValPrivate;
|
||||
bool mProposing, mValidating, mHaveCorrectLCL, mConsensusFail;
|
||||
|
||||
int mCurrentMSeconds, mClosePercent, mCloseResolution;
|
||||
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
|
||||
@@ -1771,7 +1755,7 @@ private:
|
||||
std::map<std::uint32_t, int> mCloseTimes;
|
||||
|
||||
// nodes that have bowed out of this consensus process
|
||||
NodeIDSet mDeadNodes;
|
||||
hash_set<NodeID> mDeadNodes;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -1781,12 +1765,14 @@ LedgerConsensus::~LedgerConsensus ()
|
||||
}
|
||||
|
||||
std::shared_ptr <LedgerConsensus>
|
||||
make_LedgerConsensus (LocalTxs& localtx,
|
||||
make_LedgerConsensus (int previousProposers, int previousConvergeTime,
|
||||
InboundTransactions& inboundTransactions, LocalTxs& localtx,
|
||||
LedgerHash const &prevLCLHash, Ledger::ref previousLedger,
|
||||
std::uint32_t closeTime, FeeVote& feeVote)
|
||||
{
|
||||
return std::make_shared <LedgerConsensusImp> (localtx,
|
||||
prevLCLHash, previousLedger, closeTime, feeVote);
|
||||
return std::make_shared <LedgerConsensusImp> (previousProposers,
|
||||
previousConvergeTime, inboundTransactions, localtx, prevLCLHash,
|
||||
previousLedger, closeTime, feeVote);
|
||||
}
|
||||
|
||||
/** Apply a transaction to a ledger
|
||||
@@ -1858,7 +1844,8 @@ int applyTransaction (TransactionEngine& engine
|
||||
@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).
|
||||
messages (typically new last closed
|
||||
ledger).
|
||||
@param retriableTransactions collect failed transactions in this set
|
||||
@param openLgr true if applyLedger is open, else false.
|
||||
*/
|
||||
@@ -20,11 +20,11 @@
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/ledger/LedgerMaster.h>
|
||||
#include <ripple/app/ledger/InboundLedgers.h>
|
||||
#include <ripple/app/ledger/LedgerCleaner.h>
|
||||
#include <ripple/app/ledger/LedgerHistory.h>
|
||||
#include <ripple/app/ledger/LedgerHolder.h>
|
||||
#include <ripple/app/ledger/OrderBookDB.h>
|
||||
#include <ripple/app/ledger/PendingSaves.h>
|
||||
#include <ripple/app/ledger/impl/LedgerCleaner.h>
|
||||
#include <ripple/app/main/Application.h>
|
||||
#include <ripple/app/misc/IHashRouter.h>
|
||||
#include <ripple/app/misc/NetworkOPs.h>
|
||||
@@ -179,4 +179,14 @@ int getNextLedgerTimeResolution (
|
||||
return previousResolution;
|
||||
}
|
||||
|
||||
std::uint32_t roundCloseTime (
|
||||
std::uint32_t closeTime,
|
||||
std::uint32_t closeResolution)
|
||||
{
|
||||
if (closeTime == 0)
|
||||
return 0;
|
||||
|
||||
closeTime += (closeResolution / 2);
|
||||
return closeTime - (closeTime % closeResolution);
|
||||
}
|
||||
} // ripple
|
||||
@@ -101,8 +101,8 @@ public:
|
||||
, m_clusterTimer (this)
|
||||
, m_ledgerMaster (ledgerMaster)
|
||||
, mCloseTimeOffset (0)
|
||||
, mLastCloseProposers (0)
|
||||
, mLastCloseConvergeTime (1000 * LEDGER_IDLE_INTERVAL)
|
||||
, lastCloseProposers_ (0)
|
||||
, lastCloseConvergeTook_ (1000 * LEDGER_IDLE_INTERVAL)
|
||||
, mLastCloseTime (0)
|
||||
, mLastValidationTime (0)
|
||||
, mFetchPack ("FetchPack", 65536, 45, clock,
|
||||
@@ -278,7 +278,7 @@ public:
|
||||
void processTrustedProposal (
|
||||
LedgerProposal::pointer proposal,
|
||||
std::shared_ptr<protocol::TMProposeSet> set,
|
||||
RippleAddress nodePublic, uint256 checkLedger, bool sigGood) override;
|
||||
RippleAddress const &nodePublic) override;
|
||||
|
||||
bool recvValidation (
|
||||
STValidation::ref val, std::string const& source) override;
|
||||
@@ -314,7 +314,7 @@ private:
|
||||
Ledger::pointer newLedger, bool duringConsensus);
|
||||
bool checkLastClosedLedger (
|
||||
const Overlay::PeerSequence&, uint256& networkClosed);
|
||||
int beginConsensus (
|
||||
bool beginConsensus (
|
||||
uint256 const& networkClosed, Ledger::pointer closingLedger);
|
||||
void tryStartConsensus ();
|
||||
|
||||
@@ -367,14 +367,6 @@ public:
|
||||
}
|
||||
void setAmendmentBlocked () override;
|
||||
void consensusViewChange () override;
|
||||
int getPreviousProposers () override
|
||||
{
|
||||
return mLastCloseProposers;
|
||||
}
|
||||
int getPreviousConvergeTime () override
|
||||
{
|
||||
return mLastCloseConvergeTime;
|
||||
}
|
||||
std::uint32_t getLastCloseTime () override
|
||||
{
|
||||
return mLastCloseTime;
|
||||
@@ -558,8 +550,6 @@ private:
|
||||
bool mValidating;
|
||||
bool m_amendmentBlocked;
|
||||
|
||||
boost::posix_time::ptime mConnectTime;
|
||||
|
||||
beast::DeadlineTimer m_heartbeatTimer;
|
||||
beast::DeadlineTimer m_clusterTimer;
|
||||
|
||||
@@ -571,10 +561,14 @@ private:
|
||||
|
||||
int mCloseTimeOffset;
|
||||
|
||||
// last ledger close
|
||||
int mLastCloseProposers;
|
||||
int mLastCloseConvergeTime;
|
||||
uint256 mLastCloseHash;
|
||||
// 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;
|
||||
@@ -1316,10 +1310,9 @@ bool NetworkOPsImp::checkLastClosedLedger (
|
||||
auto current = getApp().getValidations ().getCurrentValidations (
|
||||
closedLedger, prevClosedLedger);
|
||||
|
||||
using u256_cvc_pair = std::map<uint256, ValidationCounter>::value_type;
|
||||
for (auto& it: current)
|
||||
{
|
||||
ValidationCount& vc = ledgers[it.first];
|
||||
auto& vc = ledgers[it.first];
|
||||
vc.trustedValidations += it.second.first;
|
||||
|
||||
if (it.second.second > vc.highValidation)
|
||||
@@ -1327,7 +1320,7 @@ bool NetworkOPsImp::checkLastClosedLedger (
|
||||
}
|
||||
}
|
||||
|
||||
ValidationCount& ourVC = ledgers[closedLedger];
|
||||
auto& ourVC = ledgers[closedLedger];
|
||||
|
||||
if (mMode >= omTRACKING)
|
||||
{
|
||||
@@ -1347,7 +1340,7 @@ bool NetworkOPsImp::checkLastClosedLedger (
|
||||
{
|
||||
try
|
||||
{
|
||||
ValidationCount& vc = ledgers[peerLedger];
|
||||
auto& vc = ledgers[peerLedger];
|
||||
|
||||
if (vc.nodesUsing == 0 ||
|
||||
peer->getNodePublic ().getNodeID () > vc.highNodeUsing)
|
||||
@@ -1364,7 +1357,7 @@ bool NetworkOPsImp::checkLastClosedLedger (
|
||||
}
|
||||
}
|
||||
|
||||
ValidationCount bestVC = ledgers[closedLedger];
|
||||
auto bestVC = ledgers[closedLedger];
|
||||
|
||||
// 3) Is there a network ledger we'd like to switch to? If so, do we have
|
||||
// it?
|
||||
@@ -1458,16 +1451,15 @@ void NetworkOPsImp::switchLastClosedLedger (
|
||||
std::make_shared<Message> (s, protocol::mtSTATUS_CHANGE)));
|
||||
}
|
||||
|
||||
int NetworkOPsImp::beginConsensus (
|
||||
bool NetworkOPsImp::beginConsensus (
|
||||
uint256 const& networkClosed, Ledger::pointer closingLedger)
|
||||
{
|
||||
m_journal.info
|
||||
<< "Consensus time for ledger " << closingLedger->getLedgerSeq ();
|
||||
m_journal.info
|
||||
<< " LCL is " << closingLedger->getParentHash ();
|
||||
if (m_journal.info) m_journal.info <<
|
||||
"Consensus time for #" << closingLedger->getLedgerSeq () <<
|
||||
" with LCL " << closingLedger->getParentHash ();
|
||||
|
||||
auto prevLedger
|
||||
= m_ledgerMaster.getLedgerByHash (closingLedger->getParentHash ());
|
||||
auto prevLedger = m_ledgerMaster.getLedgerByHash (
|
||||
closingLedger->getParentHash ());
|
||||
|
||||
if (!prevLedger)
|
||||
{
|
||||
@@ -1478,7 +1470,7 @@ int NetworkOPsImp::beginConsensus (
|
||||
setMode (omTRACKING);
|
||||
}
|
||||
|
||||
return 3;
|
||||
return false;
|
||||
}
|
||||
|
||||
assert (prevLedger->getHash () == closingLedger->getParentHash ());
|
||||
@@ -1489,12 +1481,18 @@ int NetworkOPsImp::beginConsensus (
|
||||
assert (!mConsensus);
|
||||
prevLedger->setImmutable ();
|
||||
|
||||
mConsensus = make_LedgerConsensus (*m_localTX, networkClosed,
|
||||
prevLedger, m_ledgerMaster.getCurrentLedger ()->getCloseTimeNC (),
|
||||
mConsensus = make_LedgerConsensus (
|
||||
lastCloseProposers_,
|
||||
lastCloseConvergeTook_,
|
||||
getApp().getInboundTransactions(),
|
||||
*m_localTX,
|
||||
networkClosed,
|
||||
prevLedger,
|
||||
m_ledgerMaster.getCurrentLedger ()->getCloseTimeNC (),
|
||||
*m_feeVote);
|
||||
|
||||
m_journal.debug << "Initiating consensus engine";
|
||||
return mConsensus->startup ();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetworkOPsImp::haveConsensusObject ()
|
||||
@@ -1517,7 +1515,7 @@ bool NetworkOPsImp::haveConsensusObject ()
|
||||
{
|
||||
m_journal.info << "Beginning consensus due to peer action";
|
||||
if ( ((mMode == omTRACKING) || (mMode == omSYNCING)) &&
|
||||
(getPreviousProposers() >= m_ledgerMaster.getMinValidations()) )
|
||||
(lastCloseProposers_ >= m_ledgerMaster.getMinValidations()) )
|
||||
setMode (omFULL);
|
||||
beginConsensus (networkClosed, m_ledgerMaster.getCurrentLedger ());
|
||||
}
|
||||
@@ -1536,8 +1534,7 @@ uint256 NetworkOPsImp::getConsensusLCL ()
|
||||
|
||||
void NetworkOPsImp::processTrustedProposal (
|
||||
LedgerProposal::pointer proposal,
|
||||
std::shared_ptr<protocol::TMProposeSet> set, RippleAddress nodePublic,
|
||||
uint256 checkLedger, bool sigGood)
|
||||
std::shared_ptr<protocol::TMProposeSet> set, const RippleAddress& nodePublic)
|
||||
{
|
||||
{
|
||||
auto lock = beast::make_lock(getApp().getMasterMutex());
|
||||
@@ -1555,21 +1552,7 @@ void NetworkOPsImp::processTrustedProposal (
|
||||
{
|
||||
storeProposal (proposal, nodePublic);
|
||||
|
||||
uint256 consensusLCL = mConsensus->getLCL ();
|
||||
|
||||
if (!set->has_previousledger () && (checkLedger != consensusLCL))
|
||||
{
|
||||
m_journal.warning
|
||||
<< "Have to re-check proposal signature due to "
|
||||
<< "consensus view change";
|
||||
assert (proposal->hasSignature ());
|
||||
proposal->setPrevLedger (consensusLCL);
|
||||
|
||||
if (proposal->checkSign ())
|
||||
sigGood = true;
|
||||
}
|
||||
|
||||
if (sigGood && (consensusLCL == proposal->getPrevLedger ()))
|
||||
if (mConsensus->getLCL () == proposal->getPrevLedger ())
|
||||
{
|
||||
relay = mConsensus->peerPosition (proposal);
|
||||
m_journal.trace
|
||||
@@ -1685,7 +1668,6 @@ void NetworkOPsImp::pubServer ()
|
||||
|
||||
void NetworkOPsImp::setMode (OperatingMode om)
|
||||
{
|
||||
|
||||
if (om == omCONNECTED)
|
||||
{
|
||||
if (getApp().getLedgerMaster ().getValidatedLedgerAge () < 60)
|
||||
@@ -1703,14 +1685,9 @@ void NetworkOPsImp::setMode (OperatingMode om)
|
||||
if (mMode == om)
|
||||
return;
|
||||
|
||||
if ((om >= omCONNECTED) && (mMode == omDISCONNECTED))
|
||||
mConnectTime = boost::posix_time::second_clock::universal_time ();
|
||||
|
||||
mMode = om;
|
||||
|
||||
m_journal.stream((om < mMode)
|
||||
? beast::Journal::kWarning : beast::Journal::kInfo)
|
||||
<< "STATE->" << strOperatingMode ();
|
||||
m_journal.info << "STATE->" << strOperatingMode ();
|
||||
pubServer ();
|
||||
}
|
||||
|
||||
@@ -2060,17 +2037,17 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin)
|
||||
info[jss::peers] = Json::UInt (getApp ().overlay ().size ());
|
||||
|
||||
Json::Value lastClose = Json::objectValue;
|
||||
lastClose[jss::proposers] = getApp().getOPs ().getPreviousProposers ();
|
||||
lastClose[jss::proposers] = lastCloseProposers_;
|
||||
|
||||
if (human)
|
||||
{
|
||||
lastClose[jss::converge_time_s] = static_cast<double> (
|
||||
getApp().getOPs ().getPreviousConvergeTime ()) / 1000.0;
|
||||
lastCloseConvergeTook_) / 1000.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastClose[jss::converge_time] =
|
||||
Json::Int (getApp().getOPs ().getPreviousConvergeTime ());
|
||||
Json::Int (lastCloseConvergeTook_);
|
||||
}
|
||||
|
||||
info[jss::last_close] = lastClose;
|
||||
@@ -2592,14 +2569,22 @@ void NetworkOPsImp::newLCL (
|
||||
int proposers, int convergeTime, uint256 const& ledgerHash)
|
||||
{
|
||||
assert (convergeTime);
|
||||
mLastCloseProposers = proposers;
|
||||
mLastCloseConvergeTime = convergeTime;
|
||||
mLastCloseHash = ledgerHash;
|
||||
lastCloseProposers_ = proposers;
|
||||
lastCloseConvergeTook_ = convergeTime;
|
||||
lastCloseHash_ = ledgerHash;
|
||||
}
|
||||
|
||||
std::uint32_t NetworkOPsImp::acceptLedger ()
|
||||
{
|
||||
// accept the current transaction tree, return the new ledger's sequence
|
||||
// This code-path is exclusively used when the server is in standalone
|
||||
// mode via `ledger_accept`
|
||||
assert (m_standalone);
|
||||
|
||||
if (!m_standalone)
|
||||
throw std::runtime_error ("Operation only possible in STANDALONE mode.");
|
||||
|
||||
// FIXME Could we improve on this and remove the need for a specialized
|
||||
// API in LedgerConsensus?
|
||||
beginConsensus (
|
||||
m_ledgerMaster.getClosedLedger ()->getHash (),
|
||||
m_ledgerMaster.getCurrentLedger ());
|
||||
@@ -2612,7 +2597,7 @@ void NetworkOPsImp::storeProposal (
|
||||
{
|
||||
auto& props = mStoredProposals[peerPublic.getNodeID ()];
|
||||
|
||||
if (props.size () >= (unsigned) (mLastCloseProposers + 10))
|
||||
if (props.size () >= (unsigned) (lastCloseProposers_ + 10))
|
||||
props.pop_front ();
|
||||
|
||||
props.push_back (proposal);
|
||||
|
||||
@@ -212,8 +212,8 @@ public:
|
||||
|
||||
// ledger proposal/close functions
|
||||
virtual void processTrustedProposal (LedgerProposal::pointer proposal,
|
||||
std::shared_ptr<protocol::TMProposeSet> set, RippleAddress nodePublic,
|
||||
uint256 checkLedger, bool sigGood) = 0;
|
||||
std::shared_ptr<protocol::TMProposeSet> set,
|
||||
RippleAddress const& nodePublic) = 0;
|
||||
|
||||
virtual bool recvValidation (STValidation::ref val,
|
||||
std::string const& source) = 0;
|
||||
@@ -255,8 +255,6 @@ public:
|
||||
virtual bool isAmendmentBlocked () = 0;
|
||||
virtual void setAmendmentBlocked () = 0;
|
||||
virtual void consensusViewChange () = 0;
|
||||
virtual int getPreviousProposers () = 0;
|
||||
virtual int getPreviousConvergeTime () = 0;
|
||||
virtual std::uint32_t getLastCloseTime () = 0;
|
||||
virtual void setLastCloseTime (std::uint32_t t) = 0;
|
||||
|
||||
@@ -264,6 +262,13 @@ public:
|
||||
virtual Json::Value getServerInfo (bool human, bool admin) = 0;
|
||||
virtual void clearLedgerFetch () = 0;
|
||||
virtual Json::Value getLedgerFetchInfo () = 0;
|
||||
|
||||
/** Accepts the current transaction tree, return the new ledger's sequence
|
||||
|
||||
This API is only used via RPC with the server in STANDALONE mode and
|
||||
performs a virtual consensus round, with all the transactions we are
|
||||
proposing being accepted.
|
||||
*/
|
||||
virtual std::uint32_t acceptLedger () = 0;
|
||||
|
||||
using Proposals = hash_map <NodeID, std::deque<LedgerProposal::pointer>>;
|
||||
|
||||
@@ -1130,7 +1130,7 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMProposeSet> const& m)
|
||||
return;
|
||||
}
|
||||
|
||||
if (set.has_previousledger () && (set.previousledger ().size () != 32))
|
||||
if (set.previousledger ().size () != 32)
|
||||
{
|
||||
p_journal_.warning << "Proposal: malformed";
|
||||
fee_ = Resource::feeInvalidRequest;
|
||||
@@ -1139,17 +1139,14 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMProposeSet> const& m)
|
||||
|
||||
uint256 proposeHash, prevLedger;
|
||||
memcpy (proposeHash.begin (), set.currenttxhash ().data (), 32);
|
||||
|
||||
if (set.has_previousledger ())
|
||||
memcpy (prevLedger.begin (), set.previousledger ().data (), 32);
|
||||
|
||||
uint256 suppression = LedgerProposal::computeSuppressionID (
|
||||
uint256 suppression = proposalUniqueId (
|
||||
proposeHash, prevLedger, set.proposeseq(), set.closetime (),
|
||||
Blob(set.nodepubkey ().begin (), set.nodepubkey ().end ()),
|
||||
Blob(set.signature ().begin (), set.signature ().end ()));
|
||||
|
||||
if (! getApp().getHashRouter ().addSuppressionPeer (
|
||||
suppression, id_))
|
||||
if (! getApp().getHashRouter ().addSuppressionPeer (suppression, id_))
|
||||
{
|
||||
p_journal_.trace << "Proposal: duplicate";
|
||||
return;
|
||||
@@ -1166,24 +1163,26 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMProposeSet> const& m)
|
||||
|
||||
bool isTrusted = getApp().getUNL ().nodeInUNL (signerPublic);
|
||||
|
||||
if (!isTrusted && (sanity_.load() == Sanity::insane))
|
||||
if (!isTrusted)
|
||||
{
|
||||
if (sanity_.load() == Sanity::insane)
|
||||
{
|
||||
p_journal_.debug << "Proposal: Dropping UNTRUSTED (insane)";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isTrusted && getApp().getFeeTrack ().isLoadedLocal ())
|
||||
if (getApp().getFeeTrack ().isLoadedLocal ())
|
||||
{
|
||||
p_journal_.debug << "Proposal: Dropping UNTRUSTED (load)";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
p_journal_.trace <<
|
||||
"Proposal: " << (isTrusted ? "trusted" : "UNTRUSTED");
|
||||
|
||||
LedgerProposal::pointer proposal = std::make_shared<LedgerProposal> (
|
||||
prevLedger.isNonZero () ? prevLedger : uint256(),
|
||||
set.proposeseq (), proposeHash, set.closetime (),
|
||||
auto proposal = std::make_shared<LedgerProposal> (
|
||||
prevLedger, set.proposeseq (), proposeHash, set.closetime (),
|
||||
signerPublic, suppression);
|
||||
|
||||
getApp().getJobQueue ().addJob (isTrusted ? jtPROPOSAL_t : jtPROPOSAL_ut,
|
||||
@@ -1695,7 +1694,6 @@ PeerImp::checkPropose (Job& job,
|
||||
std::shared_ptr <protocol::TMProposeSet> const& packet,
|
||||
LedgerProposal::pointer proposal)
|
||||
{
|
||||
bool sigGood = false;
|
||||
bool isTrusted = (job.getType () == jtPROPOSAL_t);
|
||||
|
||||
p_journal_.trace <<
|
||||
@@ -1704,56 +1702,28 @@ PeerImp::checkPropose (Job& job,
|
||||
assert (packet);
|
||||
protocol::TMProposeSet& set = *packet;
|
||||
|
||||
|
||||
uint256 consensusLCL;
|
||||
if (! set.has_previousledger() || ! isTrusted)
|
||||
{
|
||||
std::lock_guard<Application::MutexType> lock(getApp().getMasterMutex());
|
||||
consensusLCL = getApp().getOPs ().getConsensusLCL ();
|
||||
}
|
||||
|
||||
uint256 prevLedger;
|
||||
if (set.has_previousledger ())
|
||||
{
|
||||
// proposal includes a previous ledger
|
||||
p_journal_.trace <<
|
||||
"proposal with previous ledger";
|
||||
memcpy (prevLedger.begin (), set.previousledger ().data (), 256 / 8);
|
||||
proposal->setPrevLedger (prevLedger);
|
||||
|
||||
if (! cluster() && ! proposal->checkSign (set.signature ()))
|
||||
{
|
||||
p_journal_.warning <<
|
||||
"Proposal with previous ledger fails sig check";
|
||||
"Proposal fails sig check";
|
||||
charge (Resource::feeInvalidSignature);
|
||||
return;
|
||||
}
|
||||
else
|
||||
sigGood = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
proposal->setPrevLedger (consensusLCL);
|
||||
if (consensusLCL.isNonZero () && proposal->checkSign (set.signature ()))
|
||||
{
|
||||
prevLedger = consensusLCL;
|
||||
sigGood = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Could be mismatched prev ledger
|
||||
p_journal_.warning <<
|
||||
"Ledger proposal fails signature check";
|
||||
proposal->setSignature (set.signature ());
|
||||
}
|
||||
}
|
||||
|
||||
if (isTrusted)
|
||||
{
|
||||
getApp().getOPs ().processTrustedProposal (
|
||||
proposal, packet, publicKey_, prevLedger, sigGood);
|
||||
proposal, packet, publicKey_);
|
||||
}
|
||||
else if (sigGood && (prevLedger == consensusLCL))
|
||||
else
|
||||
{
|
||||
uint256 consensusLCL;
|
||||
{
|
||||
std::lock_guard<Application::MutexType> lock (getApp().getMasterMutex());
|
||||
consensusLCL = getApp().getOPs ().getConsensusLCL ();
|
||||
}
|
||||
|
||||
if (consensusLCL == proposal->getPrevLedger())
|
||||
{
|
||||
// relay untrusted proposal
|
||||
p_journal_.trace <<
|
||||
@@ -1766,6 +1736,7 @@ PeerImp::checkPropose (Job& job,
|
||||
"Not relaying UNTRUSTED proposal";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PeerImp::checkValidation (Job&, STValidation::pointer val,
|
||||
|
||||
@@ -186,7 +186,7 @@ message TMProposeSet
|
||||
required bytes nodePubKey = 3;
|
||||
required uint32 closeTime = 4;
|
||||
required bytes signature = 5; // signature of above fields
|
||||
optional bytes previousledger = 6;
|
||||
required bytes previousledger = 6;
|
||||
optional bool checkedSignature = 7; // node vouches signature is correct
|
||||
repeated bytes addedTransactions = 10; // not required if number is large
|
||||
repeated bytes removedTransactions = 11; // not required if number is large
|
||||
|
||||
@@ -87,8 +87,9 @@ public:
|
||||
}
|
||||
Blob getSigned () const;
|
||||
Blob getSignature () const;
|
||||
void sign (uint256 & signingHash, const RippleAddress & raPrivate);
|
||||
void sign (const RippleAddress & raPrivate);
|
||||
|
||||
// Signs the validation and returns the signing hash
|
||||
uint256 sign (const RippleAddress & raPrivate);
|
||||
|
||||
// The validation this replaced
|
||||
uint256 const& getPreviousHash ()
|
||||
|
||||
@@ -47,7 +47,6 @@ using Currency = base_uint<160, detail::CurrencyTag>;
|
||||
using NodeID = base_uint<160, detail::NodeIDTag>;
|
||||
|
||||
using CurrencySet = hash_set<Currency>;
|
||||
using NodeIDSet = hash_set<NodeID>;
|
||||
|
||||
/** A special account that's used as the "issuer" for XRP. */
|
||||
Account const& xrpAccount();
|
||||
|
||||
@@ -57,20 +57,16 @@ STValidation::STValidation (
|
||||
setFlag (kFullFlag);
|
||||
}
|
||||
|
||||
void STValidation::sign (RippleAddress const& raPriv)
|
||||
{
|
||||
uint256 signingHash;
|
||||
sign (signingHash, raPriv);
|
||||
}
|
||||
|
||||
void STValidation::sign (uint256& signingHash, RippleAddress const& raPriv)
|
||||
uint256 STValidation::sign (RippleAddress const& raPriv)
|
||||
{
|
||||
setFlag (vfFullyCanonicalSig);
|
||||
|
||||
signingHash = getSigningHash ();
|
||||
auto signingHash = getSigningHash ();
|
||||
Blob signature;
|
||||
raPriv.signNodePrivate (signingHash, signature);
|
||||
setFieldVL (sfSignature, signature);
|
||||
|
||||
return signingHash;
|
||||
}
|
||||
|
||||
uint256 STValidation::getSigningHash () const
|
||||
|
||||
@@ -26,22 +26,22 @@
|
||||
#include <ripple/app/ledger/ConsensusTransSetSF.cpp>
|
||||
#include <ripple/app/ledger/DeferredCredits.cpp>
|
||||
#include <ripple/app/ledger/DirectoryEntryIterator.cpp>
|
||||
#include <ripple/app/ledger/DisputedTx.cpp>
|
||||
#include <ripple/app/ledger/InboundLedger.cpp>
|
||||
#include <ripple/app/ledger/InboundLedgers.cpp>
|
||||
#include <ripple/app/ledger/Ledger.cpp>
|
||||
#include <ripple/app/ledger/LedgerConsensus.cpp>
|
||||
#include <ripple/app/ledger/LedgerCleaner.cpp>
|
||||
#include <ripple/app/ledger/LedgerEntrySet.cpp>
|
||||
#include <ripple/app/ledger/LedgerHistory.cpp>
|
||||
#include <ripple/app/ledger/LedgerMaster.cpp>
|
||||
#include <ripple/app/ledger/LedgerProposal.cpp>
|
||||
#include <ripple/app/ledger/LedgerTiming.cpp>
|
||||
#include <ripple/app/ledger/OrderBookDB.cpp>
|
||||
#include <ripple/app/ledger/OrderBookIterator.cpp>
|
||||
#include <ripple/app/ledger/TransactionStateSF.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/LedgerFees.cpp>
|
||||
#include <ripple/app/ledger/impl/LedgerMaster.cpp>
|
||||
#include <ripple/app/ledger/impl/LedgerTiming.cpp>
|
||||
|
||||
#include <ripple/app/ledger/tests/common_ledger.cpp>
|
||||
#include <ripple/app/ledger/tests/DeferredCredits.test.cpp>
|
||||
|
||||
Reference in New Issue
Block a user