forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathevo_cbtx_tests.cpp
More file actions
70 lines (58 loc) · 2.79 KB
/
Copy pathevo_cbtx_tests.cpp
File metadata and controls
70 lines (58 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Copyright (c) 2026 The Dash Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <test/util/setup_common.h>
#include <bls/bls.h>
#include <chain.h>
#include <chainlock/chainlock.h>
#include <chainparams.h>
#include <consensus/validation.h>
#include <evo/cbtx.h>
#include <evo/specialtxman.h>
#include <llmq/context.h>
#include <llmq/quorumsman.h>
#include <uint256.h>
#include <validation.h>
#include <cstdint>
#include <limits>
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE(evo_cbtx_tests)
// Out-of-range bestCLHeightDiff (>= pindex->nHeight) must be rejected with
// "bad-cbtx-cldiff" so that the subsequent GetAncestor() call sees a valid height.
//
// The defensive nullptr branch after GetAncestor() returns "bad-cbtx-cldiff-ancestor".
// That branch is unreachable in practice (the range check guarantees the requested
// ancestor height is in [0, pindex->nHeight - 1], for which GetAncestor() never returns
// nullptr) and cannot be exercised from a unit test: a fake CBlockIndex with no pprev
// would trip GetAncestor()'s `assert(pprev)` while walking, not return nullptr.
BOOST_FIXTURE_TEST_CASE(check_cbtx_best_chainlock_rejects_excessive_height_diff, RegTestingSetup)
{
const auto& consensus_params = Params().GetConsensus();
const auto& chain = m_node.chainman->ActiveChain();
auto& qman = *Assert(m_node.llmq_ctx)->qman;
auto& chainlocks = *Assert(m_node.chainlocks);
// Standalone fake block index with no predecessor, so the prevBlockCoinbaseChainlock
// branch is skipped and the validation path under test is reached directly.
CBlockIndex pindex;
pindex.nHeight = 5;
// A structurally-valid BLS signature is required for the IsValid() guard.
CBLSSecretKey sk;
sk.MakeNewKey();
const bool legacy_scheme = bls::bls_legacy_scheme.load();
CBLSSignature valid_sig = sk.Sign(uint256::ONE, legacy_scheme);
BOOST_REQUIRE(valid_sig.IsValid());
CCbTx cbTx;
cbTx.nVersion = CCbTx::Version::CLSIG_AND_BALANCE;
cbTx.bestCLSignature = valid_sig;
// bestCLHeightDiff == nHeight: lower boundary of the rejected range.
cbTx.bestCLHeightDiff = static_cast<uint32_t>(pindex.nHeight);
BlockValidationState state;
BOOST_CHECK(!CheckCbTxBestChainlock(cbTx, &pindex, consensus_params, chain, qman, chainlocks, state));
BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-cbtx-cldiff");
// Upper boundary: uint32_t max.
cbTx.bestCLHeightDiff = std::numeric_limits<uint32_t>::max();
BlockValidationState state_big;
BOOST_CHECK(!CheckCbTxBestChainlock(cbTx, &pindex, consensus_params, chain, qman, chainlocks, state_big));
BOOST_CHECK_EQUAL(state_big.GetRejectReason(), "bad-cbtx-cldiff");
}
BOOST_AUTO_TEST_SUITE_END()