Locking and dispatching performance improvements:

* Avoid taking the master lock in most peer operations
* Dispatch recvGetLedger to JobQueue
* Dispatch consensus ledger fetches.
* Release master lock earlier in RPCHandler
This commit is contained in:
David Schwartz
2014-01-15 09:57:43 -08:00
committed by JoelKatz
parent 7570b6489d
commit 663e38dcdd
5 changed files with 120 additions and 110 deletions

View File

@@ -501,30 +501,29 @@ public:
return; return;
// we need to switch the ledger we're working from // we need to switch the ledger we're working from
Ledger::pointer newLCL = getApp().getLedgerMaster ().getLedgerByHash (lclHash); Ledger::pointer newLCL = getApp().getLedgerMaster ().getLedgerByHash (mPrevLedgerHash);
if (!newLCL)
if (newLCL)
{ {
assert (newLCL->isClosed ()); if (mAcquiringLedger != lclHash)
assert (newLCL->isImmutable ()); {
assert (newLCL->getHash () == lclHash); // need to start acquiring the correct consensus LCL
mPreviousLedger = newLCL; WriteLog (lsWARNING, LedgerConsensus) << "Need consensus ledger " << mPrevLedgerHash;
mPrevLedgerHash = lclHash;
}
else if (!mAcquiringLedger || (mAcquiringLedger->getHash () != mPrevLedgerHash))
{
// need to start acquiring the correct consensus LCL
WriteLog (lsWARNING, LedgerConsensus) << "Need consensus ledger " << mPrevLedgerHash;
if (mAcquiringLedger) mAcquiringLedger = mPrevLedgerHash;
getApp().getInboundLedgers ().dropLedger (mAcquiringLedger->getHash ()); getApp().getJobQueue().addJob (jtADVANCE, "getConsensusLedger",
std::bind (
mAcquiringLedger = getApp().getInboundLedgers ().findCreateConsensusLedger (mPrevLedgerHash); &InboundLedgers::findCreateConsensusLedger,
mHaveCorrectLCL = false; &getApp().getInboundLedgers(),
mPrevLedgerHash));
mHaveCorrectLCL = false;
}
return; return;
} }
else
return; assert (newLCL->isClosed () && newLCL->isImmutable ());
assert (newLCL->getHash () == lclHash);
mPreviousLedger = newLCL;
mPrevLedgerHash = lclHash;
WriteLog (lsINFO, LedgerConsensus) << "Have the consensus ledger " << mPrevLedgerHash; WriteLog (lsINFO, LedgerConsensus) << "Have the consensus ledger " << mPrevLedgerHash;
mHaveCorrectLCL = true; mHaveCorrectLCL = true;
@@ -1872,9 +1871,8 @@ private:
LCState mState; LCState mState;
uint32 mCloseTime; // The wall time this ledger closed uint32 mCloseTime; // The wall time this ledger closed
uint256 mPrevLedgerHash, mNewLedgerHash; uint256 mPrevLedgerHash, mNewLedgerHash, mAcquiringLedger;
Ledger::pointer mPreviousLedger; Ledger::pointer mPreviousLedger;
InboundLedger::pointer mAcquiringLedger;
LedgerProposal::pointer mOurPosition; LedgerProposal::pointer mOurPosition;
RippleAddress mValPublic, mValPrivate; RippleAddress mValPublic, mValPrivate;
bool mProposing, mValidating, mHaveCorrectLCL, mConsensusFail; bool mProposing, mValidating, mHaveCorrectLCL, mConsensusFail;

View File

