Browse Source

Bugfix: make CreateNewBlock return pindexPrev

0.13
Pieter Wuille 10 years ago
parent
commit
e2edf95cd3
  1. 16
      src/miner.cpp
  2. 4
      src/miner.h
  3. 4
      src/rpcmining.cpp
  4. 27
      src/test/miner_tests.cpp

16
src/miner.cpp

@ -87,7 +87,7 @@ void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev)
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
} }
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CBlockIndex*& pindexPrev)
{ {
// Create new block // Create new block
auto_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate()); auto_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
@ -132,7 +132,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
{ {
LOCK2(cs_main, mempool.cs); LOCK2(cs_main, mempool.cs);
CBlockIndex* pindexPrev = chainActive.Tip(); pindexPrev = chainActive.Tip();
const int nHeight = pindexPrev->nHeight + 1; const int nHeight = pindexPrev->nHeight + 1;
CCoinsViewCache view(pcoinsTip); 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; CPubKey pubkey;
if (!reservekey.GetReservedKey(pubkey)) if (!reservekey.GetReservedKey(pubkey))
return NULL; return NULL;
CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
return CreateNewBlock(scriptPubKey); return CreateNewBlock(scriptPubKey, pindexPrev);
} }
static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
@ -452,9 +452,9 @@ bool MineBlock(CWallet *pwallet, uint256& hash)
unsigned int nExtraNonce = 0; unsigned int nExtraNonce = 0;
while (true) { while (true) {
CBlockIndex *pindexPrev = chainActive.Tip(); // Actually needs cs_main... CBlockIndex *pindexPrev;
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey)); auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey, pindexPrev));
if (!pblocktemplate.get()) { if (!pblocktemplate.get()) {
return false; return false;
} }
@ -497,9 +497,9 @@ void static BitcoinMiner(CWallet *pwallet)
// Create new block // Create new block
// //
unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
CBlockIndex* pindexPrev = chainActive.Tip(); // Actually needs cs_main... CBlockIndex* pindexPrev;
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey)); auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey, pindexPrev));
if (!pblocktemplate.get()) if (!pblocktemplate.get())
{ {
LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n"); LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");

4
src/miner.h

@ -27,8 +27,8 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads);
/** Create a single block */ /** Create a single block */
bool MineBlock(CWallet *pwallet, uint256& hash); bool MineBlock(CWallet *pwallet, uint256& hash);
/** Generate a new block, without valid proof-of-work */ /** Generate a new block, without valid proof-of-work */
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CBlockIndex*& pindexPrev);
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, CBlockIndex*& pindexPrev);
/** Modify the extranonce in a block */ /** Modify the extranonce in a block */
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev);

4
src/rpcmining.cpp

@ -475,7 +475,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
// Store the pindexBest used before CreateNewBlock, to avoid races // Store the pindexBest used before CreateNewBlock, to avoid races
nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
CBlockIndex* pindexPrevNew = chainActive.Tip(); CBlockIndex* pindexPrevNew;
nStart = GetTime(); nStart = GetTime();
// Create new block // Create new block
@ -485,7 +485,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
pblocktemplate = NULL; pblocktemplate = NULL;
} }
CScript scriptDummy = CScript() << OP_TRUE; CScript scriptDummy = CScript() << OP_TRUE;
pblocktemplate = CreateNewBlock(scriptDummy); pblocktemplate = CreateNewBlock(scriptDummy, pindexPrevNew);
if (!pblocktemplate) if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");

27
src/test/miner_tests.cpp

@ -62,7 +62,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
Checkpoints::fEnabled = false; Checkpoints::fEnabled = false;
// Simple block creation, nothing special yet: // 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 // We can't make transactions until we have inputs
// Therefore, load 100 blocks :) // Therefore, load 100 blocks :)
@ -90,7 +91,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
delete pblocktemplate; delete pblocktemplate;
// Just to make sure we can still make simple blocks // Just to make sure we can still make simple blocks
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
// block sigops > limit: 1000 CHECKMULTISIG + 1 // 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)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
tx.vin[0].prevout.hash = hash; tx.vin[0].prevout.hash = hash;
} }
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
@ -128,14 +129,14 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
tx.vin[0].prevout.hash = hash; tx.vin[0].prevout.hash = hash;
} }
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
// orphan in mempool // orphan in mempool
hash = tx.GetHash(); hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
@ -153,7 +154,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].nValue = 5900000000LL; tx.vout[0].nValue = 5900000000LL;
hash = tx.GetHash(); hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
@ -164,7 +165,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].nValue = 0; tx.vout[0].nValue = 0;
hash = tx.GetHash(); hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
@ -182,7 +183,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].nValue -= 1000000; tx.vout[0].nValue -= 1000000;
hash = tx.GetHash(); hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
@ -196,17 +197,17 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].scriptPubKey = CScript() << OP_2; tx.vout[0].scriptPubKey = CScript() << OP_2;
hash = tx.GetHash(); hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
mempool.clear(); mempool.clear();
// subsidy changing // subsidy changing
int nHeight = chainActive.Height(); int nHeight = chainActive.Height();
chainActive.Tip()->nHeight = 209999; chainActive.Tip()->nHeight = 209999;
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
chainActive.Tip()->nHeight = 210000; chainActive.Tip()->nHeight = 210000;
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
delete pblocktemplate; delete pblocktemplate;
chainActive.Tip()->nHeight = nHeight; chainActive.Tip()->nHeight = nHeight;
@ -238,7 +239,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11)); mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11));
BOOST_CHECK(!IsFinalTx(tx2)); BOOST_CHECK(!IsFinalTx(tx2));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
// Neither tx should have make it into the template. // Neither tx should have make it into the template.
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1); 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(tx, chainActive.Tip()->nHeight + 1));
BOOST_CHECK(IsFinalTx(tx2)); BOOST_CHECK(IsFinalTx(tx2));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey, pindexPrev));
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3);
delete pblocktemplate; delete pblocktemplate;

Loading…
Cancel
Save