diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryAgent.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryAgent.java index 91e615242a..8f858a9ec3 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryAgent.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryAgent.java @@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.p2p.discovery.internal.PeerRequirement; import org.hyperledger.besu.ethereum.p2p.discovery.internal.PingPacketData; import org.hyperledger.besu.ethereum.p2p.discovery.internal.TimerUtil; import org.hyperledger.besu.ethereum.p2p.peers.EnodeURL; +import org.hyperledger.besu.ethereum.p2p.peers.MaintainedPeers; import org.hyperledger.besu.ethereum.p2p.peers.PeerId; import org.hyperledger.besu.ethereum.p2p.permissions.PeerPermissions; import org.hyperledger.besu.nat.NatService; @@ -81,13 +82,15 @@ public abstract class PeerDiscoveryAgent { /* Is discovery enabled? */ private boolean isActive = false; protected final Subscribers peerBondedObservers = Subscribers.create(); + private final MaintainedPeers maintainedPeers; protected PeerDiscoveryAgent( final NodeKey nodeKey, final DiscoveryConfiguration config, final PeerPermissions peerPermissions, final NatService natService, - final MetricsSystem metricsSystem) { + final MetricsSystem metricsSystem, + final MaintainedPeers maintainedPeers) { this.metricsSystem = metricsSystem; checkArgument(nodeKey != null, "nodeKey cannot be null"); checkArgument(config != null, "provided configuration cannot be null"); @@ -101,7 +104,7 @@ public abstract class PeerDiscoveryAgent { this.config = config; this.nodeKey = nodeKey; - + this.maintainedPeers = maintainedPeers; id = nodeKey.getPublicKey().getEncodedBytes(); } @@ -173,6 +176,7 @@ public abstract class PeerDiscoveryAgent { .peerPermissions(peerPermissions) .peerBondedObservers(peerBondedObservers) .metricsSystem(metricsSystem) + .maintainedPeers(maintainedPeers) .build(); } diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/VertxPeerDiscoveryAgent.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/VertxPeerDiscoveryAgent.java index 16560baec4..5790b3a431 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/VertxPeerDiscoveryAgent.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/VertxPeerDiscoveryAgent.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.p2p.discovery.internal.PeerDiscoveryControl import org.hyperledger.besu.ethereum.p2p.discovery.internal.PeerDiscoveryController.AsyncExecutor; import org.hyperledger.besu.ethereum.p2p.discovery.internal.TimerUtil; import org.hyperledger.besu.ethereum.p2p.discovery.internal.VertxTimerUtil; +import org.hyperledger.besu.ethereum.p2p.peers.MaintainedPeers; import org.hyperledger.besu.ethereum.p2p.permissions.PeerPermissions; import org.hyperledger.besu.metrics.BesuMetricCategory; import org.hyperledger.besu.nat.NatService; @@ -62,8 +63,9 @@ public class VertxPeerDiscoveryAgent extends PeerDiscoveryAgent { final DiscoveryConfiguration config, final PeerPermissions peerPermissions, final NatService natService, - final MetricsSystem metricsSystem) { - super(nodeKey, config, peerPermissions, natService, metricsSystem); + final MetricsSystem metricsSystem, + final MaintainedPeers maintainedPeers) { + super(nodeKey, config, peerPermissions, natService, metricsSystem, maintainedPeers); checkArgument(vertx != null, "vertx instance cannot be null"); this.vertx = vertx; diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerDiscoveryController.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerDiscoveryController.java index 88ceae7932..c399f8b91a 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerDiscoveryController.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerDiscoveryController.java @@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.p2p.discovery.DiscoveryPeer; import org.hyperledger.besu.ethereum.p2p.discovery.PeerBondedObserver; import org.hyperledger.besu.ethereum.p2p.discovery.PeerDiscoveryEvent; import org.hyperledger.besu.ethereum.p2p.discovery.PeerDiscoveryStatus; +import org.hyperledger.besu.ethereum.p2p.peers.MaintainedPeers; import org.hyperledger.besu.ethereum.p2p.peers.Peer; import org.hyperledger.besu.ethereum.p2p.peers.PeerId; import org.hyperledger.besu.ethereum.p2p.permissions.PeerPermissions; @@ -158,7 +159,8 @@ public class PeerDiscoveryController { final PeerRequirement peerRequirement, final PeerPermissions peerPermissions, final Subscribers peerBondedObservers, - final MetricsSystem metricsSystem) { + final MetricsSystem metricsSystem, + final MaintainedPeers maintainedPeers) { this.timerUtil = timerUtil; this.nodeKey = nodeKey; this.localPeer = localPeer; @@ -174,6 +176,10 @@ public class PeerDiscoveryController { this.peerPermissions = new PeerDiscoveryPermissions(localPeer, peerPermissions); + // Listening to the added and removed peer event to update the maintainted peers + maintainedPeers.subscribeAdd(this::onPeerAdded); + maintainedPeers.subscribeRemove(this::onPeerRemoved); + metricsSystem.createIntegerGauge( BesuMetricCategory.NETWORK, "discovery_inflight_interactions_current", @@ -195,6 +201,18 @@ public class PeerDiscoveryController { "type"); } + private void onPeerAdded(final Peer peer, final boolean wasAdded) { + if (wasAdded) { + addToPeerTable(DiscoveryPeer.fromEnode(peer.getEnodeURL())); + } + } + + private void onPeerRemoved(final Peer peer, final boolean wasRemoved) { + if (wasRemoved) { + peerTable.tryEvict(peer); + } + } + public static Builder builder() { return new Builder(); } @@ -694,6 +712,7 @@ public class PeerDiscoveryController { private final List bootstrapNodes = new ArrayList<>(); private PeerTable peerTable; private Subscribers peerBondedObservers = Subscribers.create(); + private MaintainedPeers maintainedPeers = new MaintainedPeers(); // Required dependencies private NodeKey nodeKey; @@ -724,7 +743,8 @@ public class PeerDiscoveryController { peerRequirement, peerPermissions, peerBondedObservers, - metricsSystem); + metricsSystem, + maintainedPeers); } private void validate() { @@ -816,5 +836,11 @@ public class PeerDiscoveryController { this.metricsSystem = metricsSystem; return this; } + + public Builder maintainedPeers(final MaintainedPeers maintainedPeers) { + checkNotNull(maintainedPeers); + this.maintainedPeers = maintainedPeers; + return this; + } } } diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetwork.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetwork.java index 1e77dfd11e..401174ce8e 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetwork.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetwork.java @@ -443,7 +443,13 @@ public class DefaultP2PNetwork implements P2PNetwork { private PeerDiscoveryAgent createDiscoveryAgent() { return new VertxPeerDiscoveryAgent( - vertx, nodeKey, config.getDiscovery(), peerPermissions, natService, metricsSystem); + vertx, + nodeKey, + config.getDiscovery(), + peerPermissions, + natService, + metricsSystem, + maintainedPeers); } private RlpxAgent createRlpxAgent( diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryTestHelper.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryTestHelper.java index ecadc23b8a..a9ee45e4fd 100644 --- a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryTestHelper.java +++ b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryTestHelper.java @@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.p2p.discovery.internal.PacketType; import org.hyperledger.besu.ethereum.p2p.discovery.internal.PingPacketData; import org.hyperledger.besu.ethereum.p2p.discovery.internal.PongPacketData; import org.hyperledger.besu.ethereum.p2p.peers.EnodeURL; +import org.hyperledger.besu.ethereum.p2p.peers.MaintainedPeers; import org.hyperledger.besu.ethereum.p2p.peers.Peer; import org.hyperledger.besu.ethereum.p2p.permissions.PeerPermissions; import org.hyperledger.besu.nat.NatService; @@ -264,8 +265,10 @@ public class PeerDiscoveryTestHelper { config.setAdvertisedHost(advertisedHost); config.setBindPort(port); config.setActive(active); + MaintainedPeers maintainedPeers = new MaintainedPeers(); - return new MockPeerDiscoveryAgent(nodeKey, config, peerPermissions, agents, natService); + return new MockPeerDiscoveryAgent( + nodeKey, config, peerPermissions, agents, natService, maintainedPeers); } } } diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/MockPeerDiscoveryAgent.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/MockPeerDiscoveryAgent.java index a1b73be48e..b9f382c553 100644 --- a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/MockPeerDiscoveryAgent.java +++ b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/MockPeerDiscoveryAgent.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.p2p.config.DiscoveryConfiguration; import org.hyperledger.besu.ethereum.p2p.discovery.DiscoveryPeer; import org.hyperledger.besu.ethereum.p2p.discovery.PeerDiscoveryAgent; import org.hyperledger.besu.ethereum.p2p.discovery.internal.PeerDiscoveryController.AsyncExecutor; +import org.hyperledger.besu.ethereum.p2p.peers.MaintainedPeers; import org.hyperledger.besu.ethereum.p2p.permissions.PeerPermissions; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.nat.NatService; @@ -48,8 +49,9 @@ public class MockPeerDiscoveryAgent extends PeerDiscoveryAgent { final DiscoveryConfiguration config, final PeerPermissions peerPermissions, final Map agentNetwork, - final NatService natService) { - super(nodeKey, config, peerPermissions, natService, new NoOpMetricsSystem()); + final NatService natService, + final MaintainedPeers maintainedPeers) { + super(nodeKey, config, peerPermissions, natService, new NoOpMetricsSystem(), maintainedPeers); this.agentNetwork = agentNetwork; }