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