/ src / test / miner_tests.cpp
miner_tests.cpp
  1  // Copyright (c) 2011-2022 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/txmempool.h>
 16  #include <txmempool.h>
 17  #include <uint256.h>
 18  #include <util/check.h>
 19  #include <util/feefrac.h>
 20  #include <util/strencodings.h>
 21  #include <util/time.h>
 22  #include <util/translation.h>
 23  #include <validation.h>
 24  #include <versionbits.h>
 25  
 26  #include <test/util/setup_common.h>
 27  
 28  #include <memory>
 29  #include <vector>
 30  
 31  #include <boost/test/unit_test.hpp>
 32  
 33  using namespace util::hex_literals;
 34  using interfaces::BlockTemplate;
 35  using interfaces::Mining;
 36  using node::BlockAssembler;
 37  
 38  namespace miner_tests {
 39  struct MinerTestingSetup : public TestingSetup {
 40      void TestPackageSelection(const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
 41      void TestBasicMining(const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst, int baseheight) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
 42      void TestPrioritisedMining(const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
 43      bool TestSequenceLocks(const CTransaction& tx, CTxMemPool& tx_mempool) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
 44      {
 45          CCoinsViewMemPool view_mempool{&m_node.chainman->ActiveChainstate().CoinsTip(), tx_mempool};
 46          CBlockIndex* tip{m_node.chainman->ActiveChain().Tip()};
 47          const std::optional<LockPoints> lock_points{CalculateLockPointsAtTip(tip, view_mempool, tx)};
 48          return lock_points.has_value() && CheckSequenceLocksAtTip(tip, *lock_points);
 49      }
 50      CTxMemPool& MakeMempool()
 51      {
 52          // Delete the previous mempool to ensure with valgrind that the old
 53          // pointer is not accessed, when the new one should be accessed
 54          // instead.
 55          m_node.mempool.reset();
 56          bilingual_str error;
 57          m_node.mempool = std::make_unique<CTxMemPool>(MemPoolOptionsForTest(m_node), error);
 58          Assert(error.empty());
 59          return *m_node.mempool;
 60      }
 61      std::unique_ptr<Mining> MakeMining()
 62      {
 63          return interfaces::MakeMining(m_node);
 64      }
 65  };
 66  } // namespace miner_tests
 67  
 68  BOOST_FIXTURE_TEST_SUITE(miner_tests, MinerTestingSetup)
 69  
 70  static CFeeRate blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE);
 71  
 72  constexpr static struct {
 73      unsigned char extranonce;
 74      unsigned int nonce;
 75  } BLOCKINFO[]{{8, 582909131},  {0, 971462344},  {2, 1169481553}, {6, 66147495},  {7, 427785981},  {8, 80538907},
 76                {8, 207348013},  {2, 1951240923}, {4, 215054351},  {1, 491520534}, {8, 1282281282}, {4, 639565734},
 77                {3, 248274685},  {8, 1160085976}, {6, 396349768},  {5, 393780549}, {5, 1096899528}, {4, 965381630},
 78                {0, 728758712},  {5, 318638310},  {3, 164591898},  {2, 274234550}, {2, 254411237},  {7, 561761812},
 79                {2, 268342573},  {0, 402816691},  {1, 221006382},  {6, 538872455}, {7, 393315655},  {4, 814555937},
 80                {7, 504879194},  {6, 467769648},  {3, 925972193},  {2, 200581872}, {3, 168915404},  {8, 430446262},
 81                {5, 773507406},  {3, 1195366164}, {0, 433361157},  {3, 297051771}, {0, 558856551},  {2, 501614039},
 82                {3, 528488272},  {2, 473587734},  {8, 230125274},  {2, 494084400}, {4, 357314010},  {8, 60361686},
 83                {7, 640624687},  {3, 480441695},  {8, 1424447925}, {4, 752745419}, {1, 288532283},  {6, 669170574},
 84                {5, 1900907591}, {3, 555326037},  {3, 1121014051}, {0, 545835650}, {8, 189196651},  {5, 252371575},
 85                {0, 199163095},  {6, 558895874},  {6, 1656839784}, {6, 815175452}, {6, 718677851},  {5, 544000334},
 86                {0, 340113484},  {6, 850744437},  {4, 496721063},  {8, 524715182}, {6, 574361898},  {6, 1642305743},
 87                {6, 355110149},  {5, 1647379658}, {8, 1103005356}, {7, 556460625}, {3, 1139533992}, {5, 304736030},
 88                {2, 361539446},  {2, 143720360},  {6, 201939025},  {7, 423141476}, {4, 574633709},  {3, 1412254823},
 89                {4, 873254135},  {0, 341817335},  {6, 53501687},   {3, 179755410}, {5, 172209688},  {8, 516810279},
 90                {4, 1228391489}, {8, 325372589},  {6, 550367589},  {0, 876291812}, {7, 412454120},  {7, 717202854},
 91                {2, 222677843},  {6, 251778867},  {7, 842004420},  {7, 194762829}, {4, 96668841},   {1, 925485796},
 92                {0, 792342903},  {6, 678455063},  {6, 773251385},  {5, 186617471}, {6, 883189502},  {7, 396077336},
 93                {8, 254702874},  {0, 455592851}};
 94  
 95  static std::unique_ptr<CBlockIndex> CreateBlockIndex(int nHeight, CBlockIndex* active_chain_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
 96  {
 97      auto index{std::make_unique<CBlockIndex>()};
 98      index->nHeight = nHeight;
 99      index->pprev = active_chain_tip;
100      return index;
101  }
102  
103  // Test suite for ancestor feerate transaction selection.
104  // Implemented as an additional function, rather than a separate test case,
105  // to allow reusing the blockchain created in CreateNewBlock_validity.
106  void MinerTestingSetup::TestPackageSelection(const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst)
107  {
108      CTxMemPool& tx_mempool{MakeMempool()};
109      auto mining{MakeMining()};
110      BlockAssembler::Options options;
111      options.coinbase_output_script = scriptPubKey;
112  
113      LOCK(tx_mempool.cs);
114      // Test the ancestor feerate transaction selection.
115      TestMemPoolEntryHelper entry;
116  
117      // Test that a medium fee transaction will be selected after a higher fee
118      // rate package with a low fee rate parent.
119      CMutableTransaction tx;
120      tx.vin.resize(1);
121      tx.vin[0].scriptSig = CScript() << OP_1;
122      tx.vin[0].prevout.hash = txFirst[0]->GetHash();
123      tx.vin[0].prevout.n = 0;
124      tx.vout.resize(1);
125      tx.vout[0].nValue = 5000000000LL - 1000;
126      // This tx has a low fee: 1000 satoshis
127      Txid hashParentTx = tx.GetHash(); // save this txid for later use
128      const auto parent_tx{entry.Fee(1000).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)};
129      AddToMempool(tx_mempool, parent_tx);
130  
131      // This tx has a medium fee: 10000 satoshis
132      tx.vin[0].prevout.hash = txFirst[1]->GetHash();
133      tx.vout[0].nValue = 5000000000LL - 10000;
134      Txid hashMediumFeeTx = tx.GetHash();
135      const auto medium_fee_tx{entry.Fee(10000).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx)};
136      AddToMempool(tx_mempool, medium_fee_tx);
137  
138      // This tx has a high fee, but depends on the first transaction
139      tx.vin[0].prevout.hash = hashParentTx;
140      tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 50k satoshi fee
141      Txid hashHighFeeTx = tx.GetHash();
142      const auto high_fee_tx{entry.Fee(50000).Time(Now<NodeSeconds>()).SpendsCoinbase(false).FromTx(tx)};
143      AddToMempool(tx_mempool, high_fee_tx);
144  
145      std::unique_ptr<BlockTemplate> block_template = mining->createNewBlock(options);
146      BOOST_REQUIRE(block_template);
147      CBlock block{block_template->getBlock()};
148      BOOST_REQUIRE_EQUAL(block.vtx.size(), 4U);
149      BOOST_CHECK(block.vtx[1]->GetHash() == hashParentTx);
150      BOOST_CHECK(block.vtx[2]->GetHash() == hashHighFeeTx);
151      BOOST_CHECK(block.vtx[3]->GetHash() == hashMediumFeeTx);
152  
153      // Test the inclusion of package feerates in the block template and ensure they are sequential.
154      const auto block_package_feerates = BlockAssembler{m_node.chainman->ActiveChainstate(), &tx_mempool, options}.CreateNewBlock()->m_package_feerates;
155      BOOST_CHECK(block_package_feerates.size() == 2);
156  
157      // parent_tx and high_fee_tx are added to the block as a package.
158      const auto combined_txs_fee = parent_tx.GetFee() + high_fee_tx.GetFee();
159      const auto combined_txs_size = parent_tx.GetTxSize() + high_fee_tx.GetTxSize();
160      FeeFrac package_feefrac{combined_txs_fee, combined_txs_size};
161      // The package should be added first.
162      BOOST_CHECK(block_package_feerates[0] == package_feefrac);
163  
164      // The medium_fee_tx should be added next.
165      FeeFrac medium_tx_feefrac{medium_fee_tx.GetFee(), medium_fee_tx.GetTxSize()};
166      BOOST_CHECK(block_package_feerates[1] == medium_tx_feefrac);
167  
168      // Test that a package below the block min tx fee doesn't get included
169      tx.vin[0].prevout.hash = hashHighFeeTx;
170      tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 0 fee
171      Txid hashFreeTx = tx.GetHash();
172      AddToMempool(tx_mempool, entry.Fee(0).FromTx(tx));
173      size_t freeTxSize = ::GetSerializeSize(TX_WITH_WITNESS(tx));
174  
175      // Calculate a fee on child transaction that will put the package just
176      // below the block min tx fee (assuming 1 child tx of the same size).
177      CAmount feeToUse = blockMinFeeRate.GetFee(2*freeTxSize) - 1;
178  
179      tx.vin[0].prevout.hash = hashFreeTx;
180      tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse;
181      Txid hashLowFeeTx = tx.GetHash();
182      AddToMempool(tx_mempool, entry.Fee(feeToUse).FromTx(tx));
183  
184      // waitNext() should return nullptr because there is no better template
185      auto should_be_nullptr = block_template->waitNext({.timeout = MillisecondsDouble{0}, .fee_threshold = 1});
186      BOOST_REQUIRE(should_be_nullptr == nullptr);
187  
188      block = block_template->getBlock();
189      // Verify that the free tx and the low fee tx didn't get selected
190      for (size_t i=0; i<block.vtx.size(); ++i) {
191          BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx);
192          BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx);
193      }
194  
195      // Test that packages above the min relay fee do get included, even if one
196      // of the transactions is below the min relay fee
197      // Remove the low fee transaction and replace with a higher fee transaction
198      tx_mempool.removeRecursive(CTransaction(tx), MemPoolRemovalReason::REPLACED);
199      tx.vout[0].nValue -= 2; // Now we should be just over the min relay fee
200      hashLowFeeTx = tx.GetHash();
201      AddToMempool(tx_mempool, entry.Fee(feeToUse + 2).FromTx(tx));
202  
203      // waitNext() should return if fees for the new template are at least 1 sat up
204      block_template = block_template->waitNext({.fee_threshold = 1});
205      BOOST_REQUIRE(block_template);
206      block = block_template->getBlock();
207      BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U);
208      BOOST_CHECK(block.vtx[4]->GetHash() == hashFreeTx);
209      BOOST_CHECK(block.vtx[5]->GetHash() == hashLowFeeTx);
210  
211      // Test that transaction selection properly updates ancestor fee
212      // calculations as ancestor transactions get included in a block.
213      // Add a 0-fee transaction that has 2 outputs.
214      tx.vin[0].prevout.hash = txFirst[2]->GetHash();
215      tx.vout.resize(2);
216      tx.vout[0].nValue = 5000000000LL - 100000000;
217      tx.vout[1].nValue = 100000000; // 1BTC output
218      Txid hashFreeTx2 = tx.GetHash();
219      AddToMempool(tx_mempool, entry.Fee(0).SpendsCoinbase(true).FromTx(tx));
220  
221      // This tx can't be mined by itself
222      tx.vin[0].prevout.hash = hashFreeTx2;
223      tx.vout.resize(1);
224      feeToUse = blockMinFeeRate.GetFee(freeTxSize);
225      tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
226      Txid hashLowFeeTx2 = tx.GetHash();
227      AddToMempool(tx_mempool, entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx));
228      block_template = mining->createNewBlock(options);
229      BOOST_REQUIRE(block_template);
230      block = block_template->getBlock();
231  
232      // Verify that this tx isn't selected.
233      for (size_t i=0; i<block.vtx.size(); ++i) {
234          BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx2);
235          BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx2);
236      }
237  
238      // This tx will be mineable, and should cause hashLowFeeTx2 to be selected
239      // as well.
240      tx.vin[0].prevout.n = 1;
241      tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee
242      AddToMempool(tx_mempool, entry.Fee(10000).FromTx(tx));
243      block_template = mining->createNewBlock(options);
244      BOOST_REQUIRE(block_template);
245      block = block_template->getBlock();
246      BOOST_REQUIRE_EQUAL(block.vtx.size(), 9U);
247      BOOST_CHECK(block.vtx[8]->GetHash() == hashLowFeeTx2);
248  }
249  
250  void MinerTestingSetup::TestBasicMining(const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst, int baseheight)
251  {
252      Txid hash;
253      CMutableTransaction tx;
254      TestMemPoolEntryHelper entry;
255      entry.nFee = 11;
256      entry.nHeight = 11;
257  
258      const CAmount BLOCKSUBSIDY = 50 * COIN;
259      const CAmount LOWFEE = CENT;
260      const CAmount HIGHFEE = COIN;
261      const CAmount HIGHERFEE = 4 * COIN;
262  
263      auto mining{MakeMining()};
264      BOOST_REQUIRE(mining);
265  
266      BlockAssembler::Options options;
267      options.coinbase_output_script = scriptPubKey;
268  
269      {
270          CTxMemPool& tx_mempool{MakeMempool()};
271          LOCK(tx_mempool.cs);
272  
273          // Just to make sure we can still make simple blocks
274          auto block_template{mining->createNewBlock(options)};
275          BOOST_REQUIRE(block_template);
276          CBlock block{block_template->getBlock()};
277  
278          // block sigops > limit: 1000 CHECKMULTISIG + 1
279          tx.vin.resize(1);
280          // NOTE: OP_NOP is used to force 20 SigOps for the CHECKMULTISIG
281          tx.vin[0].scriptSig = CScript() << OP_0 << OP_0 << OP_0 << OP_NOP << OP_CHECKMULTISIG << OP_1;
282          tx.vin[0].prevout.hash = txFirst[0]->GetHash();
283          tx.vin[0].prevout.n = 0;
284          tx.vout.resize(1);
285          tx.vout[0].nValue = BLOCKSUBSIDY;
286          for (unsigned int i = 0; i < 1001; ++i) {
287              tx.vout[0].nValue -= LOWFEE;
288              hash = tx.GetHash();
289              bool spendsCoinbase = i == 0; // only first tx spends coinbase
290              // If we don't set the # of sig ops in the CTxMemPoolEntry, template creation fails
291              AddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(spendsCoinbase).FromTx(tx));
292              tx.vin[0].prevout.hash = hash;
293          }
294  
295          BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error, HasReason("bad-blk-sigops"));
296      }
297  
298      {
299          CTxMemPool& tx_mempool{MakeMempool()};
300          LOCK(tx_mempool.cs);
301  
302          tx.vin[0].prevout.hash = txFirst[0]->GetHash();
303          tx.vout[0].nValue = BLOCKSUBSIDY;
304          for (unsigned int i = 0; i < 1001; ++i) {
305              tx.vout[0].nValue -= LOWFEE;
306              hash = tx.GetHash();
307              bool spendsCoinbase = i == 0; // only first tx spends coinbase
308              // If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes
309              AddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(spendsCoinbase).SigOpsCost(80).FromTx(tx));
310              tx.vin[0].prevout.hash = hash;
311          }
312          BOOST_REQUIRE(mining->createNewBlock(options));
313      }
314  
315      {
316          CTxMemPool& tx_mempool{MakeMempool()};
317          LOCK(tx_mempool.cs);
318  
319          // block size > limit
320          tx.vin[0].scriptSig = CScript();
321          // 18 * (520char + DROP) + OP_1 = 9433 bytes
322          std::vector<unsigned char> vchData(520);
323          for (unsigned int i = 0; i < 18; ++i) {
324              tx.vin[0].scriptSig << vchData << OP_DROP;
325          }
326          tx.vin[0].scriptSig << OP_1;
327          tx.vin[0].prevout.hash = txFirst[0]->GetHash();
328          tx.vout[0].nValue = BLOCKSUBSIDY;
329          for (unsigned int i = 0; i < 128; ++i) {
330              tx.vout[0].nValue -= LOWFEE;
331              hash = tx.GetHash();
332              bool spendsCoinbase = i == 0; // only first tx spends coinbase
333              AddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(spendsCoinbase).FromTx(tx));
334              tx.vin[0].prevout.hash = hash;
335          }
336          BOOST_REQUIRE(mining->createNewBlock(options));
337      }
338  
339      {
340          CTxMemPool& tx_mempool{MakeMempool()};
341          LOCK(tx_mempool.cs);
342  
343          // orphan in tx_mempool, template creation fails
344          hash = tx.GetHash();
345          AddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).FromTx(tx));
346          BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
347      }
348  
349      {
350          CTxMemPool& tx_mempool{MakeMempool()};
351          LOCK(tx_mempool.cs);
352  
353          // child with higher feerate than parent
354          tx.vin[0].scriptSig = CScript() << OP_1;
355          tx.vin[0].prevout.hash = txFirst[1]->GetHash();
356          tx.vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
357          hash = tx.GetHash();
358          AddToMempool(tx_mempool, entry.Fee(HIGHFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx));
359          tx.vin[0].prevout.hash = hash;
360          tx.vin.resize(2);
361          tx.vin[1].scriptSig = CScript() << OP_1;
362          tx.vin[1].prevout.hash = txFirst[0]->GetHash();
363          tx.vin[1].prevout.n = 0;
364          tx.vout[0].nValue = tx.vout[0].nValue + BLOCKSUBSIDY - HIGHERFEE; // First txn output + fresh coinbase - new txn fee
365          hash = tx.GetHash();
366          AddToMempool(tx_mempool, entry.Fee(HIGHERFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx));
367          BOOST_REQUIRE(mining->createNewBlock(options));
368      }
369  
370      {
371          CTxMemPool& tx_mempool{MakeMempool()};
372          LOCK(tx_mempool.cs);
373  
374          // coinbase in tx_mempool, template creation fails
375          tx.vin.resize(1);
376          tx.vin[0].prevout.SetNull();
377          tx.vin[0].scriptSig = CScript() << OP_0 << OP_1;
378          tx.vout[0].nValue = 0;
379          hash = tx.GetHash();
380          // give it a fee so it'll get mined
381          AddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(false).FromTx(tx));
382          // Should throw bad-cb-multiple
383          BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error, HasReason("bad-cb-multiple"));
384      }
385  
386      {
387          CTxMemPool& tx_mempool{MakeMempool()};
388          LOCK(tx_mempool.cs);
389  
390          // double spend txn pair in tx_mempool, template creation fails
391          tx.vin[0].prevout.hash = txFirst[0]->GetHash();
392          tx.vin[0].scriptSig = CScript() << OP_1;
393          tx.vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
394          tx.vout[0].scriptPubKey = CScript() << OP_1;
395          hash = tx.GetHash();
396          AddToMempool(tx_mempool, entry.Fee(HIGHFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx));
397          tx.vout[0].scriptPubKey = CScript() << OP_2;
398          hash = tx.GetHash();
399          AddToMempool(tx_mempool, entry.Fee(HIGHFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx));
400          BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
401      }
402  
403      {
404          CTxMemPool& tx_mempool{MakeMempool()};
405          LOCK(tx_mempool.cs);
406  
407          // subsidy changing
408          int nHeight = m_node.chainman->ActiveChain().Height();
409          // Create an actual 209999-long block chain (without valid blocks).
410          while (m_node.chainman->ActiveChain().Tip()->nHeight < 209999) {
411              CBlockIndex* prev = m_node.chainman->ActiveChain().Tip();
412              CBlockIndex* next = new CBlockIndex();
413              next->phashBlock = new uint256(m_rng.rand256());
414              m_node.chainman->ActiveChainstate().CoinsTip().SetBestBlock(next->GetBlockHash());
415              next->pprev = prev;
416              next->nHeight = prev->nHeight + 1;
417              next->BuildSkip();
418              m_node.chainman->ActiveChain().SetTip(*next);
419          }
420          BOOST_REQUIRE(mining->createNewBlock(options));
421          // Extend to a 210000-long block chain.
422          while (m_node.chainman->ActiveChain().Tip()->nHeight < 210000) {
423              CBlockIndex* prev = m_node.chainman->ActiveChain().Tip();
424              CBlockIndex* next = new CBlockIndex();
425              next->phashBlock = new uint256(m_rng.rand256());
426              m_node.chainman->ActiveChainstate().CoinsTip().SetBestBlock(next->GetBlockHash());
427              next->pprev = prev;
428              next->nHeight = prev->nHeight + 1;
429              next->BuildSkip();
430              m_node.chainman->ActiveChain().SetTip(*next);
431          }
432          BOOST_REQUIRE(mining->createNewBlock(options));
433  
434          // invalid p2sh txn in tx_mempool, template creation fails
435          tx.vin[0].prevout.hash = txFirst[0]->GetHash();
436          tx.vin[0].prevout.n = 0;
437          tx.vin[0].scriptSig = CScript() << OP_1;
438          tx.vout[0].nValue = BLOCKSUBSIDY - LOWFEE;
439          CScript script = CScript() << OP_0;
440          tx.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(script));
441          hash = tx.GetHash();
442          AddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx));
443          tx.vin[0].prevout.hash = hash;
444          tx.vin[0].scriptSig = CScript() << std::vector<unsigned char>(script.begin(), script.end());
445          tx.vout[0].nValue -= LOWFEE;
446          hash = tx.GetHash();
447          AddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(false).FromTx(tx));
448          BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error, HasReason("mandatory-script-verify-flag-failed"));
449  
450          // Delete the dummy blocks again.
451          while (m_node.chainman->ActiveChain().Tip()->nHeight > nHeight) {
452              CBlockIndex* del = m_node.chainman->ActiveChain().Tip();
453              m_node.chainman->ActiveChain().SetTip(*Assert(del->pprev));
454              m_node.chainman->ActiveChainstate().CoinsTip().SetBestBlock(del->pprev->GetBlockHash());
455              delete del->phashBlock;
456              delete del;
457          }
458      }
459  
460      CTxMemPool& tx_mempool{MakeMempool()};
461      LOCK(tx_mempool.cs);
462  
463      // non-final txs in mempool
464      SetMockTime(m_node.chainman->ActiveChain().Tip()->GetMedianTimePast() + 1);
465      const int flags{LOCKTIME_VERIFY_SEQUENCE};
466      // height map
467      std::vector<int> prevheights;
468  
469      // relative height locked
470      tx.version = 2;
471      tx.vin.resize(1);
472      prevheights.resize(1);
473      tx.vin[0].prevout.hash = txFirst[0]->GetHash(); // only 1 transaction
474      tx.vin[0].prevout.n = 0;
475      tx.vin[0].scriptSig = CScript() << OP_1;
476      tx.vin[0].nSequence = m_node.chainman->ActiveChain().Tip()->nHeight + 1; // txFirst[0] is the 2nd block
477      prevheights[0] = baseheight + 1;
478      tx.vout.resize(1);
479      tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
480      tx.vout[0].scriptPubKey = CScript() << OP_1;
481      tx.nLockTime = 0;
482      hash = tx.GetHash();
483      AddToMempool(tx_mempool, entry.Fee(HIGHFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx));
484      BOOST_CHECK(CheckFinalTxAtTip(*Assert(m_node.chainman->ActiveChain().Tip()), CTransaction{tx})); // Locktime passes
485      BOOST_CHECK(!TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks fail
486  
487      {
488          CBlockIndex* active_chain_tip = m_node.chainman->ActiveChain().Tip();
489          BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, *CreateBlockIndex(active_chain_tip->nHeight + 2, active_chain_tip))); // Sequence locks pass on 2nd block
490      }
491  
492      // relative time locked
493      tx.vin[0].prevout.hash = txFirst[1]->GetHash();
494      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
495      prevheights[0] = baseheight + 2;
496      hash = tx.GetHash();
497      AddToMempool(tx_mempool, entry.Time(Now<NodeSeconds>()).FromTx(tx));
498      BOOST_CHECK(CheckFinalTxAtTip(*Assert(m_node.chainman->ActiveChain().Tip()), CTransaction{tx})); // Locktime passes
499      BOOST_CHECK(!TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks fail
500  
501      const int SEQUENCE_LOCK_TIME = 512; // Sequence locks pass 512 seconds later
502      for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i)
503          m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime += SEQUENCE_LOCK_TIME; // Trick the MedianTimePast
504      {
505          CBlockIndex* active_chain_tip = m_node.chainman->ActiveChain().Tip();
506          BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, *CreateBlockIndex(active_chain_tip->nHeight + 1, active_chain_tip)));
507      }
508  
509      for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i) {
510          CBlockIndex* ancestor{Assert(m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i))};
511          ancestor->nTime -= SEQUENCE_LOCK_TIME; // undo tricked MTP
512      }
513  
514      // absolute height locked
515      tx.vin[0].prevout.hash = txFirst[2]->GetHash();
516      tx.vin[0].nSequence = CTxIn::MAX_SEQUENCE_NONFINAL;
517      prevheights[0] = baseheight + 3;
518      tx.nLockTime = m_node.chainman->ActiveChain().Tip()->nHeight + 1;
519      hash = tx.GetHash();
520      AddToMempool(tx_mempool, entry.Time(Now<NodeSeconds>()).FromTx(tx));
521      BOOST_CHECK(!CheckFinalTxAtTip(*Assert(m_node.chainman->ActiveChain().Tip()), CTransaction{tx})); // Locktime fails
522      BOOST_CHECK(TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks pass
523      BOOST_CHECK(IsFinalTx(CTransaction(tx), m_node.chainman->ActiveChain().Tip()->nHeight + 2, m_node.chainman->ActiveChain().Tip()->GetMedianTimePast())); // Locktime passes on 2nd block
524  
525      // absolute time locked
526      tx.vin[0].prevout.hash = txFirst[3]->GetHash();
527      tx.nLockTime = m_node.chainman->ActiveChain().Tip()->GetMedianTimePast();
528      prevheights.resize(1);
529      prevheights[0] = baseheight + 4;
530      hash = tx.GetHash();
531      AddToMempool(tx_mempool, entry.Time(Now<NodeSeconds>()).FromTx(tx));
532      BOOST_CHECK(!CheckFinalTxAtTip(*Assert(m_node.chainman->ActiveChain().Tip()), CTransaction{tx})); // Locktime fails
533      BOOST_CHECK(TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks pass
534      BOOST_CHECK(IsFinalTx(CTransaction(tx), m_node.chainman->ActiveChain().Tip()->nHeight + 2, m_node.chainman->ActiveChain().Tip()->GetMedianTimePast() + 1)); // Locktime passes 1 second later
535  
536      // mempool-dependent transactions (not added)
537      tx.vin[0].prevout.hash = hash;
538      prevheights[0] = m_node.chainman->ActiveChain().Tip()->nHeight + 1;
539      tx.nLockTime = 0;
540      tx.vin[0].nSequence = 0;
541      BOOST_CHECK(CheckFinalTxAtTip(*Assert(m_node.chainman->ActiveChain().Tip()), CTransaction{tx})); // Locktime passes
542      BOOST_CHECK(TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks pass
543      tx.vin[0].nSequence = 1;
544      BOOST_CHECK(!TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks fail
545      tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
546      BOOST_CHECK(TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks pass
547      tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | 1;
548      BOOST_CHECK(!TestSequenceLocks(CTransaction{tx}, tx_mempool)); // Sequence locks fail
549  
550      auto block_template = mining->createNewBlock(options);
551      BOOST_REQUIRE(block_template);
552  
553      // None of the of the absolute height/time locked tx should have made
554      // it into the template because we still check IsFinalTx in CreateNewBlock,
555      // but relative locked txs will if inconsistently added to mempool.
556      // For now these will still generate a valid template until BIP68 soft fork
557      CBlock block{block_template->getBlock()};
558      BOOST_CHECK_EQUAL(block.vtx.size(), 3U);
559      // However if we advance height by 1 and time by SEQUENCE_LOCK_TIME, all of them should be mined
560      for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i) {
561          CBlockIndex* ancestor{Assert(m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i))};
562          ancestor->nTime += SEQUENCE_LOCK_TIME; // Trick the MedianTimePast
563      }
564      m_node.chainman->ActiveChain().Tip()->nHeight++;
565      SetMockTime(m_node.chainman->ActiveChain().Tip()->GetMedianTimePast() + 1);
566  
567      block_template = mining->createNewBlock(options);
568      BOOST_REQUIRE(block_template);
569      block = block_template->getBlock();
570      BOOST_CHECK_EQUAL(block.vtx.size(), 5U);
571  }
572  
573  void MinerTestingSetup::TestPrioritisedMining(const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst)
574  {
575      auto mining{MakeMining()};
576      BOOST_REQUIRE(mining);
577  
578      BlockAssembler::Options options;
579      options.coinbase_output_script = scriptPubKey;
580  
581      CTxMemPool& tx_mempool{MakeMempool()};
582      LOCK(tx_mempool.cs);
583  
584      TestMemPoolEntryHelper entry;
585  
586      // Test that a tx below min fee but prioritised is included
587      CMutableTransaction tx;
588      tx.vin.resize(1);
589      tx.vin[0].prevout.hash = txFirst[0]->GetHash();
590      tx.vin[0].prevout.n = 0;
591      tx.vin[0].scriptSig = CScript() << OP_1;
592      tx.vout.resize(1);
593      tx.vout[0].nValue = 5000000000LL; // 0 fee
594      uint256 hashFreePrioritisedTx = tx.GetHash();
595      AddToMempool(tx_mempool, entry.Fee(0).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx));
596      tx_mempool.PrioritiseTransaction(hashFreePrioritisedTx, 5 * COIN);
597  
598      tx.vin[0].prevout.hash = txFirst[1]->GetHash();
599      tx.vin[0].prevout.n = 0;
600      tx.vout[0].nValue = 5000000000LL - 1000;
601      // This tx has a low fee: 1000 satoshis
602      Txid hashParentTx = tx.GetHash(); // save this txid for later use
603      AddToMempool(tx_mempool, entry.Fee(1000).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx));
604  
605      // This tx has a medium fee: 10000 satoshis
606      tx.vin[0].prevout.hash = txFirst[2]->GetHash();
607      tx.vout[0].nValue = 5000000000LL - 10000;
608      Txid hashMediumFeeTx = tx.GetHash();
609      AddToMempool(tx_mempool, entry.Fee(10000).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx));
610      tx_mempool.PrioritiseTransaction(hashMediumFeeTx, -5 * COIN);
611  
612      // This tx also has a low fee, but is prioritised
613      tx.vin[0].prevout.hash = hashParentTx;
614      tx.vout[0].nValue = 5000000000LL - 1000 - 1000; // 1000 satoshi fee
615      Txid hashPrioritsedChild = tx.GetHash();
616      AddToMempool(tx_mempool, entry.Fee(1000).Time(Now<NodeSeconds>()).SpendsCoinbase(false).FromTx(tx));
617      tx_mempool.PrioritiseTransaction(hashPrioritsedChild, 2 * COIN);
618  
619      // Test that transaction selection properly updates ancestor fee calculations as prioritised
620      // parents get included in a block. Create a transaction with two prioritised ancestors, each
621      // included by itself: FreeParent <- FreeChild <- FreeGrandchild.
622      // When FreeParent is added, a modified entry will be created for FreeChild + FreeGrandchild
623      // FreeParent's prioritisation should not be included in that entry.
624      // When FreeChild is included, FreeChild's prioritisation should also not be included.
625      tx.vin[0].prevout.hash = txFirst[3]->GetHash();
626      tx.vout[0].nValue = 5000000000LL; // 0 fee
627      Txid hashFreeParent = tx.GetHash();
628      AddToMempool(tx_mempool, entry.Fee(0).SpendsCoinbase(true).FromTx(tx));
629      tx_mempool.PrioritiseTransaction(hashFreeParent, 10 * COIN);
630  
631      tx.vin[0].prevout.hash = hashFreeParent;
632      tx.vout[0].nValue = 5000000000LL; // 0 fee
633      Txid hashFreeChild = tx.GetHash();
634      AddToMempool(tx_mempool, entry.Fee(0).SpendsCoinbase(false).FromTx(tx));
635      tx_mempool.PrioritiseTransaction(hashFreeChild, 1 * COIN);
636  
637      tx.vin[0].prevout.hash = hashFreeChild;
638      tx.vout[0].nValue = 5000000000LL; // 0 fee
639      Txid hashFreeGrandchild = tx.GetHash();
640      AddToMempool(tx_mempool, entry.Fee(0).SpendsCoinbase(false).FromTx(tx));
641  
642      auto block_template = mining->createNewBlock(options);
643      BOOST_REQUIRE(block_template);
644      CBlock block{block_template->getBlock()};
645      BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U);
646      BOOST_CHECK(block.vtx[1]->GetHash() == hashFreeParent);
647      BOOST_CHECK(block.vtx[2]->GetHash() == hashFreePrioritisedTx);
648      BOOST_CHECK(block.vtx[3]->GetHash() == hashParentTx);
649      BOOST_CHECK(block.vtx[4]->GetHash() == hashPrioritsedChild);
650      BOOST_CHECK(block.vtx[5]->GetHash() == hashFreeChild);
651      for (size_t i=0; i<block.vtx.size(); ++i) {
652          // The FreeParent and FreeChild's prioritisations should not impact the child.
653          BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeGrandchild);
654          // De-prioritised transaction should not be included.
655          BOOST_CHECK(block.vtx[i]->GetHash() != hashMediumFeeTx);
656      }
657  }
658  
659  // NOTE: These tests rely on CreateNewBlock doing its own self-validation!
660  BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
661  {
662      auto mining{MakeMining()};
663      BOOST_REQUIRE(mining);
664  
665      // Note that by default, these tests run with size accounting enabled.
666      CScript scriptPubKey = CScript() << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex << OP_CHECKSIG;
667      BlockAssembler::Options options;
668      options.coinbase_output_script = scriptPubKey;
669      std::unique_ptr<BlockTemplate> block_template;
670  
671      // We can't make transactions until we have inputs
672      // Therefore, load 110 blocks :)
673      static_assert(std::size(BLOCKINFO) == 110, "Should have 110 blocks to import");
674      int baseheight = 0;
675      std::vector<CTransactionRef> txFirst;
676      for (const auto& bi : BLOCKINFO) {
677          const int current_height{mining->getTip()->height};
678  
679          /**
680           * Simple block creation, nothing special yet.
681           * If current_height is odd, block_template will have already been
682           * set at the end of the previous loop.
683           */
684          if (current_height % 2 == 0) {
685              block_template = mining->createNewBlock(options);
686              BOOST_REQUIRE(block_template);
687          }
688  
689          CBlock block{block_template->getBlock()};
690          CMutableTransaction txCoinbase(*block.vtx[0]);
691          {
692              LOCK(cs_main);
693              block.nVersion = VERSIONBITS_TOP_BITS;
694              block.nTime = Assert(m_node.chainman)->ActiveChain().Tip()->GetMedianTimePast()+1;
695              txCoinbase.version = 1;
696              txCoinbase.vin[0].scriptSig = CScript{} << (current_height + 1) << bi.extranonce;
697              txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
698              txCoinbase.vout[0].scriptPubKey = CScript();
699              block.vtx[0] = MakeTransactionRef(txCoinbase);
700              if (txFirst.size() == 0)
701                  baseheight = current_height;
702              if (txFirst.size() < 4)
703                  txFirst.push_back(block.vtx[0]);
704              block.hashMerkleRoot = BlockMerkleRoot(block);
705              block.nNonce = bi.nonce;
706          }
707          std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
708          // Alternate calls between Chainman's ProcessNewBlock and submitSolution
709          // via the Mining interface. The former is used by net_processing as well
710          // as the submitblock RPC.
711          if (current_height % 2 == 0) {
712              BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(shared_pblock, /*force_processing=*/true, /*min_pow_checked=*/true, nullptr));
713          } else {
714              BOOST_REQUIRE(block_template->submitSolution(block.nVersion, block.nTime, block.nNonce, MakeTransactionRef(txCoinbase)));
715          }
716          {
717              LOCK(cs_main);
718              // The above calls don't guarantee the tip is actually updated, so
719              // we explicitly check this.
720              auto maybe_new_tip{Assert(m_node.chainman)->ActiveChain().Tip()};
721              BOOST_REQUIRE_EQUAL(maybe_new_tip->GetBlockHash(), block.GetHash());
722          }
723          if (current_height % 2 == 0) {
724              block_template = block_template->waitNext();
725              BOOST_REQUIRE(block_template);
726          } else {
727              // This just adds coverage
728              mining->waitTipChanged(block.hashPrevBlock);
729          }
730      }
731  
732      LOCK(cs_main);
733  
734      TestBasicMining(scriptPubKey, txFirst, baseheight);
735  
736      m_node.chainman->ActiveChain().Tip()->nHeight--;
737      SetMockTime(0);
738  
739      TestPackageSelection(scriptPubKey, txFirst);
740  
741      m_node.chainman->ActiveChain().Tip()->nHeight--;
742      SetMockTime(0);
743  
744      TestPrioritisedMining(scriptPubKey, txFirst);
745  }
746  
747  BOOST_AUTO_TEST_SUITE_END()