Skip to content

Commit 0f0f323

Browse files
committed
Merge pull request #6567
2016576 Fix crash when mining with empty keypool. (Daniel Kraft)
2 parents 1e92b27 + 2016576 commit 0f0f323

3 files changed

Lines changed: 24 additions & 3 deletions

File tree

qa/rpc-tests/keypool.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,21 @@ def run_test(nodes, tmpdir):
7373
except JSONRPCException,e:
7474
assert(e.error['code']==-12)
7575

76+
# refill keypool with three new addresses
77+
nodes[0].walletpassphrase('test', 12000)
78+
nodes[0].keypoolrefill(3)
79+
nodes[0].walletlock()
80+
81+
# drain them by mining
82+
nodes[0].generate(1)
83+
nodes[0].generate(1)
84+
nodes[0].generate(1)
85+
nodes[0].generate(1)
86+
try:
87+
nodes[0].generate(1)
88+
raise AssertionError('Keypool should be exhausted after three addesses')
89+
except JSONRPCException,e:
90+
assert(e.error['code']==-12)
7691

7792
def main():
7893
import optparse

src/miner.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,8 +444,10 @@ void static BitcoinMiner(const CChainParams& chainparams)
444444
GetMainSignals().ScriptForMining(coinbaseScript);
445445

446446
try {
447-
//throw an error if no script was provided
448-
if (!coinbaseScript->reserveScript.size())
447+
// Throw an error if no script was provided. This can happen
448+
// due to some internal error but also if the keypool is empty.
449+
// In the latter case, already the pointer is NULL.
450+
if (!coinbaseScript || coinbaseScript->reserveScript.empty())
449451
throw std::runtime_error("No coinbase script available (mining requires a wallet)");
450452

451453
while (true) {

src/rpcmining.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,12 @@ UniValue generate(const UniValue& params, bool fHelp)
138138
boost::shared_ptr<CReserveScript> coinbaseScript;
139139
GetMainSignals().ScriptForMining(coinbaseScript);
140140

141+
// If the keypool is exhausted, no script is returned at all. Catch this.
142+
if (!coinbaseScript)
143+
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
144+
141145
//throw an error if no script was provided
142-
if (!coinbaseScript->reserveScript.size())
146+
if (coinbaseScript->reserveScript.empty())
143147
throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)");
144148

145149
{ // Don't keep cs_main locked

0 commit comments

Comments
 (0)