#include"Boss/Mod/ConnectFinderByDns.hpp" #include"Boss/Msg/Begin.hpp" #include"Boss/Msg/Init.hpp" #include"Boss/Msg/ProposeConnectCandidates.hpp" #include"Boss/Msg/Network.hpp" #include"Boss/Msg/SolicitConnectCandidates.hpp" #include"Boss/log.hpp" #include"Boss/random_engine.hpp" #include"DnsSeed/get.hpp" #include"Ev/Io.hpp" #include"S/Bus.hpp" #include"Util/make_unique.hpp" #include #include #include namespace { auto const all_dnsseeds = std::map> { {Boss::Msg::Network_Bitcoin, { "lseed.bitcoinstats.com" /*, "lseed.darosior.ninja" */ }} }; } namespace Boss { namespace Mod { class ConnectFinderByDns::Impl { private: S::Bus& bus; std::vector const* dnsseeds; void start() { bus.subscribe([this](Msg::Begin const& _) { return begin(); }); } Ev::Io begin() { return DnsSeed::can_get().then([this](std::string why) { if (why == "") return enable(); return Boss::log( bus, Warn , "DnsSeed: Cannot seed by DNS: %s" , why.c_str() ); }); } Ev::Io enable() { bus.subscribe([this](Msg::Init const& init) { auto it = all_dnsseeds.find(init.network); if ( it != all_dnsseeds.end() && it->second.size() != 0 ) { dnsseeds = &it->second; return Ev::lift(); } return Boss::log( bus, Warn , "DnsSeed: Cannot seed by DNS: %s" , "No known seeds for this network." ); }); bus.subscribe([this](Msg::SolicitConnectCandidates const& _) { return solicit(); }); return Ev::lift(); } Ev::Io solicit() { if (!dnsseeds || dnsseeds->size() == 0) return Ev::lift(); /* Pick a DNS seed, any DNS seed. */ auto& deck = *dnsseeds; auto dist = std::uniform_int_distribution (0, deck.size() - 1); auto i = dist(random_engine); auto& seed = deck[i]; return DnsSeed::get( seed ).then([this](std::vector ns) { return bus.raise(Msg::ProposeConnectCandidates{ std::move(ns) }); }); } public: explicit Impl( S::Bus& bus_ ) : bus(bus_) , dnsseeds(nullptr) { start(); } }; ConnectFinderByDns::ConnectFinderByDns ( S::Bus& bus ) : pimpl(Util::make_unique(bus)) { } ConnectFinderByDns::ConnectFinderByDns ( ConnectFinderByDns&& o ) : pimpl(std::move(o.pimpl)) { } ConnectFinderByDns::~ConnectFinderByDns() { } }}