validation_tests.cpp raw

   1  // Copyright (c) 2014-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 <chainparams.h>
   6  #include <consensus/amount.h>
   7  #include <consensus/merkle.h>
   8  #include <core_io.h>
   9  #include <hash.h>
  10  #include <net.h>
  11  #include <signet.h>
  12  #include <uint256.h>
  13  #include <util/chaintype.h>
  14  #include <validation.h>
  15  
  16  #include <string>
  17  
  18  #include <test/util/setup_common.h>
  19  
  20  #include <boost/test/unit_test.hpp>
  21  
  22  BOOST_FIXTURE_TEST_SUITE(validation_tests, BasicTestingSetup)
  23  
  24  static void TestBlockSubsidyHalvings(const Consensus::Params& consensusParams)
  25  {
  26      int maxHalvings = 64;
  27      CAmount nInitialSubsidy = 50 * COIN;
  28  
  29      CAmount nPreviousSubsidy = nInitialSubsidy * 2; // for height == 0
  30      BOOST_CHECK_EQUAL(nPreviousSubsidy, nInitialSubsidy * 2);
  31      for (int nHalvings = 0; nHalvings < maxHalvings; nHalvings++) {
  32          int nHeight = nHalvings * consensusParams.nSubsidyHalvingInterval;
  33          CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams);
  34          BOOST_CHECK(nSubsidy <= nInitialSubsidy);
  35          BOOST_CHECK_EQUAL(nSubsidy, nPreviousSubsidy / 2);
  36          nPreviousSubsidy = nSubsidy;
  37      }
  38      BOOST_CHECK_EQUAL(GetBlockSubsidy(maxHalvings * consensusParams.nSubsidyHalvingInterval, consensusParams), 0);
  39  }
  40  
  41  static void TestBlockSubsidyHalvings(int nSubsidyHalvingInterval)
  42  {
  43      Consensus::Params consensusParams;
  44      consensusParams.nSubsidyHalvingInterval = nSubsidyHalvingInterval;
  45      TestBlockSubsidyHalvings(consensusParams);
  46  }
  47  
  48  BOOST_AUTO_TEST_CASE(block_subsidy_test)
  49  {
  50      const auto chainParams = CreateChainParams(*m_node.args, ChainType::MAIN);
  51      TestBlockSubsidyHalvings(chainParams->GetConsensus()); // As in main
  52      TestBlockSubsidyHalvings(150); // As in regtest
  53      TestBlockSubsidyHalvings(1000); // Just another interval
  54  }
  55  
  56  BOOST_AUTO_TEST_CASE(subsidy_limit_test)
  57  {
  58      const auto chainParams = CreateChainParams(*m_node.args, ChainType::MAIN);
  59      CAmount nSum = 0;
  60      for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) {
  61          CAmount nSubsidy = GetBlockSubsidy(nHeight, chainParams->GetConsensus());
  62          BOOST_CHECK(nSubsidy <= 50 * COIN);
  63          nSum += nSubsidy * 1000;
  64          BOOST_CHECK(MoneyRange(nSum));
  65      }
  66      BOOST_CHECK_EQUAL(nSum, CAmount{2099999997690000});
  67  }
  68  
  69  BOOST_AUTO_TEST_CASE(signet_parse_tests)
  70  {
  71      ArgsManager signet_argsman;
  72      signet_argsman.ForceSetArg("-signetchallenge", "51"); // set challenge to OP_TRUE
  73      const auto signet_params = CreateChainParams(signet_argsman, ChainType::SIGNET);
  74      CBlock block;
  75      BOOST_CHECK(signet_params->GetConsensus().signet_challenge == std::vector<uint8_t>{OP_TRUE});
  76      CScript challenge{OP_TRUE};
  77  
  78      // empty block is invalid
  79      BOOST_CHECK(!SignetTxs::Create(block, challenge));
  80      BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));
  81  
  82      // no witness commitment
  83      CMutableTransaction cb;
  84      cb.vout.emplace_back(0, CScript{});
  85      block.vtx.push_back(MakeTransactionRef(cb));
  86      block.vtx.push_back(MakeTransactionRef(cb)); // Add dummy tx to exercise merkle root code
  87      BOOST_CHECK(!SignetTxs::Create(block, challenge));
  88      BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));
  89  
  90      // no header is treated valid
  91      std::vector<uint8_t> witness_commitment_section_141{0xaa, 0x21, 0xa9, 0xed};
  92      for (int i = 0; i < 32; ++i) {
  93          witness_commitment_section_141.push_back(0xff);
  94      }
  95      cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141;
  96      block.vtx.at(0) = MakeTransactionRef(cb);
  97      BOOST_CHECK(SignetTxs::Create(block, challenge));
  98      BOOST_CHECK(CheckSignetBlockSolution(block, signet_params->GetConsensus()));
  99  
 100      // no data after header, valid
 101      std::vector<uint8_t> witness_commitment_section_325{0xec, 0xc7, 0xda, 0xa2};
 102      cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
 103      block.vtx.at(0) = MakeTransactionRef(cb);
 104      BOOST_CHECK(SignetTxs::Create(block, challenge));
 105      BOOST_CHECK(CheckSignetBlockSolution(block, signet_params->GetConsensus()));
 106  
 107      // Premature end of data, invalid
 108      witness_commitment_section_325.push_back(0x01);
 109      witness_commitment_section_325.push_back(0x51);
 110      cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
 111      block.vtx.at(0) = MakeTransactionRef(cb);
 112      BOOST_CHECK(!SignetTxs::Create(block, challenge));
 113      BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));
 114  
 115      // has data, valid
 116      witness_commitment_section_325.push_back(0x00);
 117      cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
 118      block.vtx.at(0) = MakeTransactionRef(cb);
 119      BOOST_CHECK(SignetTxs::Create(block, challenge));
 120      BOOST_CHECK(CheckSignetBlockSolution(block, signet_params->GetConsensus()));
 121  
 122      // Extraneous data, invalid
 123      witness_commitment_section_325.push_back(0x00);
 124      cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
 125      block.vtx.at(0) = MakeTransactionRef(cb);
 126      BOOST_CHECK(!SignetTxs::Create(block, challenge));
 127      BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));
 128  }
 129  
 130  //! Test retrieval of valid assumeutxo values.
 131  BOOST_AUTO_TEST_CASE(test_assumeutxo)
 132  {
 133      const auto params = CreateChainParams(*m_node.args, ChainType::REGTEST);
 134  
 135      // These heights don't have assumeutxo configurations associated, per the contents
 136      // of kernel/chainparams.cpp.
 137      std::vector<int> bad_heights{0, 100, 111, 115, 209, 211};
 138  
 139      for (auto empty : bad_heights) {
 140          const auto out = params->AssumeutxoForHeight(empty);
 141          BOOST_CHECK(!out);
 142      }
 143  
 144      const auto out110 = *params->AssumeutxoForHeight(110);
 145      BOOST_CHECK_EQUAL(out110.hash_serialized.ToString(), "86e9a1205b418b16dde3a18a78c730e30137e28466bda5dbf6b33ab8fc05447c");
 146      BOOST_CHECK_EQUAL(out110.m_chain_tx_count, 111U);
 147  
 148      const auto out110_2 = *params->AssumeutxoForBlockhash(uint256{"135eec25a6fb277884e5824e7aa7d052c4868161c99a5122170b5266f86c273d"});
 149      BOOST_CHECK_EQUAL(out110_2.hash_serialized.ToString(), "86e9a1205b418b16dde3a18a78c730e30137e28466bda5dbf6b33ab8fc05447c");
 150      BOOST_CHECK_EQUAL(out110_2.m_chain_tx_count, 111U);
 151  }
 152  
 153  BOOST_AUTO_TEST_CASE(block_malleation)
 154  {
 155      // Test utilities that calls `IsBlockMutated` and then clears the validity
 156      // cache flags on `CBlock`.
 157      auto is_mutated = [](CBlock& block, bool check_witness_root) {
 158          bool mutated{IsBlockMutated(block, check_witness_root)};
 159          block.fChecked = false;
 160          block.m_checked_witness_commitment = false;
 161          block.m_checked_merkle_root = false;
 162          return mutated;
 163      };
 164      auto is_not_mutated = [&is_mutated](CBlock& block, bool check_witness_root) {
 165          return !is_mutated(block, check_witness_root);
 166      };
 167  
 168      // Test utilities to create coinbase transactions and insert witness
 169      // commitments.
 170      //
 171      // Note: this will not include the witness stack by default to avoid
 172      // triggering the "no witnesses allowed for blocks that don't commit to
 173      // witnesses" rule when testing other malleation vectors.
 174      auto create_coinbase_tx = [](bool include_witness = false) {
 175          CMutableTransaction coinbase;
 176          coinbase.vin.resize(1);
 177          if (include_witness) {
 178              coinbase.vin[0].scriptWitness.stack.resize(1);
 179              coinbase.vin[0].scriptWitness.stack[0] = std::vector<unsigned char>(32, 0x00);
 180          }
 181  
 182          coinbase.vout.resize(1);
 183          coinbase.vout[0].scriptPubKey.resize(MINIMUM_WITNESS_COMMITMENT);
 184          coinbase.vout[0].scriptPubKey[0] = OP_RETURN;
 185          coinbase.vout[0].scriptPubKey[1] = 0x24;
 186          coinbase.vout[0].scriptPubKey[2] = 0xaa;
 187          coinbase.vout[0].scriptPubKey[3] = 0x21;
 188          coinbase.vout[0].scriptPubKey[4] = 0xa9;
 189          coinbase.vout[0].scriptPubKey[5] = 0xed;
 190  
 191          auto tx = MakeTransactionRef(coinbase);
 192          assert(tx->IsCoinBase());
 193          return tx;
 194      };
 195      auto insert_witness_commitment = [](CBlock& block, uint256 commitment) {
 196          assert(!block.vtx.empty() && block.vtx[0]->IsCoinBase() && !block.vtx[0]->vout.empty());
 197  
 198          CMutableTransaction mtx{*block.vtx[0]};
 199          CHash256().Write(commitment).Write(std::vector<unsigned char>(32, 0x00)).Finalize(commitment);
 200          memcpy(&mtx.vout[0].scriptPubKey[6], commitment.begin(), 32);
 201          block.vtx[0] = MakeTransactionRef(mtx);
 202      };
 203  
 204      {
 205          CBlock block;
 206  
 207          // Empty block is expected to have merkle root of 0x0.
 208          BOOST_CHECK(block.vtx.empty());
 209          block.hashMerkleRoot = uint256{1};
 210          BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false));
 211          block.hashMerkleRoot = uint256{};
 212          BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/false));
 213  
 214          // Block with a single coinbase tx is mutated if the merkle root is not
 215          // equal to the coinbase tx's hash.
 216          block.vtx.push_back(create_coinbase_tx());
 217          BOOST_CHECK(block.vtx[0]->GetHash().ToUint256() != block.hashMerkleRoot);
 218          BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false));
 219          block.hashMerkleRoot = block.vtx[0]->GetHash().ToUint256();
 220          BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/false));
 221  
 222          // Block with two transactions is mutated if the merkle root does not
 223          // match the double sha256 of the concatenation of the two transaction
 224          // hashes.
 225          block.vtx.push_back(MakeTransactionRef(CMutableTransaction{}));
 226          BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false));
 227          HashWriter hasher;
 228          hasher.write(block.vtx[0]->GetHash());
 229          hasher.write(block.vtx[1]->GetHash());
 230          block.hashMerkleRoot = hasher.GetHash();
 231          BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/false));
 232  
 233          // Block with two transactions is mutated if any node is duplicate.
 234          {
 235              block.vtx[1] = block.vtx[0];
 236              HashWriter hasher;
 237              hasher.write(block.vtx[0]->GetHash());
 238              hasher.write(block.vtx[1]->GetHash());
 239              block.hashMerkleRoot = hasher.GetHash();
 240              BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false));
 241          }
 242  
 243          // Blocks with 64-byte coinbase transactions are not considered mutated
 244          block.vtx.clear();
 245          {
 246              CMutableTransaction mtx;
 247              mtx.vin.resize(1);
 248              mtx.vout.resize(1);
 249              mtx.vout[0].scriptPubKey.resize(4);
 250              block.vtx.push_back(MakeTransactionRef(mtx));
 251              block.hashMerkleRoot = block.vtx.back()->GetHash().ToUint256();
 252              assert(block.vtx.back()->IsCoinBase());
 253              assert(GetSerializeSize(TX_NO_WITNESS(block.vtx.back())) == 64);
 254          }
 255          BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/false));
 256      }
 257  
 258      {
 259          // Test merkle root malleation
 260  
 261          // Pseudo code to mine transactions tx{1,2,3}:
 262          //
 263          // ```
 264          // loop {
 265          //   tx1 = random_tx()
 266          //   tx2 = random_tx()
 267          //   tx3 = deserialize_tx(txid(tx1) || txid(tx2));
 268          //   if serialized_size_without_witness(tx3) == 64 {
 269          //     print(hex(tx3))
 270          //     break
 271          //   }
 272          // }
 273          // ```
 274          //
 275          // The `random_tx` function used to mine the txs below simply created
 276          // empty transactions with a random version field.
 277          CMutableTransaction tx1;
 278          BOOST_CHECK(DecodeHexTx(tx1, "ff204bd0000000000000", /*try_no_witness=*/true, /*try_witness=*/false));
 279          CMutableTransaction tx2;
 280          BOOST_CHECK(DecodeHexTx(tx2, "8ae53c92000000000000", /*try_no_witness=*/true, /*try_witness=*/false));
 281          CMutableTransaction tx3;
 282          BOOST_CHECK(DecodeHexTx(tx3, "cdaf22d00002c6a7f848f8ae4d30054e61dcf3303d6fe01d282163341f06feecc10032b3160fcab87bdfe3ecfb769206ef2d991b92f8a268e423a6ef4d485f06", /*try_no_witness=*/true, /*try_witness=*/false));
 283          {
 284              // Verify that double_sha256(txid1||txid2) == txid3
 285              HashWriter hasher;
 286              hasher.write(tx1.GetHash());
 287              hasher.write(tx2.GetHash());
 288              assert(hasher.GetHash() == tx3.GetHash().ToUint256());
 289              // Verify that tx3 is 64 bytes in size (without witness).
 290              assert(GetSerializeSize(TX_NO_WITNESS(tx3)) == 64);
 291          }
 292  
 293          CBlock block;
 294          block.vtx.push_back(MakeTransactionRef(tx1));
 295          block.vtx.push_back(MakeTransactionRef(tx2));
 296          uint256 merkle_root = block.hashMerkleRoot = BlockMerkleRoot(block);
 297          BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/false));
 298  
 299          // Mutate the block by replacing the two transactions with one 64-byte
 300          // transaction that serializes into the concatenation of the txids of
 301          // the transactions in the unmutated block.
 302          block.vtx.clear();
 303          block.vtx.push_back(MakeTransactionRef(tx3));
 304          BOOST_CHECK(!block.vtx.back()->IsCoinBase());
 305          BOOST_CHECK(BlockMerkleRoot(block) == merkle_root);
 306          BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false));
 307      }
 308  
 309      {
 310          CBlock block;
 311          block.vtx.push_back(create_coinbase_tx(/*include_witness=*/true));
 312          {
 313              CMutableTransaction mtx;
 314              mtx.vin.resize(1);
 315              mtx.vin[0].scriptWitness.stack.resize(1);
 316              mtx.vin[0].scriptWitness.stack[0] = {0};
 317              block.vtx.push_back(MakeTransactionRef(mtx));
 318          }
 319          block.hashMerkleRoot = BlockMerkleRoot(block);
 320          // Block with witnesses is considered mutated if the witness commitment
 321          // is not validated.
 322          BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false));
 323          // Block with invalid witness commitment is considered mutated.
 324          BOOST_CHECK(is_mutated(block, /*check_witness_root=*/true));
 325  
 326          // Block with valid commitment is not mutated
 327          {
 328              auto commitment{BlockWitnessMerkleRoot(block)};
 329              insert_witness_commitment(block, commitment);
 330              block.hashMerkleRoot = BlockMerkleRoot(block);
 331          }
 332          BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/true));
 333  
 334          // Malleating witnesses should be caught by `IsBlockMutated`.
 335          {
 336              CMutableTransaction mtx{*block.vtx[1]};
 337              assert(!mtx.vin[0].scriptWitness.stack[0].empty());
 338              ++mtx.vin[0].scriptWitness.stack[0][0];
 339              block.vtx[1] = MakeTransactionRef(mtx);
 340          }
 341          // Without also updating the witness commitment, the merkle root should
 342          // not change when changing one of the witnesses.
 343          BOOST_CHECK(block.hashMerkleRoot == BlockMerkleRoot(block));
 344          BOOST_CHECK(is_mutated(block, /*check_witness_root=*/true));
 345          {
 346              auto commitment{BlockWitnessMerkleRoot(block)};
 347              insert_witness_commitment(block, commitment);
 348              block.hashMerkleRoot = BlockMerkleRoot(block);
 349          }
 350          BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/true));
 351  
 352          // Test malleating the coinbase witness reserved value
 353          {
 354              CMutableTransaction mtx{*block.vtx[0]};
 355              mtx.vin[0].scriptWitness.stack.resize(0);
 356              block.vtx[0] = MakeTransactionRef(mtx);
 357              block.hashMerkleRoot = BlockMerkleRoot(block);
 358          }
 359          BOOST_CHECK(is_mutated(block, /*check_witness_root=*/true));
 360      }
 361  }
 362  
 363  BOOST_AUTO_TEST_SUITE_END()
 364