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 <consensus/amount.h>
7#include <net.h>
8#include <signet.h>
9#include <uint256.h>
10#include <validation.h>
11
13
14#include <boost/test/unit_test.hpp>
15
17
18static 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
35static void TestBlockSubsidyHalvings(int nSubsidyHalvingInterval)
36{
37 Consensus::Params consensusParams;
38 consensusParams.nSubsidyHalvingInterval = nSubsidyHalvingInterval;
39 TestBlockSubsidyHalvings(consensusParams);
40}
41
42BOOST_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
50BOOST_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;
59 }
60 BOOST_CHECK_EQUAL(nSum, CAmount{2099999997690000});
61}
62
63BOOST_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
125BOOST_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
NodeContext m_node
Definition: bitcoin-gui.cpp:36
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:624
static const std::string REGTEST
static const std::string SIGNET
static const std::string MAIN
Chain name strings.
Definition: block.h:63
std::vector< CTransactionRef > vtx
Definition: block.h:66
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:406
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:12
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:387
@ OP_TRUE
Definition: script.h:77
@ OP_RETURN
Definition: script.h:104
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:345
std::vector< CTxOut > vout
Definition: transaction.h:347
Parameters that influence chain consensus.
Definition: params.h:70
int nSubsidyHalvingInterval
Definition: params.h:72
ArgsManager * args
Definition: context.h:49
Testing setup that configures a complete environment.
Definition: setup_common.h:99
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)