#pragma once #include #include #include #include #include #include namespace llarp { struct AbstractRouter; namespace rpc { using LMQ_ptr = std::shared_ptr; /// The LokidRpcClient uses loki-mq to talk to make API requests to lokid. struct LokidRpcClient : public std::enable_shared_from_this { explicit LokidRpcClient(LMQ_ptr lmq, std::weak_ptr r); /// Connect to lokid async void ConnectAsync(oxenmq::address url); /// blocking request identity key from lokid /// throws on failure SecretKey ObtainIdentityKey(); /// get what the current block height is according to oxend uint64_t BlockHeight() const { return m_BlockHeight; } void LookupLNSNameHash( dht::Key_t namehash, std::function)> resultHandler); /// inform that if connected to a router successfully void InformConnection(RouterID router, bool success); void StartPings(); private: /// do a lmq command on the current connection void Command(std::string_view cmd); /// triggers a service node list refresh from oxend; thread-safe and will do nothing if an /// update is already in progress. void UpdateServiceNodeList(); template void Request(std::string_view cmd, HandlerFunc_t func, const Args_t& args) { m_lokiMQ->request(*m_Connection, std::move(cmd), std::move(func), args); } template void Request(std::string_view cmd, HandlerFunc_t func) { m_lokiMQ->request(*m_Connection, std::move(cmd), std::move(func)); } // Handles a service node list update; takes the "service_node_states" object of an oxend // "get_service_nodes" rpc request. void HandleNewServiceNodeList(const nlohmann::json& json); // Handles request from lokid for peer stats on a specific peer void HandleGetPeerStats(oxenmq::Message& msg); // Handles notification of a new block void HandleNewBlock(oxenmq::Message& msg); std::optional m_Connection; LMQ_ptr m_lokiMQ; std::weak_ptr m_Router; std::atomic m_UpdatingList; std::string m_LastUpdateHash; std::unordered_map m_KeyMap; uint64_t m_BlockHeight; }; } // namespace rpc } // namespace llarp