Merge #7942: locking for Misbehave() and other cs_main locking fixes

719de56 lock cs_main for chainActive (Kaz Wesley)
efb54ba lock cs_main for State/Misbehaving (Kaz Wesley)
This commit is contained in:
Wladimir J. van der Laan 2016-06-03 15:28:52 +02:00
commit c141c14c9f
No known key found for this signature in database
GPG key ID: 74810B012346C9A6

View file

@ -2922,14 +2922,15 @@ static void NotifyHeaderTip() {
*/ */
bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, const CBlock *pblock) { bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, const CBlock *pblock) {
CBlockIndex *pindexMostWork = NULL; CBlockIndex *pindexMostWork = NULL;
CBlockIndex *pindexNewTip = NULL;
do { do {
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
if (ShutdownRequested()) if (ShutdownRequested())
break; break;
CBlockIndex *pindexNewTip = NULL;
const CBlockIndex *pindexFork; const CBlockIndex *pindexFork;
bool fInitialDownload; bool fInitialDownload;
int nNewHeight;
{ {
LOCK(cs_main); LOCK(cs_main);
CBlockIndex *pindexOldTip = chainActive.Tip(); CBlockIndex *pindexOldTip = chainActive.Tip();
@ -2952,6 +2953,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
pindexNewTip = chainActive.Tip(); pindexNewTip = chainActive.Tip();
pindexFork = chainActive.FindFork(pindexOldTip); pindexFork = chainActive.FindFork(pindexOldTip);
fInitialDownload = IsInitialBlockDownload(); fInitialDownload = IsInitialBlockDownload();
nNewHeight = chainActive.Height();
} }
// When we reach this point, we switched to a new tip (stored in pindexNewTip). // When we reach this point, we switched to a new tip (stored in pindexNewTip).
@ -2980,7 +2982,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
{ {
LOCK(cs_vNodes); LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes) { BOOST_FOREACH(CNode* pnode, vNodes) {
if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) { if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) {
BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) { BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) {
pnode->PushBlockHash(hash); pnode->PushBlockHash(hash);
} }
@ -2993,7 +2995,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
} }
} }
} }
} while(pindexMostWork != chainActive.Tip()); } while (pindexNewTip != pindexMostWork);
CheckBlockIndex(chainparams.GetConsensus()); CheckBlockIndex(chainparams.GetConsensus());
// Write changes periodically to disk, after relay. // Write changes periodically to disk, after relay.
@ -4569,6 +4571,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
strCommand == NetMsgType::FILTERCLEAR)) strCommand == NetMsgType::FILTERCLEAR))
{ {
if (pfrom->nVersion >= NO_BLOOM_VERSION) { if (pfrom->nVersion >= NO_BLOOM_VERSION) {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100); Misbehaving(pfrom->GetId(), 100);
return false; return false;
} else { } else {
@ -4584,6 +4587,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (pfrom->nVersion != 0) if (pfrom->nVersion != 0)
{ {
pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_DUPLICATE, string("Duplicate version message")); pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 1); Misbehaving(pfrom->GetId(), 1);
return false; return false;
} }
@ -4643,7 +4647,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
// Potentially mark this peer as a preferred download peer. // Potentially mark this peer as a preferred download peer.
{
LOCK(cs_main);
UpdatePreferredDownload(pfrom, State(pfrom->GetId())); UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
}
// Change version // Change version
pfrom->PushMessage(NetMsgType::VERACK); pfrom->PushMessage(NetMsgType::VERACK);
@ -4701,6 +4708,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
else if (pfrom->nVersion == 0) else if (pfrom->nVersion == 0)
{ {
// Must have a version message before anything else // Must have a version message before anything else
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 1); Misbehaving(pfrom->GetId(), 1);
return false; return false;
} }
@ -4736,6 +4744,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
return true; return true;
if (vAddr.size() > 1000) if (vAddr.size() > 1000)
{ {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 20); Misbehaving(pfrom->GetId(), 20);
return error("message addr size() = %u", vAddr.size()); return error("message addr size() = %u", vAddr.size());
} }
@ -4803,6 +4812,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
vRecv >> vInv; vRecv >> vInv;
if (vInv.size() > MAX_INV_SZ) if (vInv.size() > MAX_INV_SZ)
{ {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 20); Misbehaving(pfrom->GetId(), 20);
return error("message inv size() = %u", vInv.size()); return error("message inv size() = %u", vInv.size());
} }
@ -4878,6 +4888,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
vRecv >> vInv; vRecv >> vInv;
if (vInv.size() > MAX_INV_SZ) if (vInv.size() > MAX_INV_SZ)
{ {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 20); Misbehaving(pfrom->GetId(), 20);
return error("message getdata size() = %u", vInv.size()); return error("message getdata size() = %u", vInv.size());
} }
@ -5129,6 +5140,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks. // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
unsigned int nCount = ReadCompactSize(vRecv); unsigned int nCount = ReadCompactSize(vRecv);
if (nCount > MAX_HEADERS_RESULTS) { if (nCount > MAX_HEADERS_RESULTS) {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 20); Misbehaving(pfrom->GetId(), 20);
return error("headers message size = %u", nCount); return error("headers message size = %u", nCount);
} }
@ -5390,8 +5402,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
LOCK(pfrom->cs_filter); LOCK(pfrom->cs_filter);
if (!filter.IsWithinSizeConstraints()) if (!filter.IsWithinSizeConstraints())
{
// There is no excuse for sending a too-large filter // There is no excuse for sending a too-large filter
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100); Misbehaving(pfrom->GetId(), 100);
}
else else
{ {
delete pfrom->pfilter; delete pfrom->pfilter;
@ -5411,15 +5426,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// and thus, the maximum size any matched object can have) in a filteradd message // and thus, the maximum size any matched object can have) in a filteradd message
if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
{ {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100); Misbehaving(pfrom->GetId(), 100);
} else { } else {
LOCK(pfrom->cs_filter); LOCK(pfrom->cs_filter);
if (pfrom->pfilter) if (pfrom->pfilter)
pfrom->pfilter->insert(vData); pfrom->pfilter->insert(vData);
else else
{
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100); Misbehaving(pfrom->GetId(), 100);
} }
} }
}
else if (strCommand == NetMsgType::FILTERCLEAR) else if (strCommand == NetMsgType::FILTERCLEAR)