Skip to content

Bootstrap: Spec Compliance and bug fixes - #1418

Merged
seetadev merged 5 commits into
libp2p:mainfrom
sumanjeet0012:fix/bootstrap-discovery-bugs
Aug 6, 2026
Merged

Bootstrap: Spec Compliance and bug fixes#1418
seetadev merged 5 commits into
libp2p:mainfrom
sumanjeet0012:fix/bootstrap-discovery-bugs

Conversation

@sumanjeet0012

Copy link
Copy Markdown
Collaborator

What was wrong?

Issue #1417

Multiple bugs in libp2p/discovery/bootstrap/bootstrap.py and missing spec compliance:

  1. InvalidAddrError caught but never imported (NameError at runtime)
  2. _remove_bootstrap_peer used substring check instead of exact /p2p/ match
  3. _periodic_reconnect could crash system task on trio.sleep cancel
  4. _is_supported_addr was instance method with unused self
  5. connection_timeout hardcoded, not configurable
  6. stop() didn't clear _failure_counts or restore bootstrap_addrs
  7. Broad except Exception for Multiaddr parse errors instead of specific types
  8. No periodic reconnection to bootstrap peers (go-libp2p spec)
  9. No removal of unreachable bootstrap peers (go-libp2p spec)

How was it fixed?

Refactored BootstrapDiscovery class with targeted fixes:

  • Imported InvalidAddrError from libp2p.peer.peerinfo
  • Changed _remove_bootstrap_peer to use endswith(f"/p2p/{peer_id_str}") for exact match
  • Wrapped trio.sleep in _periodic_reconnect with try/except trio.Cancelled
  • Converted _is_supported_addr to @staticmethod with explicit allow_ipv6 parameter
  • Added connection_timeout parameter to __init__ (default 10.0, type float)
  • Made stop() clear all state and restore bootstrap_addrs from original_addrs
  • Changed inner except to (ValueError, TypeError) for Multiaddr parse errors
  • Added _periodic_reconnect() loop via trio.lowlevel.spawn_system_task with configurable reconnect_interval
  • Added _record_failure() and _remove_bootstrap_peer() to track consecutive failures and remove peers after MAX_CONSECUTIVE_FAILURES (3)

To-Do

  • Clean up commit history
  • Add or update documentation related to these changes
  • Add entry to the release notes

- DNS addresses: decapsulate /p2p/ from resolved addresses (with ValueError handling)
- Connection timeout: replace trio.move_on_after with trio.fail_after (TooSlowError now handled)
- allow_ipv6: enforce IPv6 filtering in _is_supported_addr
- Use ID.from_string instead of ID.from_base58 for DNS path peer ID parsing
- Fix connection_timeout type: int -> float, constant 10 -> 10.0
- Remove redundant Exception from except clause (use TypeError)
- Add type annotations on dns instance variables
- Add newsfragment for changelog
- Fix _is_supported_addr to be @staticmethod with allow_ipv6 parameter
- Add configurable connection_timeout parameter (float type)
- Fix stop() to clear all state for clean restart
- Make exception handling more specific (ValueError, TypeError, InvalidAddrError)
- Add periodic reconnection loop (go-libp2p spec)
- Add bootstrap peer removal after MAX_CONSECUTIVE_FAILURES (go-libp2p spec)
- Fix _remove_bootstrap_peer to use exact /p2p/ match (not substring)
- Import InvalidAddrError in bootstrap.py
- Update newsfragment
@sumanjeet0012 sumanjeet0012 changed the title Fix/bootstrap discovery bugs Bootstrap: Spec Compliance and bug fixes Aug 3, 2026
@sumanjeet0012

Copy link
Copy Markdown
Collaborator Author

@seetadev Ready for review.

@seetadev

seetadev commented Aug 6, 2026

Copy link
Copy Markdown
Member

Excellent work, @sumanjeet0012! Thank you for taking the initiative to bring the bootstrap discovery implementation much closer to the libp2p specification while addressing several important correctness and reliability issues.

This PR goes well beyond bug fixing. The addition of periodic reconnection, configurable connection timeouts, robust peer failure tracking, precise peer removal logic, improved exception handling, and proper cleanup during shutdown all make the bootstrap subsystem significantly more resilient for long-running deployments.

I particularly appreciate the focus on aligning behavior with the go-libp2p reference implementation. Cross-language interoperability is one of the core strengths of the libp2p ecosystem, and improvements like these help ensure Python implementations behave consistently with the rest of the network.

The refactoring also improves code quality through clearer type annotations, removal of broad exception handling, better state management, and more explicit APIs. These changes should make future maintenance and feature development much easier.

As a follow-up, I would love to see us expand interoperability and resilience testing with long-running bootstrap scenarios, intermittent network failures, IPv4/IPv6 mixed environments, DNS-based bootstrap peers, and continuous cross-implementation testing across Go, Rust, JS, and Python. Integrating observability around bootstrap success rates, reconnect latency, peer churn, and connection health would also provide valuable operational insights for node operators.

Overall, this is a thoughtful and impactful improvement to one of the most fundamental parts of peer discovery. Thanks again for the excellent contribution and for continuing to strengthen py-libp2p's interoperability and production readiness.

CCing @johannamoran and @mishmosh on this PR.

@seetadev
seetadev merged commit 52b70f1 into libp2p:main Aug 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants