Skip to content

Commit

Permalink
Boss/Mod/AmountSettingsHandler.cpp: New module to centralize some siz…
Browse files Browse the repository at this point in the history
…e settings.
  • Loading branch information
ZmnSCPxj committed Mar 25, 2022
1 parent a9ebdd1 commit c4a30a2
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 48 deletions.
178 changes: 178 additions & 0 deletions Boss/Mod/AmountSettingsHandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#include"Boss/Mod/AmountSettingsHandler.hpp"
#include"Boss/Msg/AmountSettings.hpp"
#include"Boss/Msg/EndOfOptions.hpp"
#include"Boss/Msg/ManifestOption.hpp"
#include"Boss/Msg/Manifestation.hpp"
#include"Boss/Msg/Option.hpp"
#include"Boss/log.hpp"
#include"Jsmn/Object.hpp"
#include"S/Bus.hpp"
#include"Util/make_unique.hpp"
#include<assert.h>
#include<sstream>
#include<string>

namespace {

/* Default channel boundaries. */
auto const default_min_channel = Ln::Amount::sat( 500000);
auto const default_max_channel = Ln::Amount::sat(16777215);

/* Default amount to always leave onchain for future
* channel management actions. */
auto const default_reserve = Ln::Amount::sat( 30000);

/* The absolute lowest min_channel setting. */
auto const min_min_channel = Ln::Amount::sat( 500000);
/* How much larger the max_channel should be over the min_channel. */
auto const max_channel_factor = double(2.0);
/* How much larger the channel-creation trigger should be over
* the min_channel. */
auto const trigger_factor = double(2.0);
/* How much to add to the channel-creation trigger above, to get
* the amount to leave after creation. */
auto const additional_remaining = Ln::Amount::sat(20000);

Ln::Amount parse_sats(Jsmn::Object value) {
auto is = std::istringstream(std::string(value));
auto sats = std::uint64_t();
is >> sats;
return Ln::Amount::sat(sats);
}

}

