diff options
| author | Ross Nicoll <[email protected]> | 2017-11-19 22:09:03 +0000 |
|---|---|---|
| committer | Ross Nicoll <[email protected]> | 2018-09-19 19:23:29 +0100 |
| commit | fcde8643344a3a7baadf31d97dd3e1b47aa8cff9 (patch) | |
| tree | e3f8540c7060b29b848a9964c6b6f08fe3b64b5b /src | |
| parent | Merge AuxPoW support from Namecore (diff) | |
| download | discoin-fcde8643344a3a7baadf31d97dd3e1b47aa8cff9.tar.xz discoin-fcde8643344a3a7baadf31d97dd3e1b47aa8cff9.zip | |
Sync mining code from Namecore to resolve unit test failures (#1385)
Diffstat (limited to 'src')
| -rw-r--r-- | src/miner.cpp | 5 | ||||
| -rw-r--r-- | src/miner.h | 2 | ||||
| -rw-r--r-- | src/rpc/mining.cpp | 323 | ||||
| -rw-r--r-- | src/test/miner_tests.cpp | 38 | ||||
| -rw-r--r-- | src/test/test_bitcoin.cpp | 2 |
5 files changed, 145 insertions, 225 deletions
diff --git a/src/miner.cpp b/src/miner.cpp index bac62821b..736d5f878 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -150,7 +150,10 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc nHeight = pindexPrev->nHeight + 1; const int32_t nChainId = chainparams.GetConsensus ().nAuxpowChainId; - pblock->SetBaseVersion(ComputeBlockVersion(pindexPrev, chainparams.GetConsensus()), nChainId); + // FIXME: Active version bits after the always-auxpow fork! + // const int32_t nVersion = ComputeBlockVersion(pindexPrev, chainparams.GetConsensus()), nChainId); + const int32_t nVersion = 4; + pblock->SetBaseVersion(nVersion, nChainId); // -regtest only: allow overriding block.nVersion with // -blockversion=N to test forking scenarios if (chainparams.MineBlocksOnDemand()) diff --git a/src/miner.h b/src/miner.h index 9ae287492..b3be7e52e 100644 --- a/src/miner.h +++ b/src/miner.h @@ -165,7 +165,7 @@ private: public: BlockAssembler(const CChainParams& chainparams); /** Construct a new block template with coinbase to scriptPubKeyIn */ - std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx=true); + std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx); private: // utility functions 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"} }, diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index a9ce7d1ca..b7ffa2732 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -107,7 +107,7 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, uint256 hashHighFeeTx = tx.GetHash(); mempool.addUnchecked(hashHighFeeTx, entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true); BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashParentTx); BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashHighFeeTx); BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashMediumFeeTx); @@ -127,7 +127,7 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse; uint256 hashLowFeeTx = tx.GetHash(); mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse).FromTx(tx)); - pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true); // Verify that the free tx and the low fee tx didn't get selected for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) { BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx); @@ -141,7 +141,7 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, tx.vout[0].nValue -= 2; // Now we should be just over the min relay fee hashLowFeeTx = tx.GetHash(); mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse+2).FromTx(tx)); - pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true); BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashFreeTx); BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashLowFeeTx); @@ -162,7 +162,7 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse; uint256 hashLowFeeTx2 = tx.GetHash(); mempool.addUnchecked(hashLowFeeTx2, entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx)); - pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true); // Verify that this tx isn't selected. for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) { @@ -175,7 +175,7 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, tx.vin[0].prevout.n = 1; tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee mempool.addUnchecked(tx.GetHash(), entry.Fee(10000).FromTx(tx)); - pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true); BOOST_CHECK(pblocktemplate->block.vtx[8]->GetHash() == hashLowFeeTx2); } @@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) fCheckpointsEnabled = false; // Simple block creation, nothing special yet: - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true)); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) @@ -231,7 +231,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) } // Just to make sure we can still make simple blocks - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true)); const CAmount BLOCKSUBSIDY = 50*COIN; const CAmount LOWFEE = CENT; @@ -255,7 +255,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true), std::runtime_error); mempool.clear(); tx.vin[0].prevout.hash = txFirst[0]->GetHash(); @@ -269,7 +269,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOpsCost(80).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true)); mempool.clear(); // block size > limit @@ -289,13 +289,13 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true)); mempool.clear(); // orphan in mempool, template creation fails hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).FromTx(tx)); - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true), std::runtime_error); mempool.clear(); // child with higher priority than parent @@ -312,7 +312,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = tx.vout[0].nValue+BLOCKSUBSIDY-HIGHERFEE; //First txn output + fresh coinbase - new txn fee hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(HIGHERFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true)); mempool.clear(); // coinbase in mempool, template creation fails @@ -323,7 +323,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) hash = tx.GetHash(); // give it a fee so it'll get mined mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true), std::runtime_error); mempool.clear(); // invalid (pre-p2sh) txn in mempool, template creation fails @@ -340,7 +340,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue -= LOWFEE; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true), std::runtime_error); mempool.clear(); // double spend txn pair in mempool, template creation fails @@ -353,7 +353,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true), std::runtime_error); mempool.clear(); // subsidy changing @@ -369,7 +369,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) next->BuildSkip(); chainActive.SetTip(next); } - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true)); // Extend to a 210000-long block chain. while (chainActive.Tip()->nHeight < 210000) { CBlockIndex* prev = chainActive.Tip(); @@ -381,7 +381,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) next->BuildSkip(); chainActive.SetTip(next); } - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true)); // Delete the dummy blocks again. while (chainActive.Tip()->nHeight > nHeight) { CBlockIndex* del = chainActive.Tip(); @@ -468,7 +468,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | 1; BOOST_CHECK(!TestSequenceLocks(tx, flags)); // Sequence locks fail - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true)); // None of the of the absolute height/time locked tx should have made // it into the template because we still check IsFinalTx in CreateNewBlock, @@ -482,7 +482,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) // changed to 60 second block interval for consistency SetMockTime(chainActive.Tip()->GetBlockTime() + 60); - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true)); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5); chainActive.Tip()->nHeight--; diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index e9af8f1c6..9a499357f 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -116,7 +116,7 @@ CBlock TestChain240Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey) { const CChainParams& chainparams = Params(); - std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey, true); CBlock& block = pblocktemplate->block; // Replace mempool-selected txns with just coinbase plus passed-in txns: |