/ src / test / validation_tests.cpp
validation_tests.cpp
  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, TestingSetup)
 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(), "b952555c8ab81fec46f3d4253b7af256d766ceb39fb7752b9d18cdf4a0141327");
146      BOOST_CHECK_EQUAL(out110.m_chain_tx_count, 111U);
147  
148      const auto out110_2 = *params->AssumeutxoForBlockhash(uint256{"6affe030b7965ab538f820a56ef56c8149b7dc1d1c144af57113be080db7c397"});
149      BOOST_CHECK_EQUAL(out110_2.hash_serialized.ToString(), "b952555c8ab81fec46f3d4253b7af256d766ceb39fb7752b9d18cdf4a0141327");
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()