Skip to content

discv4/dial_history.hpp

Namespaces

Name
discv4

Classes

Name
class discv4::DialHistory
Tracks recently-dialed peers and suppresses retry attempts until a configurable cooldown expires.

Source code

#pragma once

#include <array>
#include <chrono>
#include <discv4/discv4_constants.hpp>
#include <string>
#include <unordered_map>

namespace discv4 {

class DialHistory {
public:
    using Clock     = std::chrono::steady_clock;
    using TimePoint = Clock::time_point;
    using Duration  = Clock::duration;

    static constexpr Duration kDefaultExpiry = kDefaultDialHistoryExpiry;

    explicit DialHistory(Duration expiry = kDefaultExpiry) : expiry_(expiry) {}

    void add(const std::array<uint8_t, 64>& node_id)
    {
        entries_[key(node_id)] = Clock::now() + expiry_;
    }

    bool contains(const std::array<uint8_t, 64>& node_id) const
    {
        auto it = entries_.find(key(node_id));
        if (it == entries_.end()) { return false; }
        return Clock::now() < it->second;
    }

    void expire()
    {
        const auto now = Clock::now();
        for (auto it = entries_.begin(); it != entries_.end(); ) {
            if (now >= it->second) {
                it = entries_.erase(it);
            } else {
                ++it;
            }
        }
    }

    std::size_t size() const { return entries_.size(); }

private:
    Duration expiry_;
    mutable std::unordered_map<std::string, TimePoint> entries_;

    static std::string key(const std::array<uint8_t, 64>& node_id)
    {
        return std::string(reinterpret_cast<const char*>(node_id.data()), node_id.size());
    }
};

} // namespace discv4

Updated on 2026-04-13 at 23:22:46 -0700