mirror of
https://github.com/ZmnSCPxj/clboss.git
synced 2026-08-14 12:43:19 +02:00
156 lines
4.2 KiB
C++
156 lines
4.2 KiB
C++
#include"Boss/Mod/ChannelCreationDecider.hpp"
|
|
#include"Boss/Msg/ChannelFunds.hpp"
|
|
#include"Boss/Msg/NeedsOnchainFunds.hpp"
|
|
#include"Boss/Msg/OnchainFee.hpp"
|
|
#include"Boss/Msg/OnchainFunds.hpp"
|
|
#include"Boss/Msg/RequestChannelCreation.hpp"
|
|
#include"Boss/concurrent.hpp"
|
|
#include"Boss/log.hpp"
|
|
#include"S/Bus.hpp"
|
|
#include"Util/make_unique.hpp"
|
|
#include"Util/stringify.hpp"
|
|
|
|
namespace {
|
|
|
|
/* How much onchain funds to reserve for anchor commitments. */
|
|
auto const reserve = Ln::Amount::sat(30000);
|
|
/* How much minimum funds to put in channels. */
|
|
auto const min_amount = Ln::Amount::btc(0.010);
|
|
|
|
/* If high fees, if onchain funds is more than this percent of
|
|
* total funds, create channels.
|
|
* If below this, wait for low-fee region.
|
|
*/
|
|
auto const onchain_percent_max = double(25);
|
|
|
|
}
|
|
|
|
namespace Boss { namespace Mod {
|
|
|
|
class ChannelCreationDecider::Impl {
|
|
private:
|
|
S::Bus& bus;
|
|
|
|
std::unique_ptr<bool> low_fee;
|
|
std::unique_ptr<Ln::Amount> channels;
|
|
std::unique_ptr<Ln::Amount> saved_onchain;
|
|
|
|
void start() {
|
|
bus.subscribe< Msg::ChannelFunds
|
|
>([this](Msg::ChannelFunds const& m) {
|
|
if (!channels)
|
|
channels = Util::make_unique<Ln::Amount>();
|
|
*channels = m.total;
|
|
return run();
|
|
});
|
|
bus.subscribe< Msg::OnchainFee
|
|
>([this](Msg::OnchainFee const& m) {
|
|
if (!low_fee)
|
|
low_fee = Util::make_unique<bool>();
|
|
*low_fee = m.fees_low;
|
|
return run();
|
|
});
|
|
bus.subscribe< Msg::OnchainFunds
|
|
>([this](Msg::OnchainFunds const& m) {
|
|
if (!saved_onchain)
|
|
saved_onchain = Util::make_unique<Ln::Amount>();
|
|
*saved_onchain = m.onchain;
|
|
return run();
|
|
});
|
|
}
|
|
|
|
Ev::Io<void> run() {
|
|
/* Do nothing if not complete information yet. */
|
|
if (!(low_fee && channels && saved_onchain))
|
|
return Ev::lift();
|
|
|
|
/* Get this trigger. */
|
|
auto onchain = std::move(saved_onchain);
|
|
|
|
/* Is the amount the reserve? */
|
|
if (*onchain <= reserve)
|
|
/* Do nothing and be silent. */
|
|
return decide_do_nothing_silently();
|
|
|
|
/* Below our minimum channeling amount? */
|
|
if (*onchain < min_amount + reserve) {
|
|
/* Double up the reserve here because fees. */
|
|
auto more = (min_amount + reserve * 2) - *onchain;
|
|
auto more_btc = more.to_btc();
|
|
/* Totally not a "just send me more funds to
|
|
* redeem your money" scam. */
|
|
return decide( std::string("Onchain amount too low, ")
|
|
+ "add " + Util::stringify(more_btc)
|
|
+ " or more"
|
|
, nullptr
|
|
).then([this, more]() {
|
|
/* And tell everyone about the
|
|
* missingfunds. */
|
|
return bus.raise(Msg::NeedsOnchainFunds{
|
|
more
|
|
});
|
|
});
|
|
}
|
|
|
|
if (*low_fee)
|
|
return decide("Low fees now", std::move(onchain));
|
|
|
|
auto total = *channels + *onchain;
|
|
auto onchain_percent = (*onchain / total) * 100;
|
|
if (onchain_percent > onchain_percent_max)
|
|
return decide( std::string("High fees, but ")
|
|
+ Util::stringify(onchain_percent)
|
|
+ "% of our funds are onchain, "
|
|
"which is above our limit of "
|
|
+ Util::stringify(onchain_percent_max)
|
|
+ "%"
|
|
, std::move(onchain)
|
|
);
|
|
|
|
return decide("High fees now", nullptr);
|
|
}
|
|
|
|
Ev::Io<void> decide( std::string comment
|
|
, std::unique_ptr<Ln::Amount> pfunding
|
|
) {
|
|
if (!pfunding)
|
|
return Boss::log( bus, Info
|
|
, "ChannelCreationDecider: %s. "
|
|
"Will not create channels yet."
|
|
, comment.c_str()
|
|
);
|
|
auto funding = *pfunding;
|
|
auto actual = funding - reserve;
|
|
return Boss::concurrent( bus.raise(Msg::RequestChannelCreation{actual})
|
|
).then([ this
|
|
, actual
|
|
, comment
|
|
]() {
|
|
return Boss::log( bus, Info
|
|
, "ChannelCreationDecider: %s."
|
|
"Will create channels worth %s "
|
|
"(%s reserved for onchain actions)."
|
|
, comment.c_str()
|
|
, std::string(actual).c_str()
|
|
, std::string(reserve).c_str()
|
|
);
|
|
});
|
|
}
|
|
Ev::Io<void> decide_do_nothing_silently() {
|
|
return Ev::lift();
|
|
}
|
|
|
|
public:
|
|
Impl() =delete;
|
|
Impl(Impl const&) =delete;
|
|
|
|
Impl(S::Bus& bus_) : bus(bus_) { start(); }
|
|
};
|
|
|
|
ChannelCreationDecider::ChannelCreationDecider(S::Bus& bus)
|
|
: pimpl(Util::make_unique<Impl>(bus)) { }
|
|
ChannelCreationDecider::ChannelCreationDecider(ChannelCreationDecider&& o)
|
|
: pimpl(std::move(o.pimpl)) { }
|
|
ChannelCreationDecider::~ChannelCreationDecider() { }
|
|
|
|
}}
|