ethereum / consensus-specs

Ethereum Proof-of-Stake Consensus Specifications
Creative Commons Zero v1.0 Universal
3.57k stars 973 forks source link

Obtain ENR subnet bitfield or ENR from connected peers #1637

Closed AgeManning closed 4 years ago

AgeManning commented 4 years ago

Overview

Peers discover and connect to each other via ENRs (https://eips.ethereum.org/EIPS/eip-778). Discv5 is used to find new peers and their associated ENRs. Peers should store a subnet-bitfield representing the long-lived random subnets they are subscribed to. This allows one to search for and filter peers based on which long-lived subnets they are subscribed to.

Issue

Once a peer has found an ENR, they connect to other peers via tcp and negotiate libp2p protocols. A listening peer receiving the incoming connection has no mechanism to recover the ENR of the connecting peer. Therefore a client may have a number of connected peers, with no knowledge of their long-lived subnet subscriptions (which is useful information in deciding whether to search for more peers when a node needs to subscribe to a specific subnet).

Furthermore, a client listening and receiving a connection from a peer, cannot add that peer into its routing table and therefore doesn't add this peer to the DHT as it does not know the connecting peer's ENR.

Possible Solutions

1. Add the subnet bitfield to the STATUS message

In this solution, we simply add the bitfield to the RPC STATUS message. This solves the immediate problem of finding peer's long-lived subscribed subnets however only updates when either client initiates a STATUS. A peer could update their subnet bitfield and then may trigger a STATUS to all peers to inform them of the update.

This solution doesn't allow peers to add connecting peers to their local node table which is a feature we may want to improve the overall DHT and local routing table (especially for bootnodes).

2. Add a seperate RPC method for retrieving an ENR

In this solution we add a dedicated RPC method used to request/inform peers of an ENR/ENR-update. This method could be called by a node on connection to inform the listening peer of it's ENR. This method could also be used to update connected nodes when our local ENR is modified (including the subnet bitfield).

ENR's can be at most 300 bytes long and we may want to include additional information. Therefore the payload of this RPC method could include other information along with the ENR.

AgeManning commented 4 years ago

If we go with option 2, it may be coupled with #1531

arnetheduck commented 4 years ago

Option 2 and a separate request for ENR specifically seems reasonable - would have a better upgrade path when something else comes along, as things tend to do - it also fits ENR and discv5 being completely standalone from eth2 and libp2p in general.

One more reason is that it's entirely possible to use eth2 without ENR so far - ie you just need to throw in some discovery mechanism or use static peers.

I don't see any significant savings piggybacking it on some other eth2-request. Coupling it with #1531 seems wrong, semantically: the bitfield, and thus the ENR, changes periodically - should polling be the recommended method to keep up to date? Even if we're polling, 1531 suggest a message that's exchanged only once implying only static information goes in it (so far, it's unclear whether that's needed at all).

Solution 3

Do both - or a request for ENR and a separate eth2-specific mechanism for bitfield propagation and other eth2-specific information that is in ENR (gossip?) but without the rest of the ENR stuff (rlp, signatures etc).

protolambda commented 4 years ago

Ping and MetaData have been introduced in v0.11.1: https://github.com/ethereum/eth2.0-specs/pull/1684 The MetaData contains a subnet bitfield.