aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/mining.cpp
diff options
context:
space:
mode:
authorRoss Nicoll <[email protected]>2017-11-19 22:09:03 +0000
committerRoss Nicoll <[email protected]>2018-09-19 19:23:29 +0100
commitfcde8643344a3a7baadf31d97dd3e1b47aa8cff9 (patch)
treee3f8540c7060b29b848a9964c6b6f08fe3b64b5b /src/rpc/mining.cpp
parentMerge AuxPoW support from Namecore (diff)
downloaddiscoin-fcde8643344a3a7baadf31d97dd3e1b47aa8cff9.tar.xz
discoin-fcde8643344a3a7baadf31d97dd3e1b47aa8cff9.zip
Sync mining code from Namecore to resolve unit test failures (#1385)
Diffstat (limited to 'src/rpc/mining.cpp')
-rw-r--r--src/rpc/mining.cpp323
1 files changed, 120 insertions, 203 deletions
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 70192686b..b355ccdc9 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -98,6 +98,8 @@ UniValue getnetworkhashps(const JSONRPCRequest& request)
UniValue generateBlocks(boost::shared_ptr<CReserveScript> coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript)
{
+ // Dogecoin: Never mine witness tx
+ const bool fMineWitnessTx = false;
static const int nInnerLoopCount = 0x10000;
int nHeightStart = 0;
int nHeightEnd = 0;
@@ -113,7 +115,7 @@ UniValue generateBlocks(boost::shared_ptr<CReserveScript> coinbaseScript, int nG
UniValue blockHashes(UniValue::VARR);
while (nHeight < nHeightEnd)
{
- std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(Params()).CreateNewBlock(coinbaseScript->reserveScript));
+ std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(Params()).CreateNewBlock(coinbaseScript->reserveScript, fMineWitnessTx));
if (!pblocktemplate.get())
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
CBlock *pblock = &pblocktemplate->block;
@@ -319,6 +321,8 @@ std::string gbt_vb_name(const Consensus::DeploymentPos pos) {
UniValue getblocktemplate(const JSONRPCRequest& request)
{
+ // Dogecoin: Never mine witness tx
+ const bool fMineWitnessTx = false;
if (request.fHelp || request.params.size() > 1)
throw runtime_error(
"getblocktemplate ( TemplateRequest )\n"
@@ -549,7 +553,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
// Create new block
CScript scriptDummy = CScript() << OP_TRUE;
- pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy, fSupportsSegwit);
+ pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy, fMineWitnessTx);
if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
@@ -930,148 +934,6 @@ UniValue estimatesmartpriority(const JSONRPCRequest& request)
/* ************************************************************************** */
/* Merge mining. */
-/**
- * The variables below are used to keep track of created and not yet
- * submitted auxpow blocks. Lock them to be sure even for multiple
- * RPC threads running in parallel.
- */
-static CCriticalSection cs_auxblockCache;
-static std::map<uint256, CBlock*> mapNewBlock;
-static std::vector<std::unique_ptr<CBlockTemplate>> vNewBlockTemplate;
-
-static
-void AuxMiningCheck()
-{
- if(!g_connman)
- throw JSONRPCError(RPC_CLIENT_P2P_DISABLED,
- "Error: Peer-to-peer functionality missing or disabled");
-
- if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0
- && !Params().MineBlocksOnDemand())
- throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED,
- "Dogecoin is not connected!");
-
- if (IsInitialBlockDownload() && !Params().MineBlocksOnDemand())
- throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD,
- "Dogecoin is downloading blocks...");
-
- /* This should never fail, since the chain is already
- past the point of merge-mining start. Check nevertheless. */
- {
- LOCK(cs_main);
- if (chainActive.Height() + 1 < Params().GetConsensus().nAuxpowStartHeight)
- throw std::runtime_error("mining auxblock method is not yet available");
- }
-}
-
-static
-UniValue AuxMiningCreateBlock(const CScript& scriptPubKey)
-{
- AuxMiningCheck();
-
- LOCK(cs_auxblockCache);
-
- static unsigned nTransactionsUpdatedLast;
- static const CBlockIndex* pindexPrev = nullptr;
- static uint64_t nStart;
- static CBlock* pblock = nullptr;
- static unsigned nExtraNonce = 0;
-
- // Update block
- {
- LOCK(cs_main);
- if (pindexPrev != chainActive.Tip()
- || (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast
- && GetTime() - nStart > 60))
- {
- if (pindexPrev != chainActive.Tip())
- {
- // Clear old blocks since they're obsolete now.
- mapNewBlock.clear();
- vNewBlockTemplate.clear();
- pblock = nullptr;
- }
-
- // Create new block with nonce = 0 and extraNonce = 1
- std::unique_ptr<CBlockTemplate> newBlock
- = BlockAssembler(Params()).CreateNewBlock(scriptPubKey);
- if (!newBlock)
- throw JSONRPCError(RPC_OUT_OF_MEMORY, "out of memory");
-
- // Update state only when CreateNewBlock succeeded
- nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
- pindexPrev = chainActive.Tip();
- nStart = GetTime();
-
- // Finalise it by setting the version and building the merkle root
- IncrementExtraNonce(&newBlock->block, pindexPrev, nExtraNonce);
- newBlock->block.SetAuxpowFlag(true);
-
- // Save
- pblock = &newBlock->block;
- mapNewBlock[pblock->GetHash()] = pblock;
- vNewBlockTemplate.push_back(std::move(newBlock));
- }
- }
-
- // At this point, pblock is always initialised: If we make it here
- // without creating a new block above, it means that, in particular,
- // pindexPrev == chainActive.Tip(). But for that to happen, we must
- // already have created a pblock in a previous call, as pindexPrev is
- // initialised only when pblock is.
- assert(pblock);
-
- arith_uint256 target;
- bool fNegative, fOverflow;
- target.SetCompact(pblock->nBits, &fNegative, &fOverflow);
- if (fNegative || fOverflow || target == 0)
- throw std::runtime_error("invalid difficulty bits in block");
-
- UniValue result(UniValue::VOBJ);
- result.pushKV("hash", pblock->GetHash().GetHex());
- result.pushKV("chainid", pblock->GetChainId());
- result.pushKV("previousblockhash", pblock->hashPrevBlock.GetHex());
- result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0]->vout[0].nValue);
- result.pushKV("bits", strprintf("%08x", pblock->nBits));
- result.pushKV("height", static_cast<int64_t> (pindexPrev->nHeight + 1));
- result.pushKV("_target", HexStr(BEGIN(target), END(target)));
-
- return result;
-}
-
-static
-bool AuxMiningSubmitBlock(const std::string& hashHex,
- const std::string& auxpowHex)
-{
- AuxMiningCheck();
-
- LOCK(cs_auxblockCache);
-
- uint256 hash;
- hash.SetHex(hashHex);
-
- const std::map<uint256, CBlock*>::iterator mit = mapNewBlock.find(hash);
- if (mit == mapNewBlock.end())
- throw JSONRPCError(RPC_INVALID_PARAMETER, "block hash unknown");
- CBlock& block = *mit->second;
-
- const std::vector<unsigned char> vchAuxPow = ParseHex(auxpowHex);
- CDataStream ss(vchAuxPow, SER_GETHASH, PROTOCOL_VERSION);
- CAuxPow pow;
- ss >> pow;
- block.SetAuxpow(new CAuxPow(pow));
- assert(block.GetHash() == hash);
-
- submitblock_StateCatcher sc(block.GetHash());
- RegisterValidationInterface(&sc);
- std::shared_ptr<const CBlock> shared_block
- = std::make_shared<const CBlock>(block);
- bool fAccepted = ProcessNewBlock(Params(), shared_block, true, nullptr);
- UnregisterValidationInterface(&sc);
-
- return fAccepted;
-}
-
UniValue getauxblock(const JSONRPCRequest& request)
{
if (request.fHelp
@@ -1114,75 +976,132 @@ UniValue getauxblock(const JSONRPCRequest& request)
if (!coinbaseScript->reserveScript.size())
throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)");
- /* Create a new block */
+ if(!g_connman)
+ throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
+
+ if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0 && !Params().MineBlocksOnDemand())
+ throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Dogecoin is not connected!");
+
+ if (IsInitialBlockDownload() && !Params().MineBlocksOnDemand())
+ throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD,
+ "Dogecoin is downloading blocks...");
+
+ /* This should never fail, since the chain is already
+ past the point of merge-mining start. Check nevertheless. */
+ {
+ LOCK(cs_main);
+ if (chainActive.Height() + 1 < Params().GetConsensus().nAuxpowStartHeight)
+ throw std::runtime_error("getauxblock method is not yet available");
+ }
+
+ /* The variables below are used to keep track of created and not yet
+ submitted auxpow blocks. Lock them to be sure even for multiple
+ RPC threads running in parallel. */
+ static CCriticalSection cs_auxblockCache;
+ LOCK(cs_auxblockCache);
+ static std::map<uint256, CBlock*> mapNewBlock;
+ static std::vector<std::unique_ptr<CBlockTemplate>> vNewBlockTemplate;
+
+ /* Create a new block? */
if (request.params.size() == 0)
- return AuxMiningCreateBlock(coinbaseScript->reserveScript);
+ {
+ static unsigned nTransactionsUpdatedLast;
+ static const CBlockIndex* pindexPrev = nullptr;
+ static uint64_t nStart;
+ static CBlock* pblock = nullptr;
+ static unsigned nExtraNonce = 0;
+
+ // Update block
+ // Dogecoin: Never mine witness tx
+ const bool fMineWitnessTx = false;
+ {
+ LOCK(cs_main);
+ if (pindexPrev != chainActive.Tip()
+ || (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast
+ && GetTime() - nStart > 60))
+ {
+ if (pindexPrev != chainActive.Tip())
+ {
+ // Clear old blocks since they're obsolete now.
+ mapNewBlock.clear();
+ vNewBlockTemplate.clear();
+ pblock = nullptr;
+ }
+
+ // Create new block with nonce = 0 and extraNonce = 1
+ std::unique_ptr<CBlockTemplate> newBlock(BlockAssembler(Params()).CreateNewBlock(coinbaseScript->reserveScript, fMineWitnessTx));
+ if (!newBlock)
+ throw JSONRPCError(RPC_OUT_OF_MEMORY, "out of memory");
+
+ // Update state only when CreateNewBlock succeeded
+ nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
+ pindexPrev = chainActive.Tip();
+ nStart = GetTime();
+
+ // Finalise it by setting the version and building the merkle root
+ IncrementExtraNonce(&newBlock->block, pindexPrev, nExtraNonce);
+ newBlock->block.SetAuxpowFlag(true);
+
+ // Save
+ pblock = &newBlock->block;
+ mapNewBlock[pblock->GetHash()] = pblock;
+ vNewBlockTemplate.push_back(std::move(newBlock));
+ }
+ }
+
+ arith_uint256 target;
+ bool fNegative, fOverflow;
+ target.SetCompact(pblock->nBits, &fNegative, &fOverflow);
+ if (fNegative || fOverflow || target == 0)
+ throw std::runtime_error("invalid difficulty bits in block");
+
+ UniValue result(UniValue::VOBJ);
+ result.push_back(Pair("hash", pblock->GetHash().GetHex()));
+ result.push_back(Pair("chainid", pblock->GetChainId()));
+ result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
+ result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0]->vout[0].nValue));
+ result.push_back(Pair("bits", strprintf("%08x", pblock->nBits)));
+ result.push_back(Pair("height", static_cast<int64_t> (pindexPrev->nHeight + 1)));
+ result.push_back(Pair("_target", HexStr(BEGIN(target), END(target))));
+
+ return result;
+ }
/* Submit a block instead. Note that this need not lock cs_main,
since ProcessNewBlock below locks it instead. */
- assert(request.params.size() == 2);
- bool fAccepted = AuxMiningSubmitBlock(request.params[0].get_str(),
- request.params[1].get_str());
- if (fAccepted)
- coinbaseScript->KeepScript();
- return fAccepted;
-}
+ assert(request.params.size() == 2);
+ uint256 hash;
+ hash.SetHex(request.params[0].get_str());
-UniValue createauxblock(const JSONRPCRequest& request)
-{
- if (request.fHelp || request.params.size() != 1)
- throw std::runtime_error(
- "createauxblock <address>\n"
- "\ncreate a new block and return information required to merge-mine it.\n"
- "\nArguments:\n"
- "1. address (string, required) specify coinbase transaction payout address\n"
- "\nResult:\n"
- "{\n"
- " \"hash\" (string) hash of the created block\n"
- " \"chainid\" (numeric) chain ID for this block\n"
- " \"previousblockhash\" (string) hash of the previous block\n"
- " \"coinbasevalue\" (numeric) value of the block's coinbase\n"
- " \"bits\" (string) compressed target of the block\n"
- " \"height\" (numeric) height of the block\n"
- " \"_target\" (string) target in reversed byte order, deprecated\n"
- "}\n"
- "\nExamples:\n"
- + HelpExampleCli("createauxblock", "\"address\"")
- + HelpExampleRpc("createauxblock", "\"address\"")
- );
+ const std::map<uint256, CBlock*>::iterator mit = mapNewBlock.find(hash);
+ if (mit == mapNewBlock.end())
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "block hash unknown");
+ CBlock& block = *mit->second;
- // Check coinbase payout address
- CBitcoinAddress coinbaseAddress(request.params[0].get_str());
- if (!coinbaseAddress.IsValid())
- throw JSONRPCError(RPC_INVALID_PARAMETER,
- "Invalid coinbase payout address");
- const CScript scriptPubKey
- = GetScriptForDestination(coinbaseAddress.Get());
+ const std::vector<unsigned char> vchAuxPow
+ = ParseHex(request.params[1].get_str());
+ CDataStream ss(vchAuxPow, SER_GETHASH, PROTOCOL_VERSION);
+ CAuxPow pow;
+ ss >> pow;
+ block.SetAuxpow(new CAuxPow(pow));
+ assert(block.GetHash() == hash);
- return AuxMiningCreateBlock(scriptPubKey);
-}
+ submitblock_StateCatcher sc(block.GetHash());
+ RegisterValidationInterface(&sc);
+ std::shared_ptr<const CBlock> shared_block
+ = std::make_shared<const CBlock>(block);
+ bool fAccepted = ProcessNewBlock(Params(), shared_block, true, nullptr);
+ UnregisterValidationInterface(&sc);
-UniValue submitauxblock(const JSONRPCRequest& request)
-{
- if (request.fHelp || request.params.size() != 2)
- throw std::runtime_error(
- "submitauxblock <hash> <auxpow>\n"
- "\nsubmit a solved auxpow for a previously block created by 'createauxblock'.\n"
- "\nArguments:\n"
- "1. hash (string, required) hash of the block to submit\n"
- "2. auxpow (string, required) serialised auxpow found\n"
- "\nResult:\n"
- "xxxxx (boolean) whether the submitted block was correct\n"
- "\nExamples:\n"
- + HelpExampleCli("submitauxblock", "\"hash\" \"serialised auxpow\"")
- + HelpExampleRpc("submitauxblock", "\"hash\" \"serialised auxpow\"")
- );
+ if (fAccepted)
+ coinbaseScript->KeepScript();
- return AuxMiningSubmitBlock(request.params[0].get_str(),
- request.params[1].get_str());
+ return fAccepted;
}
+/* ************************************************************************** */
+
static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode
// --------------------- ------------------------ ----------------------- ----------
@@ -1192,8 +1111,6 @@ static const CRPCCommand commands[] =
{ "mining", "getblocktemplate", &getblocktemplate, true, {"template_request"} },
{ "mining", "submitblock", &submitblock, true, {"hexdata","parameters"} },
{ "mining", "getauxblock", &getauxblock, true, {"hash", "auxpow"} },
- { "mining", "createauxblock", &createauxblock, true, {"address"} },
- { "mining", "submitauxblock", &submitauxblock, true, {"hash", "auxpow"} },
{ "generating", "generate", &generate, true, {"nblocks","maxtries"} },
{ "generating", "generatetoaddress", &generatetoaddress, true, {"nblocks","address","maxtries"} },