mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Remove transaction set acquire logic from consensus object
This creates a new InboundTransactions object that handles transaction sets, removing this responsibility from the consensus object. The main benefit is that many inbound transaction operations no longer require the master lock. Improve logic to decide which peers to query, when to add more peers, and when to re-query existing peers.
This commit is contained in:
committed by
Tom Ritchford
parent
00596f1436
commit
1fedede771
@@ -31,6 +31,7 @@
|
||||
#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>
|
||||
@@ -78,7 +79,6 @@ public:
|
||||
/**
|
||||
The result of applying a transaction to a ledger.
|
||||
|
||||
@param clock The clock which will be used to measure time.
|
||||
@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)
|
||||
@@ -86,11 +86,10 @@ public:
|
||||
@param closeTime Closing time point of the LCL.
|
||||
@param feeVote Our desired fee levels and voting logic.
|
||||
*/
|
||||
LedgerConsensusImp (clock_type& clock, LocalTxs& localtx,
|
||||
LedgerConsensusImp (LocalTxs& localtx,
|
||||
LedgerHash const & prevLCLHash, Ledger::ref previousLedger,
|
||||
std::uint32_t closeTime, FeeVote& feeVote)
|
||||
: m_clock (clock)
|
||||
, m_localTX (localtx)
|
||||
: m_localTX (localtx)
|
||||
, m_feeVote (feeVote)
|
||||
, mState (lcsPRE_CLOSE)
|
||||
, mCloseTime (closeTime)
|
||||
@@ -112,6 +111,8 @@ public:
|
||||
mPreviousMSeconds = getApp().getOPs ().getPreviousConvergeTime ();
|
||||
assert (mPreviousMSeconds);
|
||||
|
||||
getApp().getInboundTransactions().newRound (mPreviousLedger->getLedgerSeq());
|
||||
|
||||
// Adapt close time resolution to recent network conditions
|
||||
mCloseResolution = ContinuousLedgerTiming::getNextLedgerTimeResolution (
|
||||
mPreviousLedger->getCloseResolution (),
|
||||
@@ -256,16 +257,6 @@ public:
|
||||
ret["acquired"] = acq;
|
||||
}
|
||||
|
||||
if (!mAcquiring.empty ())
|
||||
{
|
||||
Json::Value acq (Json::arrayValue);
|
||||
for (auto& at : mAcquiring)
|
||||
{
|
||||
acq.append (to_string (at.first));
|
||||
}
|
||||
ret["acquiring"] = acq;
|
||||
}
|
||||
|
||||
if (!mDisputes.empty ())
|
||||
{
|
||||
Json::Value dsj (Json::objectValue);
|
||||
@@ -310,64 +301,6 @@ public:
|
||||
return mPrevLedgerHash;
|
||||
}
|
||||
|
||||
/**
|
||||
Get a transaction tree, fetching it from the network if required and
|
||||
requested. When the transaction acquire engine successfully acquires
|
||||
a transaction set, it will call back.
|
||||
|
||||
@param hash hash of the requested transaction tree.
|
||||
@param doAcquire true if we should get this from the network if we don't
|
||||
already have it.
|
||||
@return Pointer to the transaction tree if we got it, else
|
||||
nullptr.
|
||||
*/
|
||||
std::shared_ptr<SHAMap>
|
||||
getTransactionTree (uint256 const& hash, bool doAcquire)
|
||||
{
|
||||
auto it = mAcquired.find (hash);
|
||||
|
||||
if (it != mAcquired.end ())
|
||||
return it->second;
|
||||
|
||||
if (mState == lcsPRE_CLOSE)
|
||||
{
|
||||
std::shared_ptr<SHAMap> currentMap
|
||||
= getApp().getLedgerMaster ().getCurrentLedger ()
|
||||
->peekTransactionMap ();
|
||||
|
||||
if (currentMap->getHash () == hash)
|
||||
{
|
||||
WriteLog (lsDEBUG, LedgerConsensus)
|
||||
<< "Map " << hash << " is our current";
|
||||
currentMap = currentMap->snapShot (false);
|
||||
mapCompleteInternal (hash, currentMap, false);
|
||||
return currentMap;
|
||||
}
|
||||
}
|
||||
|
||||
if (doAcquire)
|
||||
{
|
||||
TransactionAcquire::pointer& acquiring = mAcquiring[hash];
|
||||
|
||||
if (!acquiring)
|
||||
{
|
||||
if (hash.isZero ())
|
||||
{
|
||||
auto empty = std::make_shared<SHAMap> (
|
||||
SHAMapType::TRANSACTION, getApp().family(),
|
||||
deprecatedLogs().journal("SHAMap"));
|
||||
mapCompleteInternal (hash, empty, false);
|
||||
return empty;
|
||||
}
|
||||
|
||||
acquiring = std::make_shared<TransactionAcquire> (hash, m_clock);
|
||||
startAcquiring (acquiring);
|
||||
}
|
||||
}
|
||||
|
||||
return std::shared_ptr<SHAMap> ();
|
||||
}
|
||||
|
||||
/**
|
||||
We have a complete transaction set, typically acquired from the network
|
||||
|
||||
@@ -401,7 +334,6 @@ public:
|
||||
{
|
||||
// this is an invalid/corrupt map
|
||||
mAcquired[hash] = map;
|
||||
mAcquiring.erase (hash);
|
||||
WriteLog (lsWARNING, LedgerConsensus)
|
||||
<< "A trusted node directed us to acquire an invalid TXN map";
|
||||
return;
|
||||
@@ -416,7 +348,6 @@ public:
|
||||
{
|
||||
if (it->second)
|
||||
{
|
||||
mAcquiring.erase (hash);
|
||||
return; // we already have this map
|
||||
}
|
||||
|
||||
@@ -426,6 +357,15 @@ public:
|
||||
|
||||
// We now have a map that we did not have before
|
||||
|
||||
if (!acquired)
|
||||
{
|
||||
// Put the map where others can get it
|
||||
getApp().getInboundTransactions().giveSet (hash, map, false);
|
||||
}
|
||||
|
||||
// Inform directly-connected peers that we have this transaction set
|
||||
sendHaveTxSet (hash, true);
|
||||
|
||||
if (mOurPosition && (!mOurPosition->isBowOut ())
|
||||
&& (hash != mOurPosition->getCurrentHash ()))
|
||||
{
|
||||
@@ -448,7 +388,6 @@ public:
|
||||
<< "Not ready to create disputes";
|
||||
|
||||
mAcquired[hash] = map;
|
||||
mAcquiring.erase (hash);
|
||||
|
||||
// Adjust tracking for each peer that takes this position
|
||||
std::vector<NodeID> peers;
|
||||
@@ -469,30 +408,6 @@ public:
|
||||
<< hash << " no peers were proposing it";
|
||||
}
|
||||
|
||||
// Inform directly-connected peers that we have this transaction set
|
||||
sendHaveTxSet (hash, true);
|
||||
}
|
||||
|
||||
/**
|
||||
Determine if we still need to acquire a transaction set from the network.
|
||||
If a transaction set is popular, we probably have it. If it's unpopular,
|
||||
we probably don't need it (and the peer that initially made us
|
||||
retrieve it has probably already changed its position).
|
||||
|
||||
@param hash hash of the transaction set.
|
||||
@return true if we need to acquire it, else false.
|
||||
*/
|
||||
bool stillNeedTXSet (uint256 const& hash)
|
||||
{
|
||||
if (mAcquired.find (hash) != mAcquired.end ())
|
||||
return false;
|
||||
|
||||
for (auto const& it : mPeerPositions)
|
||||
{
|
||||
if (it.second->getCurrentHash () == hash)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -852,6 +767,20 @@ public:
|
||||
, mPreviousMSeconds, mCurrentMSeconds, forReal, mConsensusFail);
|
||||
}
|
||||
|
||||
std::shared_ptr<SHAMap> getTransactionTree (uint256 const& hash)
|
||||
{
|
||||
auto it = mAcquired.find (hash);
|
||||
if (it != mAcquired.end() && it->second)
|
||||
return it->second;
|
||||
|
||||
auto set = getApp().getInboundTransactions().getSet (hash, true);
|
||||
|
||||
if (set)
|
||||
mAcquired[hash] = set;
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
A server has taken a new position, adjust our tracking
|
||||
Called when a peer takes a new postion.
|
||||
@@ -910,7 +839,7 @@ public:
|
||||
currentPosition = newPosition;
|
||||
|
||||
std::shared_ptr<SHAMap> set
|
||||
= getTransactionTree (newPosition->getCurrentHash (), true);
|
||||
= getTransactionTree (newPosition->getCurrentHash ());
|
||||
|
||||
if (set)
|
||||
{
|
||||
@@ -926,32 +855,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
A peer has sent us some nodes from a transaction set
|
||||
|
||||
@param peer The peer which has sent the nodes
|
||||
@param setHash The transaction set
|
||||
@param nodeIDs The nodes in the transaction set
|
||||
@param nodeData The data
|
||||
@return The status results of adding the nodes.
|
||||
*/
|
||||
SHAMapAddNode peerGaveNodes (Peer::ptr const& peer
|
||||
, uint256 const& setHash, const std::list<SHAMapNodeID>& nodeIDs
|
||||
, const std::list< Blob >& nodeData)
|
||||
{
|
||||
auto acq (mAcquiring.find (setHash));
|
||||
|
||||
if (acq == mAcquiring.end ())
|
||||
{
|
||||
WriteLog (lsDEBUG, LedgerConsensus)
|
||||
<< "Got TX data for set no longer acquiring: " << setHash;
|
||||
return SHAMapAddNode ();
|
||||
}
|
||||
// We must keep the set around during the function
|
||||
TransactionAcquire::pointer set = acq->second;
|
||||
return set->takeNodes (nodeIDs, nodeData, peer);
|
||||
}
|
||||
|
||||
bool isOurPubKey (const RippleAddress & k)
|
||||
{
|
||||
return k == mValPublic;
|
||||
@@ -1197,36 +1100,6 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Begin acquiring a transaction set
|
||||
|
||||
@param acquire The transaction set to acquire.
|
||||
*/
|
||||
void startAcquiring (TransactionAcquire::pointer acquire)
|
||||
{
|
||||
// FIXME: Randomize and limit the number
|
||||
struct build_acquire_list
|
||||
{
|
||||
typedef void return_type;
|
||||
|
||||
TransactionAcquire::pointer const& acquire;
|
||||
|
||||
build_acquire_list (TransactionAcquire::pointer const& acq)
|
||||
: acquire(acq)
|
||||
{ }
|
||||
|
||||
return_type operator() (Peer::ptr const& peer) const
|
||||
{
|
||||
if (peer->hasTxSet (acquire->getHash ()))
|
||||
acquire->peerHas (peer);
|
||||
}
|
||||
};
|
||||
|
||||
getApp().overlay ().foreach (build_acquire_list (acquire));
|
||||
|
||||
acquire->setTimer ();
|
||||
}
|
||||
|
||||
/**
|
||||
Compare two proposed transaction sets and create disputed
|
||||
transctions structures for any mismatches
|
||||
@@ -1883,7 +1756,6 @@ private:
|
||||
val->setFieldU32(sfLoadFee, fee);
|
||||
}
|
||||
private:
|
||||
clock_type& m_clock;
|
||||
LocalTxs& m_localTX;
|
||||
FeeVote& m_feeVote;
|
||||
|
||||
@@ -1918,7 +1790,6 @@ private:
|
||||
|
||||
// Transaction Sets, indexed by hash of transaction tree
|
||||
hash_map<uint256, std::shared_ptr<SHAMap>> mAcquired;
|
||||
hash_map<uint256, TransactionAcquire::pointer> mAcquiring;
|
||||
|
||||
// Disputed transactions
|
||||
hash_map<uint256, DisputedTx::pointer> mDisputes;
|
||||
@@ -1938,11 +1809,11 @@ LedgerConsensus::~LedgerConsensus ()
|
||||
}
|
||||
|
||||
std::shared_ptr <LedgerConsensus>
|
||||
make_LedgerConsensus (LedgerConsensus::clock_type& clock, LocalTxs& localtx,
|
||||
make_LedgerConsensus (LocalTxs& localtx,
|
||||
LedgerHash const &prevLCLHash, Ledger::ref previousLedger,
|
||||
std::uint32_t closeTime, FeeVote& feeVote)
|
||||
{
|
||||
return std::make_shared <LedgerConsensusImp> (clock, localtx,
|
||||
return std::make_shared <LedgerConsensusImp> (localtx,
|
||||
prevLCLHash, previousLedger, closeTime, feeVote);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user