Bitcoin Core  26.1.0
P2P Digital Currency
validation_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2021 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
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 
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(), "6657b736d4fe4db0cbc796789e812d5dba7f5c143764b1b6905612f1830609d1");
146  BOOST_CHECK_EQUAL(out110.nChainTx, 111U);
147 
148  const auto out110_2 = *params->AssumeutxoForBlockhash(uint256S("0x696e92821f65549c7ee134edceeeeaaa4105647a3c4fd9f298c0aec0ab50425c"));
149  BOOST_CHECK_EQUAL(out110_2.hash_serialized.ToString(), "6657b736d4fe4db0cbc796789e812d5dba7f5c143764b1b6905612f1830609d1");
150  BOOST_CHECK_EQUAL(out110_2.nChainTx, 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() != block.hashMerkleRoot);
218  BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false));
219  block.hashMerkleRoot = block.vtx[0]->GetHash();
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(Span(reinterpret_cast<const std::byte*>(block.vtx[0]->GetHash().data()), 32));
229  hasher.write(Span(reinterpret_cast<const std::byte*>(block.vtx[1]->GetHash().data()), 32));
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  BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false));
237  HashWriter hasher;
238  hasher.write(Span(reinterpret_cast<const std::byte*>(block.vtx[0]->GetHash().data()), 32));
239  hasher.write(Span(reinterpret_cast<const std::byte*>(block.vtx[1]->GetHash().data()), 32));
240  block.hashMerkleRoot = hasher.GetHash();
241  BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false));
242  }
243 
244  // Blocks with 64-byte coinbase transactions are not considered mutated
245  block.vtx.clear();
246  {
248  mtx.vin.resize(1);
249  mtx.vout.resize(1);
250  mtx.vout[0].scriptPubKey.resize(4);
251  block.vtx.push_back(MakeTransactionRef(mtx));
252  block.hashMerkleRoot = block.vtx.back()->GetHash();
253  assert(block.vtx.back()->IsCoinBase());
255  }
256  BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/false));
257  }
258 
259  {
260  // Test merkle root malleation
261 
262  // Pseudo code to mine transactions tx{1,2,3}:
263  //
264  // ```
265  // loop {
266  // tx1 = random_tx()
267  // tx2 = random_tx()
268  // tx3 = deserialize_tx(txid(tx1) || txid(tx2));
269  // if serialized_size_without_witness(tx3) == 64 {
270  // print(hex(tx3))
271  // break
272  // }
273  // }
274  // ```
275  //
276  // The `random_tx` function used to mine the txs below simply created
277  // empty transactions with a random version field.
279  BOOST_CHECK(DecodeHexTx(tx1, "ff204bd0000000000000", /*try_no_witness=*/true, /*try_witness=*/false));
281  BOOST_CHECK(DecodeHexTx(tx2, "8ae53c92000000000000", /*try_no_witness=*/true, /*try_witness=*/false));
283  BOOST_CHECK(DecodeHexTx(tx3, "cdaf22d00002c6a7f848f8ae4d30054e61dcf3303d6fe01d282163341f06feecc10032b3160fcab87bdfe3ecfb769206ef2d991b92f8a268e423a6ef4d485f06", /*try_no_witness=*/true, /*try_witness=*/false));
284  {
285  // Verify that double_sha256(txid1||txid2) == txid3
286  HashWriter hasher;
287  hasher.write(Span(reinterpret_cast<const std::byte*>(tx1.GetHash().data()), 32));
288  hasher.write(Span(reinterpret_cast<const std::byte*>(tx2.GetHash().data()), 32));
289  assert(hasher.GetHash() == tx3.GetHash());
290  // Verify that tx3 is 64 bytes in size (without witness).
292  }
293 
294  CBlock block;
295  block.vtx.push_back(MakeTransactionRef(tx1));
296  block.vtx.push_back(MakeTransactionRef(tx2));
297  uint256 merkle_root = block.hashMerkleRoot = BlockMerkleRoot(block);
298  BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/false));
299 
300  // Mutate the block by replacing the two transactions with one 64-byte
301  // transaction that serializes into the concatenation of the txids of
302  // the transactions in the unmutated block.
303  block.vtx.clear();
304  block.vtx.push_back(MakeTransactionRef(tx3));
305  BOOST_CHECK(!block.vtx.back()->IsCoinBase());
306  BOOST_CHECK(BlockMerkleRoot(block) == merkle_root);
307  BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false));
308  }
309 
310  {
311  CBlock block;
312  block.vtx.push_back(create_coinbase_tx(/*include_witness=*/true));
313  {
315  mtx.vin.resize(1);
316  mtx.vin[0].scriptWitness.stack.resize(1);
317  mtx.vin[0].scriptWitness.stack[0] = {0};
318  block.vtx.push_back(MakeTransactionRef(mtx));
319  }
320  block.hashMerkleRoot = BlockMerkleRoot(block);
321  // Block with witnesses is considered mutated if the witness commitment
322  // is not validated.
323  BOOST_CHECK(is_mutated(block, /*check_witness_root=*/false));
324  // Block with invalid witness commitment is considered mutated.
325  BOOST_CHECK(is_mutated(block, /*check_witness_root=*/true));
326 
327  // Block with valid commitment is not mutated
328  {
329  auto commitment{BlockWitnessMerkleRoot(block)};
330  insert_witness_commitment(block, commitment);
331  block.hashMerkleRoot = BlockMerkleRoot(block);
332  }
333  BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/true));
334 
335  // Malleating witnesses should be caught by `IsBlockMutated`.
336  {
337  CMutableTransaction mtx{*block.vtx[1]};
338  assert(!mtx.vin[0].scriptWitness.stack[0].empty());
339  ++mtx.vin[0].scriptWitness.stack[0][0];
340  block.vtx[1] = MakeTransactionRef(mtx);
341  }
342  // Without also updating the witness commitment, the merkle root should
343  // not change when changing one of the witnesses.
344  BOOST_CHECK(block.hashMerkleRoot == BlockMerkleRoot(block));
345  BOOST_CHECK(is_mutated(block, /*check_witness_root=*/true));
346  {
347  auto commitment{BlockWitnessMerkleRoot(block)};
348  insert_witness_commitment(block, commitment);
349  block.hashMerkleRoot = BlockMerkleRoot(block);
350  }
351  BOOST_CHECK(is_not_mutated(block, /*check_witness_root=*/true));
352 
353  // Test malleating the coinbase witness reserved value
354  {
355  CMutableTransaction mtx{*block.vtx[0]};
356  mtx.vin[0].scriptWitness.stack.resize(0);
357  block.vtx[0] = MakeTransactionRef(mtx);
358  block.hashMerkleRoot = BlockMerkleRoot(block);
359  }
360  BOOST_CHECK(is_mutated(block, /*check_witness_root=*/true));
361  }
362 }
363 
uint256 GetHash()
Compute the double-SHA256 hash of all data written to this object.
Definition: hash.h:116
static const int SERIALIZE_TRANSACTION_NO_WITNESS
A flag that is ORed into the protocol version to designate that a transaction should be (un)serialize...
Definition: transaction.h:32
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
void Finalize(Span< unsigned char > output)
Definition: hash.h:31
static void TestBlockSubsidyHalvings(const Consensus::Params &consensusParams)
assert(!tx.IsCoinBase())
static std::optional< SignetTxs > Create(const CBlock &block, const CScript &challenge)
Definition: signet.cpp:68
Definition: block.h:68
node::NodeContext m_node
Definition: bitcoin-gui.cpp:37
std::vector< CTxIn > vin
Definition: transaction.h:381
unsigned int nHeight
bool MoneyRange(const CAmount &nValue)
Definition: amount.h:27
static constexpr size_t MINIMUM_WITNESS_COMMITMENT
Minimum size of a witness commitment structure.
Definition: validation.h:19
uint256 BlockWitnessMerkleRoot(const CBlock &block, bool *mutated)
Definition: merkle.cpp:75
A hasher class for Bitcoin&#39;s 256-bit hash (double SHA-256).
Definition: hash.h:25
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: args.cpp:545
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:1127
Transaction validation functions.
int nSubsidyHalvingInterval
Definition: params.h:76
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
bool IsBlockMutated(const CBlock &block, bool check_witness_root)
Check if a block has been mutated (with respect to its merkle root and witness commitments).
Definition: script.h:82
uint256 hashMerkleRoot
Definition: block.h:27
void write(Span< const std::byte > src)
Definition: hash.h:107
ArgsManager * args
Definition: context.h:61
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:101
BOOST_AUTO_TEST_SUITE_END()
uint256 uint256S(const char *str)
Definition: uint256.h:119
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
Definition: merkle.cpp:65
Parameters that influence chain consensus.
Definition: params.h:74
std::vector< CTxOut > vout
Definition: transaction.h:382
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:422
256-bit opaque blob.
Definition: uint256.h:106
std::vector< CTransactionRef > vtx
Definition: block.h:72
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
Definition: transaction.cpp:68
constexpr const unsigned char * data() const
Definition: uint256.h:65
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
const CChainParams & Params()
Return the currently selected parameters.
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:412
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:12
std::unique_ptr< const CChainParams > CreateChainParams(const ArgsManager &args, const ChainType chain)
Creates and returns a std::unique_ptr<CChainParams> of the chosen chain.
BOOST_AUTO_TEST_CASE(block_subsidy_test)
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness=false, bool try_witness=true)
Definition: core_read.cpp:195
bool m_checked_witness_commitment
Definition: block.h:76
A mutable version of CTransaction.
Definition: transaction.h:379
bool fChecked
Definition: block.h:75
Span(T *, EndOrSize) -> Span< T >
CHash256 & Write(Span< const unsigned char > input)
Definition: hash.h:38
Testing setup that configures a complete environment.
Definition: setup_common.h:77
bool m_checked_merkle_root
Definition: block.h:77
#define BOOST_CHECK(expr)
Definition: object.cpp:17
bool CheckSignetBlockSolution(const CBlock &block, const Consensus::Params &consensusParams)
Extract signature and check whether a block has a valid solution.
Definition: signet.cpp:124
static constexpr CAmount COIN
The amount of satoshis in one BTC.
Definition: amount.h:15