From 049cae271c69b2b0572215a0babf5b73393cf3f5 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Fri, 20 Sep 2024 15:13:09 +1000 Subject: [PATCH] 7311: Refactor PeerManager to be an interface Signed-off-by: Matilda Clerke --- .../manager/peertask/DefaultPeerManager.java | 64 +++++++++++++++++++ .../eth/manager/peertask/PeerManager.java | 51 +++++++-------- ...rTest.java => DefaultPeerManagerTest.java} | 6 +- 3 files changed, 89 insertions(+), 32 deletions(-) create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/DefaultPeerManager.java rename ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/{PeerManagerTest.java => DefaultPeerManagerTest.java} (95%) diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/DefaultPeerManager.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/DefaultPeerManager.java new file mode 100644 index 0000000000..9424ee0b48 --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/DefaultPeerManager.java @@ -0,0 +1,64 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.eth.manager.peertask; + +import org.hyperledger.besu.ethereum.eth.manager.EthPeer; +import org.hyperledger.besu.ethereum.p2p.peers.PeerId; + +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.function.Predicate; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This is a simple PeerManager implementation that can be used the default implementation in most + * situations + */ +public class DefaultPeerManager implements PeerManager { + private static final Logger LOG = LoggerFactory.getLogger(DefaultPeerManager.class); + + // use a synchronized map to ensure the map is never modified by multiple threads at once + private final Map ethPeersByPeerId = + Collections.synchronizedMap(new HashMap<>()); + + @Override + public EthPeer getPeer(final Predicate filter) throws NoAvailablePeerException { + LOG.trace("Getting peer from pool of {} peers", ethPeersByPeerId.size()); + return ethPeersByPeerId.values().stream() + .filter(filter) + .max(Comparator.naturalOrder()) + .orElseThrow(NoAvailablePeerException::new); + } + + @Override + public Optional getPeerByPeerId(final PeerId peerId) { + return Optional.ofNullable(ethPeersByPeerId.get(peerId)); + } + + @Override + public void addPeer(final EthPeer ethPeer) { + ethPeersByPeerId.put(ethPeer.getConnection().getPeer(), ethPeer); + } + + @Override + public void removePeer(final PeerId peerId) { + ethPeersByPeerId.remove(peerId); + } +} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerManager.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerManager.java index fc5bc691b7..14323474a1 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerManager.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerManager.java @@ -17,23 +17,11 @@ package org.hyperledger.besu.ethereum.eth.manager.peertask; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; import org.hyperledger.besu.ethereum.p2p.peers.PeerId; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; import java.util.Optional; import java.util.function.Predicate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** "Manages" the EthPeers for the PeerTaskExecutor */ -public class PeerManager { - private static final Logger LOG = LoggerFactory.getLogger(PeerManager.class); - - // use a synchronized map to ensure the map is never modified by multiple threads at once - private final Map ethPeersByPeerId = - Collections.synchronizedMap(new HashMap<>()); +public interface PeerManager { /** * Gets the highest reputation peer matching the supplies filter @@ -42,23 +30,28 @@ public class PeerManager { * @return the highest reputation peer matching the supplies filter * @throws NoAvailablePeerException If there are no suitable peers */ - public EthPeer getPeer(final Predicate filter) throws NoAvailablePeerException { - LOG.trace("Getting peer from pool of {} peers", ethPeersByPeerId.size()); - return ethPeersByPeerId.values().stream() - .filter(filter) - .max(Comparator.naturalOrder()) - .orElseThrow(NoAvailablePeerException::new); - } + EthPeer getPeer(final Predicate filter) throws NoAvailablePeerException; - public Optional getPeerByPeerId(final PeerId peerId) { - return Optional.ofNullable(ethPeersByPeerId.get(peerId)); - } + /** + * Attempts to get the EthPeer identified by peerId + * + * @param peerId the peerId of the desired EthPeer + * @return An Optional\ containing the EthPeer identified by peerId if present in the + * PeerManager, or empty otherwise + */ + Optional getPeerByPeerId(final PeerId peerId); - public void addPeer(final EthPeer ethPeer) { - ethPeersByPeerId.put(ethPeer.getConnection().getPeer(), ethPeer); - } + /** + * Add the supplied EthPeer to the PeerManager + * + * @param ethPeer the EthPeer to be added to the PeerManager + */ + void addPeer(final EthPeer ethPeer); - public void removePeer(final PeerId peerId) { - ethPeersByPeerId.remove(peerId); - } + /** + * Remove the EthPeer identified by peerId from the PeerManager + * + * @param peerId the PeerId of the EthPeer to be removed from the PeerManager + */ + void removePeer(final PeerId peerId); } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerManagerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/DefaultPeerManagerTest.java similarity index 95% rename from ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerManagerTest.java rename to ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/DefaultPeerManagerTest.java index 54e0b88b5f..5aa04f8f9a 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerManagerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/DefaultPeerManagerTest.java @@ -28,13 +28,13 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -public class PeerManagerTest { +public class DefaultPeerManagerTest { - public PeerManager peerManager; + public DefaultPeerManager peerManager; @BeforeEach public void beforeTest() { - peerManager = new PeerManager(); + peerManager = new DefaultPeerManager(); } @Test