Add functionality to generate auxpow blocks in regtest

This roughly reverts the work done here that disabled auxpow generation in regtest: https://github.com/dogecoin/dogecoin/pull/1431/files\#diff-ccc24453c13307f815879738d3bf00eec351417537fbf10dde1468180cacd2f1R127-R137

This is a pretty severe functionality change since auxpow is critical to Dogecoin and wallet integrators need to be able to parse the extra data in auxpow blocks.
For future wallet integrators: Dogecoin follows similar schemes as Namecoin for the merged mining support and the spec is here: https://en.bitcoin.it/wiki/Merged_mining_specification

pr review: GetHash -> GetPoWHash
This commit is contained in:
MD Islam 2021-05-25 18:23:36 -04:00
parent 02d0e99907
commit 6a2b1cce6d
No known key found for this signature in database
GPG Key ID: 376C57E1391C440A
4 changed files with 56 additions and 18 deletions

1
.gitignore vendored
View File

@ -112,3 +112,4 @@ libbitcoinconsensus.pc
contrib/devtools/split-debug.sh
.idea/
.vscode/*

View File

@ -34,8 +34,10 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "setmocktime", 0, "timestamp" },
{ "generate", 0, "nblocks" },
{ "generate", 1, "maxtries" },
{ "generate", 2, "auxpow" },
{ "generatetoaddress", 0, "nblocks" },
{ "generatetoaddress", 2, "maxtries" },
{ "generatetoaddress", 3, "auxpow" },
{ "getnetworkhashps", 0, "nblocks" },
{ "getnetworkhashps", 1, "height" },
{ "sendtoaddress", 1, "amount" },

View File

@ -97,7 +97,7 @@ UniValue getnetworkhashps(const JSONRPCRequest& request)
return GetNetworkHashPS(request.params.size() > 0 ? request.params[0].get_int() : 120, request.params.size() > 1 ? request.params[1].get_int() : -1);
}
UniValue generateBlocks(boost::shared_ptr<CReserveScript> coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript)
UniValue generateBlocks(boost::shared_ptr<CReserveScript> coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript, int nMineAuxPow)
{
// Dogecoin: Never mine witness tx
const bool fMineWitnessTx = false;
@ -124,22 +124,40 @@ UniValue generateBlocks(boost::shared_ptr<CReserveScript> coinbaseScript, int nG
LOCK(cs_main);
IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce);
}
// Dogecoin: Don't mine Aux blocks in regtest
//CAuxPow::initAuxPow(*pblock);
//CPureBlockHeader& miningHeader = pblock->auxpow->parentBlock;
while (nMaxTries > 0 && pblock->nNonce < nInnerLoopCount && !CheckProofOfWork(pblock->GetPoWHash(), pblock->nBits, Params().GetConsensus(nHeight))) {
++pblock->nNonce;
--nMaxTries;
if (!nMineAuxPow) {
while (nMaxTries > 0 && pblock->nNonce < nInnerLoopCount && !CheckProofOfWork(pblock->GetPoWHash(), pblock->nBits, Params().GetConsensus(nHeight))) {
++pblock->nNonce;
--nMaxTries;
}
} else {
CAuxPow::initAuxPow(*pblock);
CPureBlockHeader& miningHeader = pblock->auxpow->parentBlock;
while (nMaxTries > 0 && miningHeader.nNonce < nInnerLoopCount && !CheckProofOfWork(miningHeader.GetPoWHash(), pblock->nBits, Params().GetConsensus(nHeight))) {
++miningHeader.nNonce;
--nMaxTries;
}
}
if (nMaxTries == 0) {
break;
}
if (pblock->nNonce == nInnerLoopCount) {
continue;
if (!nMineAuxPow) {
if (pblock->nNonce == nInnerLoopCount) {
continue;
}
} else {
CPureBlockHeader& miningHeader = pblock->auxpow->parentBlock;
if (miningHeader.nNonce == nInnerLoopCount) {
continue;
}
}
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
if (!ProcessNewBlock(Params(), shared_pblock, true, NULL))
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
if (nMineAuxPow) {
continue;
}
else {
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
}
++nHeight;
blockHashes.push_back(pblock->GetHash().GetHex());
@ -154,13 +172,14 @@ UniValue generateBlocks(boost::shared_ptr<CReserveScript> coinbaseScript, int nG
UniValue generate(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
throw runtime_error(
"generate nblocks ( maxtries )\n"
"generate nblocks ( maxtries auxpow )\n"
"\nMine up to nblocks blocks immediately (before the RPC call returns)\n"
"\nArguments:\n"
"1. nblocks (numeric, required) How many blocks are generated immediately.\n"
"2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
"3. auxpow (numeric, optional) If the block should include the auxpow header (default = 0).\n"
"\nResult:\n"
"[ blockhashes ] (array) hashes of blocks generated\n"
"\nExamples:\n"
@ -173,6 +192,10 @@ UniValue generate(const JSONRPCRequest& request)
if (request.params.size() > 1) {
nMaxTries = request.params[1].get_int();
}
int nMineAuxPow = 0;
if (request.params.size() > 2) {
nMineAuxPow = request.params[2].get_int();
}
boost::shared_ptr<CReserveScript> coinbaseScript;
GetMainSignals().ScriptForMining(coinbaseScript);
@ -185,19 +208,21 @@ UniValue generate(const JSONRPCRequest& request)
if (coinbaseScript->reserveScript.empty())
throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)");
return generateBlocks(coinbaseScript, nGenerate, nMaxTries, true);
return generateBlocks(coinbaseScript, nGenerate, nMaxTries, true, nMineAuxPow);
}
UniValue generatetoaddress(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
if (request.fHelp || request.params.size() < 2 || request.params.size() > 4)
throw runtime_error(
"generatetoaddress nblocks address (maxtries)\n"
"generatetoaddress nblocks address (maxtries auxpow)\n"
"\nMine blocks immediately to a specified address (before the RPC call returns)\n"
"\nArguments:\n"
"1. nblocks (numeric, required) How many blocks are generated immediately.\n"
"2. address (string, required) The address to send the newly generated dogecoin to.\n"
"3. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
"4. auxpow (numeric, optional) If the block should include the auxpow header (default = 0).\n"
"\nResult:\n"
"[ blockhashes ] (array) hashes of blocks generated\n"
"\nExamples:\n"
@ -210,6 +235,10 @@ UniValue generatetoaddress(const JSONRPCRequest& request)
if (request.params.size() > 2) {
nMaxTries = request.params[2].get_int();
}
int nMineAuxPow = 0;
if (request.params.size() > 3) {
nMineAuxPow = request.params[3].get_int();
}
CBitcoinAddress address(request.params[1].get_str());
if (!address.IsValid())
@ -218,7 +247,7 @@ UniValue generatetoaddress(const JSONRPCRequest& request)
boost::shared_ptr<CReserveScript> coinbaseScript(new CReserveScript());
coinbaseScript->reserveScript = GetScriptForDestination(address.Get());
return generateBlocks(coinbaseScript, nGenerate, nMaxTries, false);
return generateBlocks(coinbaseScript, nGenerate, nMaxTries, false, nMineAuxPow);
}
UniValue getmininginfo(const JSONRPCRequest& request)
@ -1127,8 +1156,8 @@ static const CRPCCommand commands[] =
{ "mining", "submitblock", &submitblock, true, {"hexdata","parameters"} },
{ "mining", "getauxblock", &getauxblock, true, {"hash", "auxpow"} },
{ "generating", "generate", &generate, true, {"nblocks","maxtries"} },
{ "generating", "generatetoaddress", &generatetoaddress, true, {"nblocks","address","maxtries"} },
{ "generating", "generate", &generate, true, {"nblocks","maxtries","auxpow"} },
{ "generating", "generatetoaddress", &generatetoaddress, true, {"nblocks","address","maxtries","auxpow"} },
{ "util", "estimatefee", &estimatefee, true, {"nblocks"} },
{ "util", "estimatepriority", &estimatepriority, true, {"nblocks"} },

View File

@ -341,6 +341,12 @@ BOOST_AUTO_TEST_CASE(rpc_convert_values_generatetoaddress)
BOOST_CHECK_EQUAL(result[0].get_int(), 1);
BOOST_CHECK_EQUAL(result[1].get_str(), "mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU");
BOOST_CHECK_EQUAL(result[2].get_int(), 9);
BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", boost::assign::list_of("1")("mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU")("9")("1")));
BOOST_CHECK_EQUAL(result[0].get_int(), 1);
BOOST_CHECK_EQUAL(result[1].get_str(), "mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU");
BOOST_CHECK_EQUAL(result[2].get_int(), 9);
BOOST_CHECK_EQUAL(result[3].get_int(), 1);
}
BOOST_AUTO_TEST_SUITE_END()