From e8e4502c3432daf1a1540afabd20147f2c040270 Mon Sep 17 00:00:00 2001 From: Eric Voskuil Date: Fri, 18 Sep 2026 19:04:31 -0400 Subject: [PATCH 1/4] Capture local address, binding, time offset and relay in the row. --- src/protocols/protocol_observer.cpp | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/protocols/protocol_observer.cpp b/src/protocols/protocol_observer.cpp index 5d80af87..6f8eb059 100644 --- a/src/protocols/protocol_observer.cpp +++ b/src/protocols/protocol_observer.cpp @@ -50,10 +50,7 @@ void protocol_observer::start() NOEXCEPT SUBSCRIBE_CHANNEL(inventory, handle_receive_inventory, _1, _2); } - SUBSCRIBE_BROADCAST(network::diagnostics, handle_broadcast_diagnostics, - _1, _2, _3); - - ////SUBSCRIBE_CHANNEL(get_data, handle_receive_get_data, _1, _2); + SUBSCRIBE_BROADCAST(network::diagnostics, handle_broadcast_diagnostics, _1, _2, _3); protocol_peer::start(); } @@ -139,23 +136,42 @@ bool protocol_observer::handle_broadcast_diagnostics(const code& ec, if (!message->member(identifier()) && !message->member(group())) return true; + using namespace system; const auto peer = peer_version(); + uint64_t services{ service::node_none }; + network::config::address local{}; + int64_t time_offset{}; + std::string agent{}; + bool relay{}; + + if (peer) + { + time_offset = subtract(peer->timestamp, created()); + local = { peer->address_receiver }; + services = peer->services; + agent = peer->user_agent; + relay = peer->relay; + } message->add( { .identifier = identifier(), .address = outbound(), + .local = local, + .binding = binding(), .group = group(), .version = negotiated_version(), - .services = peer ? peer->services : service::node_none, + .services = services, .sent = sent(), .received = received(), .created = created(), .last_read = last_read(), .last_write = last_write(), + .time_offset = time_offset, .start_height = start_height(), .encrypted = encrypted(), - .agent = peer ? peer->user_agent : std::string{} + .relay = relay, + .agent = agent }); return true; From 22e35cb9ec927e7515cb23a3247e3369039891ec Mon Sep 17 00:00:00 2001 From: Eric Voskuil Date: Fri, 18 Sep 2026 19:40:43 -0400 Subject: [PATCH 2/4] Capture ping times in the diagnostic row. --- src/protocols/protocol_observer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/protocols/protocol_observer.cpp b/src/protocols/protocol_observer.cpp index 6f8eb059..d592ac6c 100644 --- a/src/protocols/protocol_observer.cpp +++ b/src/protocols/protocol_observer.cpp @@ -168,6 +168,9 @@ bool protocol_observer::handle_broadcast_diagnostics(const code& ec, .last_read = last_read(), .last_write = last_write(), .time_offset = time_offset, + .ping_time = ping_time(), + .minimum_ping_time = minimum_ping_time(), + .pending_ping_time = pending_ping_time(), .start_height = start_height(), .encrypted = encrypted(), .relay = relay, From e93a1791a17d5d38ef7bcdd039fc68022b905dfd Mon Sep 17 00:00:00 2001 From: Eric Voskuil Date: Fri, 18 Sep 2026 21:12:54 -0400 Subject: [PATCH 3/4] Handle terminator broadcast. --- include/bitcoin/node/chase.hpp | 2 +- .../node/protocols/protocol_observer.hpp | 4 ++++ src/full_node.cpp | 2 +- src/protocols/protocol_observer.cpp | 23 +++++++++++++++++-- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/include/bitcoin/node/chase.hpp b/include/bitcoin/node/chase.hpp index 59b0c2d0..3a691ae2 100644 --- a/include/bitcoin/node/chase.hpp +++ b/include/bitcoin/node/chase.hpp @@ -45,7 +45,7 @@ enum class chase /// Issued by 'organize' and handled by 'check', 'validate', 'confirm'. bump, - /// Channels (all) directed to stop (default). + /// Channels (all) directed to stop with the given code (default). /// Issued by 'full_node' and handled by 'observer'. suspend, diff --git a/include/bitcoin/node/protocols/protocol_observer.hpp b/include/bitcoin/node/protocols/protocol_observer.hpp index fd414b19..b7423596 100644 --- a/include/bitcoin/node/protocols/protocol_observer.hpp +++ b/include/bitcoin/node/protocols/protocol_observer.hpp @@ -68,6 +68,10 @@ class BCN_API protocol_observer virtual bool handle_broadcast_diagnostics(const code& ec, const network::diagnostics::cptr& message, uint64_t sender) NOEXCEPT; + /// Stop the channel if it is the member of a stop. + virtual bool handle_broadcast_terminator(const code& ec, + const network::terminator::cptr& message, uint64_t sender) NOEXCEPT; + /// The capture group of the channel (the session determines the group). virtual network::diagnostics::target group() const NOEXCEPT; diff --git a/src/full_node.cpp b/src/full_node.cpp index 2a724f1e..a538b38a 100644 --- a/src/full_node.cpp +++ b/src/full_node.cpp @@ -293,7 +293,7 @@ void full_node::suspend(const code& ec) NOEXCEPT { LOGS("Suspending network, " << ec.message()); net::suspend(ec); - notify(ec, chase::suspend, {}); + notify(error::suspended_channel, chase::suspend, {}); } void full_node::fault(const code& ec) NOEXCEPT diff --git a/src/protocols/protocol_observer.cpp b/src/protocols/protocol_observer.cpp index d592ac6c..fb2ed800 100644 --- a/src/protocols/protocol_observer.cpp +++ b/src/protocols/protocol_observer.cpp @@ -51,6 +51,7 @@ void protocol_observer::start() NOEXCEPT } SUBSCRIBE_BROADCAST(network::diagnostics, handle_broadcast_diagnostics, _1, _2, _3); + SUBSCRIBE_BROADCAST(network::terminator, handle_broadcast_terminator, _1, _2, _3); protocol_peer::start(); } @@ -65,7 +66,7 @@ void protocol_observer::stopping(const code& ec) NOEXCEPT // handle events (suspend) // ---------------------------------------------------------------------------- -bool protocol_observer::handle_chase(const code&, chase event_, +bool protocol_observer::handle_chase(const code& ec, chase event_, event_value) NOEXCEPT { // Do not pass ec to stopped as it is not a call status. @@ -76,7 +77,8 @@ bool protocol_observer::handle_chase(const code&, chase event_, { case chase::suspend: { - stop(error::suspended_channel); + // The code distinguishes a stop from a drop (manual removal). + stop(ec); break; } case chase::stop: @@ -180,6 +182,23 @@ bool protocol_observer::handle_broadcast_diagnostics(const code& ec, return true; } +// The first member stops, so the round completes without the other channels. +bool protocol_observer::handle_broadcast_terminator(const code& ec, + const network::terminator::cptr& message, uint64_t) NOEXCEPT +{ + BC_ASSERT(stranded()); + + if (stopped(ec)) + return false; + + if (!message->member(identifier(), outbound())) + return true; + + message->stopped(); + stop(message->reason()); + return false; +} + BC_POP_WARNING() BC_POP_WARNING() From 8e152763e925afb74584652b159ac79d33bd47b3 Mon Sep 17 00:00:00 2001 From: Eric Voskuil Date: Fri, 18 Sep 2026 21:53:06 -0400 Subject: [PATCH 4/4] Hoist peer fee min to channel. --- .../bitcoin/node/protocols/protocol_transaction_out_70013.hpp | 3 +-- src/protocols/protocol_observer.cpp | 1 + src/protocols/protocol_transaction_out_70013.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/bitcoin/node/protocols/protocol_transaction_out_70013.hpp b/include/bitcoin/node/protocols/protocol_transaction_out_70013.hpp index 0a86d6a4..687ee6a3 100644 --- a/include/bitcoin/node/protocols/protocol_transaction_out_70013.hpp +++ b/include/bitcoin/node/protocols/protocol_transaction_out_70013.hpp @@ -58,8 +58,7 @@ class BCN_API protocol_transaction_out_70013 bool insufficient(const database::fee_rate& rate) const NOEXCEPT; void do_send_fee_filter() NOEXCEPT; - // These are protected by strand. - uint64_t minimum_fee_{}; + // This is protected by strand. uint64_t sent_fee_{}; }; diff --git a/src/protocols/protocol_observer.cpp b/src/protocols/protocol_observer.cpp index fb2ed800..689e50b0 100644 --- a/src/protocols/protocol_observer.cpp +++ b/src/protocols/protocol_observer.cpp @@ -170,6 +170,7 @@ bool protocol_observer::handle_broadcast_diagnostics(const code& ec, .last_read = last_read(), .last_write = last_write(), .time_offset = time_offset, + .minimum_fee = minimum_fee(), .ping_time = ping_time(), .minimum_ping_time = minimum_ping_time(), .pending_ping_time = pending_ping_time(), diff --git a/src/protocols/protocol_transaction_out_70013.cpp b/src/protocols/protocol_transaction_out_70013.cpp index 7d22bf86..6ebc6401 100644 --- a/src/protocols/protocol_transaction_out_70013.cpp +++ b/src/protocols/protocol_transaction_out_70013.cpp @@ -106,7 +106,7 @@ bool protocol_transaction_out_70013::handle_receive_fee_filter(const code& ec, if (stopped(ec)) return false; - minimum_fee_ = message->minimum_fee; + set_minimum_fee(message->minimum_fee); return true; } @@ -140,7 +140,7 @@ bool protocol_transaction_out_70013::insufficient( const database::fee_rate& rate) const NOEXCEPT { return ceilinged_multiply(rate.fee, vbytes_per_vkbyte) < - ceilinged_multiply(minimum_fee_, + ceilinged_multiply(minimum_fee(), possible_wide_cast(rate.bytes)); }