Skip to content

Commit c8b7425

Browse files
committed
setgenerate creates multiple blocks in -regtest mode
I'm writing some wallet regression tests using -regtest mode, and need to generate an initial multi-hundred-block chain. Repeatedly calling setgenerate to generate one block is slow and doesn't work properly, because block creation happens asynchronously. This adds two features to setgenerate in -regtest mode: 1) Instead of being interpreted as number of threads to start, the third argument is the number of blocks to generate. 2) setgenerate will not return until the block creation threads have created the requested number of blocks.
1 parent 34f5b0a commit c8b7425

File tree

5 files changed

+45
-11
lines changed

5 files changed

+45
-11
lines changed

src/bitcoinrpc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ static const CRPCCommand vRPCCommands[] =
238238
{ "getdifficulty", &getdifficulty, true, false, false },
239239
{ "getnetworkhashps", &getnetworkhashps, true, false, false },
240240
{ "getgenerate", &getgenerate, true, false, false },
241-
{ "setgenerate", &setgenerate, true, false, true },
241+
{ "setgenerate", &setgenerate, true, true, false },
242242
{ "gethashespersec", &gethashespersec, true, false, false },
243243
{ "getinfo", &getinfo, true, false, false },
244244
{ "getmininginfo", &getmininginfo, true, false, false },

src/init.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ void Shutdown()
112112
ShutdownRPCMining();
113113
if (pwalletMain)
114114
bitdb.Flush(false);
115-
GenerateBitcoins(false, NULL);
115+
GenerateBitcoins(false, NULL, 0);
116116
StopNode();
117117
{
118118
LOCK(cs_main);
@@ -1050,7 +1050,7 @@ bool AppInit2(boost::thread_group& threadGroup, bool fForceServer)
10501050

10511051
// Generate coins in the background
10521052
if (pwalletMain)
1053-
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1053+
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", -1));
10541054

10551055
// ********************************************************* Step 12: finished
10561056

src/miner.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -650,11 +650,10 @@ void static BitcoinMiner(CWallet *pwallet)
650650
}
651651
}
652652

653-
void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
653+
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
654654
{
655655
static boost::thread_group* minerThreads = NULL;
656656

657-
int nThreads = GetArg("-genproclimit", -1);
658657
if (nThreads < 0) {
659658
if (Params().NetworkID() == CChainParams::REGTEST)
660659
nThreads = 1;

src/miner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class CScript;
1616
class CWallet;
1717

1818
/** Run the miner threads */
19-
void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
19+
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads);
2020
/** Generate a new block, without valid proof-of-work */
2121
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn);
2222
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);

src/rpcmining.cpp

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ Value setgenerate(const Array& params, bool fHelp)
133133
"\nArguments:\n"
134134
"1. generate (boolean, required) Set to true to turn on generation, off to turn off.\n"
135135
"2. genproclimit (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited.\n"
136+
" Note: in -regtest mode, genproclimit controls how many blocks are generated immediately.\n"
136137
"\nExamples:\n"
137138
"\nSet the generation on with a limit of one processor\n"
138139
+ HelpExampleCli("setgenerate", "true 1") +
@@ -144,21 +145,55 @@ Value setgenerate(const Array& params, bool fHelp)
144145
+ HelpExampleRpc("setgenerate", "true, 1")
145146
);
146147

148+
if (pwalletMain == NULL)
149+
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
150+
147151
bool fGenerate = true;
148152
if (params.size() > 0)
149153
fGenerate = params[0].get_bool();
150154

155+
int nGenProcLimit = -1;
151156
if (params.size() > 1)
152157
{
153-
int nGenProcLimit = params[1].get_int();
154-
mapArgs["-genproclimit"] = itostr(nGenProcLimit);
158+
nGenProcLimit = params[1].get_int();
155159
if (nGenProcLimit == 0)
156160
fGenerate = false;
157161
}
158-
mapArgs["-gen"] = (fGenerate ? "1" : "0");
159162

160-
assert(pwalletMain != NULL);
161-
GenerateBitcoins(fGenerate, pwalletMain);
163+
// -regtest mode: don't return until nGenProcLimit blocks are generated
164+
if (fGenerate && Params().NetworkID() == CChainParams::REGTEST)
165+
{
166+
int nHeightStart = 0;
167+
int nHeightEnd = 0;
168+
int nHeight = 0;
169+
int nGenerate = (nGenProcLimit > 0 ? nGenProcLimit : 1);
170+
{ // Don't keep cs_main locked
171+
LOCK(cs_main);
172+
nHeightStart = chainActive.Height();
173+
nHeight = nHeightStart;
174+
nHeightEnd = nHeightStart+nGenerate;
175+
}
176+
int nHeightLast = -1;
177+
while (nHeight < nHeightEnd)
178+
{
179+
if (nHeightLast != nHeight)
180+
{
181+
nHeightLast = nHeight;
182+
GenerateBitcoins(fGenerate, pwalletMain, 1);
183+
}
184+
MilliSleep(1);
185+
{ // Don't keep cs_main locked
186+
LOCK(cs_main);
187+
nHeight = chainActive.Height();
188+
}
189+
}
190+
}
191+
else // Not -regtest: start generate thread, return immediately
192+
{
193+
mapArgs["-gen"] = (fGenerate ? "1" : "0");
194+
GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
195+
}
196+
162197
return Value::null;
163198
}
164199

0 commit comments

Comments
 (0)