miner_tests.cpp
1 // Copyright (c) 2011-present The Bitcoin Core developers 2 // Distributed under the MIT software license, see the accompanying 3 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 5 #include <addresstype.h> 6 #include <coins.h> 7 #include <common/system.h> 8 #include <consensus/consensus.h> 9 #include <consensus/merkle.h> 10 #include <consensus/tx_verify.h> 11 #include <interfaces/mining.h> 12 #include <node/miner.h> 13 #include <policy/policy.h> 14 #include <test/util/random.h> 15 #include <test/util/transaction_utils.h> 16 #include <test/util/txmempool.h> 17 #include <txmempool.h> 18 #include <uint256.h> 19 #include <util/check.h> 20 #include <util/feefrac.h> 21 #include <util/strencodings.h> 22 #include <util/time.h> 23 #include <util/translation.h> 24 #include <validation.h> 25 #include <versionbits.h> 26 #include <pow.h> 27 28 #include <test/util/common.h> 29 #include <test/util/setup_common.h> 30 31 #include <memory> 32 #include <vector> 33 34 #include <boost/test/unit_test.hpp> 35 36 using namespace util::hex_literals; 37 using interfaces::BlockTemplate; 38 using interfaces::Mining; 39 using node::BlockAssembler; 40 41 namespace miner_tests { 42 struct MinerTestingSetup : public TestingSetup { 43 void TestPackageSelection(const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); 44 void TestBasicMining(const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst, int baseheight) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); 45 void TestPrioritisedMining(const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); 46 bool TestSequenceLocks(const CTransaction& tx, CTxMemPool& tx_mempool) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) 47 { 48 CCoinsViewMemPool view_mempool{&m_node.chainman->ActiveChainstate().CoinsTip(), tx_mempool}; 49 CBlockIndex* tip{m_node.chainman->ActiveChain().Tip()}; 50 const std::optional<LockPoints> lock_points{CalculateLockPointsAtTip(tip, view_mempool, tx)}; 51 return lock_points.has_value() && CheckSequenceLocksAtTip(tip, *lock_points); 52 } 53 CTxMemPool& MakeMempool() 54 { 55 // Delete the previous mempool to ensure with valgrind that the old 56 // pointer is not accessed, when the new one should be accessed 57 // instead. 58 m_node.mempool.reset(); 59 bilingual_str error; 60 auto opts = MemPoolOptionsForTest(m_node); 61 // The "block size > limit" test creates a cluster of 1192590 vbytes, 62 // so set the cluster vbytes limit big enough so that the txgraph 63 // doesn't become oversized. 64 opts.limits.cluster_size_vbytes = 1'200'000; 65 m_node.mempool = std::make_unique<CTxMemPool>(opts, error); 66 Assert(error.empty()); 67 return *m_node.mempool; 68 } 69 std::unique_ptr<Mining> MakeMining() 70 { 71 return interfaces::MakeMining(m_node, /*wait_loaded=*/false); 72 } 73 }; 74 } // namespace miner_tests 75 76 BOOST_FIXTURE_TEST_SUITE(miner_tests, MinerTestingSetup) 77 78 static CFeeRate blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE); 79 80 constexpr static struct { 81 unsigned int extranonce; 82 unsigned int nonce; 83 } BLOCKINFO[]{{0, 3552706918}, {500, 37506755}, {1000, 948987788}, {400, 524762339}, {800, 258510074}, {300, 102309278}, 84 {1300, 54365202}, {600, 1107740426}, {1000, 203094491}, {900, 391178848}, {800, 381177271}, {600, 87188412}, 85 {0, 66522866}, {800, 874942736}, {1000, 89200838}, {400, 312638088}, {400, 66263693}, {500, 924648304}, 86 {400, 369913599}, {500, 47630099}, {500, 115045364}, {100, 277026602}, {1100, 809621409}, {700, 155345322}, 87 {800, 943579953}, {400, 28200730}, {900, 77200495}, {0, 105935488}, {400, 698721821}, {500, 111098863}, 88 {1300, 445389594}, {500, 621849894}, {1400, 56010046}, {1100, 370669776}, {1200, 380301940}, {1200, 110654905}, 89 {400, 213771024}, {1500, 120014726}, {1200, 835019014}, {1500, 624817237}, {900, 1404297}, {400, 189414558}, 90 {400, 293178348}, {1100, 15393789}, {600, 396764180}, {800, 1387046371}, {800, 199368303}, {700, 111496662}, 91 {100, 129759616}, {200, 536577982}, {500, 125881300}, {500, 101053391}, {1200, 471590548}, {900, 86957729}, 92 {1200, 179604104}, {600, 68658642}, {1000, 203295701}, {500, 139615361}, {900, 233693412}, {300, 153225163}, 93 {0, 27616254}, {1200, 9856191}, {100, 220392722}, {200, 66257599}, {1100, 145489641}, {1300, 37859442}, 94 {400, 5816075}, {1200, 215752117}, {1400, 32361482}, {1400, 6529223}, {500, 143332977}, {800, 878392}, 95 {700, 159290408}, {400, 123197595}, {700, 43988693}, {300, 304224916}, {700, 214771621}, {1100, 274148273}, 96 {400, 285632418}, {1100, 923451065}, {600, 12818092}, {1200, 736282054}, {1000, 246683167}, {600, 92950402}, 97 {1400, 29223405}, {1000, 841327192}, {700, 174301283}, {1400, 214009854}, {1000, 6989517}, {1200, 278226956}, 98 {700, 540219613}, {400, 93663104}, {1100, 152345635}, {1500, 464194499}, {1300, 333850111}, {600, 258311263}, 99 {600, 90173162}, {1000, 33590797}, {1500, 332866027}, {100, 204704427}, {1000, 463153545}, {800, 303244785}, 100 {600, 88096214}, {0, 137477892}, {1200, 195514506}, {300, 704114595}, {900, 292087369}, {1400, 758684870}, 101 {1300, 163493028}, {1200, 53151293}}; 102 103 static std::unique_ptr<CBlockIndex> CreateBlockIndex(int nHeight, CBlockIndex* active_chain_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main) 104 { 105 auto index{std::make_unique<CBlockIndex>()}; 106 index->nHeight = nHeight; 107 index->pprev = active_chain_tip; 108 return index; 109 } 110 111 // Test suite for ancestor feerate transaction selection. 112 // Implemented as an additional function, rather than a separate test case, 113 // to allow reusing the blockchain created in CreateNewBlock_validity. 114 void MinerTestingSetup::TestPackageSelection(const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst) 115 { 116 CTxMemPool& tx_mempool{MakeMempool()}; 117 auto mining{MakeMining()}; 118 BlockAssembler::Options options; 119 options.coinbase_output_script = scriptPubKey; 120 options.include_dummy_extranonce = true; 121 122 LOCK(tx_mempool.cs); 123 BOOST_CHECK(tx_mempool.size() == 0); 124 125 // Block template should only have a coinbase when there's nothing in the mempool 126 std::unique_ptr<BlockTemplate> block_template = mining->createNewBlock(options, /*cooldown=*/false); 127 BOOST_REQUIRE(block_template); 128 CBlock block{block_template->getBlock()}; 129 BOOST_REQUIRE_EQUAL(block.vtx.size(), 1U); 130 131 // waitNext() on an empty mempool should return nullptr because there is no better template 132 auto should_be_nullptr = block_template->waitNext({.timeout = MillisecondsDouble{0}, .fee_threshold = 1}); 133 BOOST_REQUIRE(should_be_nullptr == nullptr); 134 135 // Unless fee_threshold is 0 136 block_template = block_template->waitNext({.timeout = MillisecondsDouble{0}, .fee_threshold = 0}); 137 BOOST_REQUIRE(block_template); 138 139 // Test the ancestor feerate transaction selection. 140 TestMemPoolEntryHelper entry; 141 142 // Test that a medium fee transaction will be selected after a higher fee 143 // rate package with a low fee rate parent. 144 CMutableTransaction tx; 145 tx.vin.resize(1); 146 tx.vin[0].scriptSig = CScript() << OP_1; 147 tx.vin[0].prevout.hash = txFirst[0]->GetHash(); 148 tx.vin[0].prevout.n = 0; 149 tx.vout.resize(1); 150 tx.vout[0].nValue = 5000000000LL - 1000; 151 // This tx has a low fee: 1000 satoshis 152 Txid hashParentTx = tx.GetHash(); // save this txid for later use 153 const auto parent_tx{entry.Fee(1000).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)}; 154 TryAddToMempool(tx_mempool, parent_tx); 155 156 // This tx has a medium fee: 10000 satoshis 157 tx.vin[0].prevout.hash = txFirst[1]->GetHash(); 158 tx.vout[0].nValue = 5000000000LL - 10000; 159 Txid hashMediumFeeTx = tx.GetHash(); 160 const auto medium_fee_tx{entry.Fee(10000).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)}; 161 TryAddToMempool(tx_mempool, medium_fee_tx); 162 163 // This tx has a high fee, but depends on the first transaction 164 tx.vin[0].prevout.hash = hashParentTx; 165 tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 50k satoshi fee 166 Txid hashHighFeeTx = tx.GetHash(); 167 const auto high_fee_tx{entry.Fee(50000).Time(Now<NodeSeconds>()).SpendsCoinbase(false).FromTx(tx)}; 168 TryAddToMempool(tx_mempool, high_fee_tx); 169 170 block_template = mining->createNewBlock(options, /*cooldown=*/false); 171 BOOST_REQUIRE(block_template); 172 block = block_template->getBlock(); 173 BOOST_REQUIRE_EQUAL(block.vtx.size(), 4U); 174 BOOST_CHECK(block.vtx[1]->GetHash() == hashParentTx); 175 BOOST_CHECK(block.vtx[2]->GetHash() == hashHighFeeTx); 176 BOOST_CHECK(block.vtx[3]->GetHash() == hashMediumFeeTx); 177 178 // Test the inclusion of package feerates in the block template and ensure they are sequential. 179 const auto block_package_feerates = BlockAssembler{m_node.chainman->ActiveChainstate(), &tx_mempool, options}.CreateNewBlock()->m_package_feerates; 180 BOOST_CHECK(block_package_feerates.size() == 2); 181 182 // parent_tx and high_fee_tx are added to the block as a package. 183 const auto combined_txs_fee = parent_tx.GetFee() + high_fee_tx.GetFee(); 184 const auto combined_txs_size = parent_tx.GetTxSize() + high_fee_tx.GetTxSize(); 185 FeeFrac package_feefrac{combined_txs_fee, combined_txs_size}; 186 // The package should be added first. 187 BOOST_CHECK(block_package_feerates[0] == package_feefrac); 188 189 // The medium_fee_tx should be added next. 190 FeeFrac medium_tx_feefrac{medium_fee_tx.GetFee(), medium_fee_tx.GetTxSize()}; 191 BOOST_CHECK(block_package_feerates[1] == medium_tx_feefrac); 192 193 // Test that a package below the block min tx fee doesn't get included 194 tx.vin[0].prevout.hash = hashHighFeeTx; 195 tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 0 fee 196 Txid hashFreeTx = tx.GetHash(); 197 TryAddToMempool(tx_mempool, entry.Fee(0).FromTx(tx)); 198 uint64_t freeTxSize{::GetSerializeSize(TX_WITH_WITNESS(tx))}; 199 200 // Calculate a fee on child transaction that will put the package just 201 // below the block min tx fee (assuming 1 child tx of the same size). 202 CAmount feeToUse = blockMinFeeRate.GetFee(2*freeTxSize) - 1; 203 204 tx.vin[0].prevout.hash = hashFreeTx; 205 tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse; 206 Txid hashLowFeeTx = tx.GetHash(); 207 TryAddToMempool(tx_mempool, entry.Fee(feeToUse).FromTx(tx)); 208 209 // waitNext() should return nullptr because there is no better template 210 should_be_nullptr = block_template->waitNext({.timeout = MillisecondsDouble{0}, .fee_threshold = 1}); 211 BOOST_REQUIRE(should_be_nullptr == nullptr); 212 213 block = block_template->getBlock(); 214 // Verify that the free tx and the low fee tx didn't get selected 215 for (size_t i=0; i<block.vtx.size(); ++i) { 216 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx); 217 BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx); 218 } 219 220 // Test that packages above the min relay fee do get included, even if one 221 // of the transactions is below the min relay fee 222 // Remove the low fee transaction and replace with a higher fee transaction 223 tx_mempool.removeRecursive(CTransaction(tx), MemPoolRemovalReason::REPLACED); 224 tx.vout[0].nValue -= 2; // Now we should be just over the min relay fee 225 hashLowFeeTx = tx.GetHash(); 226 TryAddToMempool(tx_mempool, entry.Fee(feeToUse + 2).FromTx(tx)); 227 228 // waitNext() should return if fees for the new template are at least 1 sat up 229 block_template = block_template->waitNext({.fee_threshold = 1}); 230 BOOST_REQUIRE(block_template); 231 block = block_template->getBlock(); 232 BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U); 233 BOOST_CHECK(block.vtx[4]->GetHash() == hashFreeTx); 234 BOOST_CHECK(block.vtx[5]->GetHash() == hashLowFeeTx); 235 236 // Test that transaction selection properly updates ancestor fee 237 // calculations as ancestor transactions get included in a block. 238 // Add a 0-fee transaction that has 2 outputs. 239 tx.vin[0].prevout.hash = txFirst[2]->GetHash(); 240 tx.vout.resize(2); 241 tx.vout[0].nValue = 5000000000LL - 100000000; 242 tx.vout[1].nValue = 100000000; // 1BTC output 243 // Increase size to avoid rounding errors: when the feerate is extremely small (i.e. 1sat/kvB), evaluating the fee 244 // at smaller sizes gives us rounded values that are equal to each other, which means we incorrectly include 245 // hashFreeTx2 + hashLowFeeTx2. 246 BulkTransaction(tx, 4000); 247 Txid hashFreeTx2 = tx.GetHash(); 248 TryAddToMempool(tx_mempool, entry.Fee(0).SpendsCoinbase(true).FromTx(tx)); 249 250 // This tx can't be mined by itself 251 tx.vin[0].prevout.hash = hashFreeTx2; 252 tx.vout.resize(1); 253 feeToUse = blockMinFeeRate.GetFee(freeTxSize); 254 tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse; 255 Txid hashLowFeeTx2 = tx.GetHash(); 256 TryAddToMempool(tx_mempool, entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx)); 257 block_template = mining->createNewBlock(options, /*cooldown=*/false); 258 BOOST_REQUIRE(block_template); 259 block = block_template->getBlock(); 260 261 // Verify that this tx isn't selected. 262 for (size_t i=0; i<block.vtx.size(); ++i) { 263 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx2); 264 BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx2); 265 } 266 267 // This tx will be mineable, and should cause hashLowFeeTx2 to be selected 268 // as well. 269 tx.vin[0].prevout.n = 1; 270 tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee 271 TryAddToMempool(tx_mempool, entry.Fee(10000).FromTx(tx)); 272 block_template = mining->createNewBlock(options, /*cooldown=*/false); 273 BOOST_REQUIRE(block_template); 274 block = block_template->getBlock(); 275 BOOST_REQUIRE_EQUAL(block.vtx.size(), 9U); 276 BOOST_CHECK(block.vtx[8]->GetHash() == hashLowFeeTx2); 277 } 278 279 std::vector<CTransactionRef> CreateBigSigOpsCluster(const CTransactionRef& first_tx) 280 { 281 std::vector<CTransactionRef> ret; 282 283 CMutableTransaction tx; 284 // block sigops > limit: 1000 CHECKMULTISIG + 1 285 tx.vin.resize(1); 286 // NOTE: OP_NOP is used to force 20 SigOps for the CHECKMULTISIG 287 tx.vin[0].scriptSig = CScript() << OP_0 << OP_0 << OP_CHECKSIG << OP_1; 288 tx.vin[0].prevout.hash = first_tx->GetHash(); 289 tx.vin[0].prevout.n = 0; 290 tx.vout.resize(50); 291 for (auto &out : tx.vout) { 292 out.nValue = first_tx->vout[0].nValue / 50; 293 out.scriptPubKey = CScript() << OP_1; 294 } 295 296 tx.vout[0].nValue -= CENT; 297 CTransactionRef parent_tx = MakeTransactionRef(tx); 298 ret.push_back(parent_tx); 299 assert(GetLegacySigOpCount(*parent_tx) == 1); 300 301 // Tx1 has 1 sigops, 1 input, 50 outputs. 302 // Tx2-51 has 400 sigops: 1 input, 20 CHECKMULTISIG outputs 303 // Total: 1000 CHECKMULTISIG + 1 304 for (unsigned int i = 0; i < 50; ++i) { 305 auto tx2 = tx; 306 tx2.vin.resize(1); 307 tx2.vin[0].prevout.hash = parent_tx->GetHash(); 308 tx2.vin[0].prevout.n = i; 309 tx2.vin[0].scriptSig = CScript() << OP_1; 310 tx2.vout.resize(20); 311 tx2.vout[0].nValue = parent_tx->vout[i].nValue - CENT; 312 for (auto &out : tx2.vout) { 313 out.nValue = 0; 314 out.scriptPubKey = CScript() << OP_0 << OP_0 << OP_0 << OP_NOP << OP_CHECKMULTISIG << OP_1; 315 } 316 ret.push_back(MakeTransactionRef(tx2)); 317 } 318 return ret; 319 } 320 321 void MinerTestingSetup::TestBasicMining(const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst, int baseheight) 322 { 323 Txid hash; 324 CMutableTransaction tx; 325 TestMemPoolEntryHelper entry; 326 entry.nFee = 11; 327 entry.nHeight = 11; 328 329 const CAmount BLOCKSUBSIDY = 50 * COIN; 330 const CAmount LOWFEE = CENT; 331 const CAmount HIGHFEE = COIN; 332 const CAmount HIGHERFEE = 4 * COIN; 333 334 auto mining{MakeMining()}; 335 BOOST_REQUIRE(mining); 336 337 BlockAssembler::Options options; 338 options.coinbase_output_script = scriptPubKey; 339 options.include_dummy_extranonce = true; 340 341 { 342 CTxMemPool& tx_mempool{MakeMempool()}; 343 LOCK(tx_mempool.cs); 344 345 // Just to make sure we can still make simple blocks 346 auto block_template{mining->createNewBlock(options, /*cooldown=*/false)}; 347 BOOST_REQUIRE(block_template); 348 CBlock block{block_template->getBlock()}; 349 350 auto txs = CreateBigSigOpsCluster(txFirst[0]); 351 352 int64_t legacy_sigops = 0; 353 for (auto& t : txs) { 354 // If we don't set the number of sigops in the CTxMemPoolEntry, 355 // template creation fails during sanity checks. 356 TryAddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(t)); 357 legacy_sigops += GetLegacySigOpCount(*t); 358 BOOST_CHECK(tx_mempool.GetIter(t->GetHash()).has_value()); 359 } 360 assert(tx_mempool.mapTx.size() == 51); 361 assert(legacy_sigops == 20001); 362 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options, /*cooldown=*/false), std::runtime_error, HasReason("bad-blk-sigops")); 363 } 364 365 { 366 CTxMemPool& tx_mempool{MakeMempool()}; 367 LOCK(tx_mempool.cs); 368 369 // Check that the mempool is empty. 370 assert(tx_mempool.mapTx.empty()); 371 372 // Just to make sure we can still make simple blocks 373 auto block_template{mining->createNewBlock(options, /*cooldown=*/false)}; 374 BOOST_REQUIRE(block_template); 375 CBlock block{block_template->getBlock()}; 376 377 auto txs = CreateBigSigOpsCluster(txFirst[0]); 378 379 int64_t legacy_sigops = 0; 380 for (auto& t : txs) { 381 TryAddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).SigOpsCost(GetLegacySigOpCount(*t)*WITNESS_SCALE_FACTOR).FromTx(t)); 382 legacy_sigops += GetLegacySigOpCount(*t); 383 BOOST_CHECK(tx_mempool.GetIter(t->GetHash()).has_value()); 384 } 385 assert(tx_mempool.mapTx.size() == 51); 386 assert(legacy_sigops == 20001); 387 388 BOOST_REQUIRE(mining->createNewBlock(options, /*cooldown=*/false)); 389 } 390 391 { 392 CTxMemPool& tx_mempool{MakeMempool()}; 393 LOCK(tx_mempool.cs); 394 395 // block size > limit 396 tx.vin.resize(1); 397 tx.vout.resize(1); 398 tx.vout[0].nValue = BLOCKSUBSIDY; 399 // 36 * (520char + DROP) + OP_1 = 18757 bytes 400 std::vector<unsigned char> vchData(520); 401 for (unsigned int i = 0; i < 18; ++i) { 402 tx.vin[0].scriptSig << vchData << OP_DROP; 403 tx.vout[0].scriptPubKey << vchData << OP_DROP; 404 } 405 tx.vin[0].scriptSig << OP_1; 406 tx.vout[0].scriptPubKey << OP_1; 407 tx.vin[0].prevout.hash = txFirst[0]->GetHash(); 408 tx.vin[0].prevout.n = 0; 409 tx.vout[0].nValue = BLOCKSUBSIDY; 410 for (unsigned int i = 0; i < 63; ++i) { 411 tx.vout[0].nValue -= LOWFEE; 412 hash = tx.GetHash(); 413 bool spendsCoinbase = i == 0; // only first tx spends coinbase 414 TryAddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); 415 BOOST_CHECK(tx_mempool.GetIter(hash).has_value()); 416 tx.vin[0].prevout.hash = hash; 417 } 418 BOOST_REQUIRE(mining->createNewBlock(options, /*cooldown=*/false)); 419 } 420 421 { 422 CTxMemPool& tx_mempool{MakeMempool()}; 423 LOCK(tx_mempool.cs); 424 425 // orphan in tx_mempool, template creation fails 426 hash = tx.GetHash(); 427 TryAddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).FromTx(tx)); 428 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options, /*cooldown=*/false), std::runtime_error, HasReason("bad-txns-inputs-missingorspent")); 429 } 430 431 { 432 CTxMemPool& tx_mempool{MakeMempool()}; 433 LOCK(tx_mempool.cs); 434 435 // child with higher feerate than parent 436 tx.vin[0].scriptSig = CScript() << OP_1; 437 tx.vin[0].prevout.hash = txFirst[1]->GetHash(); 438 tx.vout[0].nValue = BLOCKSUBSIDY - HIGHFEE; 439 hash = tx.GetHash(); 440 TryAddToMempool(tx_mempool, entry.Fee(HIGHFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)); 441 tx.vin[0].prevout.hash = hash; 442 tx.vin.resize(2); 443 tx.vin[1].scriptSig = CScript() << OP_1; 444 tx.vin[1].prevout.hash = txFirst[0]->GetHash(); 445 tx.vin[1].prevout.n = 0; 446 tx.vout[0].nValue = tx.vout[0].nValue + BLOCKSUBSIDY - HIGHERFEE; // First txn output + fresh coinbase - new txn fee 447 hash = tx.GetHash(); 448 TryAddToMempool(tx_mempool, entry.Fee(HIGHERFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)); 449 BOOST_REQUIRE(mining->createNewBlock(options, /*cooldown=*/false)); 450 } 451 452 { 453 CTxMemPool& tx_mempool{MakeMempool()}; 454 LOCK(tx_mempool.cs); 455 456 // coinbase in tx_mempool, template creation fails 457 tx.vin.resize(1); 458 tx.vin[0].prevout.SetNull(); 459 tx.vin[0].scriptSig = CScript() << OP_0 << OP_1; 460 tx.vout[0].nValue = 0; 461 hash = tx.GetHash(); 462 // give it a fee so it'll get mined 463 TryAddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(false).FromTx(tx)); 464 // Should throw bad-cb-multiple 465 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options, /*cooldown=*/false), std::runtime_error, HasReason("bad-cb-multiple")); 466 } 467 468 { 469 CTxMemPool& tx_mempool{MakeMempool()}; 470 LOCK(tx_mempool.cs); 471 472 // double spend txn pair in tx_mempool, template creation fails 473 tx.vin[0].prevout.hash = txFirst[0]->GetHash(); 474 tx.vin[0].scriptSig = CScript() << OP_1; 475 tx.vout[0].nValue = BLOCKSUBSIDY - HIGHFEE; 476 tx.vout[0].scriptPubKey = CScript() << OP_1; 477 hash = tx.GetHash(); 478 TryAddToMempool(tx_mempool, entry.Fee(HIGHFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)); 479 tx.vout[0].scriptPubKey = CScript() << OP_2; 480 hash = tx.GetHash(); 481 TryAddToMempool(tx_mempool, entry.Fee(HIGHFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)); 482 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options, /*cooldown=*/false), std::runtime_error, HasReason("bad-txns-inputs-missingorspent")); 483 } 484 485 { 486 CTxMemPool& tx_mempool{MakeMempool()}; 487 LOCK(tx_mempool.cs); 488 489 // subsidy changing 490 int nHeight = m_node.chainman->ActiveChain().Height(); 491 // Create an actual 209999-long block chain (without valid blocks). 492 while (m_node.chainman->ActiveChain().Tip()->nHeight < 209999) { 493 CBlockIndex* prev = m_node.chainman->ActiveChain().Tip(); 494 CBlockIndex* next = new CBlockIndex(); 495 next->phashBlock = new uint256(m_rng.rand256()); 496 m_node.chainman->ActiveChainstate().CoinsTip().SetBestBlock(next->GetBlockHash()); 497 next->pprev = prev; 498 next->nHeight = prev->nHeight + 1; 499 next->BuildSkip(); 500 m_node.chainman->ActiveChain().SetTip(*next); 501 } 502 BOOST_REQUIRE(mining->createNewBlock(options, /*cooldown=*/false)); 503 // Extend to a 210000-long block chain. 504 while (m_node.chainman->ActiveChain().Tip()->nHeight < 210000) { 505 CBlockIndex* prev = m_node.chainman->ActiveChain().Tip(); 506 CBlockIndex* next = new CBlockIndex(); 507 next->phashBlock = new uint256(m_rng.rand256()); 508 m_node.chainman->ActiveChainstate().CoinsTip().SetBestBlock(next->GetBlockHash()); 509 next->pprev = prev; 510 next->nHeight = prev->nHeight + 1; 511 next->BuildSkip(); 512 m_node.chainman->ActiveChain().SetTip(*next); 513 } 514 BOOST_REQUIRE(mining->createNewBlock(options, /*cooldown=*/false)); 515 516 // invalid p2sh txn in tx_mempool, template creation fails 517 tx.vin[0].prevout.hash = txFirst[0]->GetHash(); 518 tx.vin[0].prevout.n = 0; 519 tx.vin[0].scriptSig = CScript() << OP_1; 520 tx.vout[0].nValue = BLOCKSUBSIDY - LOWFEE; 521 CScript script = CScript() << OP_0; 522 tx.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(script)); 523 hash = tx.GetHash(); 524 TryAddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)); 525 tx.vin[0].prevout.hash = hash; 526 tx.vin[0].scriptSig = CScript() << std::vector<unsigned char>(script.begin(), script.end()); 527 tx.vout[0].nValue -= LOWFEE; 528 hash = tx.GetHash(); 529 TryAddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(false).FromTx(tx)); 530 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options, /*cooldown=*/false), std::runtime_error, HasReason("block-script-verify-flag-failed")); 531 532 // Delete the dummy blocks again. 533 while (m_node.chainman->ActiveChain().Tip()->nHeight > nHeight) { 534 CBlockIndex* del = m_node.chainman->ActiveChain().Tip(); 535 m_node.chainman->ActiveChain().SetTip(*Assert(del->pprev)); 536 m_node.chainman->ActiveChainstate().CoinsTip().SetBestBlock(del->pprev->GetBlockHash()); 537 delete del->phashBlock; 538 delete del; 539 } 540 } 541 542 CTxMemPool& tx_mempool{MakeMempool()}; 543 LOCK(tx_mempool.cs); 544 545 // non-final txs in mempool 546 SetMockTime(m_node.chainman->ActiveChain().Tip()->GetMedianTimePast() + 1); 547 const int flags{LOCKTIME_VERIFY_SEQUENCE}; 548 // height map 549 std::vector<int> prevheights; 550 551 // relative height locked 552 tx.version = 2; 553 tx.vin.resize(1); 554 prevheights.resize(1); 555 tx.vin[0].prevout.hash = txFirst[0]->GetHash(); // only 1 transaction 556 tx.vin[0].prevout.n = 0; 557 tx.vin[0].scriptSig = CScript() << OP_1; 558 tx.vin[0].nSequence = m_node.chainman->ActiveChain().Tip()->nHeight + 1; // txFirst[0] is the 2nd block 559 prevheights[0] = baseheight + 1; 560 tx.vout.resize(1); 561 tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE; 562 tx.vout[0].scriptPubKey = CScript() << OP_1; 563 tx.nLockTime = 0; 564 hash = tx.GetHash(); 565 TryAddToMempool(tx_mempool, entry.Fee(HIGHFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)); 566 BOOST_CHECK(CheckFinalTxAtTip(*Assert(m_node.chainman->ActiveChain().Tip()), CTransaction{tx})); // Locktime passes 567 BOOST_CHECK(!TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks fail 568 569 { 570 CBlockIndex* active_chain_tip = m_node.chainman->ActiveChain().Tip(); 571 BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, *CreateBlockIndex(active_chain_tip->nHeight + 2, active_chain_tip))); // Sequence locks pass on 2nd block 572 } 573 574 // relative time locked 575 tx.vin[0].prevout.hash = txFirst[1]->GetHash(); 576 tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | (((m_node.chainman->ActiveChain().Tip()->GetMedianTimePast()+1-m_node.chainman->ActiveChain()[1]->GetMedianTimePast()) >> CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) + 1); // txFirst[1] is the 3rd block 577 prevheights[0] = baseheight + 2; 578 hash = tx.GetHash(); 579 TryAddToMempool(tx_mempool, entry.Time(Now<NodeSeconds>()).FromTx(tx)); 580 BOOST_CHECK(CheckFinalTxAtTip(*Assert(m_node.chainman->ActiveChain().Tip()), CTransaction{tx})); // Locktime passes 581 BOOST_CHECK(!TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks fail 582 583 const int SEQUENCE_LOCK_TIME = 512; // Sequence locks pass 512 seconds later 584 for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i) 585 m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime += SEQUENCE_LOCK_TIME; // Trick the MedianTimePast 586 { 587 CBlockIndex* active_chain_tip = m_node.chainman->ActiveChain().Tip(); 588 BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, *CreateBlockIndex(active_chain_tip->nHeight + 1, active_chain_tip))); 589 } 590 591 for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i) { 592 CBlockIndex* ancestor{Assert(m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i))}; 593 ancestor->nTime -= SEQUENCE_LOCK_TIME; // undo tricked MTP 594 } 595 596 // absolute height locked 597 tx.vin[0].prevout.hash = txFirst[2]->GetHash(); 598 tx.vin[0].nSequence = CTxIn::MAX_SEQUENCE_NONFINAL; 599 prevheights[0] = baseheight + 3; 600 tx.nLockTime = m_node.chainman->ActiveChain().Tip()->nHeight + 1; 601 hash = tx.GetHash(); 602 TryAddToMempool(tx_mempool, entry.Time(Now<NodeSeconds>()).FromTx(tx)); 603 BOOST_CHECK(!CheckFinalTxAtTip(*Assert(m_node.chainman->ActiveChain().Tip()), CTransaction{tx})); // Locktime fails 604 BOOST_CHECK(TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks pass 605 BOOST_CHECK(IsFinalTx(CTransaction(tx), m_node.chainman->ActiveChain().Tip()->nHeight + 2, m_node.chainman->ActiveChain().Tip()->GetMedianTimePast())); // Locktime passes on 2nd block 606 607 // ensure tx is final for a specific case where there is no locktime and block height is zero 608 tx.nLockTime = 0; 609 BOOST_CHECK(IsFinalTx(CTransaction(tx), /*nBlockHeight=*/0, m_node.chainman->ActiveChain().Tip()->GetMedianTimePast())); 610 611 // absolute time locked 612 tx.vin[0].prevout.hash = txFirst[3]->GetHash(); 613 tx.nLockTime = m_node.chainman->ActiveChain().Tip()->GetMedianTimePast(); 614 prevheights.resize(1); 615 prevheights[0] = baseheight + 4; 616 hash = tx.GetHash(); 617 TryAddToMempool(tx_mempool, entry.Time(Now<NodeSeconds>()).FromTx(tx)); 618 BOOST_CHECK(!CheckFinalTxAtTip(*Assert(m_node.chainman->ActiveChain().Tip()), CTransaction{tx})); // Locktime fails 619 BOOST_CHECK(TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks pass 620 BOOST_CHECK(IsFinalTx(CTransaction(tx), m_node.chainman->ActiveChain().Tip()->nHeight + 2, m_node.chainman->ActiveChain().Tip()->GetMedianTimePast() + 1)); // Locktime passes 1 second later 621 622 // mempool-dependent transactions (not added) 623 tx.vin[0].prevout.hash = hash; 624 prevheights[0] = m_node.chainman->ActiveChain().Tip()->nHeight + 1; 625 tx.nLockTime = 0; 626 tx.vin[0].nSequence = 0; 627 BOOST_CHECK(CheckFinalTxAtTip(*Assert(m_node.chainman->ActiveChain().Tip()), CTransaction{tx})); // Locktime passes 628 BOOST_CHECK(TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks pass 629 tx.vin[0].nSequence = 1; 630 BOOST_CHECK(!TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks fail 631 tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG; 632 BOOST_CHECK(TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks pass 633 tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | 1; 634 BOOST_CHECK(!TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks fail 635 636 auto block_template = mining->createNewBlock(options, /*cooldown=*/false); 637 BOOST_REQUIRE(block_template); 638 639 // None of the of the absolute height/time locked tx should have made 640 // it into the template because we still check IsFinalTx in CreateNewBlock, 641 // but relative locked txs will if inconsistently added to mempool. 642 // For now these will still generate a valid template until BIP68 soft fork 643 CBlock block{block_template->getBlock()}; 644 BOOST_CHECK_EQUAL(block.vtx.size(), 3U); 645 // However if we advance height by 1 and time by SEQUENCE_LOCK_TIME, all of them should be mined 646 for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i) { 647 CBlockIndex* ancestor{Assert(m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i))}; 648 ancestor->nTime += SEQUENCE_LOCK_TIME; // Trick the MedianTimePast 649 } 650 m_node.chainman->ActiveChain().Tip()->nHeight++; 651 SetMockTime(m_node.chainman->ActiveChain().Tip()->GetMedianTimePast() + 1); 652 653 block_template = mining->createNewBlock(options, /*cooldown=*/false); 654 BOOST_REQUIRE(block_template); 655 block = block_template->getBlock(); 656 BOOST_CHECK_EQUAL(block.vtx.size(), 5U); 657 } 658 659 void MinerTestingSetup::TestPrioritisedMining(const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst) 660 { 661 auto mining{MakeMining()}; 662 BOOST_REQUIRE(mining); 663 664 BlockAssembler::Options options; 665 options.coinbase_output_script = scriptPubKey; 666 options.include_dummy_extranonce = true; 667 668 CTxMemPool& tx_mempool{MakeMempool()}; 669 LOCK(tx_mempool.cs); 670 671 TestMemPoolEntryHelper entry; 672 673 // Test that a tx below min fee but prioritised is included 674 CMutableTransaction tx; 675 tx.vin.resize(1); 676 tx.vin[0].prevout.hash = txFirst[0]->GetHash(); 677 tx.vin[0].prevout.n = 0; 678 tx.vin[0].scriptSig = CScript() << OP_1; 679 tx.vout.resize(1); 680 tx.vout[0].nValue = 5000000000LL; // 0 fee 681 Txid hashFreePrioritisedTx = tx.GetHash(); 682 TryAddToMempool(tx_mempool, entry.Fee(0).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)); 683 tx_mempool.PrioritiseTransaction(hashFreePrioritisedTx, 5 * COIN); 684 685 tx.vin[0].prevout.hash = txFirst[1]->GetHash(); 686 tx.vin[0].prevout.n = 0; 687 tx.vout[0].nValue = 5000000000LL - 1000; 688 // This tx has a low fee: 1000 satoshis 689 Txid hashParentTx = tx.GetHash(); // save this txid for later use 690 TryAddToMempool(tx_mempool, entry.Fee(1000).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)); 691 692 // This tx has a medium fee: 10000 satoshis 693 tx.vin[0].prevout.hash = txFirst[2]->GetHash(); 694 tx.vout[0].nValue = 5000000000LL - 10000; 695 Txid hashMediumFeeTx = tx.GetHash(); 696 TryAddToMempool(tx_mempool, entry.Fee(10000).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)); 697 tx_mempool.PrioritiseTransaction(hashMediumFeeTx, -5 * COIN); 698 699 // This tx also has a low fee, but is prioritised 700 tx.vin[0].prevout.hash = hashParentTx; 701 tx.vout[0].nValue = 5000000000LL - 1000 - 1000; // 1000 satoshi fee 702 Txid hashPrioritsedChild = tx.GetHash(); 703 TryAddToMempool(tx_mempool, entry.Fee(1000).Time(Now<NodeSeconds>()).SpendsCoinbase(false).FromTx(tx)); 704 tx_mempool.PrioritiseTransaction(hashPrioritsedChild, 2 * COIN); 705 706 // Test that transaction selection properly updates ancestor fee calculations as prioritised 707 // parents get included in a block. Create a transaction with two prioritised ancestors, each 708 // included by itself: FreeParent <- FreeChild <- FreeGrandchild. 709 // When FreeParent is added, a modified entry will be created for FreeChild + FreeGrandchild 710 // FreeParent's prioritisation should not be included in that entry. 711 // When FreeChild is included, FreeChild's prioritisation should also not be included. 712 tx.vin[0].prevout.hash = txFirst[3]->GetHash(); 713 tx.vout[0].nValue = 5000000000LL; // 0 fee 714 Txid hashFreeParent = tx.GetHash(); 715 TryAddToMempool(tx_mempool, entry.Fee(0).SpendsCoinbase(true).FromTx(tx)); 716 tx_mempool.PrioritiseTransaction(hashFreeParent, 10 * COIN); 717 718 tx.vin[0].prevout.hash = hashFreeParent; 719 tx.vout[0].nValue = 5000000000LL; // 0 fee 720 Txid hashFreeChild = tx.GetHash(); 721 TryAddToMempool(tx_mempool, entry.Fee(0).SpendsCoinbase(false).FromTx(tx)); 722 tx_mempool.PrioritiseTransaction(hashFreeChild, 1 * COIN); 723 724 tx.vin[0].prevout.hash = hashFreeChild; 725 tx.vout[0].nValue = 5000000000LL; // 0 fee 726 Txid hashFreeGrandchild = tx.GetHash(); 727 TryAddToMempool(tx_mempool, entry.Fee(0).SpendsCoinbase(false).FromTx(tx)); 728 729 auto block_template = mining->createNewBlock(options, /*cooldown=*/false); 730 BOOST_REQUIRE(block_template); 731 CBlock block{block_template->getBlock()}; 732 BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U); 733 BOOST_CHECK(block.vtx[1]->GetHash() == hashFreeParent); 734 BOOST_CHECK(block.vtx[2]->GetHash() == hashFreePrioritisedTx); 735 BOOST_CHECK(block.vtx[3]->GetHash() == hashParentTx); 736 BOOST_CHECK(block.vtx[4]->GetHash() == hashPrioritsedChild); 737 BOOST_CHECK(block.vtx[5]->GetHash() == hashFreeChild); 738 for (size_t i=0; i<block.vtx.size(); ++i) { 739 // The FreeParent and FreeChild's prioritisations should not impact the child. 740 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeGrandchild); 741 // De-prioritised transaction should not be included. 742 BOOST_CHECK(block.vtx[i]->GetHash() != hashMediumFeeTx); 743 } 744 } 745 746 // NOTE: These tests rely on CreateNewBlock doing its own self-validation! 747 BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) 748 { 749 auto mining{MakeMining()}; 750 BOOST_REQUIRE(mining); 751 752 // Note that by default, these tests run with size accounting enabled. 753 CScript scriptPubKey = CScript() << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex << OP_CHECKSIG; 754 BlockAssembler::Options options; 755 options.coinbase_output_script = scriptPubKey; 756 options.include_dummy_extranonce = true; 757 758 // Create and check a simple template 759 std::unique_ptr<BlockTemplate> block_template = mining->createNewBlock(options, /*cooldown=*/false); 760 BOOST_REQUIRE(block_template); 761 { 762 CBlock block{block_template->getBlock()}; 763 { 764 std::string reason; 765 std::string debug; 766 BOOST_REQUIRE(!mining->checkBlock(block, {.check_pow = false}, reason, debug)); 767 BOOST_REQUIRE_EQUAL(reason, "bad-txnmrklroot"); 768 BOOST_REQUIRE_EQUAL(debug, "hashMerkleRoot mismatch"); 769 } 770 771 block.hashMerkleRoot = BlockMerkleRoot(block); 772 773 { 774 std::string reason; 775 std::string debug; 776 BOOST_REQUIRE(mining->checkBlock(block, {.check_pow = false}, reason, debug)); 777 BOOST_REQUIRE_EQUAL(reason, ""); 778 BOOST_REQUIRE_EQUAL(debug, ""); 779 } 780 781 { 782 // A block template does not have proof-of-work, but it might pass 783 // verification by coincidence. Grind the nonce if needed: 784 while (CheckProofOfWork(block.GetHash(), block.nBits, Assert(m_node.chainman)->GetParams().GetConsensus())) { 785 block.nNonce++; 786 } 787 788 std::string reason; 789 std::string debug; 790 BOOST_REQUIRE(!mining->checkBlock(block, {.check_pow = true}, reason, debug)); 791 BOOST_REQUIRE_EQUAL(reason, "high-hash"); 792 BOOST_REQUIRE_EQUAL(debug, "proof of work failed"); 793 } 794 } 795 796 // We can't make transactions until we have inputs 797 // Therefore, load 110 blocks :) 798 static_assert(std::size(BLOCKINFO) == 110, "Should have 110 blocks to import"); 799 int baseheight = 0; 800 std::vector<CTransactionRef> txFirst; 801 for (const auto& bi : BLOCKINFO) { 802 const int current_height{mining->getTip()->height}; 803 804 /** 805 * Simple block creation, nothing special yet. 806 * If current_height is odd, block_template will have already been 807 * set at the end of the previous loop. 808 */ 809 if (current_height % 2 == 0) { 810 block_template = mining->createNewBlock(options, /*cooldown=*/false); 811 BOOST_REQUIRE(block_template); 812 } 813 814 CBlock block{block_template->getBlock()}; 815 CMutableTransaction txCoinbase(*block.vtx[0]); 816 { 817 LOCK(cs_main); 818 block.nVersion = VERSIONBITS_TOP_BITS; 819 block.nTime = Assert(m_node.chainman)->ActiveChain().Tip()->GetMedianTimePast()+1; 820 txCoinbase.version = 1; 821 txCoinbase.vin[0].scriptSig = CScript{} << (current_height + 1) << bi.extranonce; 822 txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this) 823 txCoinbase.vout[0].scriptPubKey = CScript(); 824 block.vtx[0] = MakeTransactionRef(txCoinbase); 825 if (txFirst.size() == 0) 826 baseheight = current_height; 827 if (txFirst.size() < 4) 828 txFirst.push_back(block.vtx[0]); 829 block.hashMerkleRoot = BlockMerkleRoot(block); 830 block.nNonce = bi.nonce; 831 } 832 std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block); 833 // Alternate calls between Chainman's ProcessNewBlock and submitSolution 834 // via the Mining interface. The former is used by net_processing as well 835 // as the submitblock RPC. 836 if (current_height % 2 == 0) { 837 BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(shared_pblock, /*force_processing=*/true, /*min_pow_checked=*/true, nullptr)); 838 } else { 839 BOOST_REQUIRE(block_template->submitSolution(block.nVersion, block.nTime, block.nNonce, MakeTransactionRef(txCoinbase))); 840 } 841 { 842 LOCK(cs_main); 843 // The above calls don't guarantee the tip is actually updated, so 844 // we explicitly check this. 845 auto maybe_new_tip{Assert(m_node.chainman)->ActiveChain().Tip()}; 846 BOOST_REQUIRE_EQUAL(maybe_new_tip->GetBlockHash(), block.GetHash()); 847 } 848 if (current_height % 2 == 0) { 849 block_template = block_template->waitNext(); 850 BOOST_REQUIRE(block_template); 851 } else { 852 // This just adds coverage 853 mining->waitTipChanged(block.hashPrevBlock); 854 } 855 } 856 857 LOCK(cs_main); 858 859 TestBasicMining(scriptPubKey, txFirst, baseheight); 860 861 m_node.chainman->ActiveChain().Tip()->nHeight--; 862 SetMockTime(0); 863 864 TestPackageSelection(scriptPubKey, txFirst); 865 866 m_node.chainman->ActiveChain().Tip()->nHeight--; 867 SetMockTime(0); 868 869 TestPrioritisedMining(scriptPubKey, txFirst); 870 } 871 872 BOOST_AUTO_TEST_SUITE_END()