Skip to content

Commit 786ed11

Browse files
committed
Merge pull request #5994
a7b9623 miner: rename UpdateRequestCount signal to ResetRequestCount (Jonas Schnelli) 5496253 add CReserveScript to allow modular script keeping/returning (Jonas Schnelli) 087e65d fix GetScriptForMining() CReserveKey::keepKey() issue (Jonas Schnelli) d0fc10a detach wallet from miner (Jonas Schnelli)
2 parents da77a6f + a7b9623 commit 786ed11

File tree

10 files changed

+80
-62
lines changed

10 files changed

+80
-62
lines changed

src/init.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ void Shutdown()
156156
#ifdef ENABLE_WALLET
157157
if (pwalletMain)
158158
pwalletMain->Flush(false);
159-
GenerateBitcoins(false, NULL, 0);
160159
#endif
160+
GenerateBitcoins(false, 0, Params());
161161
StopNode();
162162
UnregisterNodeSignals(GetNodeSignals());
163163

@@ -370,10 +370,8 @@ std::string HelpMessage(HelpMessageMode mode)
370370
debugCategories += ", qt";
371371
strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
372372
_("If <category> is not supplied or if <category> = 1, output all debugging information.") + _("<category> can be:") + " " + debugCategories + ".");
373-
#ifdef ENABLE_WALLET
374373
strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0));
375374
strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1));
376-
#endif
377375
strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)"));
378376
strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0));
379377
strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1));
@@ -1439,11 +1437,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
14391437
boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing);
14401438
scheduler.scheduleEvery(f, nPowTargetSpacing);
14411439

1442-
#ifdef ENABLE_WALLET
14431440
// Generate coins in the background
1444-
if (pwalletMain)
1445-
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1));
1446-
#endif
1441+
GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), Params());
14471442

14481443
// ********************************************************* Step 11: finished
14491444

src/miner.cpp

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
#include "timedata.h"
1818
#include "util.h"
1919
#include "utilmoneystr.h"
20-
#ifdef ENABLE_WALLET
21-
#include "wallet/wallet.h"
22-
#endif
20+
#include "validationinterface.h"
2321

2422
#include <boost/thread.hpp>
2523
#include <boost/tuple/tuple.hpp>
@@ -362,7 +360,6 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
362360
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
363361
}
364362

365-
#ifdef ENABLE_WALLET
366363
//////////////////////////////////////////////////////////////////////////////
367364
//
368365
// Internal miner
@@ -401,17 +398,7 @@ bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phas
401398
}
402399
}
403400

404-
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
405-
{
406-
CPubKey pubkey;
407-
if (!reservekey.GetReservedKey(pubkey))
408-
return NULL;
409-
410-
CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
411-
return CreateNewBlock(scriptPubKey);
412-
}
413-
414-
static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
401+
static bool ProcessBlockFound(CBlock* pblock, const CChainParams& chainparams)
415402
{
416403
LogPrintf("%s\n", pblock->ToString());
417404
LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
@@ -423,14 +410,8 @@ static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& rese
423410
return error("BitcoinMiner: generated block is stale");
424411
}
425412

426-
// Remove key from key pool
427-
reservekey.KeepKey();
428-
429-
// Track how many getdata requests this block gets
430-
{
431-
LOCK(wallet.cs_wallet);
432-
wallet.mapRequestCount[pblock->GetHash()] = 0;
433-
}
413+
// Inform about the new block
414+
GetMainSignals().BlockFound(pblock->GetHash());
434415

435416
// Process this block the same as if we had received it from another node
436417
CValidationState state;
@@ -440,18 +421,22 @@ static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& rese
440421
return true;
441422
}
442423

443-
void static BitcoinMiner(CWallet *pwallet)
424+
void static BitcoinMiner(const CChainParams& chainparams)
444425
{
445426
LogPrintf("BitcoinMiner started\n");
446427
SetThreadPriority(THREAD_PRIORITY_LOWEST);
447428
RenameThread("bitcoin-miner");
448-
const CChainParams& chainparams = Params();
449429

450-
// Each thread has its own key and counter
451-
CReserveKey reservekey(pwallet);
452430
unsigned int nExtraNonce = 0;
453431

432+
boost::shared_ptr<CReserveScript> coinbaseScript;
433+
GetMainSignals().ScriptForMining(coinbaseScript);
434+
454435
try {
436+
//throw an error if no script was provided
437+
if (!coinbaseScript->reserveScript.size())
438+
throw std::runtime_error("No coinbase script available (mining requires a wallet)");
439+
455440
while (true) {
456441
if (chainparams.MiningRequiresPeers()) {
457442
// Busy-wait for the network to come online so we don't waste time mining
@@ -474,7 +459,7 @@ void static BitcoinMiner(CWallet *pwallet)
474459
unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
475460
CBlockIndex* pindexPrev = chainActive.Tip();
476461

477-
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
462+
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript));
478463
if (!pblocktemplate.get())
479464
{
480465
LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
@@ -506,8 +491,9 @@ void static BitcoinMiner(CWallet *pwallet)
506491
SetThreadPriority(THREAD_PRIORITY_NORMAL);
507492
LogPrintf("BitcoinMiner:\n");
508493
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex());
509-
ProcessBlockFound(pblock, *pwallet, reservekey);
494+
ProcessBlockFound(pblock, chainparams);
510495
SetThreadPriority(THREAD_PRIORITY_LOWEST);
496+
coinbaseScript->KeepScript();
511497

512498
// In regression test mode, stop mining after a block is found.
513499
if (chainparams.MineBlocksOnDemand())
@@ -551,7 +537,7 @@ void static BitcoinMiner(CWallet *pwallet)
551537
}
552538
}
553539

