Skip to content

discv5/discv5_crawler.hpp

Namespaces

Name
discv5

Classes

Name
struct discv5::CrawlerStats
Snapshot of crawler activity counters.
class discv5::discv5_crawler
Discv5 peer crawler: seed → FINDNODE loop → ValidatedPeer emission.

Source code

// Copyright 2025 GeniusVentures
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <atomic>
#include <chrono>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <discv5/discv5_error.hpp>
#include <discv5/discv5_types.hpp>

namespace discv5
{

// ---------------------------------------------------------------------------
// CrawlerStats
// ---------------------------------------------------------------------------

struct CrawlerStats
{
    size_t queued{};        
    size_t measured{};      
    size_t failed{};        
    size_t discovered{};    
    size_t invalid_enr{};   
    size_t wrong_chain{};   
    size_t no_eth_entry{};  
    size_t duplicates{};    
};

// ---------------------------------------------------------------------------
// discv5_crawler
// ---------------------------------------------------------------------------

class discv5_crawler
{
public:
    explicit discv5_crawler(const discv5Config& config) noexcept;

    ~discv5_crawler() = default;

    // Non-copyable, non-movable (owns the peer-set state).
    discv5_crawler(const discv5_crawler&)            = delete;
    discv5_crawler& operator=(const discv5_crawler&) = delete;
    discv5_crawler(discv5_crawler&&)                 = delete;
    discv5_crawler& operator=(discv5_crawler&&)      = delete;

    // -----------------------------------------------------------------------
    // Public interface
    // -----------------------------------------------------------------------

    void add_bootstrap(const EnrRecord& record) noexcept;

    void set_peer_discovered_callback(PeerDiscoveredCallback callback) noexcept;

    void set_error_callback(ErrorCallback callback) noexcept;

    VoidResult start() noexcept;

    VoidResult stop() noexcept;

    void process_found_peers(const std::vector<ValidatedPeer>& peers) noexcept;

    void ingest_discovered_peers(const std::vector<ValidatedPeer>& peers) noexcept;

    [[nodiscard]] CrawlerStats stats() const noexcept;

    [[nodiscard]] bool is_running() const noexcept;

    // -----------------------------------------------------------------------
    // Internal helpers (public for testing)
    // -----------------------------------------------------------------------

    void mark_measured(const NodeId& node_id) noexcept;

    void mark_failed(const NodeId& node_id) noexcept;

    std::optional<ValidatedPeer> dequeue_next() noexcept;

    [[nodiscard]] bool is_discovered(const NodeId& node_id) const noexcept;

private:
    // -----------------------------------------------------------------------
    // Helpers
    // -----------------------------------------------------------------------

    void enqueue_enr_uri(const std::string& uri) noexcept;

    void enqueue_enode_uri(const std::string& uri) noexcept;

    void emit_peer(const ValidatedPeer& peer) noexcept;

    static std::string node_key(const NodeId& id) noexcept;

    // -----------------------------------------------------------------------
    // State
    // -----------------------------------------------------------------------

    discv5Config config_;

    mutable std::mutex state_mutex_;

    std::vector<ValidatedPeer>            queued_peers_;

    std::unordered_set<std::string>       measured_ids_;

    std::unordered_set<std::string>       failed_ids_;

    std::unordered_set<std::string>       discovered_ids_;

    // Activity counters — mirrored from the set sizes for lock-free reads.
    std::atomic<size_t> stat_discovered_{};
    std::atomic<size_t> stat_invalid_enr_{};
    std::atomic<size_t> stat_wrong_chain_{};
    std::atomic<size_t> stat_no_eth_entry_{};
    std::atomic<size_t> stat_duplicates_{};

    std::atomic<bool>   running_{false};

    PeerDiscoveredCallback peer_callback_{};
    ErrorCallback          error_callback_{};
};

} // namespace discv5

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