Context
When migrating from DiscV4 to DiscV5, there is a gap in how runtime permission changes are handled.
In DiscV4, PeerDiscoveryController subscribes to PeerPermissions.subscribeUpdate() and evicts newly-disallowed peers from the peer table immediately when permissions change at runtime (e.g., admin updates node permissioning config file).
In DiscV5 (PR #9950), there is no equivalent subscribeUpdate handler. If permissions change while the node is running, already-known peers in the DiscV5 routing table are not evicted. They linger until:
candidatePeers() filters them out (defense-in-depth prevents RLPx connection)
- RLPx layer's
handlePermissionsUpdate disconnects existing connections
- The peer is naturally evicted by the routing table
Proposed fix
Subscribe to peerPermissions.subscribeUpdate() in PeerDiscoveryAgentV5 and iterate streamLiveNodes() (or getNodeRecordBuckets()) to evict disallowed peers via MutableDiscoverySystem.deleteNodeRecord(nodeId).
DiscV4 reference: PeerDiscoveryController.handlePermissionsUpdate() + PeerDiscoveryPermissions.isAllowedInPeerTable().
DiscV4 vs DiscV5 permission checkpoint comparison
| Checkpoint |
DiscV4 Action |
DiscV4 |
DiscV5 |
| Peer table insertion |
DISCOVERY_ALLOW_IN_PEER_TABLE |
isAllowedInPeerTable() |
allow(NodeRecord) + isPeerPermitted() |
| Inbound bonding |
DISCOVERY_ACCEPT_INBOUND_BONDING |
allowInboundBonding() on PING |
allow(InetSocketAddress) on UDP |
| Outbound bonding |
DISCOVERY_ALLOW_OUTBOUND_BONDING |
allowOutboundBonding() before PING |
N/A (DiscV5 WHOAREYOU is library-managed) |
| Inbound FINDNODE |
DISCOVERY_SERVE_INBOUND_NEIGHBORS_REQUEST |
allowInboundNeighborsRequest() |
allow(NodeRecord) in AddressAccessPolicy |
| Outbound FINDNODE |
DISCOVERY_ALLOW_OUTBOUND_NEIGHBORS_REQUEST |
allowOutboundNeighborsRequest() |
N/A (library-managed) |
| Permissions update |
N/A |
handlePermissionsUpdate() drops peers |
Missing |
Related
Context
When migrating from DiscV4 to DiscV5, there is a gap in how runtime permission changes are handled.
In DiscV4,
PeerDiscoveryControllersubscribes toPeerPermissions.subscribeUpdate()and evicts newly-disallowed peers from the peer table immediately when permissions change at runtime (e.g., admin updates node permissioning config file).In DiscV5 (PR #9950), there is no equivalent
subscribeUpdatehandler. If permissions change while the node is running, already-known peers in the DiscV5 routing table are not evicted. They linger until:candidatePeers()filters them out (defense-in-depth prevents RLPx connection)handlePermissionsUpdatedisconnects existing connectionsProposed fix
Subscribe to
peerPermissions.subscribeUpdate()inPeerDiscoveryAgentV5and iteratestreamLiveNodes()(orgetNodeRecordBuckets()) to evict disallowed peers viaMutableDiscoverySystem.deleteNodeRecord(nodeId).DiscV4 reference:
PeerDiscoveryController.handlePermissionsUpdate()+PeerDiscoveryPermissions.isAllowedInPeerTable().DiscV4 vs DiscV5 permission checkpoint comparison
DISCOVERY_ALLOW_IN_PEER_TABLEisAllowedInPeerTable()allow(NodeRecord)+isPeerPermitted()DISCOVERY_ACCEPT_INBOUND_BONDINGallowInboundBonding()on PINGallow(InetSocketAddress)on UDPDISCOVERY_ALLOW_OUTBOUND_BONDINGallowOutboundBonding()before PINGDISCOVERY_SERVE_INBOUND_NEIGHBORS_REQUESTallowInboundNeighborsRequest()allow(NodeRecord)in AddressAccessPolicyDISCOVERY_ALLOW_OUTBOUND_NEIGHBORS_REQUESTallowOutboundNeighborsRequest()handlePermissionsUpdate()drops peersRelated