Browse Source

Merge pull request #6567

2016576 Fix crash when mining with empty keypool. (Daniel Kraft)
0.13
Wladimir J. van der Laan 9 years ago
parent
commit
0f0f323c9a
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 15
      qa/rpc-tests/keypool.py
  2. 6
      src/miner.cpp
  3. 6
      src/rpcmining.cpp

15
qa/rpc-tests/keypool.py

@ -73,6 +73,21 @@ def run_test(nodes, tmpdir):
except JSONRPCException,e: except JSONRPCException,e:
assert(e.error['code']==-12) assert(e.error['code']==-12)
# refill keypool with three new addresses
nodes[0].walletpassphrase('test', 12000)
nodes[0].keypoolrefill(3)
nodes[0].walletlock()
# drain them by mining
nodes[0].generate(1)
nodes[0].generate(1)
nodes[0].generate(1)
nodes[0].generate(1)
try:
nodes[0].generate(1)
raise AssertionError('Keypool should be exhausted after three addesses')
except JSONRPCException,e:
assert(e.error['code']==-12)
def main(): def main():
import optparse import optparse

6
src/miner.cpp

@ -444,8 +444,10 @@ void static BitcoinMiner(const CChainParams& chainparams)
GetMainSignals().ScriptForMining(coinbaseScript); GetMainSignals().ScriptForMining(coinbaseScript);
try { try {
//throw an error if no script was provided // Throw an error if no script was provided. This can happen
if (!coinbaseScript->reserveScript.size()) // due to some internal error but also if the keypool is empty.
// In the latter case, already the pointer is NULL.
if (!coinbaseScript || coinbaseScript->reserveScript.empty())
throw std::runtime_error("No coinbase script available (mining requires a wallet)"); throw std::runtime_error("No coinbase script available (mining requires a wallet)");
while (true) { while (true) {

6
src/rpcmining.cpp

@ -138,8 +138,12 @@ UniValue generate(const UniValue& params, bool fHelp)
boost::shared_ptr<CReserveScript> coinbaseScript; boost::shared_ptr<CReserveScript> coinbaseScript;
GetMainSignals().ScriptForMining(coinbaseScript); GetMainSignals().ScriptForMining(coinbaseScript);
// If the keypool is exhausted, no script is returned at all. Catch this.
if (!coinbaseScript)
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
//throw an error if no script was provided //throw an error if no script was provided
if (!coinbaseScript->reserveScript.size()) if (coinbaseScript->reserveScript.empty())
throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)"); throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)");
{ // Don't keep cs_main locked { // Don't keep cs_main locked

Loading…
Cancel
Save