⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content

Conversation

@gacevicljubisa
Copy link
Member

@gacevicljubisa gacevicljubisa commented Jan 22, 2026

Checklist

  • I have read the coding guide.
  • My change requires a documentation update, and I have done it.
  • I have added tests to cover my changes.
  • I have filled out the description and linked the related issues.

Description

Allow peers without dialable underlay addresses (e.g., browsers, WebRTC
clients, NAT-restricted nodes) to establish connections and use protocols
over existing streams.

Changes:

  • Remove empty underlay validation in bzz.ParseAddress and MarshalJSON
  • Skip addressbook persistence for peers with empty underlays
  • Add nil check in notifyReacherConnected to prevent reacher crashes
  • Rename peerRegistry.underlays to overlayToPeerID for clarity

Inbound-only peers can participate in protocols (pricing, retrieval, pss)
but are excluded from Kademlia topology and hive gossip since they cannot
be dialed back.

Open API Spec Version Changes (if applicable)

Motivation and Context (Optional)

Related Issue (Optional)

Screenshots (if appropriate):

Copy link
Member

@janos janos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice, maybe just to add some tests for behaviour changes.

@janos
Copy link
Member

janos commented Jan 22, 2026

Also, do not add peer without underlays to the addressbook in hive here https://github.com/ethersphere/bee/blob/master/pkg/hive/hive.go#L314.

@gacevicljubisa
Copy link
Member Author

Also, do not add peer without underlays to the addressbook in hive here https://github.com/ethersphere/bee/blob/master/pkg/hive/hive.go#L314.

They are skipped here

bee/pkg/hive/hive.go

Lines 288 to 291 in 706fe4c

if len(multiUnderlays) == 0 {
s.logger.Debug("check and add peers, no underlays", "overlay", swarm.NewAddress(p.Overlay).String())
continue // no underlays sent
}

@gacevicljubisa gacevicljubisa marked this pull request as ready for review January 23, 2026 10:29
// If emptyUnderlays is set, use a custom host factory that creates a host with no listen addresses
// This simulates an inbound-only peer (browser, WebRTC connection, strict NAT)
if o.emptyUnderlays {
opts = libp2p.WithHostFactory(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This overwrites opts, losing any previously set fields like FullNode from o.libp2pOpts.
I think we should append to previous opts ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this makes emptyUnderlays option coupled with libp2pOpts in a not transparent way.

It is a problem with WithHostFactory function that, just returns the new libp2p.Options instead just to set the unexported field internally. This is just not practical, or composable.

I suggest to add in export_test.go:

func SetHostFactory(o *Options, factory func(...libp2pm.Option) (host.Host, error)) {
	o.hostFactory = factory
}

as more flexible alternative. WithHostFactory is not even named clearly, its name does not suggest that it is (one of) a constructor of the Options type.

expectPeers(t, s2, overlay1)
expectPeersEventually(t, s1, overlay2)

// Verify s1 (has underlays) is persisted in s2's addressbook
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add this test case:
s2 should not be saved in s1's addressbook

@lat-murmeldjur
Copy link

I'm not sure this is necessary. From browser connecting to testnet wss addresses is already possible. The browser node also has an (ephemeral) underlay.

@v1rtl
Copy link

v1rtl commented Jan 27, 2026

Without this Bee in browser fails to maintain connections. It is really necessary. I dont see any drawback to not support inbound-only peers

@gacevicljubisa
Copy link
Member Author

gacevicljubisa commented Jan 28, 2026

I'm not sure this is necessary. From browser connecting to testnet wss addresses is already possible. The browser node also has an (ephemeral) underlay.

@lat-murmeldjur Can you provide more details about ephemeral underlay?

@lat-murmeldjur
Copy link

lat-murmeldjur commented Jan 28, 2026

I'm not sure this is necessary. From browser connecting to testnet wss addresses is already possible. The browser node also has an (ephemeral) underlay.

@lat-murmeldjur Can you provide more details about ephemeral underlay?

Yes.
If you go to the weeb-3 client here: https://lat-murmeldjur.github.io/weeb-3/
In the logs at the bottom of the page you can see lines like
Observed address /ip4/37.76.0.186/tcp/28943/wss for peer QmfSx1ujzboapD5h2CiqTJqUy46FeTDwXBszB3XUCfKEEj stored/overwritten

This is our ephemeral underlay in the browser, observed by the bee node, and sent back to the browser in the libp2p-identify protocol.

The reason why getting it through this libp2p-protocol was necessary, is because connecting to a tls/ws address broke 1 thing:
In the handshake, we no longer get back our observed underlay field filled out by the bee node. I suspect that could have been the reason for v1rtl requiring this PR as well. So without observed underlay being signed after handshake i got disconnected immediately. Now that i read it from the libp2p-identify, wait for it (after dial, before handshake) and then use it for the handshake it completes and I can upload and download after that.

@gacevicljubisa
Copy link
Member Author

Without this Bee in browser fails to maintain connections. It is really necessary. I dont see any drawback to not support inbound-only peers

As I understand, with this PR, the browser client doesn't need the workaround of reading the observed underlay from libp2p-identify before the handshake. The handshake now accepts empty underlays, so the browser can complete the handshake immediately without waiting for the observed address.

@lat-murmeldjur
Copy link

Without this Bee in browser fails to maintain connections. It is really necessary. I dont see any drawback to not support inbound-only peers

As I understand, with this PR, the browser client doesn't need the workaround of reading the observed underlay from libp2p-identify before the handshake. The handshake now accepts empty underlays, so the browser can complete the handshake immediately without waiting for the observed address.

It's okay I'm not objecting to this change just wanted to make it clear that strictly speaking you don't need this to make connections work.

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.

6 participants