Decongest the master lock:

* Reduce scope of lock in ledger accept
* Remove duplicate tracking of transaction sets
* Need master lock to secure ledger sequencing
This commit is contained in:
David Schwartz
2015-03-06 13:22:20 -08:00
committed by Nik Bougalis
parent e44e75fa6b
commit 60a7abcef6
6 changed files with 192 additions and 277 deletions

View File

@@ -925,36 +925,6 @@ public:
return true;
}
/**
A peer has informed us that it can give us a transaction set
@param peer The peer we can get it from.
@param hashSet The transaction set we can get.
@param status Says whether or not the peer has the transaction set
locally.
@return true if we have or acquire the transaction set.
*/
bool peerHasSet (Peer::ptr const& peer, uint256 const& hashSet
, protocol::TxSetStatus status)
{
if (status != protocol::tsHAVE) // Indirect requests for future support
return true;
std::vector< std::weak_ptr<Peer> >& set = mPeerData[hashSet];
for (std::weak_ptr<Peer>& iit : set)
if (iit.lock () == peer)
return false;
set.push_back (peer);
auto acq (mAcquiring.find (hashSet));
if (acq != mAcquiring.end ())
getApp().getJobQueue().addJob(jtTXN_DATA, "peerHasTxnData",
std::bind(&TransactionAcquire::peerHasVoid, acq->second, peer));
return true;
}
/**
A peer has sent us some nodes from a transaction set
@@ -1017,6 +987,7 @@ private:
assert (set->getHash () == mOurPosition->getCurrentHash ());
// these are now obsolete
getApp().getOPs ().peekStoredProposals ().clear ();
}
std::uint32_t closeTime = roundCloseTime (mOurPosition->getCloseTime ());
bool closeTimeCorrect = true;
@@ -1130,8 +1101,6 @@ private:
// Build new open ledger
Ledger::pointer newOL = std::make_shared<Ledger>
(true, *newLCL);
LedgerMaster::ScopedLockType sl
(getApp().getLedgerMaster ().peekMutex ());
// Apply disputed transactions that didn't get in
TransactionEngine engine (newOL);
@@ -1160,6 +1129,7 @@ private:
}
}
}
if (anyDisputes)
{
applyTransactions (std::shared_ptr<SHAMap>(),
@@ -1167,6 +1137,12 @@ private:
}
{
Application::ScopedLockType lock
(getApp ().getMasterLock ());
LedgerMaster::ScopedLockType sl
(getApp().getLedgerMaster ().peekMutex ());
// Apply transactions from the old open ledger
Ledger::pointer oldOL = getApp().getLedgerMaster().getCurrentLedger();
if (oldOL->peekTransactionMap()->getHash().isNonZero ())
@@ -1176,19 +1152,17 @@ private:
applyTransactions (oldOL->peekTransactionMap (),
newOL, newLCL, retriableTransactions, true);
}
}
{
// Apply local transactions
TransactionEngine engine (newOL);
m_localTX.apply (engine);
}
// We have a new Last Closed Ledger and new Open Ledger
getApp().getLedgerMaster ().pushLedger (newLCL, newOL);
}
mNewLedgerHash = newLCL->getHash ();
mState = lcsACCEPTED;
sl.unlock ();
if (mValidating)
{
@@ -1223,7 +1197,6 @@ private:
getApp().getOPs ().closeTimeOffset (offset);
}
}
}
/**
Begin acquiring a transaction set
@@ -1232,31 +1205,7 @@ private:
*/
void startAcquiring (TransactionAcquire::pointer acquire)
{
auto it = mPeerData.find (acquire->getHash ());
if (it != mPeerData.end ())
{
// Add any peers we already know have his transaction set
std::vector< std::weak_ptr<Peer> >& peerList = it->second;
std::vector< std::weak_ptr<Peer> >::iterator pit
= peerList.begin ();
while (pit != peerList.end ())
{
Peer::ptr pr = pit->lock ();
if (!pr)
{
pit = peerList.erase (pit);
}
else
{
acquire->peerHas (pr);
++pit;
}
}
}
// FIXME: Randomize and limit the number
struct build_acquire_list
{
typedef void return_type;
@@ -1972,9 +1921,6 @@ private:
hash_map<uint256, std::shared_ptr<SHAMap>> mAcquired;
hash_map<uint256, TransactionAcquire::pointer> mAcquiring;
// Peer sets
hash_map<uint256, std::vector< std::weak_ptr<Peer> > > mPeerData;
// Disputed transactions
hash_map<uint256, DisputedTx::pointer> mDisputes;
hash_set<uint256> mCompares;

View File

@@ -77,9 +77,6 @@ public:
virtual bool peerPosition (LedgerProposal::ref) = 0;
virtual bool peerHasSet (Peer::ptr const& peer, uint256 const& set,
protocol::TxSetStatus status) = 0;
virtual SHAMapAddNode peerGaveNodes (Peer::ptr const& peer,
uint256 const& setHash,
const std::list<SHAMapNodeID>& nodeIDs,

View File

@@ -1709,19 +1709,6 @@ SHAMapAddNode NetworkOPsImp::gotTXData (
return mConsensus->peerGaveNodes (peer, hash, nodeIDs, nodeData);
}
bool NetworkOPsImp::hasTXSet (
const std::shared_ptr<Peer>& peer, uint256 const& set,
protocol::TxSetStatus status)
{
if (mConsensus == nullptr)
{
m_journal.info << "Peer has TX set, not during consensus";
return false;
}
return mConsensus->peerHasSet (peer, set, status);
}
bool NetworkOPsImp::stillNeedTXSet (uint256 const& hash)
{
if (!mConsensus)

View File

@@ -222,9 +222,6 @@ public:
virtual std::shared_ptr<SHAMap> getTXMap (uint256 const& hash) = 0;
virtual bool hasTXSet (const std::shared_ptr<Peer>& peer,
uint256 const& set, protocol::TxSetStatus status) = 0;
virtual void mapComplete (uint256 const& hash,
std::shared_ptr<SHAMap> const& map) = 0;

View File

@@ -1146,14 +1146,20 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMHaveTransactionSet> const& m)
memcpy (hash.begin (), m->hash ().data (), 32);
if (m->status () == protocol::tsHAVE)
addTxSet (hash);
{
Application::ScopedLockType lock (getApp ().getMasterLock ());
std::lock_guard<std::mutex> sl(recentLock_);
if (!getApp().getOPs ().hasTXSet (
shared_from_this (), hash, m->status ()))
if (std::find (recentTxSets_.begin (),
recentTxSets_.end (), hash) != recentTxSets_.end ())
{
fee_ = Resource::feeUnwantedData;
return;
}
if (recentTxSets_.size () == 128)
recentTxSets_.pop_front ();
recentTxSets_.push_back (hash);
}
}
@@ -1387,21 +1393,6 @@ PeerImp::addLedger (uint256 const& hash)
recentLedgers_.push_back (hash);
}
void
PeerImp::addTxSet (uint256 const& hash)
{
std::lock_guard<std::mutex> sl(recentLock_);
if (std::find (recentTxSets_.begin (),
recentTxSets_.end (), hash) != recentTxSets_.end ())
return;
if (recentTxSets_.size () == 128)
recentTxSets_.pop_front ();
recentTxSets_.push_back (hash);
}
void
PeerImp::doFetchPack (const std::shared_ptr<protocol::TMGetObjectByHash>& packet)
{

View File

@@ -396,9 +396,6 @@ private:
void
addLedger (uint256 const& hash);
void
addTxSet (uint256 const& hash);
void
doFetchPack (const std::shared_ptr<protocol::TMGetObjectByHash>& packet);