554-
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
540+
void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainparams)
555541
{
556542
static boost::thread_group* minerThreads = NULL;
557543

@@ -575,7 +561,5 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
575561

576562
minerThreads = new boost::thread_group();
577563
for (int i = 0; i < nThreads; i++)
578-
minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet));
564+
minerThreads->create_thread(boost::bind(&BitcoinMiner, boost::cref(chainparams)));
579565
}
580-
581-
#endif // ENABLE_WALLET

src/miner.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <stdint.h>
1212

1313
class CBlockIndex;
14+
class CChainParams;
1415
class CReserveKey;
1516
class CScript;
1617
class CWallet;
@@ -24,10 +25,9 @@ struct CBlockTemplate
2425
};
2526

2627
/** Run the miner threads */
27-
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads);
28+
void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainparams);
2829
/** Generate a new block, without valid proof-of-work */
2930
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn);
30-
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
3131
/** Modify the extranonce in a block */
3232
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
3333
void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);

src/rpcmining.cpp

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,11 @@
1616
#include "rpcserver.h"
1717
#include "util.h"
1818
#include "validationinterface.h"
19-
#ifdef ENABLE_WALLET
20-
#include "wallet/wallet.h"
21-
#endif
2219

2320
#include <stdint.h>
2421

2522
#include <boost/assign/list_of.hpp>
23+
#include <boost/shared_ptr.hpp>
2624

2725
#include "univalue/univalue.h"
2826

@@ -92,7 +90,6 @@ UniValue getnetworkhashps(const UniValue& params, bool fHelp)
9290
return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
9391
}
9492

95-
#ifdef ENABLE_WALLET
9693
UniValue getgenerate(const UniValue& params, bool fHelp)
9794
{
9895
if (fHelp || params.size() != 0)
@@ -127,16 +124,20 @@ UniValue generate(const UniValue& params, bool fHelp)
127124
+ HelpExampleCli("generate", "11")
128125
);
129126

130-
if (pwalletMain == NULL)
131-
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
132127
if (!Params().MineBlocksOnDemand())
133128
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest");
134129

135130
int nHeightStart = 0;
136131
int nHeightEnd = 0;
137132
int nHeight = 0;
138133
int nGenerate = params[0].get_int();
139-
CReserveKey reservekey(pwalletMain);
134+
135+
boost::shared_ptr<CReserveScript> coinbaseScript;
136+
GetMainSignals().ScriptForMining(coinbaseScript);
137+
138+
//throw an error if no script was provided
139+
if (!coinbaseScript->reserveScript.size())
140+
throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)");
140141

141142
{ // Don't keep cs_main locked
142143
LOCK(cs_main);
@@ -148,9 +149,9 @@ UniValue generate(const UniValue& params, bool fHelp)
148149
UniValue blockHashes(UniValue::VARR);
149150
while (nHeight < nHeightEnd)
150151
{
151-
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
152+
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript));
152153
if (!pblocktemplate.get())
153-
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty");
154+
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
154155
CBlock *pblock = &pblocktemplate->block;
155156
{
156157
LOCK(cs_main);
@@ -166,11 +167,13 @@ UniValue generate(const UniValue& params, bool fHelp)
166167
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
167168
++nHeight;
168169
blockHashes.push_back(pblock->GetHash().GetHex());
170+
171+
//mark script as important because it was used at least for one coinbase output
172+
coinbaseScript->KeepScript();
169173
}
170174
return blockHashes;
171175
}
172176

173-
174177
UniValue setgenerate(const UniValue& params, bool fHelp)
175178
{
176179
if (fHelp || params.size() < 1 || params.size() > 2)
@@ -193,8 +196,6 @@ UniValue setgenerate(const UniValue& params, bool fHelp)
193196
+ HelpExampleRpc("setgenerate", "true, 1")
194197
);
195198

196-
if (pwalletMain == NULL)
197-
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
198199
if (Params().MineBlocksOnDemand())
199200
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Use the generate method instead of setgenerate on this network");
200201

@@ -212,12 +213,10 @@ UniValue setgenerate(const UniValue& params, bool fHelp)
212213

