Bee v2.7.1 is a stability-focused patch release that hardens the P2P networking layer for safe WSS (AutoTLS) adoption at scale. With v2.7.0 introducing AutoTLS and WSS support, enabling it across many nodes exposed connectivity issues — timeout starvation, transport mismatch, reacher inefficiency, and unreachable address gossip. This release addresses all of them with five interlocking P2P fixes, alongside postage performance improvements and codebase cleanup.
💬 Join us on Discord if you have questions or feedback!
Note
📢 Operator Notice — Heads Up on Hosting Provider Alerts
We've observed that some operators have had their hosting provider flag their node's behaviour as a scanning attack, likely triggered by the libp2p networking. This does not happen with every provider or in every environment — but we want to make you aware of it in case you run into the same.
If your provider sends you a warning or your node gets throttled/suspended for suspicious network activity, the likely cause is the node attempting to connect to peer addresses that fall within private IP ranges. The good news is it's straightforward to mitigate.
If you experience this, adding the following iptables rules will resolve it:
/usr/sbin/iptables -I OUTPUT 1 -s $(/usr/bin/curl -4 ifconfig.me) -d 172.16.0.0/12 -j DROP
/usr/sbin/iptables -I OUTPUT 1 -s $(/usr/bin/curl -4 ifconfig.me) -d 192.168.0.0/16 -j DROP
/usr/sbin/iptables -I OUTPUT 1 -s $(/usr/bin/curl -4 ifconfig.me) -d 10.0.0.0/8 -j DROP
/usr/sbin/iptables -I OUTPUT 1 -s $(/usr/bin/curl -4 ifconfig.me) -d 100.64.0.0/10 -j DROP
/usr/sbin/iptables -I FORWARD 1 -s $(/usr/bin/curl -4 ifconfig.me) -d 172.16.0.0/12 -p tcp -j DROP
/usr/sbin/iptables -I FORWARD 1 -s $(/usr/bin/curl -4 ifconfig.me) -d 192.168.0.0/16 -p tcp -j DROP
/usr/sbin/iptables -I FORWARD 1 -s $(/usr/bin/curl -4 ifconfig.me) -d 10.0.0.0/8 -p tcp -j DROP
/usr/sbin/iptables -I FORWARD 1 -s $(/usr/bin/curl -4 ifconfig.me) -d 100.64.0.0/10 -p tcp -j DROP
No action is needed if you haven't experienced any issues. This is purely a mitigation guide to keep in your back pocket.
Bug Fixes
-
P2P: Fresh connection timeout per underlay address — Each underlay address now gets its own dedicated 15-second connection timeout instead of sharing a single timeout context across all addresses. Previously, when connecting to a peer with multiple addresses (TCP + WSS), later addresses were starved of connection time. Bootnode connection timeout also raised from 15s to 45s to accommodate multiple sequential address attempts. (#5328)
-
P2P: Transport-aware address selection and filtering — Introduced a new
TransportTypeclassification system (TCP > WS > WSS) withClassifyTransport(),SelectBestAdvertisedAddress(), andfilterSupportedAddresses()functions. The reacher now only selects addresses matching locally enabled transports, preventing WSS-only addresses from being selected on nodes without WSS enabled. (#5347) -
P2P: Update peer address on reconnect and optimize reacher — Replaced the reacher's internal
map[string]*peerwith a min-heap (container/heap) for O(1) peek and O(log n) updates instead of O(n) per scheduling cycle. When a peer reconnects with a different underlay, the address is now updated and the peer is immediately re-pinged instead of being silently ignored. (#5348) -
P2P: Skip addressbook and reacher for unreachable addresses — Removed the
RemoteMultiaddrfallback frompeerMultiaddrs()which was returning NAT IPs with ephemeral ports. These unreachable addresses were being stored in the addressbook, gossipped via hive, and sent to the reacher for pinging (always failing). Addressbook storage and reacher notifications are now gated on having valid peerstore addresses. (#5370) -
P2P: Exponential backoff for reacher — Reacher now uses exponential backoff with ±20% jitter instead of flat retry intervals. Healthy peers are checked less often (5m → 10m → 20m), while unreachable peers are backed off more aggressively (up to 80m). Worker count reduced from 16 to 8. Added a generation counter to discard stale in-flight ping results, and new Prometheus metrics for queue depth, ping attempts/errors, and duration histograms. (#5371)
-
P2P: Set reachability status metric value correctly — Fixed the reachability status Prometheus metric to use value 1 instead of 0 when the node is reachable. (#5368)
-
Postage: Prevent nil pointer panic in
TopUpBatch— Fixed a crash in light nodes runningstamps topupwherereceipt.TxHashwas accessed aftersendTopUpBatchTransactionreturned an error. ThetxHashassignment is now moved after the nil-check/success path. Same pattern fixed inCreateBatchandDiluteBatch. (#5332)
Improvements
-
Optimize postage batch snapshot loading — Introduced a
pendingChainStatebuffer that holds ChainState in memory duringTransactionStart()…TransactionEnd()windows. During large batch processing (e.g., 50,000 blocks snapshot replay), disk writes are reduced from 50,000+ down to a single write atTransactionEnd(). (#5343) -
Refactor: Extract p2p-forge code into separate file — Moved p2p-forge related code into its own file for better code organization. (#5349)
Maintenance
-
Remove dead
use-postage-snapshotflag and unused bootstrapping logic — The flag was intended to bootstrap nodes by fetching a postage snapshot from a Swarm feed, but the feed address was hardcoded to a zero address, making it non-functional. Removed the entirebootstrap.gofile and related config entries across 13 files. −561 lines of dead code. (#5318) -
Remove timebomb — Removed time-based expiration check. (#5359)
-
Update postage snapshot to v0.0.6 — Updated the postage snapshot dependency to block number 45,195,454. (#5401)
-
OpenAPI spec improvements — Bumped OpenAPI version to 7.4.0 (#5353) and 7.4.1 (#5375), with additional spec improvements (#5363).
What's Changed
- chore: bump open api version to 7.4.0 by @gacevicljubisa in #5353
- fix(workflows): add failure checks for gsoc, postage-stamps, stake, w… by @akrem-chabchoub in #5354
- fix(p2p): give each underlay address fresh 15s connection timeout by @gacevicljubisa in #5328
- fix(postage): prevent nil pointer panic in TopUpBatch on transaction … by @akrem-chabchoub in #5332
- fix(p2p): improve reacher address selection and transport filtering by @gacevicljubisa in #5347
- chore: remove timebomb by @acud in #5359
- refactor(libp2p): extract p2p-forge code into separate file by @gacevicljubisa in #5349
- fix(p2p): update peer address on reconnect and optimize reacher by @gacevicljubisa in #5348
- fix(kademlia): set reachability status metric value to 1 instead of 0 by @gacevicljubisa in #5368
- chore: improve openapi spec by @acud in #5363
- chore: remove unused code and enable extra linters by @martinconic in #5369
- feat: optimize postage batch snapshot by @martinconic in #5343
- chore: remove dead use-postage-snapshot flag and unused bootstrapping logic by @martinconic in #5318
- fix(p2p): add exponential backoff for reacher by @gacevicljubisa in #5371
- chore: bump version of OpenAPI to 7.4.1 by @gacevicljubisa in #5375
- fix(p2p): skip addressbook and reacher for unreachable addresses by @gacevicljubisa in #5370
- chore: update postage snapshot to v0.0.6 by @martinconic in #5401
Full Changelog: v2.7.0...v2.7.1