* Network selector * Make sure network option is checked before working path is called (migration). Also remove bool assignment from error. * Formatting * Fix merge error * Use network_params for RPC port config (rebase) * Formatting * Rebase * Rebase (debug_opencl, merge fix) * Rebase fix * post-rebase update
131 lines
5.6 KiB
C++
131 lines
5.6 KiB
C++
#pragma once
|
|
|
|
#include <boost/asio/ip/address.hpp>
|
|
#include <boost/multi_index/hashed_index.hpp>
|
|
#include <boost/multi_index/member.hpp>
|
|
#include <boost/multi_index/ordered_index.hpp>
|
|
#include <boost/multi_index/random_access_index.hpp>
|
|
#include <boost/multi_index_container.hpp>
|
|
#include <boost/optional.hpp>
|
|
#include <chrono>
|
|
#include <deque>
|
|
#include <mutex>
|
|
#include <nano/lib/config.hpp>
|
|
#include <nano/lib/numbers.hpp>
|
|
#include <nano/node/common.hpp>
|
|
#include <unordered_set>
|
|
#include <vector>
|
|
|
|
namespace nano
|
|
{
|
|
nano::endpoint map_endpoint_to_v6 (nano::endpoint const &);
|
|
|
|
/** Multi-index helper */
|
|
class peer_by_ip_addr
|
|
{
|
|
};
|
|
|
|
/** Multi-index helper */
|
|
class peer_attempt
|
|
{
|
|
public:
|
|
nano::endpoint endpoint;
|
|
std::chrono::steady_clock::time_point last_attempt;
|
|
};
|
|
|
|
/** Node handshake cookie */
|
|
class syn_cookie_info
|
|
{
|
|
public:
|
|
nano::uint256_union cookie;
|
|
std::chrono::steady_clock::time_point created_at;
|
|
};
|
|
|
|
/** Collects peer contact information */
|
|
class peer_information
|
|
{
|
|
public:
|
|
peer_information (nano::endpoint const &, unsigned, boost::optional<nano::account> = boost::none);
|
|
peer_information (nano::endpoint const &, std::chrono::steady_clock::time_point const &, std::chrono::steady_clock::time_point const &);
|
|
nano::endpoint endpoint;
|
|
boost::asio::ip::address ip_address;
|
|
std::chrono::steady_clock::time_point last_contact;
|
|
std::chrono::steady_clock::time_point last_attempt;
|
|
std::chrono::steady_clock::time_point last_bootstrap_attempt{ std::chrono::steady_clock::time_point () };
|
|
unsigned network_version{ nano::protocol_version };
|
|
boost::optional<nano::account> node_id;
|
|
bool operator< (nano::peer_information const &) const;
|
|
};
|
|
|
|
/** Manages a set of disovered peers */
|
|
class peer_container
|
|
{
|
|
public:
|
|
peer_container (nano::endpoint const &);
|
|
// We were contacted by endpoint, update peers
|
|
// Returns true if a Node ID handshake should begin
|
|
bool contacted (nano::endpoint const &, unsigned);
|
|
// Unassigned, reserved, self
|
|
bool not_a_peer (nano::endpoint const &, bool = false);
|
|
// Returns true if peer was already known
|
|
bool known_peer (nano::endpoint const &);
|
|
// Notify of peer we received from
|
|
bool insert (nano::endpoint const &, unsigned, bool = false, boost::optional<nano::account> = boost::none);
|
|
std::unordered_set<nano::endpoint> random_set (size_t);
|
|
void random_fill (std::array<nano::endpoint, 8> &);
|
|
// List of all peers
|
|
std::deque<nano::endpoint> list (size_t count_a = std::numeric_limits<size_t>::max ());
|
|
std::vector<peer_information> list_vector (size_t);
|
|
// A list of random peers sized for the configured rebroadcast fanout
|
|
std::deque<nano::endpoint> list_fanout ();
|
|
// Returns a list of probable reps and their weight
|
|
std::vector<peer_information> list_probable_rep_weights ();
|
|
// Get the next peer for attempting bootstrap
|
|
nano::endpoint bootstrap_peer ();
|
|
// Purge any peer where last_contact < time_point and return what was left
|
|
std::vector<nano::peer_information> purge_list (std::chrono::steady_clock::time_point const &);
|
|
void purge_syn_cookies (std::chrono::steady_clock::time_point const &);
|
|
// Should we reach out to this endpoint with a keepalive message
|
|
bool reachout (nano::endpoint const &, bool = false);
|
|
// Returns boost::none if the IP is rate capped on syn cookie requests,
|
|
// or if the endpoint already has a syn cookie query
|
|
boost::optional<nano::uint256_union> assign_syn_cookie (nano::endpoint const &);
|
|
// Returns false if valid, true if invalid (true on error convention)
|
|
// Also removes the syn cookie from the store if valid
|
|
bool validate_syn_cookie (nano::endpoint const &, nano::account, nano::signature);
|
|
size_t size ();
|
|
size_t size_sqrt ();
|
|
bool empty ();
|
|
nano::network_params network_params;
|
|
std::mutex mutex;
|
|
nano::endpoint self;
|
|
boost::multi_index_container<
|
|
peer_information,
|
|
boost::multi_index::indexed_by<
|
|
boost::multi_index::hashed_unique<boost::multi_index::member<peer_information, nano::endpoint, &peer_information::endpoint>>,
|
|
boost::multi_index::ordered_non_unique<boost::multi_index::member<peer_information, std::chrono::steady_clock::time_point, &peer_information::last_contact>>,
|
|
boost::multi_index::ordered_non_unique<boost::multi_index::member<peer_information, std::chrono::steady_clock::time_point, &peer_information::last_attempt>, std::greater<std::chrono::steady_clock::time_point>>,
|
|
boost::multi_index::random_access<>,
|
|
boost::multi_index::ordered_non_unique<boost::multi_index::member<peer_information, std::chrono::steady_clock::time_point, &peer_information::last_bootstrap_attempt>>,
|
|
boost::multi_index::ordered_non_unique<boost::multi_index::tag<peer_by_ip_addr>, boost::multi_index::member<peer_information, boost::asio::ip::address, &peer_information::ip_address>>>>
|
|
peers;
|
|
boost::multi_index_container<
|
|
peer_attempt,
|
|
boost::multi_index::indexed_by<
|
|
boost::multi_index::hashed_unique<boost::multi_index::member<peer_attempt, nano::endpoint, &peer_attempt::endpoint>>,
|
|
boost::multi_index::ordered_non_unique<boost::multi_index::member<peer_attempt, std::chrono::steady_clock::time_point, &peer_attempt::last_attempt>>>>
|
|
attempts;
|
|
std::mutex syn_cookie_mutex;
|
|
std::unordered_map<nano::endpoint, syn_cookie_info> syn_cookies;
|
|
std::unordered_map<boost::asio::ip::address, unsigned> syn_cookies_per_ip;
|
|
// Called when a new peer is observed
|
|
std::function<void(nano::endpoint const &)> peer_observer;
|
|
std::function<void()> disconnect_observer;
|
|
// Number of peers to crawl for being a rep every period
|
|
static size_t constexpr peers_per_crawl = 8;
|
|
// Maximum number of peers per IP
|
|
static size_t constexpr max_peers_per_ip = 10;
|
|
};
|
|
|
|
std::unique_ptr<seq_con_info_component> collect_seq_con_info (peer_container & peer_container, const std::string & name);
|
|
}
|