Branch data Line data Source code
1 : : // Copyright (c) 2024-present 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 <util/feefrac.h>
6 : : #include <random.h>
7 : :
8 : : #include <boost/test/unit_test.hpp>
9 : :
10 : : BOOST_AUTO_TEST_SUITE(feefrac_tests)
11 : :
12 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(feefrac_operators)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
13 : : {
14 : 1 : FeeFrac p1{1000, 100}, p2{500, 300};
15 : 1 : FeeFrac sum{1500, 400};
16 : 1 : FeeFrac diff{500, -200};
17 : 1 : FeeFrac empty{0, 0};
18 : 1 : FeeFrac zero_fee{0, 1}; // zero-fee allowed
19 : :
20 [ + - ]: 1 : BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeDown(0), 0);
21 [ + - ]: 1 : BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeDown(1), 0);
22 [ + - ]: 1 : BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeDown(1000000), 0);
23 [ + - ]: 1 : BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeDown(0x7fffffff), 0);
24 [ + - ]: 1 : BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeUp(0), 0);
25 [ + - ]: 1 : BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeUp(1), 0);
26 [ + - ]: 1 : BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeUp(1000000), 0);
27 [ + - ]: 1 : BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeUp(0x7fffffff), 0);
28 : :
29 [ + - ]: 1 : BOOST_CHECK_EQUAL(p1.EvaluateFeeDown(0), 0);
30 [ + - ]: 1 : BOOST_CHECK_EQUAL(p1.EvaluateFeeDown(1), 10);
31 [ + - ]: 1 : BOOST_CHECK_EQUAL(p1.EvaluateFeeDown(100000000), 1000000000);
32 [ + - ]: 1 : BOOST_CHECK_EQUAL(p1.EvaluateFeeDown(0x7fffffff), int64_t(0x7fffffff) * 10);
33 [ + - ]: 1 : BOOST_CHECK_EQUAL(p1.EvaluateFeeUp(0), 0);
34 [ + - ]: 1 : BOOST_CHECK_EQUAL(p1.EvaluateFeeUp(1), 10);
35 [ + - ]: 1 : BOOST_CHECK_EQUAL(p1.EvaluateFeeUp(100000000), 1000000000);
36 [ + - ]: 1 : BOOST_CHECK_EQUAL(p1.EvaluateFeeUp(0x7fffffff), int64_t(0x7fffffff) * 10);
37 : :
38 : 1 : FeeFrac neg{-1001, 100};
39 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(0), 0);
40 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(1), -11);
41 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(2), -21);
42 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(3), -31);
43 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(100), -1001);
44 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(101), -1012);
45 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(100000000), -1001000000);
46 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(100000001), -1001000011);
47 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(0x7fffffff), -21496311307);
48 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(0), 0);
49 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(1), -10);
50 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(2), -20);
51 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(3), -30);
52 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(100), -1001);
53 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(101), -1011);
54 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(100000000), -1001000000);
55 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(100000001), -1001000010);
56 [ + - ]: 1 : BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(0x7fffffff), -21496311306);
57 : :
58 [ + - + - ]: 3 : BOOST_CHECK(empty == FeeFrac{}); // same as no-args
59 : :
60 [ + - ]: 2 : BOOST_CHECK(p1 == p1);
61 [ + - + - ]: 3 : BOOST_CHECK(p1 + p2 == sum);
62 [ + - + - ]: 3 : BOOST_CHECK(p1 - p2 == diff);
63 : :
64 : 1 : FeeFrac p3{2000, 200};
65 [ - + + - ]: 3 : BOOST_CHECK(p1 != p3); // feefracs only equal if both fee and size are same
66 [ - + + - ]: 3 : BOOST_CHECK(p2 != p3);
67 : :
68 : 1 : FeeFrac p4{3000, 300};
69 [ + - + - ]: 3 : BOOST_CHECK(p1 == p4-p3);
70 [ + - + - ]: 3 : BOOST_CHECK(p1 + p3 == p4);
71 : :
72 : : // Fee-rate comparison
73 [ + - ]: 2 : BOOST_CHECK(p1 > p2);
74 [ + - ]: 2 : BOOST_CHECK(p1 >= p2);
75 [ + - ]: 2 : BOOST_CHECK(p1 >= p4-p3);
76 [ + - ]: 2 : BOOST_CHECK(!(p1 >> p3)); // not strictly better
77 [ + - ]: 2 : BOOST_CHECK(p1 >> p2); // strictly greater feerate
78 : :
79 [ + - ]: 2 : BOOST_CHECK(p2 < p1);
80 [ + - ]: 2 : BOOST_CHECK(p2 <= p1);
81 [ + - ]: 2 : BOOST_CHECK(p1 <= p4-p3);
82 [ + - ]: 2 : BOOST_CHECK(!(p3 << p1)); // not strictly worse
83 [ + - + - ]: 2 : BOOST_CHECK(p2 << p1); // strictly lower feerate
84 : :
85 : : // "empty" comparisons
86 [ + - ]: 2 : BOOST_CHECK(!(p1 >> empty)); // << will always result in false
87 [ + - ]: 2 : BOOST_CHECK(!(p1 << empty));
88 [ + - ]: 2 : BOOST_CHECK(!(empty >> empty));
89 [ + - ]: 2 : BOOST_CHECK(!(empty << empty));
90 : :
91 : : // empty is always bigger than everything else
92 [ + - ]: 2 : BOOST_CHECK(empty > p1);
93 [ + - ]: 2 : BOOST_CHECK(empty > p2);
94 [ + - ]: 2 : BOOST_CHECK(empty > p3);
95 [ + - ]: 2 : BOOST_CHECK(empty >= p1);
96 [ + - ]: 2 : BOOST_CHECK(empty >= p2);
97 [ + - ]: 2 : BOOST_CHECK(empty >= p3);
98 : :
99 : : // check "max" values for comparison
100 : 1 : FeeFrac oversized_1{4611686000000, 4000000};
101 : 1 : FeeFrac oversized_2{184467440000000, 100000};
102 : :
103 [ + - ]: 2 : BOOST_CHECK(oversized_1 < oversized_2);
104 [ + - ]: 2 : BOOST_CHECK(oversized_1 <= oversized_2);
105 [ + - ]: 2 : BOOST_CHECK(oversized_1 << oversized_2);
106 [ - + + - ]: 3 : BOOST_CHECK(oversized_1 != oversized_2);
107 : :
108 [ + - ]: 1 : BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeDown(0), 0);
109 [ + - ]: 1 : BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeDown(1), 1152921);
110 [ + - ]: 1 : BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeDown(2), 2305843);
111 [ + - ]: 1 : BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeDown(1548031267), 1784758530396540);
112 [ + - ]: 1 : BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeUp(0), 0);
113 [ + - ]: 1 : BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeUp(1), 1152922);
114 [ + - ]: 1 : BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeUp(2), 2305843);
115 [ + - ]: 1 : BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeUp(1548031267), 1784758530396541);
116 : :
117 : : // Test cases on the threshold where FeeFrac::Evaluate start using Mul/Div.
118 [ + - ]: 1 : BOOST_CHECK_EQUAL(FeeFrac(0x1ffffffff, 123456789).EvaluateFeeDown(98765432), 6871947728);
119 [ + - ]: 1 : BOOST_CHECK_EQUAL(FeeFrac(0x200000000, 123456789).EvaluateFeeDown(98765432), 6871947729);
120 [ + - ]: 1 : BOOST_CHECK_EQUAL(FeeFrac(0x200000001, 123456789).EvaluateFeeDown(98765432), 6871947730);
121 [ + - ]: 1 : BOOST_CHECK_EQUAL(FeeFrac(0x1ffffffff, 123456789).EvaluateFeeUp(98765432), 6871947729);
122 [ + - ]: 1 : BOOST_CHECK_EQUAL(FeeFrac(0x200000000, 123456789).EvaluateFeeUp(98765432), 6871947730);
123 [ + - ]: 1 : BOOST_CHECK_EQUAL(FeeFrac(0x200000001, 123456789).EvaluateFeeUp(98765432), 6871947731);
124 : :
125 : : // Tests paths that use double arithmetic
126 : 1 : FeeFrac busted{(static_cast<int64_t>(INT32_MAX)) + 1, INT32_MAX};
127 [ + - ]: 2 : BOOST_CHECK(!(busted < busted));
128 : :
129 : 1 : FeeFrac max_fee{2100000000000000, INT32_MAX};
130 [ + - ]: 2 : BOOST_CHECK(!(max_fee < max_fee));
131 [ + - ]: 2 : BOOST_CHECK(!(max_fee > max_fee));
132 [ + - ]: 2 : BOOST_CHECK(max_fee <= max_fee);
133 [ + - ]: 2 : BOOST_CHECK(max_fee >= max_fee);
134 : :
135 [ + - ]: 1 : BOOST_CHECK_EQUAL(max_fee.EvaluateFeeDown(0), 0);
136 [ + - ]: 1 : BOOST_CHECK_EQUAL(max_fee.EvaluateFeeDown(1), 977888);
137 [ + - ]: 1 : BOOST_CHECK_EQUAL(max_fee.EvaluateFeeDown(2), 1955777);
138 [ + - ]: 1 : BOOST_CHECK_EQUAL(max_fee.EvaluateFeeDown(3), 2933666);
139 [ + - ]: 1 : BOOST_CHECK_EQUAL(max_fee.EvaluateFeeDown(1256796054), 1229006664189047);
140 [ + - ]: 1 : BOOST_CHECK_EQUAL(max_fee.EvaluateFeeDown(INT32_MAX), 2100000000000000);
141 [ + - ]: 1 : BOOST_CHECK_EQUAL(max_fee.EvaluateFeeUp(0), 0);
142 [ + - ]: 1 : BOOST_CHECK_EQUAL(max_fee.EvaluateFeeUp(1), 977889);
143 [ + - ]: 1 : BOOST_CHECK_EQUAL(max_fee.EvaluateFeeUp(2), 1955778);
144 [ + - ]: 1 : BOOST_CHECK_EQUAL(max_fee.EvaluateFeeUp(3), 2933667);
145 [ + - ]: 1 : BOOST_CHECK_EQUAL(max_fee.EvaluateFeeUp(1256796054), 1229006664189048);
146 [ + - ]: 1 : BOOST_CHECK_EQUAL(max_fee.EvaluateFeeUp(INT32_MAX), 2100000000000000);
147 : :
148 : 1 : FeeFrac max_fee2{1, 1};
149 [ + - ]: 2 : BOOST_CHECK(max_fee >= max_fee2);
150 : :
151 : : // Test for integer overflow issue (https://github.com/bitcoin/bitcoin/issues/32294)
152 [ + - ]: 1 : BOOST_CHECK_EQUAL((FeeFrac{0x7ffffffdfffffffb, 0x7ffffffd}.EvaluateFeeDown(0x7fffffff)), 0x7fffffffffffffff);
153 : 1 : }
154 : :
155 : : BOOST_AUTO_TEST_SUITE_END()
|