From 9a6a9ac93ea81cd2c0239f7a61fbd429b629a014 Mon Sep 17 00:00:00 2001 From: woodser Date: Mon, 1 Jan 2024 08:32:54 -0500 Subject: [PATCH] synchronize peer manager's reported peers to fix concurrency error --- .../haveno/network/p2p/peers/PeerManager.java | 69 +++++++++++-------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/p2p/src/main/java/haveno/network/p2p/peers/PeerManager.java b/p2p/src/main/java/haveno/network/p2p/peers/PeerManager.java index 457457deed..6b7bf80157 100644 --- a/p2p/src/main/java/haveno/network/p2p/peers/PeerManager.java +++ b/p2p/src/main/java/haveno/network/p2p/peers/PeerManager.java @@ -365,14 +365,16 @@ public final class PeerManager implements ConnectionListener, PersistedDataHost // We check if the reported msg is not violating our rules if (peers.size() <= (MAX_REPORTED_PEERS + maxConnectionsAbsolute + 10)) { - reportedPeers.addAll(peers); - purgeReportedPeersIfExceeds(); + synchronized (reportedPeers) { + reportedPeers.addAll(peers); + purgeReportedPeersIfExceeds(); - getPersistedPeers().addAll(peers); - purgePersistedPeersIfExceeds(); - requestPersistence(); + getPersistedPeers().addAll(peers); + purgePersistedPeersIfExceeds(); + requestPersistence(); - printReportedPeers(); + printReportedPeers(); + } } else { // If a node is trying to send too many list we treat it as rule violation. // Reported list include the connected list. We use the max value and give some extra headroom. @@ -589,8 +591,11 @@ public final class PeerManager implements ConnectionListener, PersistedDataHost /////////////////////////////////////////////////////////////////////////////////////////// private void removeReportedPeer(Peer reportedPeer) { - reportedPeers.remove(reportedPeer); - printReportedPeers(); + synchronized (reportedPeers) { + reportedPeers.remove(reportedPeer); + printReportedPeers(); + } + } private void removeReportedPeer(NodeAddress nodeAddress) { @@ -611,35 +616,39 @@ public final class PeerManager implements ConnectionListener, PersistedDataHost private void purgeReportedPeersIfExceeds() { - int size = reportedPeers.size(); - if (size > MAX_REPORTED_PEERS) { - log.info("We have already {} reported peers which exceeds our limit of {}." + - "We remove random peers from the reported peers list.", size, MAX_REPORTED_PEERS); - int diff = size - MAX_REPORTED_PEERS; - List list = new ArrayList<>(reportedPeers); - // we don't use sorting by lastActivityDate to keep it more random - for (int i = 0; i < diff; i++) { - if (!list.isEmpty()) { - Peer toRemove = list.remove(new Random().nextInt(list.size())); - removeReportedPeer(toRemove); + synchronized (reportedPeers) { + int size = reportedPeers.size(); + if (size > MAX_REPORTED_PEERS) { + log.info("We have already {} reported peers which exceeds our limit of {}." + + "We remove random peers from the reported peers list.", size, MAX_REPORTED_PEERS); + int diff = size - MAX_REPORTED_PEERS; + List list = new ArrayList<>(reportedPeers); + // we don't use sorting by lastActivityDate to keep it more random + for (int i = 0; i < diff; i++) { + if (!list.isEmpty()) { + Peer toRemove = list.remove(new Random().nextInt(list.size())); + removeReportedPeer(toRemove); + } } + } else { + log.trace("No need to purge reported peers.\n\tWe don't have more then {} reported peers yet.", MAX_REPORTED_PEERS); } - } else { - log.trace("No need to purge reported peers.\n\tWe don't have more then {} reported peers yet.", MAX_REPORTED_PEERS); } } private void printReportedPeers() { - if (!reportedPeers.isEmpty()) { - if (PRINT_REPORTED_PEERS_DETAILS) { - StringBuilder result = new StringBuilder("\n\n------------------------------------------------------------\n" + - "Collected reported peers:"); - List reportedPeersClone = new ArrayList<>(reportedPeers); - reportedPeersClone.forEach(e -> result.append("\n").append(e)); - result.append("\n------------------------------------------------------------\n"); - log.trace(result.toString()); + synchronized (reportedPeers) { + if (!reportedPeers.isEmpty()) { + if (PRINT_REPORTED_PEERS_DETAILS) { + StringBuilder result = new StringBuilder("\n\n------------------------------------------------------------\n" + + "Collected reported peers:"); + List reportedPeersClone = new ArrayList<>(reportedPeers); + reportedPeersClone.forEach(e -> result.append("\n").append(e)); + result.append("\n------------------------------------------------------------\n"); + log.trace(result.toString()); + } + log.debug("Number of reported peers: {}", reportedPeers.size()); } - log.debug("Number of reported peers: {}", reportedPeers.size()); } }