Skip to content

Commit

Permalink
Convert ListpeerResult to use ConstructedListpeers
Browse files Browse the repository at this point in the history
Construct a "compatibility struct" to convert `listpeerchannels`
output into legacy `listpeers` format.

Tests written using the legacy listpeers format can use the
`convert_legacy_listpeers` utility to construct a compatibility
struct.

The test_peerjudge_datagatherer malformed test needed to be malformed
differently to achieve the desired effect.
  • Loading branch information
ksedgwic committed Apr 29, 2024
1 parent 1e2f6f7 commit 1cfd860
Show file tree
Hide file tree
Showing 17 changed files with 230 additions and 86 deletions.
47 changes: 47 additions & 0 deletions Boss/Mod/ConstructedListpeers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include"Boss/Mod/ConstructedListpeers.hpp"
#include"Jsmn/Object.hpp"
#include<sstream>

namespace Boss { namespace Mod {

/*
* IMPORTANT - the msg is no longer directly obtained from
* `listpeers` but rather is constructed by "convolving" the value
* from `listpeerchannels`. Specifically, the top level `peer`
* objects are non-standard and only have what CLBOSS uses ...
*/

/* This helper is used by tests which use the old listpeers format */
Boss::Mod::ConstructedListpeers convert_legacy_listpeers(Jsmn::Object const & legacy_listpeers) {
Boss::Mod::ConstructedListpeers cpeers;
for (auto p : legacy_listpeers) {
if (!p.has("id"))
continue;
auto id = Ln::NodeId(std::string(p["id"]));
cpeers[id].connected = false;
if (p.has("connected")) {
auto connected = p["connected"];
cpeers[id].connected = connected.is_boolean() && bool(connected);
}
auto cs = p["channels"];
for (auto c : cs) {
cpeers[id].channels.push_back(c);
}
}
return cpeers;
}

std::ostream& operator<<(std::ostream& os, Boss::Mod::ConstructedListpeers const& o) {
for (auto p : o) {
os << p.first << ':'
<< "connected: " << p.second.connected
<< ", channels: ";
for (auto c : p.second.channels) {
os << c;
}
}
return os;
}


}}
33 changes: 33 additions & 0 deletions Boss/Mod/ConstructedListpeers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef BOSS_MOD_CONSTRUCTEDLISTPEERS_HPP
#define BOSS_MOD_CONSTRUCTEDLISTPEERS_HPP

#include<map>
#include"Ln/NodeId.hpp"
#include"Jsmn/Object.hpp"

namespace Boss { namespace Mod {

/*
* IMPORTANT - the msg is no longer directly obtained from
* `listpeers` but rather is constructed by "convolving" the value
* from `listpeerchannels`. Specifically, the top level `peer`
* objects are non-standard and only have what CLBOSS uses ...
*/

/** class Boss::Mod::ConstructedListpeers
*/
struct ConstructedListpeer {
bool connected;
std::vector<Jsmn::Object> channels;
};

typedef std::map<Ln::NodeId, ConstructedListpeer> ConstructedListpeers;

std::ostream& operator<<(std::ostream& os, ConstructedListpeers const& o);


/* for unit tests w/ legacy listpeer setups */
Boss::Mod::ConstructedListpeers convert_legacy_listpeers(Jsmn::Object const & legacy_listpeers);

}}
#endif /* !defined(BOSS_MOD_CONSTRUCTEDLISTPEERS_HPP) */
11 changes: 5 additions & 6 deletions Boss/Mod/EarningsRebalancer.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

#include"Boss/Mod/EarningsRebalancer.hpp"
#include"Boss/ModG/RebalanceUnmanagerProxy.hpp"
#include"Boss/ModG/ReqResp.hpp"
Expand Down Expand Up @@ -119,7 +120,7 @@ class EarningsRebalancer::Impl {
>([this](Msg::ListpeersResult const& m) {
if (m.initial)
return Ev::lift();
return update_balances(m.peers);
return update_balances(m.cpeers);
});

/* Command to trigger the algorithm for testing. */
Expand All @@ -144,19 +145,17 @@ class EarningsRebalancer::Impl {
});
}

