Browse Source

Fix some locks

This makes sure that cs_filter is never held while taking cs_main
or CNode::cs_vSend.
0.13
Pieter Wuille 8 years ago
parent
commit
bbf379b055
  1. 36
      src/main.cpp

36
src/main.cpp

@ -4803,10 +4803,16 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam @@ -4803,10 +4803,16 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
pfrom->PushMessage(NetMsgType::BLOCK, block);
else if (inv.type == MSG_FILTERED_BLOCK)
{
LOCK(pfrom->cs_filter);
if (pfrom->pfilter)
bool send = false;
CMerkleBlock merkleBlock;
{
CMerkleBlock merkleBlock(block, *pfrom->pfilter);
LOCK(pfrom->cs_filter);
if (pfrom->pfilter) {
send = true;
merkleBlock = CMerkleBlock(block, *pfrom->pfilter);
}
}
if (send) {
pfrom->PushMessage(NetMsgType::MERKLEBLOCK, merkleBlock);
// CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
// This avoids hurting performance by pointlessly requiring a round-trip
@ -6074,8 +6080,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, @@ -6074,8 +6080,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CBloomFilter filter;
vRecv >> filter;
LOCK(pfrom->cs_filter);
if (!filter.IsWithinSizeConstraints())
{
// There is no excuse for sending a too-large filter
@ -6084,11 +6088,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, @@ -6084,11 +6088,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
else
{
LOCK(pfrom->cs_filter);
delete pfrom->pfilter;
pfrom->pfilter = new CBloomFilter(filter);
pfrom->pfilter->UpdateEmptyFull();
pfrom->fRelayTxes = true;
}
pfrom->fRelayTxes = true;
}
@ -6099,20 +6104,21 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, @@ -6099,20 +6104,21 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
// and thus, the maximum size any matched object can have) in a filteradd message
if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
{
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100);
bool bad = false;
if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) {
bad = true;
} else {
LOCK(pfrom->cs_filter);
if (pfrom->pfilter)
if (pfrom->pfilter) {
pfrom->pfilter->insert(vData);
else
{
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100);
} else {
bad = true;
}
}
if (bad) {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100);
}
}

Loading…
Cancel
Save