Skip to content

Better interoperability with Go/rust peers#10

Open
waus wants to merge 5 commits into
stephanfeb:mainfrom
waus:main
Open

Better interoperability with Go/rust peers#10
waus wants to merge 5 commits into
stephanfeb:mainfrom
waus:main

Conversation

@waus
Copy link
Copy Markdown

@waus waus commented Apr 25, 2026

Summary

This change improves interoperability with Go/libp2p peers, especially legacy RSA peer IDs used by public IPFS/libp2p bootstrap nodes.

Changes

  • PeerId parsing now falls back to decoding any valid raw base58 multihash, not only strings that start with 1.
  • This allows long RSA peer IDs such as Qm..., 22..., and DA... forms to be parsed when they are not represented as CIDv1 libp2p-key strings.
  • Invalid CID peer IDs are still rejected when the string is a CID with an unsupported peer ID codec.
  • Removed the local dart_udx path dependency override from pubspec.yaml and restored the published dependency constraint.

Why

Go/libp2p and the public IPFS DHT still expose many RSA peers as raw base58 multihashes. The previous parser only accepted CID-style IDs and a narrow legacy identity-multihash case, so valid RSA peers could not be dialed or used as DHT bootstrap/query peers.

This blocked DHT traversal against mixed public networks and made discovery fail before the DHT protocol exchange could happen.

Validation

  • Added focused peer ID coverage under test/core/peer/.
  • Verified against real public DHT peers whose IDs are RSA/raw base58 multihashes.

dazwin and others added 5 commits April 3, 2026 10:03
rust-libp2p uses lazy yamux acknowledgement — the ACK flag is
piggybacked on the first data/window-update frame rather than sent
as a standalone ACK. dart_libp2p blocks on a Completer awaiting an
explicit ACK after sending SYN, causing a deadlock: the dart side
waits for ACK before sending data, while the rust side waits for
data before sending ACK.

The yamux spec allows the initiator to send data immediately after
SYN without waiting for ACK. This change makes the ACK wait
non-blocking — the Completer is still tracked for logging, but
stream.open() proceeds immediately after SYN is sent.

See: https://github.com/hashicorp/yamux/blob/master/spec.md
Tested against: rust-libp2p 0.56.0 (yamux 0.12.1 / 0.13.10)
The Noise handshake payload verification was hardcoded to Ed25519,
rejecting connections to any peer using RSA keys (PeerIDs starting
with "Qm"). This blocked connectivity to IPFS bootstrap relay
servers which all use RSA keys.

Changes:
- noise_protocol.dart: Use generic publicKeyFromProto() to unmarshal
  remote identity keys in _verifyHandshakePayload, secureOutbound,
  and secureInbound. Supports Ed25519, RSA, and ECDSA.
- rsa.dart: Handle SPKI (SubjectPublicKeyInfo) format in
  fromRawBytes() alongside PKCS#1. IPFS nodes encode RSA public
  keys in SPKI format which wraps the key in an algorithm
  identifier sequence.

Tested: dart_libp2p successfully connects to IPFS bootstrap relay
QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN via TCP + Noise.
Fix yamux ACK deadlock when interoperating with rust-libp2p
Support RSA peers in Noise handshake for relay connectivity
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