213214
mapArgs["-gen"] = (fGenerate ? "1" : "0");
214215
mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
215-
GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
216+
GenerateBitcoins(fGenerate, nGenProcLimit, Params());
216217

217218
return NullUniValue;
218219
}
219-
#endif
220-
221220

222221
UniValue getmininginfo(const UniValue& params, bool fHelp)
223222
{
@@ -257,9 +256,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp)
257256
obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
258257
obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
259258
obj.push_back(Pair("chain", Params().NetworkIDString()));
260-
#ifdef ENABLE_WALLET
261259
obj.push_back(Pair("generate", getgenerate(params, false)));
262-
#endif
263260
return obj;
264261
}
265262

src/rpcserver.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,10 @@ static const CRPCCommand vRPCCommands[] =
306306
{ "mining", "prioritisetransaction", &prioritisetransaction, true },
307307
{ "mining", "submitblock", &submitblock, true },
308308

309-
#ifdef ENABLE_WALLET
310309
/* Coin generation */
311310
{ "generating", "getgenerate", &getgenerate, true },
312311
{ "generating", "setgenerate", &setgenerate, true },
313312
{ "generating", "generate", &generate, true },
314-
#endif
315313

316314
/* Raw transactions */
317315
{ "rawtransactions", "createrawtransaction", &createrawtransaction, true },

src/script/script.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,4 +609,13 @@ class CScript : public std::vector<unsigned char>
609609
}
610610
};
611611

612+
class CReserveScript
613+
{
614+
public:
615+
CScript reserveScript;
616+
virtual void KeepScript() {}
617+
CReserveScript() {}
618+
virtual ~CReserveScript() {}
619+
};
620+
612621
#endif // BITCOIN_SCRIPT_SCRIPT_H

src/validationinterface.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
1919
g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
2020
g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
2121
g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
22+
g_signals.ScriptForMining.connect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1));
23+
g_signals.BlockFound.connect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, _1));
2224
}
2325

2426
void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
27+
g_signals.BlockFound.disconnect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, _1));
28+
g_signals.ScriptForMining.disconnect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1));
2529
g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
2630
g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
2731
g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
@@ -31,6 +35,8 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
3135
}
3236

3337
void UnregisterAllValidationInterfaces() {
38+
g_signals.BlockFound.disconnect_all_slots();
39+
g_signals.ScriptForMining.disconnect_all_slots();
3440
g_signals.BlockChecked.disconnect_all_slots();
3541
g_signals.Broadcast.disconnect_all_slots();
3642
g_signals.Inventory.disconnect_all_slots();

src/validationinterface.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
#define BITCOIN_VALIDATIONINTERFACE_H
88

99
#include <boost/signals2/signal.hpp>
10+
#include <boost/shared_ptr.hpp>
1011

1112
class CBlock;
1213
struct CBlockLocator;
14+
class CReserveScript;
1315
class CTransaction;
1416
class CValidationInterface;
1517
class CValidationState;
@@ -34,6 +36,8 @@ class CValidationInterface {
3436
virtual void Inventory(const uint256 &hash) {}
3537
virtual void ResendWalletTransactions(int64_t nBestBlockTime) {}
3638
virtual void BlockChecked(const CBlock&, const CValidationState&) {}
39+
virtual void GetScriptForMining(boost::shared_ptr<CReserveScript>&) {};
40+
virtual void ResetRequestCount(const uint256 &hash) {};
3741
friend void ::RegisterValidationInterface(CValidationInterface*);
3842
friend void ::UnregisterValidationInterface(CValidationInterface*);
3943
friend void ::UnregisterAllValidationInterfaces();
@@ -52,6 +56,10 @@ struct CMainSignals {
5256
boost::signals2::signal<void (int64_t nBestBlockTime)> Broadcast;
5357
/** Notifies listeners of a block validation result */
5458
boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
59+
/** Notifies listeners that a key for mining is required (coinbase) */
60+
boost::signals2::signal<void (boost::shared_ptr<CReserveScript>&)> ScriptForMining;
61+
/** Notifies listeners that a block has been successfully mined */
62+
boost::signals2::signal<void (const uint256 &)> BlockFound;
5563
};
5664

5765
CMainSignals& GetMainSignals();

src/wallet/wallet.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2583,6 +2583,17 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx)
25832583
}
25842584
}
25852585

2586+
void CWallet::GetScriptForMining(boost::shared_ptr<CReserveScript> &script)
2587+
{
2588+
boost::shared_ptr<CReserveKey> rKey(new CReserveKey(this));
2589+
CPubKey pubkey;
2590+
if (!rKey->GetReservedKey(pubkey))
2591+
return;
2592+
2593+
script = rKey;
2594+
script->reserveScript = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
2595+
}
2596+
25862597
void CWallet::LockCoin(COutPoint& output)
25872598
{
25882599
AssertLockHeld(cs_wallet); // setLockedCoins

0 commit comments

Comments
 (0)