diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj
index 98c252fd0d..07adb5fac7 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj
+++ b/Builds/VisualStudio2013/RippleD.vcxproj
@@ -1394,26 +1394,44 @@
-
+
True
True
-
+
+
+ True
+ True
+
+
+ True
+ True
+
+
+ True
+ True
+
+
+
+
+ True
+ True
+
True
True
-
+
+ True
+ True
+
+
True
True
-
- True
- True
-
@@ -1422,16 +1440,6 @@
-
- True
- True
-
-
-
-
- True
- True
-
@@ -1450,10 +1458,6 @@
-
- True
- True
-
@@ -1462,10 +1466,6 @@
-
- True
- True
-
diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters
index bb9eadb998..3d4e48f432 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters
@@ -2115,24 +2115,39 @@
ripple\app\ledger
-
- ripple\app\ledger
+
+ ripple\app\ledger\impl
-
- ripple\app\ledger
+
+ ripple\app\ledger\impl
+
+ ripple\app\ledger\impl
+
+
+ ripple\app\ledger\impl
+
+
+ ripple\app\ledger\impl
+
+
+ ripple\app\ledger\impl
+
+
+ ripple\app\ledger\impl
+
ripple\app\ledger\impl
-
- ripple\app\ledger
+
+ ripple\app\ledger\impl
+
+
+ ripple\app\ledger\impl
ripple\app\ledger
-
- ripple\app\ledger
-
ripple\app\ledger
@@ -2142,15 +2157,6 @@
ripple\app\ledger
-
- ripple\app\ledger
-
-
- ripple\app\ledger
-
-
- ripple\app\ledger
-
ripple\app\ledger
@@ -2172,9 +2178,6 @@
ripple\app\ledger
-
- ripple\app\ledger
-
ripple\app\ledger
@@ -2184,9 +2187,6 @@
ripple\app\ledger
-
- ripple\app\ledger
-
ripple\app\ledger
diff --git a/src/ripple/app/ledger/InboundLedger.h b/src/ripple/app/ledger/InboundLedger.h
index 802229c95a..4648072d04 100644
--- a/src/ripple/app/ledger/InboundLedger.h
+++ b/src/ripple/app/ledger/InboundLedger.h
@@ -27,7 +27,6 @@
namespace ripple {
-// VFALCO TODO Rename to InboundLedger
// A ledger we are trying to acquire
class InboundLedger
: public PeerSet
diff --git a/src/ripple/app/ledger/Ledger.cpp b/src/ripple/app/ledger/Ledger.cpp
index ac37c2b303..418dfc26bf 100644
--- a/src/ripple/app/ledger/Ledger.cpp
+++ b/src/ripple/app/ledger/Ledger.cpp
@@ -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
*/
diff --git a/src/ripple/app/ledger/Ledger.h b/src/ripple/app/ledger/Ledger.h
index 126a5b77bc..70197fb477 100644
--- a/src/ripple/app/ledger/Ledger.h
+++ b/src/ripple/app/ledger/Ledger.h
@@ -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 ()
diff --git a/src/ripple/app/ledger/LedgerConsensus.h b/src/ripple/app/ledger/LedgerConsensus.h
index 7d26e5f0bd..650bc53a1f 100644
--- a/src/ripple/app/ledger/LedgerConsensus.h
+++ b/src/ripple/app/ledger/LedgerConsensus.h
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -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
-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);
diff --git a/src/ripple/app/ledger/LedgerProposal.cpp b/src/ripple/app/ledger/LedgerProposal.cpp
index d238939a41..26242f3f92 100644
--- a/src/ripple/app/ledger/LedgerProposal.cpp
+++ b/src/ripple/app/ledger/LedgerProposal.cpp
@@ -26,35 +26,39 @@
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)
+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)
{
- // 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 ();
+ 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 (
+ RippleAddress const& publicKey,
+ uint256 const& prevLgr,
+ uint256 const& position,
+ std::uint32_t closeTime)
+ : mPreviousLedger (prevLgr)
+ , mCurrentHash (position)
+ , mCloseTime (closeTime)
+ , mProposeSeq (seqJoin)
+ , mPublicKey (publicKey)
{
- mPeerID = mPublicKey.getNodeID ();
- mTime = std::chrono::steady_clock::now ();
-}
+ if (mPublicKey.isValid ())
+ mPeerID = mPublicKey.getNodeID ();
-LedgerProposal::LedgerProposal (uint256 const& prevLgr, uint256 const& position,
- std::uint32_t closeTime) :
- mPreviousLedger (prevLgr), mCurrentHash (position), mCloseTime (closeTime), mProposeSeq (0)
-{
- mTime = std::chrono::steady_clock::now ();
+ mTime = std::chrono::steady_clock::now ();
}
uint256 LedgerProposal::getSigningHash () const
@@ -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
diff --git a/src/ripple/app/ledger/LedgerProposal.h b/src/ripple/app/ledger/LedgerProposal.h
index ee4e1c3f51..4f9f0139d1 100644
--- a/src/ripple/app/ledger/LedgerProposal.h
+++ b/src/ripple/app/ledger/LedgerProposal.h
@@ -24,7 +24,7 @@
#include
#include
#include
-#include
+#include
#include
#include
@@ -33,35 +33,38 @@ namespace ripple {
class LedgerProposal
: public CountedObject
{
+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;
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
diff --git a/src/ripple/app/ledger/LedgerTiming.h b/src/ripple/app/ledger/LedgerTiming.h
index e16ddee3a1..c4f37d4d94 100644
--- a/src/ripple/app/ledger/LedgerTiming.h
+++ b/src/ripple/app/ledger/LedgerTiming.h
@@ -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
diff --git a/src/ripple/app/ledger/DisputedTx.cpp b/src/ripple/app/ledger/impl/DisputedTx.cpp
similarity index 99%
rename from src/ripple/app/ledger/DisputedTx.cpp
rename to src/ripple/app/ledger/impl/DisputedTx.cpp
index 62ddf2599e..209b0f28e6 100644
--- a/src/ripple/app/ledger/DisputedTx.cpp
+++ b/src/ripple/app/ledger/impl/DisputedTx.cpp
@@ -18,7 +18,7 @@
//==============================================================================
#include
-#include
+#include
#include
#include
#include
diff --git a/src/ripple/app/ledger/DisputedTx.h b/src/ripple/app/ledger/impl/DisputedTx.h
similarity index 100%
rename from src/ripple/app/ledger/DisputedTx.h
rename to src/ripple/app/ledger/impl/DisputedTx.h
diff --git a/src/ripple/app/ledger/InboundLedger.cpp b/src/ripple/app/ledger/impl/InboundLedger.cpp
similarity index 100%
rename from src/ripple/app/ledger/InboundLedger.cpp
rename to src/ripple/app/ledger/impl/InboundLedger.cpp
diff --git a/src/ripple/app/ledger/InboundLedgers.cpp b/src/ripple/app/ledger/impl/InboundLedgers.cpp
similarity index 100%
rename from src/ripple/app/ledger/InboundLedgers.cpp
rename to src/ripple/app/ledger/impl/InboundLedgers.cpp
diff --git a/src/ripple/app/ledger/LedgerCleaner.cpp b/src/ripple/app/ledger/impl/LedgerCleaner.cpp
similarity index 99%
rename from src/ripple/app/ledger/LedgerCleaner.cpp
rename to src/ripple/app/ledger/impl/LedgerCleaner.cpp
index 2f0068030d..c3df8bd9bf 100644
--- a/src/ripple/app/ledger/LedgerCleaner.cpp
+++ b/src/ripple/app/ledger/impl/LedgerCleaner.cpp
@@ -18,10 +18,10 @@
//==============================================================================
#include
-#include
#include
#include
#include
+#include
#include
#include
#include
diff --git a/src/ripple/app/ledger/LedgerCleaner.h b/src/ripple/app/ledger/impl/LedgerCleaner.h
similarity index 100%
rename from src/ripple/app/ledger/LedgerCleaner.h
rename to src/ripple/app/ledger/impl/LedgerCleaner.h
diff --git a/src/ripple/app/ledger/LedgerConsensus.cpp b/src/ripple/app/ledger/impl/LedgerConsensus.cpp
similarity index 90%
rename from src/ripple/app/ledger/LedgerConsensus.cpp
rename to src/ripple/app/ledger/impl/LedgerConsensus.cpp
index 0ff9197459..d78c3aa2a8 100644
--- a/src/ripple/app/ledger/LedgerConsensus.cpp
+++ b/src/ripple/app/ledger/impl/LedgerConsensus.cpp
@@ -18,12 +18,12 @@
//==============================================================================
#include
-#include
#include
#include
#include
#include
#include
+#include
#include
#include
#include
@@ -31,7 +31,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -66,6 +65,22 @@ class LedgerConsensusImp
, public std::enable_shared_from_this
, public CountedObject
{
+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 prevLCLHash The hash of the Last Closed Ledger (LCL).
- @param previousLedger Best guess of what the Last Closed Ledger (LCL)
- was.
- @param closeTime Closing time point of the LCL.
- @param feeVote Our desired fee levels and voting logic.
+ @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 (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::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 set)
{
-
{
- std::lock_guard 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 (false
- , *mPreviousLedger);
+ auto newLCL = std::make_shared (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
- (true, *newLCL);
+ auto newOL = std::make_shared (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 (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
- (mValPublic, mValPrivate
- , initialLedger.getParentHash ()
- , txSet, mCloseTime);
- }
- else
- {
- mOurPosition
- = std::make_shared
- (initialLedger.getParentHash (), txSet, mCloseTime);
- }
+ mOurPosition = std::make_shared
+ (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,12 +1725,21 @@ 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;
- int mPreviousMSeconds;
+
+ // 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 mPeerPositions;
@@ -1771,7 +1755,7 @@ private:
std::map mCloseTimes;
// nodes that have bowed out of this consensus process
- NodeIDSet mDeadNodes;
+ hash_set mDeadNodes;
};
//------------------------------------------------------------------------------
@@ -1781,12 +1765,14 @@ LedgerConsensus::~LedgerConsensus ()
}
std::shared_ptr
-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)
+ std::uint32_t closeTime, FeeVote& feeVote)
{
- return std::make_shared (localtx,
- prevLCLHash, previousLedger, closeTime, feeVote);
+ return std::make_shared (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.
*/
diff --git a/src/ripple/app/ledger/LedgerMaster.cpp b/src/ripple/app/ledger/impl/LedgerMaster.cpp
similarity index 99%
rename from src/ripple/app/ledger/LedgerMaster.cpp
rename to src/ripple/app/ledger/impl/LedgerMaster.cpp
index 7a812cfd09..374d6ba9e9 100644
--- a/src/ripple/app/ledger/LedgerMaster.cpp
+++ b/src/ripple/app/ledger/impl/LedgerMaster.cpp
@@ -20,11 +20,11 @@
#include
#include
#include
-#include
#include
#include
#include
#include
+#include
#include
#include
#include
diff --git a/src/ripple/app/ledger/LedgerTiming.cpp b/src/ripple/app/ledger/impl/LedgerTiming.cpp
similarity index 96%
rename from src/ripple/app/ledger/LedgerTiming.cpp
rename to src/ripple/app/ledger/impl/LedgerTiming.cpp
index d7cff8459b..a9342f8784 100644
--- a/src/ripple/app/ledger/LedgerTiming.cpp
+++ b/src/ripple/app/ledger/impl/LedgerTiming.cpp
@@ -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
diff --git a/src/ripple/app/misc/NetworkOPs.cpp b/src/ripple/app/misc/NetworkOPs.cpp
index 3509753845..1aa9915bdf 100644
--- a/src/ripple/app/misc/NetworkOPs.cpp
+++ b/src/ripple/app/misc/NetworkOPs.cpp
@@ -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 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::value_type;
- for (auto & it: current)
+ 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 (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 (),
- *m_feeVote);
+ 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 set, RippleAddress nodePublic,
- uint256 checkLedger, bool sigGood)
+ std::shared_ptr 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 (
- 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);
diff --git a/src/ripple/app/misc/NetworkOPs.h b/src/ripple/app/misc/NetworkOPs.h
index 3898561e27..fc6f0ce979 100644
--- a/src/ripple/app/misc/NetworkOPs.h
+++ b/src/ripple/app/misc/NetworkOPs.h
@@ -212,8 +212,8 @@ public:
// ledger proposal/close functions
virtual void processTrustedProposal (LedgerProposal::pointer proposal,
- std::shared_ptr set, RippleAddress nodePublic,
- uint256 checkLedger, bool sigGood) = 0;
+ std::shared_ptr 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 >;
diff --git a/src/ripple/overlay/impl/PeerImp.cpp b/src/ripple/overlay/impl/PeerImp.cpp
index ef2460fa19..ba65af9dcc 100644
--- a/src/ripple/overlay/impl/PeerImp.cpp
+++ b/src/ripple/overlay/impl/PeerImp.cpp
@@ -1130,7 +1130,7 @@ PeerImp::onMessage (std::shared_ptr 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 const& m)
uint256 proposeHash, prevLedger;
memcpy (proposeHash.begin (), set.currenttxhash ().data (), 32);
+ memcpy (prevLedger.begin (), set.previousledger ().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 ()));
+ 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,25 +1163,27 @@ PeerImp::onMessage (std::shared_ptr const& m)
bool isTrusted = getApp().getUNL ().nodeInUNL (signerPublic);
- if (!isTrusted && (sanity_.load() == Sanity::insane))
+ if (!isTrusted)
{
- p_journal_.debug << "Proposal: Dropping UNTRUSTED (insane)";
- return;
- }
+ if (sanity_.load() == Sanity::insane)
+ {
+ p_journal_.debug << "Proposal: Dropping UNTRUSTED (insane)";
+ return;
+ }
- if (!isTrusted && getApp().getFeeTrack ().isLoadedLocal ())
- {
- p_journal_.debug << "Proposal: Dropping UNTRUSTED (load)";
- return;
+ 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 (
- prevLedger.isNonZero () ? prevLedger : uint256(),
- set.proposeseq (), proposeHash, set.closetime (),
- signerPublic, suppression);
+ auto proposal = std::make_shared (
+ prevLedger, set.proposeseq (), proposeHash, set.closetime (),
+ signerPublic, suppression);
getApp().getJobQueue ().addJob (isTrusted ? jtPROPOSAL_t : jtPROPOSAL_ut,
"recvPropose->checkPropose", std::bind(beast::weak_fn(
@@ -1695,7 +1694,6 @@ PeerImp::checkPropose (Job& job,
std::shared_ptr const& packet,
LedgerProposal::pointer proposal)
{
- bool sigGood = false;
bool isTrusted = (job.getType () == jtPROPOSAL_t);
p_journal_.trace <<
@@ -1704,66 +1702,39 @@ PeerImp::checkPropose (Job& job,
assert (packet);
protocol::TMProposeSet& set = *packet;
-
- uint256 consensusLCL;
- if (! set.has_previousledger() || ! isTrusted)
+ if (! cluster() && ! proposal->checkSign (set.signature ()))
{
- std::lock_guard 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";
- 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 ());
- }
+ p_journal_.warning <<
+ "Proposal fails sig check";
+ charge (Resource::feeInvalidSignature);
+ return;
}
if (isTrusted)
{
getApp().getOPs ().processTrustedProposal (
- proposal, packet, publicKey_, prevLedger, sigGood);
- }
- else if (sigGood && (prevLedger == consensusLCL))
- {
- // relay untrusted proposal
- p_journal_.trace <<
- "relaying UNTRUSTED proposal";
- overlay_.relay(set, proposal->getSuppressionID());
+ proposal, packet, publicKey_);
}
else
{
- p_journal_.debug <<
- "Not relaying UNTRUSTED proposal";
+ uint256 consensusLCL;
+ {
+ std::lock_guard lock (getApp().getMasterMutex());
+ consensusLCL = getApp().getOPs ().getConsensusLCL ();
+ }
+
+ if (consensusLCL == proposal->getPrevLedger())
+ {
+ // relay untrusted proposal
+ p_journal_.trace <<
+ "relaying UNTRUSTED proposal";
+ overlay_.relay(set, proposal->getSuppressionID());
+ }
+ else
+ {
+ p_journal_.debug <<
+ "Not relaying UNTRUSTED proposal";
+ }
}
}
diff --git a/src/ripple/proto/ripple.proto b/src/ripple/proto/ripple.proto
index a50314727a..406fd44042 100644
--- a/src/ripple/proto/ripple.proto
+++ b/src/ripple/proto/ripple.proto
@@ -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
diff --git a/src/ripple/protocol/STValidation.h b/src/ripple/protocol/STValidation.h
index fdce28acbe..cd4faef62f 100644
--- a/src/ripple/protocol/STValidation.h
+++ b/src/ripple/protocol/STValidation.h
@@ -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 ()
diff --git a/src/ripple/protocol/UintTypes.h b/src/ripple/protocol/UintTypes.h
index 8f15c35544..050eb8f794 100644
--- a/src/ripple/protocol/UintTypes.h
+++ b/src/ripple/protocol/UintTypes.h
@@ -47,7 +47,6 @@ using Currency = base_uint<160, detail::CurrencyTag>;
using NodeID = base_uint<160, detail::NodeIDTag>;
using CurrencySet = hash_set;
-using NodeIDSet = hash_set;
/** A special account that's used as the "issuer" for XRP. */
Account const& xrpAccount();
diff --git a/src/ripple/protocol/impl/STValidation.cpp b/src/ripple/protocol/impl/STValidation.cpp
index 0a7a4e9b2e..90d0905433 100644
--- a/src/ripple/protocol/impl/STValidation.cpp
+++ b/src/ripple/protocol/impl/STValidation.cpp
@@ -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
diff --git a/src/ripple/unity/app_ledger.cpp b/src/ripple/unity/app_ledger.cpp
index 9b8f674cf0..ac07d6fe4d 100644
--- a/src/ripple/unity/app_ledger.cpp
+++ b/src/ripple/unity/app_ledger.cpp
@@ -26,22 +26,22 @@
#include
#include
#include
-#include
-#include
-#include
#include
-#include
-#include
#include
#include
-#include
#include
-#include
#include
#include
#include
+#include
+#include
+#include
+#include
+#include
#include
+#include
+#include
#include
#include