@@ -279,11 +279,7 @@ private:
WriteLog (lsINFO, Peer) << "Peer: Body: Error: " << getIP () << ": " << error.category ().name () << ": " << error.message () << ": " << error; WriteLog (lsINFO, Peer) << "Peer: Body: Error: " << getIP () << ": " << error.category ().name () << ": " << error.message () << ": " << error;
} }
{ detach ("hrb", true);
Application::ScopedLockType lock (getApp ().getMasterLock (), __FILE__, __LINE__);
detach ("hrb", true);
}
return; return;
} }
@@ -416,23 +412,22 @@ private:
void recvHello (protocol::TMHello & packet); void recvHello (protocol::TMHello & packet);
void recvCluster (protocol::TMCluster & packet); void recvCluster (protocol::TMCluster & packet);
void recvTransaction (protocol::TMTransaction & packet, Application::ScopedLockType& masterLockHolder); void recvTransaction (protocol::TMTransaction & packet);
void recvValidation (const boost::shared_ptr<protocol::TMValidation>& packet, Application::ScopedLockType& masterLockHolder); void recvValidation (const boost::shared_ptr<protocol::TMValidation>& packet);
void recvGetValidation (protocol::TMGetValidations & packet); void recvGetValidation (protocol::TMGetValidations & packet);
void recvContact (protocol::TMContact & packet); void recvContact (protocol::TMContact & packet);
void recvGetContacts (protocol::TMGetContacts & packet); void recvGetContacts (protocol::TMGetContacts & packet);
void recvGetPeers (protocol::TMGetPeers & packet, Application::ScopedLockType& masterLockHolder); void recvGetPeers (protocol::TMGetPeers & packet);
void recvPeers (protocol::TMPeers & packet); void recvPeers (protocol::TMPeers & packet);
void recvEndpoints (protocol::TMEndpoints & packet); void recvEndpoints (protocol::TMEndpoints & packet);
void recvGetObjectByHash (const boost::shared_ptr<protocol::TMGetObjectByHash>& packet, void recvGetObjectByHash (const boost::shared_ptr<protocol::TMGetObjectByHash>& packet);
Application::ScopedLockType& masterLockHolder);
void recvPing (protocol::TMPing & packet); void recvPing (protocol::TMPing & packet);
void recvErrorMessage (protocol::TMErrorMsg & packet); void recvErrorMessage (protocol::TMErrorMsg & packet);
void recvSearchTransaction (protocol::TMSearchTransaction & packet); void recvSearchTransaction (protocol::TMSearchTransaction & packet);
void recvGetAccount (protocol::TMGetAccount & packet); void recvGetAccount (protocol::TMGetAccount & packet);
void recvAccount (protocol::TMAccount & packet); void recvAccount (protocol::TMAccount & packet);
void recvGetLedger (protocol::TMGetLedger & packet, Application::ScopedLockType& masterLockHolder); void recvGetLedger (const boost::shared_ptr<protocol::TMGetLedger> & packet);
void recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packet, Application::ScopedLockType& masterLockHolder); void recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packet);
void recvStatus (protocol::TMStatusChange & packet); void recvStatus (protocol::TMStatusChange & packet);
void recvPropose (const boost::shared_ptr<protocol::TMProposeSet>& packet); void recvPropose (const boost::shared_ptr<protocol::TMProposeSet>& packet);
void recvHaveTxSet (protocol::TMHaveTransactionSet & packet); void recvHaveTxSet (protocol::TMHaveTransactionSet & packet);
@@ -441,6 +436,7 @@ private:
void getSessionCookie (std::string & strDst); void getSessionCookie (std::string & strDst);
void addLedger (uint256 const & ledger); void addLedger (uint256 const & ledger);
void getLedger (protocol::TMGetLedger & packet);
void addTxSet (uint256 const & TxSet); void addTxSet (uint256 const & TxSet);
void doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>& packet); void doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>& packet);
@@ -823,8 +819,6 @@ void PeerImp::processReadBuffer ()
LoadEvent::autoptr event (getApp().getJobQueue ().getLoadEventAP (jtPEER, "Peer::read")); LoadEvent::autoptr event (getApp().getJobQueue ().getLoadEventAP (jtPEER, "Peer::read"));
{ {
Application::ScopedLockType lock (getApp ().getMasterLock (), __FILE__, __LINE__);
// If connected and get a mtHELLO or if not connected and get a non-mtHELLO, wrong message was sent. // If connected and get a mtHELLO or if not connected and get a non-mtHELLO, wrong message was sent.
if (mHelloed == (type == protocol::mtHELLO)) if (mHelloed == (type == protocol::mtHELLO))
{ {
@@ -912,7 +906,7 @@ void PeerImp::processReadBuffer ()
protocol::TMGetPeers msg; protocol::TMGetPeers msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
recvGetPeers (msg, lock); recvGetPeers (msg);
else else
WriteLog (lsWARNING, Peer) << "parse error: " << type; WriteLog (lsWARNING, Peer) << "parse error: " << type;
} }
@@ -984,7 +978,7 @@ void PeerImp::processReadBuffer ()
protocol::TMTransaction msg; protocol::TMTransaction msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
recvTransaction (msg, lock); recvTransaction (msg);
else else
WriteLog (lsWARNING, Peer) << "parse error: " << type; WriteLog (lsWARNING, Peer) << "parse error: " << type;
} }
@@ -1017,10 +1011,10 @@ void PeerImp::processReadBuffer ()
case protocol::mtGET_LEDGER: case protocol::mtGET_LEDGER:
{ {
event->reName ("Peer::getledger"); event->reName ("Peer::getledger");
protocol::TMGetLedger msg; boost::shared_ptr<protocol::TMGetLedger> msg = boost::make_shared<protocol::TMGetLedger> ();
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
recvGetLedger (msg, lock); recvGetLedger (msg);
else else
WriteLog (lsWARNING, Peer) << "parse error: " << type; WriteLog (lsWARNING, Peer) << "parse error: " << type;
} }
@@ -1032,7 +1026,7 @@ void PeerImp::processReadBuffer ()
boost::shared_ptr<protocol::TMLedgerData> msg = boost::make_shared<protocol::TMLedgerData> (); boost::shared_ptr<protocol::TMLedgerData> msg = boost::make_shared<protocol::TMLedgerData> ();
if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
recvLedger (msg, lock); recvLedger (msg);
else else
WriteLog (lsWARNING, Peer) << "parse error: " << type; WriteLog (lsWARNING, Peer) << "parse error: " << type;
} }
@@ -1056,7 +1050,7 @@ void PeerImp::processReadBuffer ()
boost::shared_ptr<protocol::TMValidation> msg = boost::make_shared<protocol::TMValidation> (); boost::shared_ptr<protocol::TMValidation> msg = boost::make_shared<protocol::TMValidation> ();
if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
recvValidation (msg, lock); recvValidation (msg);
else else
WriteLog (lsWARNING, Peer) << "parse error: " << type; WriteLog (lsWARNING, Peer) << "parse error: " << type;
} }
@@ -1082,7 +1076,7 @@ void PeerImp::processReadBuffer ()
boost::shared_ptr<protocol::TMGetObjectByHash> msg = boost::make_shared<protocol::TMGetObjectByHash> (); boost::shared_ptr<protocol::TMGetObjectByHash> msg = boost::make_shared<protocol::TMGetObjectByHash> ();
if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
recvGetObjectByHash (msg, lock); recvGetObjectByHash (msg);
else else
WriteLog (lsWARNING, Peer) << "parse error: " << type; WriteLog (lsWARNING, Peer) << "parse error: " << type;
} }
@@ -1294,9 +1288,8 @@ static void checkTransaction (Job&, int flags, SerializedTransaction::pointer st
#endif #endif
} }
void PeerImp::recvTransaction (protocol::TMTransaction& packet, Application::ScopedLockType& masterLockHolder) void PeerImp::recvTransaction (protocol::TMTransaction& packet)
{ {
masterLockHolder.unlock ();
Transaction::pointer tx; Transaction::pointer tx;
#ifndef TRUST_NETWORK #ifndef TRUST_NETWORK
@@ -1475,7 +1468,12 @@ void PeerImp::recvPropose (const boost::shared_ptr<protocol::TMProposeSet>& pack
WriteLog (lsTRACE, Peer) << "Received " << (isTrusted ? "trusted" : "UNtrusted") << " proposal from " << mPeerId; WriteLog (lsTRACE, Peer) << "Received " << (isTrusted ? "trusted" : "UNtrusted") << " proposal from " << mPeerId;
uint256 consensusLCL = getApp().getOPs ().getConsensusLCL (); uint256 consensusLCL;
{
Application::ScopedLockType lock (getApp ().getMasterLock (), __FILE__, __LINE__);
consensusLCL = getApp().getOPs ().getConsensusLCL ();
}
LedgerProposal::pointer proposal = boost::make_shared<LedgerProposal> ( LedgerProposal::pointer proposal = boost::make_shared<LedgerProposal> (
prevLedger.isNonZero () ? prevLedger : consensusLCL, prevLedger.isNonZero () ? prevLedger : consensusLCL,
set.proposeseq (), proposeHash, set.closetime (), signerPublic, suppression); set.proposeseq (), proposeHash, set.closetime (), signerPublic, suppression);
@@ -1505,9 +1503,12 @@ void PeerImp::recvHaveTxSet (protocol::TMHaveTransactionSet& packet)
if (packet.status () == protocol::tsHAVE) if (packet.status () == protocol::tsHAVE)
addTxSet (hash); addTxSet (hash);
if (!getApp().getOPs ().hasTXSet (shared_from_this (), hash, packet.status ()))
{ {
charge (Resource::feeUnwantedData); Application::ScopedLockType lock (getApp ().getMasterLock (), __FILE__, __LINE__);
if (!getApp().getOPs ().hasTXSet (shared_from_this (), hash, packet.status ()))
{
charge (Resource::feeUnwantedData);
}
} }
} }
@@ -1567,10 +1568,9 @@ static void checkValidation (Job&, SerializedValidation::pointer val, bool isTru
#endif #endif
} }
void PeerImp::recvValidation (const boost::shared_ptr<protocol::TMValidation>& packet, Application::ScopedLockType& masterLockHolder) void PeerImp::recvValidation (const boost::shared_ptr<protocol::TMValidation>& packet)
{ {
uint32 closeTime = getApp().getOPs().getCloseTimeNC(); uint32 closeTime = getApp().getOPs().getCloseTimeNC();
masterLockHolder.unlock ();
if (packet->validation ().size () < 50) if (packet->validation ().size () < 50)
{ {
@@ -1677,9 +1677,8 @@ void PeerImp::recvGetContacts (protocol::TMGetContacts& packet)
// Return a list of your favorite people // Return a list of your favorite people
// TODO: filter out all the LAN peers // TODO: filter out all the LAN peers
void PeerImp::recvGetPeers (protocol::TMGetPeers& packet, Application::ScopedLockType& masterLockHolder) void PeerImp::recvGetPeers (protocol::TMGetPeers& packet)
{ {
masterLockHolder.unlock ();
std::vector<std::string> addrs; std::vector<std::string> addrs;
getApp().getPeers ().getTopNAddrs (30, addrs); getApp().getPeers ().getTopNAddrs (30, addrs);
@@ -1794,11 +1793,8 @@ void PeerImp::recvEndpoints (protocol::TMEndpoints& packet)
PeerFinder::PeerID (mNodePublic), endpoints); PeerFinder::PeerID (mNodePublic), endpoints);
} }
void PeerImp::recvGetObjectByHash (const boost::shared_ptr<protocol::TMGetObjectByHash>& ptr, void PeerImp::recvGetObjectByHash (const boost::shared_ptr<protocol::TMGetObjectByHash>& ptr)
Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
protocol::TMGetObjectByHash& packet = *ptr; protocol::TMGetObjectByHash& packet = *ptr;
if (packet.query ()) if (packet.query ())
@@ -2069,7 +2065,17 @@ void PeerImp::recvStatus (protocol::TMStatusChange& packet)
} }
} }
void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedLockType& masterLockHolder) /** Handle a TMGetLedger received from a peer
Dispatched by the JobQueue
*/
static void sGetLedger (boost::weak_ptr<Peer> wPeer, boost::shared_ptr<protocol::TMGetLedger> pPacket)
{
boost::shared_ptr<Peer> peer = wPeer.lock ();
if (peer)
peer->getLedger (*pPacket);
}
void PeerImp::getLedger (protocol::TMGetLedger & packet)
{ {
SHAMap::pointer map; SHAMap::pointer map;
protocol::TMLedgerData reply; protocol::TMLedgerData reply;
@@ -2094,8 +2100,11 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
uint256 txHash; uint256 txHash;
memcpy (txHash.begin (), packet.ledgerhash ().data (), 32); memcpy (txHash.begin (), packet.ledgerhash ().data (), 32);
map = getApp().getOPs ().getTXMap (txHash);
masterLockHolder.unlock(); {
Application::ScopedLockType lock (getApp ().getMasterLock (), __FILE__, __LINE__);
map = getApp().getOPs ().getTXMap (txHash);
}
if (!map) if (!map)
{ {
@@ -2135,7 +2144,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
} }
else else
{ {
masterLockHolder.unlock ();
if (getApp().getFeeTrack().isLoadedLocal() && !mCluster) if (getApp().getFeeTrack().isLoadedLocal() && !mCluster)
{ {
WriteLog (lsDEBUG, Peer) << "Too busy to fetch ledger data"; WriteLog (lsDEBUG, Peer) << "Too busy to fetch ledger data";
@@ -2267,7 +2275,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
} }
PackedMessage::pointer oPacket = boost::make_shared<PackedMessage> (reply, protocol::mtLEDGER_DATA); PackedMessage::pointer oPacket = boost::make_shared<PackedMessage> (reply, protocol::mtLEDGER_DATA);
sendPacket (oPacket, true); sendPacket (oPacket, false);
return; return;
} }
@@ -2351,12 +2359,17 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
} }
PackedMessage::pointer oPacket = boost::make_shared<PackedMessage> (reply, protocol::mtLEDGER_DATA); PackedMessage::pointer oPacket = boost::make_shared<PackedMessage> (reply, protocol::mtLEDGER_DATA);
sendPacket (oPacket, true); sendPacket (oPacket, false);
} }
void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packet_ptr, Application::ScopedLockType& masterLockHolder) void PeerImp::recvGetLedger (boost::shared_ptr<protocol::TMGetLedger> const& packet)
{
getApp().getJobQueue().addJob (jtPACK, "recvGetLedger",
std::bind (&sGetLedger, boost::weak_ptr<Peer> (shared_from_this ()), packet));
}
void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packet_ptr)
{ {
masterLockHolder.unlock ();
protocol::TMLedgerData& packet = *packet_ptr; protocol::TMLedgerData& packet = *packet_ptr;
if (packet.nodes ().size () <= 0) if (packet.nodes ().size () <= 0)
@@ -2416,9 +2429,14 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
nodeData.push_back (Blob (node.nodedata ().begin (), node.nodedata ().end ())); nodeData.push_back (Blob (node.nodedata ().begin (), node.nodedata ().end ()));
} }
SHAMapAddNode san = getApp().getOPs ().gotTXData (shared_from_this (), hash, nodeIDs, nodeData); bool doCharge = false;
{
Application::ScopedLockType lock (getApp ().getMasterLock (), __FILE__, __LINE__);
if (getApp().getOPs ().gotTXData (shared_from_this (), hash, nodeIDs, nodeData).isInvalid ())
doCharge = true;
}
if (san.isInvalid ()) if (doCharge)
{ {
charge (Resource::feeUnwantedData); charge (Resource::feeUnwantedData);
} }
@@ -2479,7 +2497,7 @@ bool PeerImp::hasTxSet (uint256 const& hash) const
{ {
if (set == hash) if (set == hash)
return true; return true;
} }
return false; return false;
} }
@@ -2491,7 +2509,7 @@ void PeerImp::addTxSet (uint256 const& hash)
{ {
if (set == hash) if (set == hash)
return; return;
} }
if (mRecentTxSets.size () == 128) if (mRecentTxSets.size () == 128)
mRecentTxSets.pop_front (); mRecentTxSets.pop_front ();