Ev::Io<void> update_balances(Jsmn::Object const& peers) {
Ev::Io<void> update_balances(Boss::Mod::ConstructedListpeers const& peers) {
auto new_balances = std::map<Ln::NodeId, BalanceInfo>();
try {
for (auto p : peers) {
auto spendable = Ln::Amount::sat(0);
auto receivable = Ln::Amount::sat(0);
auto total = Ln::Amount::sat(0);

auto id = Ln::NodeId(std::string(
p["id"]
));
auto id = p.first;

for (auto c : p["channels"]) {
for (auto c : p.second.channels) {
auto state = std::string(
c["state"]
);
Expand Down
20 changes: 9 additions & 11 deletions Boss/Mod/InitialRebalancer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class InitialRebalancer::Impl {
*/
if (m.initial)
return Ev::lift();
return run(m.peers);
return run(m.cpeers);
});
}

Expand All @@ -92,7 +92,7 @@ class InitialRebalancer::Impl {
~Run() =default;

explicit
Run( S::Bus& bus, Jsmn::Object const& peers
Run( S::Bus& bus, Boss::Mod::ConstructedListpeers const& peers
, MoveRR& move_rr, ExpenseRR& expense_rr
, std::set<Ln::NodeId>& current_sources
, std::set<Ln::NodeId> const& unmanaged
Expand All @@ -101,8 +101,8 @@ class InitialRebalancer::Impl {
};

Ev::Io<void>
run(Jsmn::Object const& peers) {
auto ppeers = std::make_shared<Jsmn::Object>(peers);
run(Boss::Mod::ConstructedListpeers const& peers) {
auto ppeers = std::make_shared<Boss::Mod::ConstructedListpeers>(peers);
return Ev::lift().then([this]() {
return unmanager.get_unmanaged();
}).then([ this
Expand Down Expand Up @@ -137,7 +137,7 @@ class InitialRebalancer::Impl::Run::Impl
: public std::enable_shared_from_this<Impl> {
private:
S::Bus& bus;
Jsmn::Object peers;
Boss::Mod::ConstructedListpeers peers;

/* Data about a peer. */
struct Info {
Expand Down Expand Up @@ -174,13 +174,11 @@ class InitialRebalancer::Impl::Run::Impl
auto receivable = Ln::Amount::sat(0);
auto total = Ln::Amount::sat(0);

auto id = Ln::NodeId(std::string(
p["id"]
));
auto id = p.first;
if (unmanaged.count(id) != 0)
continue;

auto cs = p["channels"];
auto cs = p.second.channels;
for (auto c : cs) {
auto state = std::string(
c["state"]
Expand Down Expand Up @@ -468,7 +466,7 @@ class InitialRebalancer::Impl::Run::Impl

public:
Impl( S::Bus& bus_
, Jsmn::Object const& peers_
, Boss::Mod::ConstructedListpeers const& peers_
, MoveRR& move_rr_
, ExpenseRR& expense_rr_
, std::set<Ln::NodeId>& current_sources_
Expand All @@ -491,7 +489,7 @@ class InitialRebalancer::Impl::Run::Impl
};

InitialRebalancer::Impl::Run::Run( S::Bus& bus
, Jsmn::Object const& peers
, Boss::Mod::ConstructedListpeers const& peers
, MoveRR& move_rr, ExpenseRR& expense_rr
, std::set<Ln::NodeId>& current_sources
, std::set<Ln::NodeId> const& unmanaged
Expand Down
26 changes: 4 additions & 22 deletions Boss/Mod/ListpeersAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,13 @@ ListpeersAnalyzer::ListpeersAnalyzer(S::Bus& bus) {
auto ar = Msg::ListpeersAnalyzedResult();
ar.initial = l.initial;

for (auto peer : l.peers) {
if (!peer.is_object() || !peer.has("id"))
continue;
if (!peer.has("connected"))
continue;
if (!peer.has("channels"))
continue;
for (auto peer : l.cpeers) {

auto id_j = peer["id"];
if (!id_j.is_string())
continue;
auto id_s = std::string(id_j);
if (!Ln::NodeId::valid_string(id_s))
continue;
auto id = Ln::NodeId(id_s);

auto connected_j = peer["connected"];
if (!connected_j.is_boolean())
continue;
auto connected = bool(connected_j);
auto id = peer.first;
auto connected = peer.second.connected;

auto has_chan = bool(false);
auto chans = peer["channels"];
if (!chans.is_array())
continue;
auto chans = peer.second.channels;
for (auto chan : chans) {
if (!chan.is_object() || !chan.has("state"))
continue;
Expand Down
49 changes: 32 additions & 17 deletions Boss/Mod/ListpeersAnnouncer.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include"Boss/Mod/ListpeersAnnouncer.hpp"
#include"Boss/Mod/ConstructedListpeers.hpp"
#include"Boss/ModG/RpcProxy.hpp"
#include"Boss/Msg/Init.hpp"
#include"Boss/Msg/ListpeersResult.hpp"
Expand All @@ -15,42 +16,57 @@

namespace Boss { namespace Mod {

/*
* IMPORTANT - the msg is no longer directly obtained from
* `listpeers` but rather is constructed by "convolving" the value
* from `listpeerchannels`. Specifically, the top level `peer`
* objects are non-standard and only have what CLBOSS uses ...
*/

void ListpeersAnnouncer::start() {
auto invalid_listpeers = [this](Jsmn::Object result) {
auto invalid_listpeerchannels = [this](Jsmn::Object result) {
auto os = std::ostringstream();
os << result;
return Boss::log( bus, Error
, "ListpeersAnnouncer: invalid result from "
"`listpeers`."
"`listpeerchannels`."
);
};
auto do_listpeers = [ this
, invalid_listpeers
auto do_listpeerchannels = [ this
, invalid_listpeerchannels
](bool initial) {
return rpc->command("listpeers"
return rpc->command("listpeerchannels"
, Json::Out::empty_object()
).then([ this
, initial
, invalid_listpeers
, invalid_listpeerchannels
](Jsmn::Object result) {
if (!result.is_object() || !result.has("peers"))
return invalid_listpeers(std::move(result));
auto peers = result["peers"];
if (!peers.is_array())
return invalid_listpeers(std::move(result));
if (!result.is_object() || !result.has("channels"))
return invalid_listpeerchannels(std::move(result));
auto channels = result["channels"];
if (!channels.is_array())
return invalid_listpeerchannels(std::move(result));

Boss::Mod::ConstructedListpeers cpeers;
for (auto c : channels) {
auto id = Ln::NodeId(std::string(c["peer_id"]));
auto connected = c["peer_connected"];
cpeers[id].connected = connected.is_boolean() && bool(connected);
cpeers[id].channels.push_back(c);
}

return bus.raise(Msg::ListpeersResult{
std::move(peers), initial
std::move(cpeers), initial
});
});
};
bus.subscribe<Msg::Init
>([do_listpeers](Msg::Init const& init) {
return Boss::concurrent(do_listpeers(true));
>([do_listpeerchannels](Msg::Init const& init) {
return Boss::concurrent(do_listpeerchannels(true));
});
bus.subscribe<Msg::Timer10Minutes
>([do_listpeers](Msg::Timer10Minutes const& _) {
return Boss::concurrent(do_listpeers(false));
>([do_listpeerchannels](Msg::Timer10Minutes const& _) {
return Boss::concurrent(do_listpeerchannels(false));
});
}

Expand All @@ -60,5 +76,4 @@ ListpeersAnnouncer::ListpeersAnnouncer(S::Bus& bus_)
{ start(); }

ListpeersAnnouncer::~ListpeersAnnouncer() =default;

}}
5 changes: 5 additions & 0 deletions Boss/Mod/ListpeersAnnouncer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ namespace Boss { namespace Mod {
*
* @brief announces `listpeers` at `init` and
* every 10 minutes thereafter.
*
* IMPORTANT - this msg is no longer directly obtained from
* `listpeers` but rather is constructed by "convolving" the value
* from `listpeerchannels`. Specifically, the top level `peer`
* objects are non-standard and only have what CLBOSS uses ...
*/
class ListpeersAnnouncer {
private:
Expand Down
6 changes: 3 additions & 3 deletions Boss/Mod/NodeBalanceSwapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ class NodeBalanceSwapper::Impl : ModG::Swapper {
auto total_recv = Ln::Amount::sat(0);
auto total_send = Ln::Amount::sat(0);
try {
for (auto peer : m.peers) {
auto channels = peer["channels"];
for (auto peer : m.cpeers) {
auto channels = peer.second.channels;
for (auto chan : channels) {
/* Skip non-active channels.
*/
Expand All @@ -69,7 +69,7 @@ class NodeBalanceSwapper::Impl : ModG::Swapper {
} catch (Jsmn::TypeError const&) {
/* Should never happen.... */
auto os = std::ostringstream();
os << m.peers;
os << m.cpeers;
return Boss::log( bus, Error
, "NodeBalanceSwapper: "
"Unexpected listpeers: %s"
Expand Down
14 changes: 3 additions & 11 deletions Boss/Mod/PeerFromScidMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,9 @@ class PeerFromScidMapper::Impl {
bus.subscribe<Msg::ListpeersResult
>([this](Msg::ListpeersResult const& m) {
auto tmp = std::map<Ln::Scid, Ln::NodeId>();
for (auto p : m.peers) {
if (!p.has("id"))
continue;
auto node_j = p["id"];
if (!node_j.is_string())
continue;
auto node_s = std::string(node_j);
if (!Ln::NodeId::valid_string(node_s))
continue;
auto node = Ln::NodeId(node_s);
auto cs = p["channels"];
for (auto p : m.cpeers) {
auto node = p.first;
auto cs = p.second.channels;
for (auto c : cs) {
if (!c.has("short_channel_id"))
continue;
Expand Down
10 changes: 4 additions & 6 deletions Boss/Mod/PeerJudge/DataGatherer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class DataGatherer::Impl {
if (running)
return Ev::lift();

auto peers = m.peers;
auto peers = m.cpeers;

running = true;
auto code = Ev::lift().then([this, peers]() {
Expand All @@ -64,17 +64,15 @@ class DataGatherer::Impl {
return Boss::concurrent(code);
});
}
Ev::Io<void> process_peers(Jsmn::Object const& peers) {
Ev::Io<void> process_peers(Boss::Mod::ConstructedListpeers const& peers) {
auto infos = std::make_shared<std::vector<Info>>();
return Ev::lift().then([this, peers, infos]() {
try {
for (auto p : peers) {
auto id = Ln::NodeId(std::string(
p["id"]
));
auto id = p.first;
auto total = Ln::Amount::sat(0);

for (auto c : p["channels"]) {
for (auto c : p.second.channels) {
auto state = std::string(
c["state"]
);
Expand Down
Loading

0 comments on commit 1cfd860

Please sign in to comment.