From ec52d78611bac9e17d71a6b18f3a747184f4dfc6 Mon Sep 17 00:00:00 2001 From: frstrtr Date: Sat, 20 Jun 2026 02:09:15 +0000 Subject: [PATCH] nmc(PE-2d/1): CoinBroadcaster::submit_block_raw returns relayed-peer count Embedded aux backends (nmc::coin::AuxChainEmbedded::submit_block) wire their P2P-primary BlockRelayFn (size_t(block_hex)) to CoinBroadcaster::submit_block_raw, but the broadcaster discarded its internal sent count and returned void. The backend therefore could not honour the never-silent-drop invariant (#162): a block that reached 0 peers would be indistinguishable from a successful relay. Return static_cast(sent) so the wiring site can propagate the true peer count. Backward-compatible: the sole host caller (mm_manager block-relay lambda) ignores the value. +1 KAT: no peers => submit_block_raw == 0. --- src/c2pool/merged/coin_broadcaster.hpp | 7 ++++++- test/test_coin_broadcaster.cpp | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/c2pool/merged/coin_broadcaster.hpp b/src/c2pool/merged/coin_broadcaster.hpp index 33af61565..c8b9d82d6 100644 --- a/src/c2pool/merged/coin_broadcaster.hpp +++ b/src/c2pool/merged/coin_broadcaster.hpp @@ -251,7 +251,11 @@ class CoinBroadcaster } /// Broadcast raw block bytes to ALL connected peers (parent chain). - void submit_block_raw(const std::vector& block_bytes) + /// Relay a raw block to every connected peer. Returns the number of peers + /// the block was successfully sent to (0 => NOT broadcast). Embedded aux + /// backends rely on this count to honour the never-silent-drop invariant + /// (#162): a found block that reached 0 peers must surface as a failure. + size_t submit_block_raw(const std::vector& block_bytes) { std::lock_guard lock(m_mutex); int sent = 0, failed = 0; @@ -275,6 +279,7 @@ class CoinBroadcaster << sent << "/" << (sent + failed) << " peers (" << block_bytes.size() << " bytes)"; } + return static_cast(sent); } /// Send inv announcement to ALL connected peers (merged chain relay). diff --git a/test/test_coin_broadcaster.cpp b/test/test_coin_broadcaster.cpp index 108ab2c19..ccca84cde 100644 --- a/test/test_coin_broadcaster.cpp +++ b/test/test_coin_broadcaster.cpp @@ -500,6 +500,22 @@ TEST(CoinBroadcaster, ConstructionDefaults) EXPECT_EQ(bc.connected_count(), 0); } +// PE never-silent-drop (#162): with no peers connected, submit_block_raw must +// report 0 relays so embedded aux backends surface a found block as a failure +// rather than claiming a phantom broadcast. +TEST(CoinBroadcaster, SubmitBlockRawNoPeersReturnsZero) +{ + boost::asio::io_context ioc; + std::vector prefix = {std::byte{0xfd}, std::byte{0xd2}, + std::byte{0xc8}, std::byte{0xf1}}; + CoinBroadcaster bc(ioc, "LTC", prefix, NetService("192.168.1.1", 19335)); + + ASSERT_EQ(bc.connected_count(), 0); + std::vector dummy_block(80, 0x00); + EXPECT_EQ(bc.submit_block_raw(dummy_block), 0u) + << "no peers => 0 relays => caller must NOT claim broadcast success"; +} + TEST(CoinBroadcaster, ConstructionWithConfig) { boost::asio::io_context ioc;