View File

@@ -68,6 +68,8 @@ public:
virtual void sendGetPeers () = 0; virtual void sendGetPeers () = 0;
virtual void getLedger (protocol::TMGetLedger &) = 0;
// VFALCO NOTE what's with this odd parameter passing? Why the static member? // VFALCO NOTE what's with this odd parameter passing? Why the static member?
// //
/** Adjust this peer's load balance based on the type of load imposed. /** Adjust this peer's load balance based on the type of load imposed.

View File

@@ -633,13 +633,12 @@ Json::Value RPCHandler::accountFromString (Ledger::ref lrLedger, RippleAddress&
Json::Value RPCHandler::doAccountCurrencies (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doAccountCurrencies (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
Ledger::pointer lpLedger; Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger); Json::Value jvResult = lookupLedger (params, lpLedger);
if (!lpLedger) if (!lpLedger)
return jvResult; return jvResult;
if (lpLedger->isImmutable ())
masterLockHolder.unlock ();
if (!params.isMember ("account") && !params.isMember ("ident")) if (!params.isMember ("account") && !params.isMember ("ident"))
return rpcError (rpcINVALID_PARAMS); return rpcError (rpcINVALID_PARAMS);
@@ -699,6 +698,8 @@ Json::Value RPCHandler::doAccountCurrencies (Json::Value params, Resource::Charg
// } // }
Json::Value RPCHandler::doAccountInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doAccountInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
Ledger::pointer lpLedger; Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger); Json::Value jvResult = lookupLedger (params, lpLedger);
@@ -1182,20 +1183,14 @@ Json::Value RPCHandler::doProofVerify (Json::Value params, Resource::Charge& loa
// } // }
Json::Value RPCHandler::doAccountLines (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doAccountLines (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
Ledger::pointer lpLedger; Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger); Json::Value jvResult = lookupLedger (params, lpLedger);
if (!lpLedger) if (!lpLedger)
return jvResult; return jvResult;
bool bUnlocked = false;
if (lpLedger->isImmutable ())
{
masterLockHolder.unlock ();
bUnlocked = true;
}
if (!params.isMember ("account")) if (!params.isMember ("account"))
return rpcError (rpcINVALID_PARAMS); return rpcError (rpcINVALID_PARAMS);
@@ -1232,8 +1227,6 @@ Json::Value RPCHandler::doAccountLines (Json::Value params, Resource::Charge& lo
if (lpLedger->hasAccount (raAccount)) if (lpLedger->hasAccount (raAccount))
{ {
AccountItems rippleLines (raAccount.getAccountID (), lpLedger, AccountItem::pointer (new RippleState ())); AccountItems rippleLines (raAccount.getAccountID (), lpLedger, AccountItem::pointer (new RippleState ()));
if (!bUnlocked)
masterLockHolder.unlock ();
jvResult["account"] = raAccount.humanAccountID (); jvResult["account"] = raAccount.humanAccountID ();
Json::Value& jsonLines = (jvResult["lines"] = Json::arrayValue); Json::Value& jsonLines = (jvResult["lines"] = Json::arrayValue);
@@ -1301,20 +1294,14 @@ static void offerAdder (Json::Value& jvLines, SLE::ref offer)
// } // }
Json::Value RPCHandler::doAccountOffers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doAccountOffers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
Ledger::pointer lpLedger; Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger); Json::Value jvResult = lookupLedger (params, lpLedger);
if (!lpLedger) if (!lpLedger)
return jvResult; return jvResult;
bool bUnlocked = false;
if (lpLedger->isImmutable ())
{
masterLockHolder.unlock ();
bUnlocked = true;
}
if (!params.isMember ("account")) if (!params.isMember ("account"))
return rpcError (rpcINVALID_PARAMS); return rpcError (rpcINVALID_PARAMS);
@@ -1342,8 +1329,6 @@ Json::Value RPCHandler::doAccountOffers (Json::Value params, Resource::Charge& l
Json::Value& jvsOffers = (jvResult["offers"] = Json::arrayValue); Json::Value& jvsOffers = (jvResult["offers"] = Json::arrayValue);
lpLedger->visitAccountItems (raAccount.getAccountID (), BIND_TYPE (&offerAdder, boost::ref (jvsOffers), P_1)); lpLedger->visitAccountItems (raAccount.getAccountID (), BIND_TYPE (&offerAdder, boost::ref (jvsOffers), P_1));
if (!bUnlocked)
masterLockHolder.unlock ();
loadType = Resource::feeMediumBurdenRPC; loadType = Resource::feeMediumBurdenRPC;
return jvResult; return jvResult;
@@ -1361,6 +1346,8 @@ Json::Value RPCHandler::doAccountOffers (Json::Value params, Resource::Charge& l
// } // }
Json::Value RPCHandler::doBookOffers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doBookOffers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
if (getApp().getJobQueue ().getJobCountGE (jtCLIENT) > 200) if (getApp().getJobQueue ().getJobCountGE (jtCLIENT) > 200)
{ {
return rpcError (rpcTOO_BUSY); return rpcError (rpcTOO_BUSY);
@@ -1372,9 +1359,6 @@ Json::Value RPCHandler::doBookOffers (Json::Value params, Resource::Charge& load
if (!lpLedger) if (!lpLedger)
return jvResult; return jvResult;
if (lpLedger->isImmutable ())
masterLockHolder.unlock ();
if (!params.isMember ("taker_pays") || !params.isMember ("taker_gets") || !params["taker_pays"].isObject () || !params["taker_gets"].isObject ()) if (!params.isMember ("taker_pays") || !params.isMember ("taker_gets") || !params["taker_pays"].isObject () || !params["taker_gets"].isObject ())
return rpcError (rpcINVALID_PARAMS); return rpcError (rpcINVALID_PARAMS);
@@ -1529,6 +1513,8 @@ Json::Value RPCHandler::doPathFind (Json::Value params, Resource::Charge& loadTy
// This interface is deprecated. // This interface is deprecated.
Json::Value RPCHandler::doRipplePathFind (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doRipplePathFind (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
LegacyPathFind lpf (mRole == Config::ADMIN); LegacyPathFind lpf (mRole == Config::ADMIN);
if (!lpf.isOkay ()) if (!lpf.isOkay ())
return rpcError (rpcTOO_BUSY); return rpcError (rpcTOO_BUSY);
@@ -1603,8 +1589,6 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value params, Resource::Charge&
cache = getApp().getPathRequests().getLineCache(lpLedger, false); cache = getApp().getPathRequests().getLineCache(lpLedger, false);
} }
masterLockHolder.unlock (); // As long as we have a locked copy of the ledger, we can unlock.
Json::Value jvSrcCurrencies; Json::Value jvSrcCurrencies;
if (params.isMember ("source_currencies")) if (params.isMember ("source_currencies"))
@@ -1944,8 +1928,8 @@ Json::Value RPCHandler::doServerState (Json::Value, Resource::Charge& loadType,
// } // }
Json::Value RPCHandler::doTxHistory (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doTxHistory (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
loadType = Resource::feeMediumBurdenRPC;
masterLockHolder.unlock (); masterLockHolder.unlock ();
loadType = Resource::feeMediumBurdenRPC;
if (!params.isMember ("start")) if (!params.isMember ("start"))
return rpcError (rpcINVALID_PARAMS); return rpcError (rpcINVALID_PARAMS);
@@ -2054,6 +2038,7 @@ Json::Value RPCHandler::doTx (Json::Value params, Resource::Charge& loadType, Ap
Json::Value RPCHandler::doLedgerClosed (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doLedgerClosed (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
Json::Value jvResult; Json::Value jvResult;
uint256 uLedger = mNetOps->getClosedLedgerHash (); uint256 uLedger = mNetOps->getClosedLedgerHash ();
@@ -2067,6 +2052,7 @@ Json::Value RPCHandler::doLedgerClosed (Json::Value, Resource::Charge& loadType,
Json::Value RPCHandler::doLedgerCurrent (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doLedgerCurrent (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
Json::Value jvResult; Json::Value jvResult;
jvResult["ledger_current_index"] = mNetOps->getCurrentLedgerID (); jvResult["ledger_current_index"] = mNetOps->getCurrentLedgerID ();
@@ -2081,6 +2067,7 @@ Json::Value RPCHandler::doLedgerCurrent (Json::Value, Resource::Charge& loadType
// } // }
Json::Value RPCHandler::doLedger (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doLedger (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
if (!params.isMember ("ledger") && !params.isMember ("ledger_hash") && !params.isMember ("ledger_index")) if (!params.isMember ("ledger") && !params.isMember ("ledger_hash") && !params.isMember ("ledger_index"))
{ {
Json::Value ret (Json::objectValue), current (Json::objectValue), closed (Json::objectValue); Json::Value ret (Json::objectValue), current (Json::objectValue), closed (Json::objectValue);
@@ -2100,9 +2087,6 @@ Json::Value RPCHandler::doLedger (Json::Value params, Resource::Charge& loadType
if (!lpLedger) if (!lpLedger)
return jvResult; return jvResult;
if (lpLedger->isImmutable ())
masterLockHolder.unlock ();
bool bFull = params.isMember ("full") && params["full"].asBool (); bool bFull = params.isMember ("full") && params["full"].asBool ();
bool bTransactions = params.isMember ("transactions") && params["transactions"].asBool (); bool bTransactions = params.isMember ("transactions") && params["transactions"].asBool ();
bool bAccounts = params.isMember ("accounts") && params["accounts"].asBool (); bool bAccounts = params.isMember ("accounts") && params["accounts"].asBool ();
@@ -2150,6 +2134,8 @@ Json::Value RPCHandler::doAccountTxSwitch (Json::Value params, Resource::Charge&
// } // }
Json::Value RPCHandler::doAccountTxOld (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doAccountTxOld (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
RippleAddress raAccount; RippleAddress raAccount;
uint32 offset = params.isMember ("offset") ? params["offset"].asUInt () : 0; uint32 offset = params.isMember ("offset") ? params["offset"].asUInt () : 0;
int limit = params.isMember ("limit") ? params["limit"].asUInt () : -1; int limit = params.isMember ("limit") ? params["limit"].asUInt () : -1;
@@ -2224,7 +2210,6 @@ Json::Value RPCHandler::doAccountTxOld (Json::Value params, Resource::Charge& lo
try try
{ {
#endif #endif
masterLockHolder.unlock ();
Json::Value ret (Json::objectValue); Json::Value ret (Json::objectValue);
@@ -2310,6 +2295,8 @@ Json::Value RPCHandler::doAccountTxOld (Json::Value params, Resource::Charge& lo
// } // }
Json::Value RPCHandler::doAccountTx (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doAccountTx (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
RippleAddress raAccount; RippleAddress raAccount;
int limit = params.isMember ("limit") ? params["limit"].asUInt () : -1; int limit = params.isMember ("limit") ? params["limit"].asUInt () : -1;
bool bBinary = params.isMember ("binary") && params["binary"].asBool (); bool bBinary = params.isMember ("binary") && params["binary"].asBool ();
@@ -2371,8 +2358,6 @@ Json::Value RPCHandler::doAccountTx (Json::Value params, Resource::Charge& loadT
try try
{ {
#endif #endif
masterLockHolder.unlock ();
Json::Value ret (Json::objectValue); Json::Value ret (Json::objectValue);
ret["account"] = raAccount.humanAccountID (); ret["account"] = raAccount.humanAccountID ();
@@ -2585,6 +2570,7 @@ Json::Value RPCHandler::doWalletAccounts (Json::Value params, Resource::Charge&
Json::Value RPCHandler::doLogRotate (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doLogRotate (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
return LogSink::get()->rotateLog (); return LogSink::get()->rotateLog ();
} }
@@ -2929,6 +2915,7 @@ Json::Value RPCHandler::doUnlScore (Json::Value, Resource::Charge& loadType, App
Json::Value RPCHandler::doSMS (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doSMS (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
if (!params.isMember ("text")) if (!params.isMember ("text"))
return rpcError (rpcINVALID_PARAMS); return rpcError (rpcINVALID_PARAMS);
@@ -2975,15 +2962,14 @@ Json::Value RPCHandler::doLedgerCleaner (Json::Value parameters, Resource::Charg
// XXX In this case, not specify either ledger does not mean ledger current. It means any ledger. // XXX In this case, not specify either ledger does not mean ledger current. It means any ledger.
Json::Value RPCHandler::doTransactionEntry (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doTransactionEntry (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
Ledger::pointer lpLedger; Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger); Json::Value jvResult = lookupLedger (params, lpLedger);
if (!lpLedger) if (!lpLedger)
return jvResult; return jvResult;
if (lpLedger->isImmutable())
masterLockHolder.unlock();
if (!params.isMember ("tx_hash")) if (!params.isMember ("tx_hash"))
{ {
jvResult["error"] = "fieldNotFoundTransaction"; jvResult["error"] = "fieldNotFoundTransaction";
@@ -3148,15 +3134,14 @@ Json::Value RPCHandler::lookupLedger (Json::Value params, Ledger::pointer& lpLed
// } // }
Json::Value RPCHandler::doLedgerEntry (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doLedgerEntry (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
Ledger::pointer lpLedger; Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger); Json::Value jvResult = lookupLedger (params, lpLedger);
if (!lpLedger) if (!lpLedger)
return jvResult; return jvResult;
if (lpLedger->isImmutable ())
masterLockHolder.unlock ();
uint256 uNodeIndex; uint256 uNodeIndex;
bool bNodeBinary = false; bool bNodeBinary = false;
@@ -3364,6 +3349,8 @@ Json::Value RPCHandler::doLedgerEntry (Json::Value params, Resource::Charge& loa
// } // }
Json::Value RPCHandler::doLedgerHeader (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doLedgerHeader (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
masterLockHolder.unlock ();
Ledger::pointer lpLedger; Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger (params, lpLedger); Json::Value jvResult = lookupLedger (params, lpLedger);
@@ -3406,6 +3393,9 @@ boost::unordered_set<RippleAddress> RPCHandler::parseAccountIds (const Json::Val
Json::Value RPCHandler::doSubscribe (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doSubscribe (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
{ {
// FIXME: This needs to release the master lock immediately
// Subscriptions need to be protected by their own lock
InfoSub::pointer ispSub; InfoSub::pointer ispSub;
Json::Value jvResult (Json::objectValue); Json::Value jvResult (Json::objectValue);
uint32 uLedgerIndex = params.isMember ("ledger_index") && params["ledger_index"].isNumeric () uint32 uLedgerIndex = params.isMember ("ledger_index") && params["ledger_index"].isNumeric ()
@@ -3670,6 +3660,8 @@ Json::Value RPCHandler::doSubscribe (Json::Value params, Resource::Charge& loadT
if (bSnapshot) if (bSnapshot)
{ {
masterLockHolder.unlock ();
loadType = Resource::feeMediumBurdenRPC; loadType = Resource::feeMediumBurdenRPC;
Ledger::pointer lpLedger = getApp().getLedgerMaster ().getPublishedLedger (); Ledger::pointer lpLedger = getApp().getLedgerMaster ().getPublishedLedger ();
if (lpLedger) if (lpLedger)

View File

@@ -101,7 +101,7 @@ const char* Job::toString (JobType t)
switch (t) switch (t)
{ {
case jtINVALID: return "invalid"; case jtINVALID: return "invalid";
case jtPACK: return "makeFetchPack"; case jtPACK: return "peerLedgerReq";
case jtPUBOLDLEDGER: return "publishAcqLedger"; case jtPUBOLDLEDGER: return "publishAcqLedger";
case jtVALIDATION_ut: return "untrustedValidation"; case jtVALIDATION_ut: return "untrustedValidation";
case jtPROOFWORK: return "proofOfWork"; case jtPROOFWORK: return "proofOfWork";