aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2015-08-19 15:02:40 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2015-08-19 15:07:38 +0200
commit0f0f323c9a58437b33ba4fa9a67e1edf5fc6cc88 (patch)
tree56692e75f44ad30ef55eaa42764e46f0643b35b1
parent1e92b275406e3fbc7ab59d2ada1c882ca15fb36f (diff)
parent20165769989ed5aa744af2b73dfcf9d5a5cf7aa0 (diff)
downloadbitcoin-0f0f323c9a58437b33ba4fa9a67e1edf5fc6cc88.tar.xz
Merge pull request #6567
2016576 Fix crash when mining with empty keypool. (Daniel Kraft)
-rwxr-xr-xqa/rpc-tests/keypool.py15
-rw-r--r--src/miner.cpp6
-rw-r--r--src/rpcmining.cpp6
3 files changed, 24 insertions, 3 deletions
diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py
index aee29a596a..5a67220021 100755
--- a/qa/rpc-tests/keypool.py
+++ b/qa/rpc-tests/keypool.py
@@ -73,6 +73,21 @@ def run_test(nodes, tmpdir):
except JSONRPCException,e:
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():
import optparse
diff --git a/src/miner.cpp b/src/miner.cpp
index 4172266067..9dd1d459b5 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -444,8 +444,10 @@ void static BitcoinMiner(const CChainParams& chainparams)
GetMainSignals().ScriptForMining(coinbaseScript);
try {
- //throw an error if no script was provided
- if (!coinbaseScript->reserveScript.size())
+ // Throw an error if no script was provided. This can happen
+ // 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)");
while (true) {
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index b7d4ff58fc..620a46be15 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -138,8 +138,12 @@ UniValue generate(const UniValue& params, bool fHelp)
boost::shared_ptr<CReserveScript> 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
- if (!coinbaseScript->reserveScript.size())
+ if (coinbaseScript->reserveScript.empty())
throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)");
{ // Don't keep cs_main locked