Bitcoin Core  24.99.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 <net.h>
8 #include <signet.h>
9 #include <uint256.h>
10 #include <validation.h>
11 
12 #include <test/util/setup_common.h>
13 
14 #include <boost/test/unit_test.hpp>
15 
16 BOOST_FIXTURE_TEST_SUITE(validation_tests, TestingSetup)
17 
18 static void TestBlockSubsidyHalvings(const Consensus::Params& consensusParams)
19 {
20  int maxHalvings = 64;
21  CAmount nInitialSubsidy = 50 * COIN;
22 
23  CAmount nPreviousSubsidy = nInitialSubsidy * 2; // for height == 0
24  BOOST_CHECK_EQUAL(nPreviousSubsidy, nInitialSubsidy * 2);
25  for (int nHalvings = 0; nHalvings < maxHalvings; nHalvings++) {
26  int nHeight = nHalvings * consensusParams.nSubsidyHalvingInterval;
27  CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams);
28  BOOST_CHECK(nSubsidy <= nInitialSubsidy);
29  BOOST_CHECK_EQUAL(nSubsidy, nPreviousSubsidy / 2);
30  nPreviousSubsidy = nSubsidy;
31  }
32  BOOST_CHECK_EQUAL(GetBlockSubsidy(maxHalvings * consensusParams.nSubsidyHalvingInterval, consensusParams), 0);
33 }
34 
35 static void TestBlockSubsidyHalvings(int nSubsidyHalvingInterval)
36 {
37  Consensus::Params consensusParams;
38  consensusParams.nSubsidyHalvingInterval = nSubsidyHalvingInterval;
39  TestBlockSubsidyHalvings(consensusParams);
40 }
41 
42 BOOST_AUTO_TEST_CASE(block_subsidy_test)
43 {
44  const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
45  TestBlockSubsidyHalvings(chainParams->GetConsensus()); // As in main
46  TestBlockSubsidyHalvings(150); // As in regtest
47  TestBlockSubsidyHalvings(1000); // Just another interval
48 }
49 
50 BOOST_AUTO_TEST_CASE(subsidy_limit_test)
51 {
52  const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
53  CAmount nSum = 0;
54  for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) {
55  CAmount nSubsidy = GetBlockSubsidy(nHeight, chainParams->GetConsensus());
56  BOOST_CHECK(nSubsidy <= 50 * COIN);
57  nSum += nSubsidy * 1000;
58  BOOST_CHECK(MoneyRange(nSum));
59  }
60  BOOST_CHECK_EQUAL(nSum, CAmount{2099999997690000});
61 }
62 
63 BOOST_AUTO_TEST_CASE(signet_parse_tests)
64 {
65  ArgsManager signet_argsman;
66  signet_argsman.ForceSetArg("-signetchallenge", "51"); // set challenge to OP_TRUE
67  const auto signet_params = CreateChainParams(signet_argsman, CBaseChainParams::SIGNET);
68  CBlock block;
69  BOOST_CHECK(signet_params->GetConsensus().signet_challenge == std::vector<uint8_t>{OP_TRUE});
70  CScript challenge{OP_TRUE};
71 
72  // empty block is invalid
73  BOOST_CHECK(!SignetTxs::Create(block, challenge));
74  BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));
75 
76  // no witness commitment
78  cb.vout.emplace_back(0, CScript{});
79  block.vtx.push_back(MakeTransactionRef(cb));
80  block.vtx.push_back(MakeTransactionRef(cb)); // Add dummy tx to exercise merkle root code
81  BOOST_CHECK(!SignetTxs::Create(block, challenge));
82  BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));
83 
84  // no header is treated valid
85  std::vector<uint8_t> witness_commitment_section_141{0xaa, 0x21, 0xa9, 0xed};
86  for (int i = 0; i < 32; ++i) {
87  witness_commitment_section_141.push_back(0xff);
88  }
89  cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141;
90  block.vtx.at(0) = MakeTransactionRef(cb);
91  BOOST_CHECK(SignetTxs::Create(block, challenge));
92  BOOST_CHECK(CheckSignetBlockSolution(block, signet_params->GetConsensus()));
93 
94  // no data after header, valid
95  std::vector<uint8_t> witness_commitment_section_325{0xec, 0xc7, 0xda, 0xa2};
96  cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
97  block.vtx.at(0) = MakeTransactionRef(cb);
98  BOOST_CHECK(SignetTxs::Create(block, challenge));
99  BOOST_CHECK(CheckSignetBlockSolution(block, signet_params->GetConsensus()));
100 
101  // Premature end of data, invalid
102  witness_commitment_section_325.push_back(0x01);
103  witness_commitment_section_325.push_back(0x51);
104  cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
105  block.vtx.at(0) = MakeTransactionRef(cb);
106  BOOST_CHECK(!SignetTxs::Create(block, challenge));
107  BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));
108 
109  // has data, valid
110  witness_commitment_section_325.push_back(0x00);
111  cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
112  block.vtx.at(0) = MakeTransactionRef(cb);
113  BOOST_CHECK(SignetTxs::Create(block, challenge));
114  BOOST_CHECK(CheckSignetBlockSolution(block, signet_params->GetConsensus()));
115 
116  // Extraneous data, invalid
117  witness_commitment_section_325.push_back(0x00);
118  cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
119  block.vtx.at(0) = MakeTransactionRef(cb);
120  BOOST_CHECK(!SignetTxs::Create(block, challenge));
121  BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));
122 }
123 
125 BOOST_AUTO_TEST_CASE(test_assumeutxo)
126 {
128 
129  // These heights don't have assumeutxo configurations associated, per the contents
130  // of chainparams.cpp.
131  std::vector<int> bad_heights{0, 100, 111, 115, 209, 211};
132 
133  for (auto empty : bad_heights) {
134  const auto out = ExpectedAssumeutxo(empty, *params);
135  BOOST_CHECK(!out);
136  }
137 
138  const auto out110 = *ExpectedAssumeutxo(110, *params);
139  BOOST_CHECK_EQUAL(out110.hash_serialized.ToString(), "1ebbf5850204c0bdb15bf030f47c7fe91d45c44c712697e4509ba67adb01c618");
140  BOOST_CHECK_EQUAL(out110.nChainTx, 110U);
141 
142  const auto out210 = *ExpectedAssumeutxo(200, *params);
143  BOOST_CHECK_EQUAL(out210.hash_serialized.ToString(), "51c8d11d8b5c1de51543c579736e786aa2736206d1e11e627568029ce092cf62");
144  BOOST_CHECK_EQUAL(out210.nChainTx, 200U);
145 }
146 
bool MoneyRange(const CAmount &nValue)
Definition: amount.h:27
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
static constexpr CAmount COIN
The amount of satoshis in one BTC.
Definition: amount.h:15
node::NodeContext m_node
Definition: bitcoin-gui.cpp:37
std::unique_ptr< const CChainParams > CreateChainParams(const ArgsManager &args, const std::string &chain)
Creates and returns a std::unique_ptr<CChainParams> of the chosen chain.
const CChainParams & Params()
Return the currently selected parameters.
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: system.cpp:693
static const std::string REGTEST
static const std::string SIGNET
static const std::string MAIN
Chain name strings.
Definition: block.h:69
std::vector< CTransactionRef > vtx
Definition: block.h:72
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:411
static std::optional< SignetTxs > Create(const CBlock &block, const CScript &challenge)
Definition: signet.cpp:68
BOOST_AUTO_TEST_SUITE_END()
unsigned int nHeight
Transaction validation functions.
Definition: params.h:15
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:17
#define BOOST_CHECK(expr)
Definition: object.cpp:16
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:415
@ OP_TRUE
Definition: script.h:80
@ OP_RETURN
Definition: script.h:107
bool CheckSignetBlockSolution(const CBlock &block, const Consensus::Params &consensusParams)
Extract signature and check whether a block has a valid solution.
Definition: signet.cpp:124
A mutable version of CTransaction.
Definition: transaction.h:373
std::vector< CTxOut > vout
Definition: transaction.h:375
Parameters that influence chain consensus.
Definition: params.h:73
int nSubsidyHalvingInterval
Definition: params.h:75
Testing setup that configures a complete environment.
Definition: setup_common.h:109
ArgsManager * args
Definition: context.h:56
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
const AssumeutxoData * ExpectedAssumeutxo(const int height, const CChainParams &chainparams)
Return the expected assumeutxo value for a given height, if one exists.
static void TestBlockSubsidyHalvings(const Consensus::Params &consensusParams)
BOOST_AUTO_TEST_CASE(block_subsidy_test)