diff --git a/include/llarp.hpp b/include/llarp.hpp index e6a22c520..50561db9d 100644 --- a/include/llarp.hpp +++ b/include/llarp.hpp @@ -15,13 +15,6 @@ struct llarp_ev_loop; -#ifdef LOKINET_HIVE -namespace tooling -{ - struct RouterHive; -} // namespace tooling -#endif - namespace llarp { class Logic; @@ -97,11 +90,6 @@ namespace llarp llarp_ev_loop_ptr __netloop, std::shared_ptr logic); -#ifdef LOKINET_HIVE - void - InjectHive(tooling::RouterHive* hive); -#endif - private: void SigINT(); diff --git a/llarp/context.cpp b/llarp/context.cpp index 9457235c2..15d0dc38b 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -204,14 +204,6 @@ namespace llarp llarp::LogDebug("free logic"); logic.reset(); } - -#ifdef LOKINET_HIVE - void - Context::InjectHive(tooling::RouterHive* hive) - { - router->hive = hive; - } -#endif } // namespace llarp extern "C" diff --git a/llarp/router/abstractrouter.hpp b/llarp/router/abstractrouter.hpp index f53c2917a..0ee28aa75 100644 --- a/llarp/router/abstractrouter.hpp +++ b/llarp/router/abstractrouter.hpp @@ -14,7 +14,7 @@ #include #ifdef LOKINET_HIVE -#include "tooling/router_hive.hpp" +#include "tooling/router_event.hpp" #endif struct llarp_buffer_t; @@ -292,14 +292,23 @@ namespace llarp virtual void GossipRCIfNeeded(const RouterContact rc) = 0; + /// Templated convenience function to generate a RouterHive event and + /// delegate to non-templated (and overridable) function for handling. template void NotifyRouterEvent([[maybe_unused]] Params&&... args) const { -#ifdef LOKINET_HIVE - hive->NotifyEvent(std::make_unique(std::forward(args)...)); -#endif + // TODO: no-op when appropriate + auto event = std::make_unique(args...); + HandleRouterEvent(std::move(event)); } + + protected: + /// Virtual function to handle RouterEvent. HiveRouter overrides this in + /// order to inject the event. The default implementation in Router simply + /// logs it. + virtual void + HandleRouterEvent(tooling::RouterEventPtr event) const = 0; }; } // namespace llarp diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 7da06ccbc..a09813082 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -1240,4 +1240,11 @@ namespace llarp LogDebug("Message failed sending to ", remote); } } + + void + Router::HandleRouterEvent(tooling::RouterEventPtr event) const + { + LogDebug(event->ToString()); + } + } // namespace llarp diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index 8d49d8ddf..e701711bb 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -530,6 +530,9 @@ namespace llarp MessageSent(const RouterID& remote, SendStatus status); protected: + virtual void + HandleRouterEvent(tooling::RouterEventPtr event) const override; + virtual bool disableGossipingRC_TestingOnly() { diff --git a/llarp/tooling/hive_context.cpp b/llarp/tooling/hive_context.cpp index 94b9ef770..4f1d169e2 100644 --- a/llarp/tooling/hive_context.cpp +++ b/llarp/tooling/hive_context.cpp @@ -4,13 +4,31 @@ namespace tooling { + HiveContext::HiveContext(RouterHive* hive) : m_hive(hive) + { + } + std::unique_ptr HiveContext::makeRouter( std::shared_ptr worker, llarp_ev_loop_ptr netloop, std::shared_ptr logic) { - return std::make_unique(worker, netloop, logic); + return std::make_unique(worker, netloop, logic, m_hive); + } + + HiveRouter* + HiveContext::getRouterAsHiveRouter() + { + if (not router) + return nullptr; + + HiveRouter* hiveRouter = dynamic_cast(router.get()); + + if (hiveRouter == nullptr) + throw std::runtime_error("HiveContext has a router not of type HiveRouter"); + + return hiveRouter; } } // namespace tooling diff --git a/llarp/tooling/hive_context.hpp b/llarp/tooling/hive_context.hpp index 8851b3835..61ecd32bb 100644 --- a/llarp/tooling/hive_context.hpp +++ b/llarp/tooling/hive_context.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace tooling { @@ -8,11 +9,23 @@ namespace tooling /// perform custom behavior which might be undesirable in production code. struct HiveContext : public llarp::Context { + HiveContext(RouterHive* hive); + std::unique_ptr makeRouter( std::shared_ptr worker, llarp_ev_loop_ptr netloop, std::shared_ptr logic) override; + + /// Get this context's router as a HiveRouter. + /// + /// Returns nullptr if there is no router or throws an exception if the + /// router is somehow not an instance of HiveRouter. + HiveRouter* + getRouterAsHiveRouter(); + + protected: + RouterHive* m_hive = nullptr; }; } // namespace tooling diff --git a/llarp/tooling/hive_router.cpp b/llarp/tooling/hive_router.cpp index 55bae5cf8..744f76914 100644 --- a/llarp/tooling/hive_router.cpp +++ b/llarp/tooling/hive_router.cpp @@ -1,12 +1,15 @@ #include +#include + namespace tooling { HiveRouter::HiveRouter( std::shared_ptr worker, llarp_ev_loop_ptr netloop, - std::shared_ptr logic) - : Router(worker, netloop, logic) + std::shared_ptr logic, + RouterHive* hive) + : Router(worker, netloop, logic), m_hive(hive) { } @@ -28,4 +31,10 @@ namespace tooling m_disableGossiping = true; } + void + HiveRouter::HandleRouterEvent(RouterEventPtr event) const + { + m_hive->NotifyEvent(std::move(event)); + } + } // namespace tooling diff --git a/llarp/tooling/hive_router.hpp b/llarp/tooling/hive_router.hpp index 743588550..4c3ed5076 100644 --- a/llarp/tooling/hive_router.hpp +++ b/llarp/tooling/hive_router.hpp @@ -13,7 +13,8 @@ namespace tooling HiveRouter( std::shared_ptr worker, llarp_ev_loop_ptr netloop, - std::shared_ptr logic); + std::shared_ptr logic, + RouterHive* hive); virtual ~HiveRouter() = default; @@ -29,6 +30,10 @@ namespace tooling protected: bool m_disableGossiping = false; + RouterHive* m_hive = nullptr; + + virtual void + HandleRouterEvent(RouterEventPtr event) const override; }; } // namespace tooling diff --git a/llarp/tooling/router_hive.cpp b/llarp/tooling/router_hive.cpp index 3fca59d1f..f8f9d0a28 100644 --- a/llarp/tooling/router_hive.cpp +++ b/llarp/tooling/router_hive.cpp @@ -14,17 +14,19 @@ using namespace std::chrono_literals; namespace tooling { void - RouterHive::AddRouter(const std::shared_ptr& config, bool isRelay) + RouterHive::AddRouter(const std::shared_ptr& config, bool isRouter) { - auto& container = (isRelay ? relays : clients); + auto& container = (isRouter ? relays : clients); + + llarp::RuntimeOptions opts; + opts.isRouter = isRouter; - Context_ptr context = std::make_shared(); + Context_ptr context = std::make_shared(this); context->config = std::make_unique(*config.get()); - context->Configure(isRelay, {}); - context->Setup(isRelay); + context->Configure(opts, {}); + context->Setup(opts); auto routerId = llarp::RouterID(context->router->pubkey()); - context->InjectHive(this); container[routerId] = context; std::cout << "Generated router with ID " << routerId << std::endl; } @@ -150,7 +152,7 @@ namespace tooling LogicCall(ctx->logic, [visit, ctx]() { visit(ctx); }); } - llarp::AbstractRouter* + HiveRouter* RouterHive::GetRelay(const llarp::RouterID& id, bool needMutexLock) { auto guard = @@ -161,7 +163,7 @@ namespace tooling return nullptr; auto ctx = itr->second; - return ctx->router.get(); + return ctx->getRouterAsHiveRouter(); } std::vector @@ -218,34 +220,7 @@ namespace tooling } void - RouterHive::ForEachRelayRouter(std::function visit) - { - std::lock_guard guard{routerMutex}; - for (auto [routerId, ctx] : relays) - { - visit(GetRelay(routerId, false)); - } - } - - void - RouterHive::ForEachClientRouter(std::function visit) - { - std::lock_guard guard{routerMutex}; - for (auto [routerId, ctx] : clients) - { - visit(GetRelay(routerId, false)); - } - } - - void - RouterHive::ForEachRouterRouter(std::function visit) - { - ForEachRelayRouter(visit); - ForEachClientRouter(visit); - } - - void - RouterHive::ForEachRelayContext(std::function visit) + RouterHive::ForEachRelay(std::function visit) { for (auto [routerId, ctx] : relays) { @@ -254,7 +229,7 @@ namespace tooling } void - RouterHive::ForEachClientContext(std::function visit) + RouterHive::ForEachClient(std::function visit) { for (auto [routerId, ctx] : clients) { @@ -264,10 +239,10 @@ namespace tooling /// safely visit every router context void - RouterHive::ForEachRouterContext(std::function visit) + RouterHive::ForEachRouter(std::function visit) { - ForEachRelayContext(visit); - ForEachClientContext(visit); + ForEachRelay(visit); + ForEachClient(visit); } } // namespace tooling diff --git a/llarp/tooling/router_hive.hpp b/llarp/tooling/router_hive.hpp index 05590cb36..8cb8fa37b 100644 --- a/llarp/tooling/router_hive.hpp +++ b/llarp/tooling/router_hive.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -16,7 +17,6 @@ struct llarp_main; namespace llarp { struct Context; - struct AbstractRouter; } // namespace llarp namespace tooling @@ -25,7 +25,7 @@ namespace tooling struct RouterHive { - using Context_ptr = std::shared_ptr; + using Context_ptr = std::shared_ptr; private: void @@ -65,22 +65,15 @@ namespace tooling std::deque GetAllEvents(); - // functions to safely visit each relay and/or client's AbstractRouter or Context + // functions to safely visit each relay and/or client's HiveContext void - ForEachRelayRouter(std::function visit); + ForEachRelay(std::function visit); void - ForEachClientRouter(std::function visit); + ForEachClient(std::function visit); void - ForEachRouterRouter(std::function visit); + ForEachRouter(std::function visit); - void - ForEachRelayContext(std::function visit); - void - ForEachClientContext(std::function visit); - void - ForEachRouterContext(std::function visit); - - llarp::AbstractRouter* + HiveRouter* GetRelay(const llarp::RouterID& id, bool needMutexLock = true); std::vector diff --git a/pybind/llarp/context.cpp b/pybind/llarp/context.cpp index 2c60098fe..1ed3aa2de 100644 --- a/pybind/llarp/context.cpp +++ b/pybind/llarp/context.cpp @@ -1,5 +1,6 @@ #include "common.hpp" #include +#include #include #include "llarp/handlers/pyhandler.hpp" namespace llarp @@ -9,7 +10,11 @@ namespace llarp { using Context_ptr = std::shared_ptr; py::class_(mod, "Context") - .def("Setup", [](Context_ptr self, bool isRelay) { self->Setup(isRelay); }) + .def( + "Setup", + [](Context_ptr self, bool isRouter) { + self->Setup({false, false, isRouter}); + }) .def("Run", [](Context_ptr self) -> int { return self->Run(RuntimeOptions{}); }) .def("Stop", [](Context_ptr self) { self->CloseAsync(); }) .def("IsUp", &Context::IsUp) diff --git a/pybind/llarp/tooling/router_hive.cpp b/pybind/llarp/tooling/router_hive.cpp index 098d46e9b..86156f5dc 100644 --- a/pybind/llarp/tooling/router_hive.cpp +++ b/pybind/llarp/tooling/router_hive.cpp @@ -19,12 +19,9 @@ namespace tooling .def("StartRelays", &RouterHive::StartRelays) .def("StartClients", &RouterHive::StartClients) .def("StopAll", &RouterHive::StopRouters) - .def("ForEachRelayContext", &RouterHive::ForEachRelayContext) - .def("ForEachClientContext", &RouterHive::ForEachClientContext) - .def("ForEachRouterContext", &RouterHive::ForEachRouterContext) - .def("ForEachRelayRouter", &RouterHive::ForEachRelayRouter) - .def("ForEachClientRouter", &RouterHive::ForEachClientRouter) - .def("ForEachRouterRouter", &RouterHive::ForEachRouterRouter) + .def("ForEachRelay", &RouterHive::ForEachRelay) + .def("ForEachClient", &RouterHive::ForEachClient) + .def("ForEachRouter", &RouterHive::ForEachRouter) .def("GetNextEvent", &RouterHive::GetNextEvent) .def("GetAllEvents", &RouterHive::GetAllEvents) .def("RelayConnectedRelays", &RouterHive::RelayConnectedRelays) diff --git a/test/hive/test_peer_stats.py b/test/hive/test_peer_stats.py index 4d0530ed0..48cbebd52 100644 --- a/test/hive/test_peer_stats.py +++ b/test/hive/test_peer_stats.py @@ -87,7 +87,7 @@ def tally_rc_received_for_peer(hive, routerId): numFound += stats.numDistinctRCsReceived - hive.ForEachRelayRouter(visit) + hive.ForEachRelay(visit) return numFound;