Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2024-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <util/feefrac.h>6#include <random.h>8#include <boost/test/unit_test.hpp>10BOOST_AUTO_TEST_SUITE(feefrac_tests)12BOOST_AUTO_TEST_CASE(feefrac_operators)13{14FeeFrac p1{1000, 100}, p2{500, 300};15FeeFrac sum{1500, 400};16FeeFrac diff{500, -200};17FeeFrac empty{0, 0};18FeeFrac zero_fee{0, 1}; // zero-fee allowed20BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeDown(0), 0);21BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeDown(1), 0);22BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeDown(1000000), 0);23BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeDown(0x7fffffff), 0);24BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeUp(0), 0);25BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeUp(1), 0);26BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeUp(1000000), 0);27BOOST_CHECK_EQUAL(zero_fee.EvaluateFeeUp(0x7fffffff), 0);29BOOST_CHECK_EQUAL(p1.EvaluateFeeDown(0), 0);30BOOST_CHECK_EQUAL(p1.EvaluateFeeDown(1), 10);31BOOST_CHECK_EQUAL(p1.EvaluateFeeDown(100000000), 1000000000);32BOOST_CHECK_EQUAL(p1.EvaluateFeeDown(0x7fffffff), int64_t(0x7fffffff) * 10);33BOOST_CHECK_EQUAL(p1.EvaluateFeeUp(0), 0);34BOOST_CHECK_EQUAL(p1.EvaluateFeeUp(1), 10);35BOOST_CHECK_EQUAL(p1.EvaluateFeeUp(100000000), 1000000000);36BOOST_CHECK_EQUAL(p1.EvaluateFeeUp(0x7fffffff), int64_t(0x7fffffff) * 10);38FeeFrac neg{-1001, 100};39BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(0), 0);40BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(1), -11);41BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(2), -21);42BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(3), -31);43BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(100), -1001);44BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(101), -1012);45BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(100000000), -1001000000);46BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(100000001), -1001000011);47BOOST_CHECK_EQUAL(neg.EvaluateFeeDown(0x7fffffff), -21496311307);48BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(0), 0);49BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(1), -10);50BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(2), -20);51BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(3), -30);52BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(100), -1001);53BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(101), -1011);54BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(100000000), -1001000000);55BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(100000001), -1001000010);56BOOST_CHECK_EQUAL(neg.EvaluateFeeUp(0x7fffffff), -21496311306);58BOOST_CHECK(empty == FeeFrac{}); // same as no-args60BOOST_CHECK(p1 == p1);61BOOST_CHECK(p1 + p2 == sum);62BOOST_CHECK(p1 - p2 == diff);64FeeFrac p3{2000, 200};65BOOST_CHECK(p1 != p3); // feefracs only equal if both fee and size are same66BOOST_CHECK(p2 != p3);68FeeFrac p4{3000, 300};69BOOST_CHECK(p1 == p4-p3);70BOOST_CHECK(p1 + p3 == p4);72// Fee-rate comparison73BOOST_CHECK(ByRatioNegSize{p1} > ByRatioNegSize{p2});74BOOST_CHECK(ByRatioNegSize{p1} >= ByRatioNegSize{p2});75BOOST_CHECK(ByRatioNegSize{p1} >= ByRatioNegSize{p4-p3});76BOOST_CHECK(!(ByRatio{p1} > ByRatio{p3})); // not strictly better77BOOST_CHECK(ByRatio{p1} > ByRatio{p2}); // strictly greater feerate79BOOST_CHECK(ByRatioNegSize{p2} < ByRatioNegSize{p1});80BOOST_CHECK(ByRatioNegSize{p2} <= ByRatioNegSize{p1});81BOOST_CHECK(ByRatioNegSize{p1} <= ByRatioNegSize{p4-p3});82BOOST_CHECK(!(ByRatio{p3} < ByRatio{p1})); // not strictly worse83BOOST_CHECK(ByRatio{p2} < ByRatio{p1}); // strictly lower feerate85// "empty" comparisons86BOOST_CHECK(!(ByRatio{p1} > ByRatio{empty})); // << will always result in false87BOOST_CHECK(!(ByRatio{p1} < ByRatio{empty}));88BOOST_CHECK(!(ByRatio{empty} > ByRatio{empty}));89BOOST_CHECK(!(ByRatio{empty} < ByRatio{empty}));91// empty is always bigger than everything else92BOOST_CHECK(ByRatioNegSize{empty} > ByRatioNegSize{p1});93BOOST_CHECK(ByRatioNegSize{empty} > ByRatioNegSize{p2});94BOOST_CHECK(ByRatioNegSize{empty} > ByRatioNegSize{p3});95BOOST_CHECK(ByRatioNegSize{empty} >= ByRatioNegSize{p1});96BOOST_CHECK(ByRatioNegSize{empty} >= ByRatioNegSize{p2});97BOOST_CHECK(ByRatioNegSize{empty} >= ByRatioNegSize{p3});99// check "max" values for comparison100FeeFrac oversized_1{4611686000000, 4000000};101FeeFrac oversized_2{184467440000000, 100000};103BOOST_CHECK(ByRatioNegSize{oversized_1} < ByRatioNegSize{oversized_2});104BOOST_CHECK(ByRatioNegSize{oversized_1} <= ByRatioNegSize{oversized_2});105BOOST_CHECK(ByRatio{oversized_1} < ByRatio{oversized_2});106BOOST_CHECK(ByRatioNegSize{oversized_1} != ByRatioNegSize{oversized_2});108BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeDown(0), 0);109BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeDown(1), 1152921);110BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeDown(2), 2305843);111BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeDown(1548031267), 1784758530396540);112BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeUp(0), 0);113BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeUp(1), 1152922);114BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeUp(2), 2305843);115BOOST_CHECK_EQUAL(oversized_1.EvaluateFeeUp(1548031267), 1784758530396541);117// Test cases on the threshold where FeeFrac::Evaluate start using Mul/Div.118BOOST_CHECK_EQUAL(FeeFrac(0x1ffffffff, 123456789).EvaluateFeeDown(98765432), 6871947728);119BOOST_CHECK_EQUAL(FeeFrac(0x200000000, 123456789).EvaluateFeeDown(98765432), 6871947729);120BOOST_CHECK_EQUAL(FeeFrac(0x200000001, 123456789).EvaluateFeeDown(98765432), 6871947730);121BOOST_CHECK_EQUAL(FeeFrac(0x1ffffffff, 123456789).EvaluateFeeUp(98765432), 6871947729);122BOOST_CHECK_EQUAL(FeeFrac(0x200000000, 123456789).EvaluateFeeUp(98765432), 6871947730);123BOOST_CHECK_EQUAL(FeeFrac(0x200000001, 123456789).EvaluateFeeUp(98765432), 6871947731);125// Tests paths that use double arithmetic126FeeFrac busted{(static_cast<int64_t>(INT32_MAX)) + 1, INT32_MAX};127BOOST_CHECK(!(ByRatioNegSize{busted} < ByRatioNegSize{busted}));129FeeFrac max_fee{2100000000000000, INT32_MAX};130BOOST_CHECK(!(ByRatioNegSize{max_fee} < ByRatioNegSize{max_fee}));131BOOST_CHECK(!(ByRatioNegSize{max_fee} > ByRatioNegSize{max_fee}));132BOOST_CHECK(ByRatioNegSize{max_fee} <= ByRatioNegSize{max_fee});133BOOST_CHECK(ByRatioNegSize{max_fee} >= ByRatioNegSize{max_fee});135BOOST_CHECK_EQUAL(max_fee.EvaluateFeeDown(0), 0);136BOOST_CHECK_EQUAL(max_fee.EvaluateFeeDown(1), 977888);137BOOST_CHECK_EQUAL(max_fee.EvaluateFeeDown(2), 1955777);138BOOST_CHECK_EQUAL(max_fee.EvaluateFeeDown(3), 2933666);139BOOST_CHECK_EQUAL(max_fee.EvaluateFeeDown(1256796054), 1229006664189047);140BOOST_CHECK_EQUAL(max_fee.EvaluateFeeDown(INT32_MAX), 2100000000000000);141BOOST_CHECK_EQUAL(max_fee.EvaluateFeeUp(0), 0);142BOOST_CHECK_EQUAL(max_fee.EvaluateFeeUp(1), 977889);143BOOST_CHECK_EQUAL(max_fee.EvaluateFeeUp(2), 1955778);144BOOST_CHECK_EQUAL(max_fee.EvaluateFeeUp(3), 2933667);145BOOST_CHECK_EQUAL(max_fee.EvaluateFeeUp(1256796054), 1229006664189048);146BOOST_CHECK_EQUAL(max_fee.EvaluateFeeUp(INT32_MAX), 2100000000000000);148FeeFrac max_fee2{1, 1};149BOOST_CHECK(ByRatioNegSize{max_fee} >= ByRatioNegSize{max_fee2});151// Test for integer overflow issue (https://github.com/bitcoin/bitcoin/issues/32294)152BOOST_CHECK_EQUAL((FeeFrac{0x7ffffffdfffffffb, 0x7ffffffd}.EvaluateFeeDown(0x7fffffff)), 0x7fffffffffffffff);153}155BOOST_AUTO_TEST_SUITE_END()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.