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.
2001BOOST_AUTO_TEST_CASE(token_bucket_drain_and_refill)2002{2003util::TokenBucket<NodeClock> b(/*rate=*/10, /*value=*/20, /*cap=*/100);2004b.decrement(20); // drain to 02005BOOST_CHECK_EQUAL(b.value(), 0);2007b.increment(NodeClock::time_point{1s});2008b.increment(NodeClock::time_point{4s}); // +302009BOOST_CHECK_EQUAL(b.value(), 30);2010}2013BOOST_AUTO_TEST_CASE(token_bucket_first_increment_at_epoch)2014{2015// The first increment establishes the baseline (no refill) even when it2016// lands exactly on the clock epoch; later increments then refill normally.2017util::TokenBucket<NodeClock> b(/*rate=*/100, /*value=*/0, /*cap=*/1000);2018b.increment(NodeClock::time_point{0s});2019BOOST_CHECK_EQUAL(b.value(), 0);2020b.increment(NodeClock::time_point{5s});2021BOOST_CHECK_EQUAL(b.value(), 500); // 100/s * 5s2022}2024BOOST_AUTO_TEST_CASE(token_bucket_at_cap_advances_baseline)2025{2026util::TokenBucket<NodeClock> b(/*rate=*/10, /*value=*/100, /*cap=*/100);2027BOOST_CHECK_EQUAL(b.value(), 100); // already at cap2028b.increment(NodeClock::time_point{1s}); // baseline established at 1s2029b.increment(NodeClock::time_point{100s}); // 99s spent at the cap; baseline -> 100s2030BOOST_CHECK_EQUAL(b.value(), 100);2032b.decrement(100); // drain to 02033BOOST_CHECK_EQUAL(b.value(), 0);2035// refill doesn't "bank" the extra 99s we were at cap2036b.increment(NodeClock::time_point{101s});2037BOOST_CHECK_EQUAL(b.value(), 10);2039// And when real time genuinely elapses, a single increment refills straight2040// back to the cap immediately.2041b.increment(NodeClock::time_point{200s}); // 99s elapsed -> +990, clamped to cap2042BOOST_CHECK_EQUAL(b.value(), 100);2043}2045BOOST_AUTO_TEST_CASE(token_bucket_fractional_refill)2046{2047// Sub-second elapsed time accumulates fractional tokens via double math.2048util::TokenBucket<NodeClock> b(/*rate=*/10, /*value=*/0, /*cap=*/100);2049b.increment(NodeClock::time_point{1s});2050b.increment(NodeClock::time_point{1250ms}); // 10/s * 0.25s = 2.52051BOOST_CHECK_EQUAL(b.value(), 2.5);2052}2054BOOST_AUTO_TEST_CASE(token_bucket_refill_from_debt)2055{2056// Refilling from a negative (debt) balance accrues normally and still2057// clamps to the cap rather than to debt + increment.2058util::TokenBucket<NodeClock> b(/*rate=*/10, /*value=*/0, /*cap=*/100);2059BOOST_CHECK(!b.decrement(50)); // -> -50, below floor 02060BOOST_CHECK_EQUAL(b.value(), -50);2061b.increment(NodeClock::time_point{1s}); // baseline2062b.increment(NodeClock::time_point{4s}); // +30 -> -202063BOOST_CHECK_EQUAL(b.value(), -20);2064b.increment(NodeClock::time_point{100s}); // +960 but clamped to cap2065BOOST_CHECK_EQUAL(b.value(), 100);2066}2068BOOST_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.