LCOV - code coverage report
Current view: top level - src/util - tokenbucket.h (source / functions) Coverage Total Hit
Test: total_coverage.info Lines: 100.0 % 12 12
Test Date: 2026-08-05 07:16:25 Functions: 100.0 % 1 1
Branches: 60.0 % 80 48

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 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                 :             : #ifndef BITCOIN_UTIL_TOKENBUCKET_H
       6                 :             : #define BITCOIN_UTIL_TOKENBUCKET_H
       7                 :             : 
       8                 :             : #include <util/time.h>
       9                 :             : 
      10                 :             : namespace util {
      11                 :             : 
      12                 :             : /** A token bucket rate limiter.
      13                 :             :  *
      14                 :             :  * Tokens are added at a steady rate (m_rate per second) up to a capacity
      15                 :             :  * cap (m_cap). Tokens are removed by calling decrement(), which returns
      16                 :             :  * false if the bucket is emptied.
      17                 :             :  *
      18                 :             :  * Typical usage:
      19                 :             :  *   bucket.increment(now);   // refill based on elapsed time
      20                 :             :  *   if (bucket.value() >= 1) bucket.decrement(1);  // consume a token
      21                 :             :  */
      22                 :             : template <typename Clock>
      23                 :             : class TokenBucket
      24                 :             : {
      25                 :             : public:
      26                 :             :     using clock = Clock;
      27                 :             :     using time_point = typename Clock::time_point;
      28                 :             :     using duration = typename Clock::duration;
      29                 :             : 
      30                 :             :     const double m_rate{1};     //!< Tokens added per second
      31                 :             :     const double m_cap{0};      //!< Maximum token balance
      32                 :             : 
      33                 :             :     /** @param rate   Tokens added per second.
      34                 :             :      *  @param value  Initial token balance (clamped to cap).
      35                 :             :      *  @param cap    Maximum token balance. */
      36                 :        2512 :     TokenBucket(double rate, double value, double cap) : m_rate{rate}, m_cap{cap}, m_value{std::min(value, cap)} {}
      37                 :             : 
      38                 :             :     /** Refill tokens based on elapsed time since last call. No refill
      39                 :             :      *  occurs on the first call (establishes the time baseline). */
      40                 :      334960 :     void increment(const time_point& now)
      41                 :             :     {
      42         [ +  + ]:      334960 :         if (now > m_last_updated) {
      43   [ +  +  +  + ]:      333027 :             if (m_value < m_cap && m_last_updated > MIN_TIME) {
      44         [ +  + ]:      231700 :                 double inc = m_rate * std::chrono::duration_cast<SecondsDouble>(now - m_last_updated).count();
      45         [ +  + ]:      236697 :                 m_value = std::min(m_cap, m_value + inc);
      46                 :             :             }
      47                 :             :         }
      48                 :      334960 :         m_last_updated = now;
      49                 :      334960 :     }
      50                 :             : 
      51                 :             :     /** Consume n tokens. Returns false if the balance dropped to/below the given floor. */
      52                 :       46680 :     bool decrement(double n = 1.0, double floor = 0.0)
      53                 :             :     {
      54   [ +  -  +  -  :       46679 :         m_value -= n;
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
      55         [ +  + ]:       46669 :         return (m_value > floor);
      56                 :             :     }
      57                 :             : 
      58                 :             :     /** Current token balance. */
      59   [ -  +  -  +  :       97889 :     double value() const { return m_value; }
          +  -  -  +  +  
             -  +  +  +  
           + ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
      60                 :             : 
      61                 :             : private:
      62                 :             :     static constexpr time_point MIN_TIME{time_point::min()};
      63                 :             :     time_point m_last_updated{MIN_TIME};
      64                 :             :     double m_value{0};
      65                 :             : };
      66                 :             : 
      67                 :             : } // namespace util
      68                 :             : 
      69                 :             : #endif // BITCOIN_UTIL_TOKENBUCKET_H
        

Generated by: LCOV version 2.0-1