namespace Boss { namespace Mod {

class AmountSettingsHandler::Impl {
private:
S::Bus& bus;
std::unique_ptr<Msg::AmountSettings> settings;

void start() {
settings->min_channel = default_min_channel;
settings->max_channel = default_max_channel;
settings->reserve = default_reserve;

bus.subscribe<Msg::Manifestation
>([this](Msg::Manifestation const& _) {
assert(settings);
return bus.raise(Msg::ManifestOption{
"clboss-min-onchain",
Msg::OptionType_String,
Json::Out::direct(default_reserve.to_sat()),
"Target to leave this number of satoshis "
"onchain, putting the rest into channels."
}) + bus.raise(Msg::ManifestOption{
"clboss-min-channel",
Msg::OptionType_String,
Json::Out::direct(default_min_channel.to_sat()),
"Minimum size of channels to make."
}) + bus.raise(Msg::ManifestOption{
"clboss-max-channel",
Msg::OptionType_String,
Json::Out::direct(default_max_channel.to_sat()),
"Maximum size of channels to make."
});
});

bus.subscribe<Msg::Option
>([this](Msg::Option o) {
assert(settings);
auto const& name = o.name;
if (name == "clboss-min-onchain") {
settings->reserve = parse_sats(o.value);
if (settings->reserve == default_reserve)
return Ev::lift();
return Boss::log( bus, Info
, "AmountSettingsHandler: "
"Onchain reserve set by "
"--clboss-min-onchain to "
"%s satoshis."
, std::string(o.value).c_str()
);
} else if (name == "clboss-min-channel") {
settings->min_channel = parse_sats(o.value);
if (settings->min_channel == default_min_channel)
return Ev::lift();
return Boss::log( bus, Info
, "AmountSettingsHandler: "
"Minimum channel size set by "
"--clboss-min-channel to "
"%s satoshis."
, std::string(o.value).c_str()
);
} else if (name == "clboss-max-channel") {
settings->max_channel = parse_sats(o.value);
if (settings->max_channel == default_max_channel)
return Ev::lift();
return Boss::log( bus, Info
, "AmountSettingsHandler: "
"Maximum channel size set by "
"--clboss-max-channel to "
"%s satoshis."
, std::string(o.value).c_str()
);
}
return Ev::lift();
});

bus.subscribe<Msg::EndOfOptions
>([this](Msg::EndOfOptions const& _) {
assert(settings);

auto act = Ev::lift();

/* Validate settings. */
if (settings->min_channel < min_min_channel) {
settings->min_channel = min_min_channel;
act += Boss::log( bus, Info
, "AmountSettingsHandler: "
"--clboss-min-channel too "
"low, forced to %u."
, (unsigned int)
min_min_channel.to_sat()
);
}
if (settings->max_channel < ( max_channel_factor
* settings->min_channel
)) {
settings->max_channel = ( max_channel_factor
* settings->min_channel
);
act += Boss::log( bus, Info
, "AmountSettingsHandler: "
"--clboss-max-channel too "
"low, forced to %u."
, (unsigned int)
settings->max_channel.to_sat()
);
}

/* Compute the rest. */
settings->min_amount = trigger_factor
* settings->min_channel
;
settings->min_remaining = settings->min_amount
+ additional_remaining
;

/* Grab the settings and send it. */
auto msg = std::move(settings);
return act + bus.raise(std::move(*msg));
});
}

public:
Impl() =delete;
Impl(Impl&&) =delete;
Impl(Impl const&) =delete;

explicit
Impl( S::Bus& bus_
) : bus(bus_)
, settings(Util::make_unique<Msg::AmountSettings>())
{ start(); }
};

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

#include<memory>

namespace S { class Bus; }

namespace Boss { namespace Mod {

class AmountSettingsHandler {
private:
class Impl;
std::unique_ptr<Impl> pimpl;

public:
AmountSettingsHandler() =delete;
AmountSettingsHandler(AmountSettingsHandler const&) =delete;

AmountSettingsHandler(AmountSettingsHandler&&);

explicit
AmountSettingsHandler(S::Bus&);
};

}}

#endif /* !defined(BOSS_MOD_AMOUNTSETTINGSHANDLER_HPP) */
47 changes: 8 additions & 39 deletions Boss/Mod/ChannelCreationDecider.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#include"Boss/Mod/ChannelCreationDecider.hpp"
#include"Boss/Msg/AmountSettings.hpp"
#include"Boss/Msg/ChannelFunds.hpp"
#include"Boss/Msg/ManifestOption.hpp"
#include"Boss/Msg/Manifestation.hpp"
#include"Boss/Msg/NeedsOnchainFunds.hpp"
#include"Boss/Msg/OnchainFee.hpp"
#include"Boss/Msg/OnchainFunds.hpp"
#include"Boss/Msg/Option.hpp"
#include"Boss/Msg/RequestChannelCreation.hpp"
#include"Boss/concurrent.hpp"
#include"Boss/log.hpp"
Expand All @@ -16,12 +14,8 @@

namespace {

/* How much onchain funds to reserve for anchor commitments. */
auto const default_reserve = Ln::Amount::sat(30000);
/* How much onchain funds to add when emitting NeedsOnchainFunds. */
auto const needs_reserve = Ln::Amount::sat(30000);
/* How much minimum funds to put in channels. */
auto const min_amount = Ln::Amount::btc(0.010);
/* How much we are willing to emit as "needs onchain". */
auto const max_needs_onchain = Ln::Amount::btc(0.010);

Expand Down Expand Up @@ -55,11 +49,11 @@ class ChannelCreationDecider::Impl {
std::unique_ptr<bool> low_fee;
std::unique_ptr<Ln::Amount> channels;
std::unique_ptr<Ln::Amount> saved_onchain;

Ln::Amount reserve;
Ln::Amount min_amount;

void start() {
reserve = default_reserve;

bus.subscribe< Msg::ChannelFunds
>([this](Msg::ChannelFunds const& m) {
if (!channels)
Expand All @@ -82,36 +76,11 @@ class ChannelCreationDecider::Impl {
return run();
});

/* Option --clboss-min-onchain. */
bus.subscribe< Msg::Manifestation
>([this](Msg::Manifestation const& _) {
return bus.raise(Msg::ManifestOption{
"clboss-min-onchain", Msg::OptionType_String,
Json::Out::direct(default_reserve.to_sat()),
"Target to leave this number of satoshis "
"onchain, putting the rest into channels."
});
});
bus.subscribe< Msg::Option
>([this](Msg::Option const& o) {
if (o.name != "clboss-min-onchain")
return Ev::lift();
auto is = std::istringstream(std::string(o.value));
auto sats = std::uint64_t();
is >> sats;
reserve = Ln::Amount::sat(sats);

/* If same as default value, do not spam logs. */
if (reserve == default_reserve)
return Ev::lift();

return Boss::log( bus, Info
, "ChannelCreationDecider: "
"Onchain reserve set by "
"--clboss-min-onchain to "
"%s satoshis."
, std::string(o.value).c_str()
);
bus.subscribe<Msg::AmountSettings
>([this](Msg::AmountSettings const& m) {
reserve = m.reserve;
min_amount = m.min_amount;
return Ev::lift();
});
}

Expand Down
18 changes: 9 additions & 9 deletions Boss/Mod/ChannelCreator/Manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include"Boss/Mod/ChannelCreator/Planner.hpp"
#include"Boss/Mod/ChannelCreator/RearrangerBySize.hpp"
#include"Boss/Mod/Rpc.hpp"
#include"Boss/Msg/AmountSettings.hpp"
#include"Boss/Msg/Init.hpp"
#include"Boss/Msg/RequestChannelCreation.hpp"
#include"Boss/Msg/SolicitChannelCandidates.hpp"
Expand All @@ -25,15 +26,6 @@

namespace {

/* Minimum and maximum channel size. */
auto const min_amount = Ln::Amount::btc(0.005);
auto const max_amount = Ln::Amount::sat(16777215);
/* If it is difficult to fit the amount among multiple
* proposals, how much should we target leaving until
* next time?
*/
auto const min_remaining = Ln::Amount::btc(0.0105);

/* If all the entries in the plan are 0, the plan is empty. */
bool plan_is_empty(std::map<Ln::NodeId, Ln::Amount> const& plan) {
return std::all_of( plan.begin(), plan.end()
Expand Down Expand Up @@ -68,6 +60,13 @@ Ev::Io<void> report_proposals( S::Bus& bus, char const* prefix
namespace Boss { namespace Mod { namespace ChannelCreator {

void Manager::start() {
bus.subscribe<Msg::AmountSettings
>([this](Msg::AmountSettings const& m) {
min_amount = m.min_channel;
max_amount = m.max_channel;
min_remaining = m.min_remaining;
return Ev::lift();
});
bus.subscribe<Msg::Init
>([this](Msg::Init const& init) {
rpc = &init.rpc;
Expand Down Expand Up @@ -156,6 +155,7 @@ Manager::on_request_channel_creation(Ln::Amount amt) {
}).then([ num_chans
, amt
, dowser_func
, this
](std::vector<std::pair<Ln::NodeId, Ln::NodeId>> proposals) {
auto planner = Planner( std::move(dowser_func)
, amt
Expand Down
4 changes: 4 additions & 0 deletions Boss/Mod/ChannelCreator/Manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ class Manager {

std::unique_ptr<Boss::Mod::ChannelCreator::Reprioritizer> reprioritizer;

Ln::Amount min_amount;
Ln::Amount max_amount;
Ln::Amount min_remaining;

void start();
Ev::Io<void> on_request_channel_creation(Ln::Amount);

Expand Down
32 changes: 32 additions & 0 deletions Boss/Msg/AmountSettings.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef BOSS_MSG_AMOUNTSETTINGS_HPP
#define BOSS_MSG_AMOUNTSETTINGS_HPP

#include"Ln/Amount.hpp"

namespace Boss { namespace Msg {

/** struct Boss::Msg::AmountSettings
*
* @brief Broadcast before `init` completes (before RPC
* and DB are available) with all the various settings
* related to how large the node is.
*/
struct AmountSettings {
/* Minimum and maximum channel size. */
Ln::Amount min_channel;
Ln::Amount max_channel;
/* How much we will always definitely leave onchain for
* various actions? */
Ln::Amount reserve;
/* How much should be onchain in order to trigger channel
* creation?
*/
Ln::Amount min_amount;
/* On channel creation, how much to leave onchain at minimum
* for the next channel creation event? */
Ln::Amount min_remaining;
};

}}

#endif /* !defined(BOSS_MSG_AMOUNTSETTINGS_HPP) */
3 changes: 3 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ libclboss_la_SOURCES = \
Boss/Main.hpp \
Boss/Mod/ActiveProber.cpp \
Boss/Mod/ActiveProber.hpp \
Boss/Mod/AmountSettingsHandler.cpp \
Boss/Mod/AmountSettingsHandler.hpp \
Boss/Mod/AutoDisconnector.cpp \
Boss/Mod/AutoDisconnector.hpp \
Boss/Mod/BlockTracker.cpp \
Expand Down Expand Up @@ -260,6 +262,7 @@ libclboss_la_SOURCES = \
Boss/ModG/Swapper.cpp \
Boss/ModG/Swapper.hpp \
Boss/Msg/AcceptSwapQuotation.hpp \
Boss/Msg/AmountSettings.hpp \
Boss/Msg/Begin.hpp \
Boss/Msg/Block.hpp \
Boss/Msg/ChannelCreateResult.hpp \
Expand Down
Loading

0 comments on commit c4a30a2

Please sign in to comment.