From e2edf95cd3f43331843676e49a82830128a95050 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 31 Mar 2015 20:35:04 -0700 Subject: [PATCH] Bugfix: make CreateNewBlock return pindexPrev --- src/miner.cpp | 16 ++++++++-------- src/miner.h | 4 ++-- src/rpcmining.cpp | 4 ++-- src/test/miner_tests.cpp | 27 ++++++++++++++------------- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index fdbc47a1c..7f01918ee 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -87,7 +87,7 @@ void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev) pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); } -CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) +CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CBlockIndex*& pindexPrev) { // Create new block auto_ptr pblocktemplate(new CBlockTemplate()); @@ -132,7 +132,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) { LOCK2(cs_main, mempool.cs); - CBlockIndex* pindexPrev = chainActive.Tip(); + pindexPrev = chainActive.Tip(); const int nHeight = pindexPrev->nHeight + 1; CCoinsViewCache view(pcoinsTip); @@ -385,14 +385,14 @@ bool static ScanHash(CBlockHeader *pblock, uint256 *phash) } } -CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) +CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, CBlockIndex*& pindexPrev) { CPubKey pubkey; if (!reservekey.GetReservedKey(pubkey)) return NULL; CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; - return CreateNewBlock(scriptPubKey); + return CreateNewBlock(scriptPubKey, pindexPrev); } static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) @@ -452,9 +452,9 @@ bool MineBlock(CWallet *pwallet, uint256& hash) unsigned int nExtraNonce = 0; while (true) { - CBlockIndex *pindexPrev = chainActive.Tip(); // Actually needs cs_main... + CBlockIndex *pindexPrev; - auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); + auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey, pindexPrev)); if (!pblocktemplate.get()) { return false; } @@ -497,9 +497,9 @@ void static BitcoinMiner(CWallet *pwallet) // Create new block // unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex* pindexPrev = chainActive.Tip(); // Actually needs cs_main... + CBlockIndex* pindexPrev; - auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); + auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey, pindexPrev)); if (!pblocktemplate.get()) { LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n"); diff --git a/src/miner.h b/src/miner.h index 549658ec1..00ad29951 100644 --- a/src/miner.h +++ b/src/miner.h @@ -27,8 +27,8 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads); /** Create a single block */ bool MineBlock(CWallet *pwallet, uint256& hash); /** Generate a new block, without valid proof-of-work */ -CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); -CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); +CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CBlockIndex*& pindexPrev); +CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, CBlockIndex*& pindexPrev); /** Modify the extranonce in a block */ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 49c5c3ca5..6f165028d 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -475,7 +475,7 @@ Value getblocktemplate(const Array& params, bool fHelp) // Store the pindexBest used before CreateNewBlock, to avoid races nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex* pindexPrevNew = chainActive.Tip(); + CBlockIndex* pindexPrevNew; nStart = GetTime(); // Create new block @@ -485,7 +485,7 @@ Value getblocktemplate(const Array& params, bool fHelp) pblocktemplate = NULL; } CScript scriptDummy = CScript() << OP_TRUE; - pblocktemplate = CreateNewBlock(scriptDummy); + pblocktemplate = CreateNewBlock(scriptDummy, pindexPrevNew); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 6ab9cb8a4..27c0a08de 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -62,7 +62,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) Checkpoints::fEnabled = false; // Simple block creation, nothing special yet: - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + CBlockIndex* pindexPrev; + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) @@ -90,7 +91,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) delete pblocktemplate; // Just to make sure we can still make simple blocks - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; // block sigops > limit: 1000 CHECKMULTISIG + 1 @@ -108,7 +109,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); @@ -128,14 +129,14 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); // orphan in mempool hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); @@ -153,7 +154,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 5900000000LL; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); @@ -164,7 +165,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 0; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); @@ -182,7 +183,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue -= 1000000; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); @@ -196,17 +197,17 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; mempool.clear(); // subsidy changing int nHeight = chainActive.Height(); chainActive.Tip()->nHeight = 209999; - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; chainActive.Tip()->nHeight = 210000; - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); delete pblocktemplate; chainActive.Tip()->nHeight = nHeight; @@ -238,7 +239,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11)); BOOST_CHECK(!IsFinalTx(tx2)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); // Neither tx should have make it into the template. BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1); @@ -251,7 +252,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) BOOST_CHECK(IsFinalTx(tx, chainActive.Tip()->nHeight + 1)); BOOST_CHECK(IsFinalTx(tx2)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev)); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3); delete pblocktemplate;