Skip to content

Commit 2d6e561

Browse files
committed
Switch pblock in ProcessNewBlock to a shared_ptr
This (finally) fixes a performance regression in b3b3c2a
1 parent 2736c44 commit 2d6e561

File tree

6 files changed

+20
-21
lines changed

6 files changed

+20
-21
lines changed

src/net_processing.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,7 +1895,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
18951895
BlockTransactions resp;
18961896
vRecv >> resp;
18971897

1898-
CBlock block;
1898+
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
18991899
bool fBlockRead = false;
19001900
{
19011901
LOCK(cs_main);
@@ -1908,7 +1908,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
19081908
}
19091909

19101910
PartiallyDownloadedBlock& partialBlock = *it->second.second->partialBlock;
1911-
ReadStatus status = partialBlock.FillBlock(block, resp.txn);
1911+
ReadStatus status = partialBlock.FillBlock(*pblock, resp.txn);
19121912
if (status == READ_STATUS_INVALID) {
19131913
MarkBlockAsReceived(resp.blockhash); // Reset in-flight state in case of whitelist
19141914
Misbehaving(pfrom->GetId(), 100);
@@ -1951,7 +1951,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
19511951
bool fNewBlock = false;
19521952
// Since we requested this block (it was in mapBlocksInFlight), force it to be processed,
19531953
// even if it would not be a candidate for new tip (missing previous block, chain not long enough, etc)
1954-
ProcessNewBlock(chainparams, &block, true, NULL, &fNewBlock);
1954+
ProcessNewBlock(chainparams, pblock, true, NULL, &fNewBlock);
19551955
if (fNewBlock)
19561956
pfrom->nLastBlockTime = GetTime();
19571957
}
@@ -2112,17 +2112,17 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
21122112

21132113
else if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) // Ignore blocks received while importing
21142114
{
2115-
CBlock block;
2116-
vRecv >> block;
2115+
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2116+
vRecv >> *pblock;
21172117

2118-
LogPrint("net", "received block %s peer=%d\n", block.GetHash().ToString(), pfrom->id);
2118+
LogPrint("net", "received block %s peer=%d\n", pblock->GetHash().ToString(), pfrom->id);
21192119

21202120
// Process all blocks from whitelisted peers, even if not requested,
21212121
// unless we're still syncing with the network.
21222122
// Such an unrequested block may still be processed, subject to the
21232123
// conditions in AcceptBlock().
21242124
bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
2125-
const uint256 hash(block.GetHash());
2125+
const uint256 hash(pblock->GetHash());
21262126
{
21272127
LOCK(cs_main);
21282128
// Also always process if we requested the block explicitly, as we may
@@ -2133,7 +2133,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
21332133
mapBlockSource.emplace(hash, std::make_pair(pfrom->GetId(), true));
21342134
}
21352135
bool fNewBlock = false;
2136-
ProcessNewBlock(chainparams, &block, forceProcessing, NULL, &fNewBlock);
2136+
ProcessNewBlock(chainparams, pblock, forceProcessing, NULL, &fNewBlock);
21372137
if (fNewBlock)
21382138
pfrom->nLastBlockTime = GetTime();
21392139
}

src/rpc/mining.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ UniValue generateBlocks(boost::shared_ptr<CReserveScript> coinbaseScript, int nG
131131
if (pblock->nNonce == nInnerLoopCount) {
132132
continue;
133133
}
134-
if (!ProcessNewBlock(Params(), pblock, true, NULL, NULL))
134+
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
135+
if (!ProcessNewBlock(Params(), shared_pblock, true, NULL, NULL))
135136
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
136137
++nHeight;
137138
blockHashes.push_back(pblock->GetHash().GetHex());
@@ -728,7 +729,8 @@ UniValue submitblock(const JSONRPCRequest& request)
728729
+ HelpExampleRpc("submitblock", "\"mydata\"")
729730
);
730731

731-
CBlock block;
732+
std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>();
733+
CBlock& block = *blockptr;
732734
if (!DecodeHexBlk(block, request.params[0].get_str()))
733735
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
734736

@@ -758,7 +760,7 @@ UniValue submitblock(const JSONRPCRequest& request)
758760

759761
submitblock_StateCatcher sc(block.GetHash());
760762
RegisterValidationInterface(&sc);
761-
bool fAccepted = ProcessNewBlock(Params(), &block, true, NULL, NULL);
763+
bool fAccepted = ProcessNewBlock(Params(), blockptr, true, NULL, NULL);
762764
UnregisterValidationInterface(&sc);
763765
if (fBlockPresent)
764766
{

src/test/miner_tests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
223223
txFirst.push_back(pblock->vtx[0]);
224224
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
225225
pblock->nNonce = blockinfo[i].nonce;
226-
BOOST_CHECK(ProcessNewBlock(chainparams, pblock, true, NULL, NULL));
226+
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
227+
BOOST_CHECK(ProcessNewBlock(chainparams, shared_pblock, true, NULL, NULL));
227228
pblock->hashPrevBlock = pblock->GetHash();
228229
}
229230

src/test/test_bitcoin.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>&
127127

128128
while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
129129

130-
ProcessNewBlock(chainparams, &block, true, NULL, NULL);
130+
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
131+
ProcessNewBlock(chainparams, shared_pblock, true, NULL, NULL);
131132

132133
CBlock result = block;
133134
return result;

src/validation.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3123,7 +3123,7 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha
31233123
return true;
31243124
}
31253125

3126-
bool ProcessNewBlock(const CChainParams& chainparams, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool *fNewBlock)
3126+
bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool *fNewBlock)
31273127
{
31283128
{
31293129
LOCK(cs_main);
@@ -3142,13 +3142,8 @@ bool ProcessNewBlock(const CChainParams& chainparams, const CBlock* pblock, bool
31423142

31433143
NotifyHeaderTip();
31443144

3145-
//TODO: This copy is a major performance regression, but callers need updated to fix this
3146-
std::shared_ptr<const CBlock> block_ptr;
3147-
if (pblock)
3148-
block_ptr.reset(new CBlock(*pblock));
3149-
31503145
CValidationState state; // Only used to report errors, not invalidity - ignore it
3151-
if (!ActivateBestChain(state, chainparams, block_ptr))
3146+
if (!ActivateBestChain(state, chainparams, pblock))
31523147
return error("%s: ActivateBestChain failed", __func__);
31533148

31543149
return true;

src/validation.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024;
233233
* @param[out] fNewBlock A boolean which is set to indicate if the block was first received via this call
234234
* @return True if state.IsValid()
235235
*/
236-
bool ProcessNewBlock(const CChainParams& chainparams, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool* fNewBlock);
236+
bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool* fNewBlock);
237237

238238
/**
239239
* Process incoming block headers.

0 commit comments

Comments
 (0)