Skip to content

Commit 7c98ce5

Browse files
committed
Remove pfrom parameter from ProcessNewBlock
This further decouples ProcessNewBlock from networking/peer logic.
1 parent e2e069d commit 7c98ce5

File tree

5 files changed

+29
-18
lines changed

5 files changed

+29
-18
lines changed

src/main.cpp

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3787,19 +3787,15 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha
37873787
return true;
37883788
}
37893789

3790-
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool fMayBanPeerIfInvalid)
3790+
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool *fNewBlock)
37913791
{
37923792
{
37933793
LOCK(cs_main);
37943794

37953795
// Store to disk
37963796
CBlockIndex *pindex = NULL;
3797-
bool fNewBlock = false;
3798-
bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fForceProcessing, dbp, &fNewBlock);
3799-
if (pindex && pfrom) {
3800-
mapBlockSource[pindex->GetBlockHash()] = std::make_pair(pfrom->GetId(), fMayBanPeerIfInvalid);
3801-
if (fNewBlock) pfrom->nLastBlockTime = GetTime();
3802-
}
3797+
if (fNewBlock) *fNewBlock = false;
3798+
bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fForceProcessing, dbp, fNewBlock);
38033799
CheckBlockIndex(chainparams.GetConsensus());
38043800
if (!ret)
38053801
return error("%s: AcceptBlock FAILED", __func__);
@@ -5914,22 +5910,29 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
59145910
// updated, reject messages go out, etc.
59155911
MarkBlockAsReceived(resp.blockhash); // it is now an empty pointer
59165912
fBlockRead = true;
5913+
// mapBlockSource is only used for sending reject messages and DoS scores,
5914+
// so the race between here and cs_main in ProcessNewBlock is fine.
5915+
mapBlockSource.emplace(resp.blockhash, std::make_pair(pfrom->GetId(), false));
59175916
}
59185917
} // Don't hold cs_main when we call into ProcessNewBlock
59195918
if (fBlockRead) {
59205919
CValidationState state;
5920+
bool fNewBlock = false;
59215921
// Since we requested this block (it was in mapBlocksInFlight), force it to be processed,
59225922
// even if it would not be a candidate for new tip (missing previous block, chain not long enough, etc)
59235923
// BIP 152 permits peers to relay compact blocks after validating
59245924
// the header only; we should not punish peers if the block turns
59255925
// out to be invalid.
5926-
ProcessNewBlock(state, chainparams, pfrom, &block, true, NULL, false);
5926+
ProcessNewBlock(state, chainparams, &block, true, NULL, &fNewBlock);
59275927
int nDoS;
59285928
if (state.IsInvalid(nDoS)) {
59295929
assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
59305930
connman.PushMessage(pfrom, NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(),
59315931
state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), block.GetHash());
5932-
}
5932+
LOCK(cs_main);
5933+
mapBlockSource.erase(resp.blockhash);
5934+
} else if (fNewBlock)
5935+
pfrom->nLastBlockTime = GetTime();
59335936
}
59345937
}
59355938

@@ -6093,13 +6096,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
60936096
// Such an unrequested block may still be processed, subject to the
60946097
// conditions in AcceptBlock().
60956098
bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
6099+
const uint256 hash(block.GetHash());
60966100
{
60976101
LOCK(cs_main);
60986102
// Also always process if we requested the block explicitly, as we may
60996103
// need it even though it is not a candidate for a new best tip.
6100-
forceProcessing |= MarkBlockAsReceived(block.GetHash());
6104+
forceProcessing |= MarkBlockAsReceived(hash);
6105+
// mapBlockSource is only used for sending reject messages and DoS scores,
6106+
// so the race between here and cs_main in ProcessNewBlock is fine.
6107+
mapBlockSource.emplace(hash, std::make_pair(pfrom->GetId(), true));
61016108
}
6102-
ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL, true);
6109+
bool fNewBlock = false;
6110+
ProcessNewBlock(state, chainparams, &block, forceProcessing, NULL, &fNewBlock);
61036111
int nDoS;
61046112
if (state.IsInvalid(nDoS)) {
61056113
assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
@@ -6109,7 +6117,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
61096117
LOCK(cs_main);
61106118
Misbehaving(pfrom->GetId(), nDoS);
61116119
}
6112-
}
6120+
LOCK(cs_main);
6121+
mapBlockSource.erase(hash);
6122+
} else if (fNewBlock)
6123+
pfrom->nLastBlockTime = GetTime();
61136124

61146125
}
61156126

src/main.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,13 +217,13 @@ static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024;
217217
* specific block passed to it has been checked for validity!
218218
*
219219
* @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganization; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation.
220-
* @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid.
221220
* @param[in] pblock The block we want to process.
222221
* @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers.
223222
* @param[out] dbp The already known disk position of pblock, or NULL if not yet stored.
223+
* @param[out] fNewBlock A boolean which is set to indicate if the block was first received via this call
224224
* @return True if state.IsValid()
225225
*/
226-
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool fMayBanPeerIfInvalid);
226+
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool* fNewBlock);
227227
/** Check whether enough disk space is available for an incoming block */
228228
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
229229
/** Open a block file (blk?????.dat) */

src/rpc/mining.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ UniValue generateBlocks(boost::shared_ptr<CReserveScript> coinbaseScript, int nG
132132
continue;
133133
}
134134
CValidationState state;
135-
if (!ProcessNewBlock(state, Params(), NULL, pblock, true, NULL, false))
135+
if (!ProcessNewBlock(state, Params(), pblock, true, NULL, NULL))
136136
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
137137
++nHeight;
138138
blockHashes.push_back(pblock->GetHash().GetHex());
@@ -757,7 +757,7 @@ UniValue submitblock(const JSONRPCRequest& request)
757757
CValidationState state;
758758
submitblock_StateCatcher sc(block.GetHash());
759759
RegisterValidationInterface(&sc);
760-
bool fAccepted = ProcessNewBlock(state, Params(), NULL, &block, true, NULL, false);
760+
bool fAccepted = ProcessNewBlock(state, Params(), &block, true, NULL, NULL);
761761
UnregisterValidationInterface(&sc);
762762
if (fBlockPresent)
763763
{

src/test/miner_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
223223
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
224224
pblock->nNonce = blockinfo[i].nonce;
225225
CValidationState state;
226-
BOOST_CHECK(ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL, false));
226+
BOOST_CHECK(ProcessNewBlock(state, chainparams, pblock, true, NULL, NULL));
227227
BOOST_CHECK(state.IsValid());
228228
pblock->hashPrevBlock = pblock->GetHash();
229229
}

src/test/test_bitcoin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>&
127127
while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
128128

129129
CValidationState state;
130-
ProcessNewBlock(state, chainparams, NULL, &block, true, NULL, false);
130+
ProcessNewBlock(state, chainparams, &block, true, NULL, NULL);
131131

132132
CBlock result = block;
133133
return result;

0 commit comments

Comments
 (0)