From 50d205f388e42d059c8d222ec00dc051742250b6 Mon Sep 17 00:00:00 2001 From: Eric Voskuil Date: Tue, 22 Sep 2026 19:58:32 -0400 Subject: [PATCH] Reduce outbound connections to node.current_outbound while current. --- .../node/sessions/session_outbound.hpp | 11 ++- include/bitcoin/node/settings.hpp | 1 + src/protocols/protocol_observer.cpp | 6 +- src/sessions/session_outbound.cpp | 80 +++++++++++++++++++ src/settings.cpp | 1 + test/settings.cpp | 1 + 6 files changed, 98 insertions(+), 2 deletions(-) diff --git a/include/bitcoin/node/sessions/session_outbound.hpp b/include/bitcoin/node/sessions/session_outbound.hpp index 796dc601..ab7e8ca7 100644 --- a/include/bitcoin/node/sessions/session_outbound.hpp +++ b/include/bitcoin/node/sessions/session_outbound.hpp @@ -24,7 +24,7 @@ namespace libbitcoin { namespace node { - + class BCN_API session_outbound : public session_peer { @@ -33,6 +33,9 @@ class BCN_API session_outbound using base = session_peer; using base::base; + /// Start connections, reduced when current (call from network strand). + void start(network::result_handler&& handler) NOEXCEPT override; + protected: /// Outbound connections require the configured node services. uint64_t services_required() const NOEXCEPT override @@ -40,6 +43,12 @@ class BCN_API session_outbound return system::bit_or(base::services_required(), node_settings().services_required()); } + +private: + void handle_started(const code& ec, + const network::result_handler& handler) NOEXCEPT; + bool handle_chase(const code& ec, event_value value) NOEXCEPT; + void update_connections() NOEXCEPT; }; } // namespace node diff --git a/include/bitcoin/node/settings.hpp b/include/bitcoin/node/settings.hpp index d6d48501..91643aac 100644 --- a/include/bitcoin/node/settings.hpp +++ b/include/bitcoin/node/settings.hpp @@ -50,6 +50,7 @@ class BCN_API settings double minimum_fee_rate; double minimum_bump_rate; uint64_t batch_signatures; + uint16_t current_connections; uint16_t announcement_cache; uint16_t fee_estimate_horizon; uint32_t maximum_height; diff --git a/src/protocols/protocol_observer.cpp b/src/protocols/protocol_observer.cpp index 586047f0..b6abff4a 100644 --- a/src/protocols/protocol_observer.cpp +++ b/src/protocols/protocol_observer.cpp @@ -197,7 +197,11 @@ bool protocol_observer::handle_broadcast_terminator(const code& ec, if (stopped(ec)) return false; - if (!message->targets(identifier(), outbound(), opposite())) + using target = network::diagnostics::target; + const auto slotted = (group() == target::outbound) && + is_terminal(message->slots()); + + if (!slotted && !message->targets(identifier(), outbound(), opposite())) return true; message->stopped(); diff --git a/src/sessions/session_outbound.cpp b/src/sessions/session_outbound.cpp index 33404da1..346a1b81 100644 --- a/src/sessions/session_outbound.cpp +++ b/src/sessions/session_outbound.cpp @@ -18,8 +18,88 @@ */ #include +#include +#include + namespace libbitcoin { namespace node { +#define CLASS session_outbound + +using namespace system; +using namespace std::placeholders; + +BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) + +// Start/stop sequence. +// ---------------------------------------------------------------------------- + +void session_outbound::start(network::result_handler&& handler) NOEXCEPT +{ + BC_ASSERT(stranded()); + + update_connections(); + base::start(BIND(handle_started, _1, std::move(handler))); +} + +void session_outbound::handle_started(const code& ec, + const network::result_handler& handler) NOEXCEPT +{ + BC_ASSERT(stranded()); + + if (ec || stopped() || is_zero(node_settings().current_connections)) + { + handler(ec); + return; + } + + subscribe_chase(BIND(handle_chase, _1, _2)); + update_connections(); + handler(ec); +} + +// Currency. +// ---------------------------------------------------------------------------- + +bool session_outbound::handle_chase(const code&, event_value value) NOEXCEPT +{ + BC_ASSERT(stranded()); + + if (stopped()) + return false; + + switch (to_chase(value)) + { + case chase::block: + case chase::stale: + { + update_connections(); + break; + } + case chase::stop: + { + return false; + } + default: + { + break; + } + } + + return true; +} + +// Outbound is reduced when current, when inbound is enabled (delay_inbound). +void session_outbound::update_connections() NOEXCEPT +{ + BC_ASSERT(stranded()); + + const auto reduced = node_settings().current_connections; + const auto configured = network_settings().outbound.connections; + set_connections((is_recent() && to_bool(reduced)) ? reduced : configured); +} + +BC_POP_WARNING() + } // namespace node } // namespace libbitcoin diff --git a/src/settings.cpp b/src/settings.cpp index f699509b..90876f76 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -45,6 +45,7 @@ settings::settings() NOEXCEPT minimum_fee_rate{ 0.0 }, minimum_bump_rate{ 0.0 }, allowed_deviation{ 1.5 }, + current_connections{ 10 }, announcement_cache{ 42 }, fee_estimate_horizon{ 0 }, ////snapshot_bytes{ 200'000'000'000 }, diff --git a/test/settings.cpp b/test/settings.cpp index 534b63bb..5d89ea17 100644 --- a/test/settings.cpp +++ b/test/settings.cpp @@ -47,6 +47,7 @@ BOOST_AUTO_TEST_CASE(settings__node__default_context__expected) BOOST_REQUIRE_EQUAL(node.minimum_bump_rate, 0.0); BOOST_REQUIRE_EQUAL(node.allowed_deviation, 1.5); BOOST_REQUIRE_EQUAL(node.batch_signatures, 0_u64); + BOOST_REQUIRE_EQUAL(node.current_connections, 10_u16); BOOST_REQUIRE_EQUAL(node.announcement_cache, 42_u16); BOOST_REQUIRE_EQUAL(node.fee_estimate_horizon, 0u); BOOST_REQUIRE_EQUAL(node.maximum_height, 0_u32);