diff options
Diffstat (limited to 'src/rpcmining.cpp')
-rw-r--r-- | src/rpcmining.cpp | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 6f165028d5..1e6531f68a 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -119,6 +119,7 @@ Value generate(const Array& params, bool fHelp) throw runtime_error( "generate numblocks\n" "\nMine blocks immediately (before the RPC call returns)\n" + "\nNote: this function can only be used on the regtest network\n" "1. numblocks (numeric) How many blocks are generated immediately.\n" "\nResult\n" "[ blockhashes ] (array) hashes of blocks generated\n" @@ -129,11 +130,14 @@ Value generate(const Array& params, bool fHelp) if (pwalletMain == NULL) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); + if (!Params().MineBlocksOnDemand()) + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest"); int nHeightStart = 0; int nHeightEnd = 0; int nHeight = 0; int nGenerate = params[0].get_int(); + CReserveKey reservekey(pwalletMain); { // Don't keep cs_main locked LOCK(cs_main); @@ -141,18 +145,33 @@ Value generate(const Array& params, bool fHelp) nHeight = nHeightStart; nHeightEnd = nHeightStart+nGenerate; } + unsigned int nExtraNonce = 0; Array blockHashes; - while (nHeight < nHeightEnd) { - uint256 hash; - if (!MineBlock(pwalletMain, hash)) + while (nHeight < nHeightEnd) + { + auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey)); + if (!pblocktemplate.get()) throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty"); - + CBlock *pblock = &pblocktemplate->block; + { + LOCK(cs_main); + IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce); + } + while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) { + // Yes, there is a chance every nonce could fail to satisfy the -regtest + // target -- 1 in 2^(2^32). That ain't gonna happen. + ++pblock->nNonce; + } + CValidationState state; + if (!ProcessNewBlock(state, NULL, pblock)) + throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); ++nHeight; - blockHashes.push_back(hash.GetHex()); + blockHashes.push_back(pblock->GetHash().GetHex()); } return blockHashes; } + Value setgenerate(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) @@ -475,7 +494,7 @@ Value getblocktemplate(const Array& params, bool fHelp) // Store the pindexBest used before CreateNewBlock, to avoid races nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex* pindexPrevNew; + CBlockIndex* pindexPrevNew = chainActive.Tip(); nStart = GetTime(); // Create new block @@ -485,7 +504,7 @@ Value getblocktemplate(const Array& params, bool fHelp) pblocktemplate = NULL; } CScript scriptDummy = CScript() << OP_TRUE; - pblocktemplate = CreateNewBlock(scriptDummy, pindexPrevNew); + pblocktemplate = CreateNewBlock(scriptDummy); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); |