-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathamount_tests.cpp
More file actions
156 lines (134 loc) · 6.29 KB
/
Copy pathamount_tests.cpp
File metadata and controls
156 lines (134 loc) · 6.29 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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright (c) 2016-2020 The Bitcoin Core developers
// Copyright (c) 2016-2023 The Reddcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <amount.h>
#include <policy/feerate.h>
#include <test/util/setup_common.h>
#include <limits>
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE(amount_tests)
BOOST_AUTO_TEST_CASE(MoneyRangeTest)
{
BOOST_CHECK_EQUAL(MoneyRange(CAmount(-1)), false);
BOOST_CHECK_EQUAL(MoneyRange(CAmount(0)), true);
BOOST_CHECK_EQUAL(MoneyRange(CAmount(1)), true);
BOOST_CHECK_EQUAL(MoneyRange(MAX_MONEY), true);
BOOST_CHECK_EQUAL(MoneyRange(MAX_MONEY + CAmount(1)), false);
}
BOOST_AUTO_TEST_CASE(GetFeeTest)
{
CFeeRate feeRate, altFeeRate;
feeRate = CFeeRate(0);
// Must always return 0
BOOST_CHECK_EQUAL(feeRate.GetFee(0), CAmount(0));
BOOST_CHECK_EQUAL(feeRate.GetFee(1e5), CAmount(0));
feeRate = CFeeRate(1000);
// Must always just return the arg
BOOST_CHECK_EQUAL(feeRate.GetFee(0), CAmount(0));
BOOST_CHECK_EQUAL(feeRate.GetFee(1), CAmount(1));
BOOST_CHECK_EQUAL(feeRate.GetFee(121), CAmount(121));
BOOST_CHECK_EQUAL(feeRate.GetFee(999), CAmount(999));
BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), CAmount(1e3));
BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), CAmount(9e3));
feeRate = CFeeRate(-1000);
// Must always just return -1 * arg
BOOST_CHECK_EQUAL(feeRate.GetFee(0), CAmount(0));
BOOST_CHECK_EQUAL(feeRate.GetFee(1), CAmount(-1));
BOOST_CHECK_EQUAL(feeRate.GetFee(121), CAmount(-121));
BOOST_CHECK_EQUAL(feeRate.GetFee(999), CAmount(-999));
BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), CAmount(-1e3));
BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), CAmount(-9e3));
feeRate = CFeeRate(123);
// Rounds up the result, if not integer
BOOST_CHECK_EQUAL(feeRate.GetFee(0), CAmount(0));
BOOST_CHECK_EQUAL(feeRate.GetFee(8), CAmount(1)); // Special case: returns 1 instead of 0
BOOST_CHECK_EQUAL(feeRate.GetFee(9), CAmount(2));
BOOST_CHECK_EQUAL(feeRate.GetFee(121), CAmount(15));
BOOST_CHECK_EQUAL(feeRate.GetFee(122), CAmount(16));
BOOST_CHECK_EQUAL(feeRate.GetFee(999), CAmount(123));
BOOST_CHECK_EQUAL(feeRate.GetFee(1e3), CAmount(123));
BOOST_CHECK_EQUAL(feeRate.GetFee(9e3), CAmount(1107));
feeRate = CFeeRate(-123);
// Truncates the result, if not integer
BOOST_CHECK_EQUAL(feeRate.GetFee(0), CAmount(0));
BOOST_CHECK_EQUAL(feeRate.GetFee(8), CAmount(-1)); // Special case: returns -1 instead of 0
BOOST_CHECK_EQUAL(feeRate.GetFee(9), CAmount(-1));
// check alternate constructor
feeRate = CFeeRate(1000);
altFeeRate = CFeeRate(feeRate);
BOOST_CHECK_EQUAL(feeRate.GetFee(100), altFeeRate.GetFee(100));
// Check full constructor
BOOST_CHECK(CFeeRate(CAmount(-1), 0) == CFeeRate(0));
BOOST_CHECK(CFeeRate(CAmount(0), 0) == CFeeRate(0));
BOOST_CHECK(CFeeRate(CAmount(1), 0) == CFeeRate(0));
// default value
BOOST_CHECK(CFeeRate(CAmount(-1), 1000) == CFeeRate(-1));
BOOST_CHECK(CFeeRate(CAmount(0), 1000) == CFeeRate(0));
BOOST_CHECK(CFeeRate(CAmount(1), 1000) == CFeeRate(1));
// lost precision (can only resolve satoshis per kB)
BOOST_CHECK(CFeeRate(CAmount(1), 1001) == CFeeRate(0));
BOOST_CHECK(CFeeRate(CAmount(2), 1001) == CFeeRate(1));
// some more integer checks
BOOST_CHECK(CFeeRate(CAmount(26), 789) == CFeeRate(32));
BOOST_CHECK(CFeeRate(CAmount(27), 789) == CFeeRate(34));
}
BOOST_AUTO_TEST_CASE(GetFeeOverflowTest)
{
// Regression test for the out-of-range double->int64 conversion in
// CFeeRate::GetFee(). The constructor clamps an overflowing rate to INT64_MAX,
// after which GetFee()'s double math can land exactly on 2^63. Because
// static_cast<double>(INT64_MAX) rounds up to 2^63, a strict ">" bound let that
// value fall through to an undefined static_cast<CAmount>(2^63); GetFee() must
// clamp with ">=" and return INT64_MAX instead.
constexpr CAmount int64_max{std::numeric_limits<int64_t>::max()};
constexpr CAmount int64_min{std::numeric_limits<int64_t>::min()};
constexpr uint32_t u32_max{std::numeric_limits<uint32_t>::max()};
const CFeeRate maxRate{int64_max};
// size 1000 -> dFee == 2^63 exactly: must clamp, not trap.
BOOST_CHECK_EQUAL(maxRate.GetFee(1000), int64_max);
// larger sizes overflow further; still clamped.
BOOST_CHECK_EQUAL(maxRate.GetFee(2000), int64_max);
BOOST_CHECK_EQUAL(maxRate.GetFee(u32_max), int64_max);
const CFeeRate minRate{int64_min};
// negative side: -2^63 is exactly representable, so the boundary is well-defined.
BOOST_CHECK_EQUAL(minRate.GetFee(1000), int64_min);
BOOST_CHECK_EQUAL(minRate.GetFee(2000), int64_min);
BOOST_CHECK_EQUAL(minRate.GetFee(u32_max), int64_min);
// full constructor must clamp an overflowing rate (bits() > 63 path) to
// INT64_MAX rather than wrapping, and GetFee() must stay clamped afterwards.
BOOST_CHECK_EQUAL(CFeeRate(int64_max, 1).GetFee(1000), int64_max);
}
BOOST_AUTO_TEST_CASE(SizeLimitTest)
{
// Maximum size in bytes, should not crash
BOOST_CHECK(CFeeRate(MAX_MONEY, std::numeric_limits<uint32_t>::max()) == CFeeRate(2147483648487));
BOOST_CHECK_EQUAL(CFeeRate(MAX_MONEY, std::numeric_limits<uint32_t>::max()).ToString() , "21474.83648487 RDD/kvB");
BOOST_CHECK_EQUAL(CFeeRate(MAX_MONEY, std::numeric_limits<uint32_t>::max()).ToString(FeeEstimateMode::BTC_KVB) , "21474.83648487 RDD/kvB");
BOOST_CHECK_EQUAL(CFeeRate(MAX_MONEY, std::numeric_limits<uint32_t>::max()).ToString(FeeEstimateMode::SAT_VB) , "2147483648.487 sat/vB");
}
BOOST_AUTO_TEST_CASE(BinaryOperatorTest)
{
CFeeRate a, b;
a = CFeeRate(1);
b = CFeeRate(2);
BOOST_CHECK(a < b);
BOOST_CHECK(b > a);
BOOST_CHECK(a == a);
BOOST_CHECK(a <= b);
BOOST_CHECK(a <= a);
BOOST_CHECK(b >= a);
BOOST_CHECK(b >= b);
// a should be 0.00000002 BTC/kvB now
a += a;
BOOST_CHECK(a == b);
}
BOOST_AUTO_TEST_CASE(ToStringTest)
{
CFeeRate feeRate;
feeRate = CFeeRate(1);
BOOST_CHECK_EQUAL(feeRate.ToString(), "0.00000001 RDD/kvB");
BOOST_CHECK_EQUAL(feeRate.ToString(FeeEstimateMode::BTC_KVB), "0.00000001 RDD/kvB");
BOOST_CHECK_EQUAL(feeRate.ToString(FeeEstimateMode::SAT_VB), "0.001 sat/vB");
}
BOOST_AUTO_TEST_SUITE_END()