From 47efbf574f8837cef701be5ac296492986daa6da Mon Sep 17 00:00:00 2001
From: blavenie <benoit.lavenier@e-is.pro>
Date: Fri, 1 Feb 2019 18:32:40 +0100
Subject: [PATCH] [fix] Network: filter on last 100 blocks

---
 .../i18n/duniter4j-client_en_GB.properties    |  2 +-
 .../i18n/duniter4j-client_fr_FR.properties    |  2 +-
 .../service/bma/NetworkRemoteServiceImpl.java | 10 +++++++--
 .../service/bma/WotRemoteServiceImpl.java     |  5 ++++-
 .../client/service/local/NetworkService.java  |  1 +
 .../service/local/NetworkServiceImpl.java     | 22 ++++++++++++++++---
 6 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/duniter4j-client/src/main/resources/i18n/duniter4j-client_en_GB.properties b/duniter4j-client/src/main/resources/i18n/duniter4j-client_en_GB.properties
index 8003be8e..faf477cc 100644
--- a/duniter4j-client/src/main/resources/i18n/duniter4j-client_en_GB.properties
+++ b/duniter4j-client/src/main/resources/i18n/duniter4j-client_en_GB.properties
@@ -4,7 +4,7 @@ duniter4j.client.network.action=Display network peers
 duniter4j.client.network.cesiumPlus=Cs+
 duniter4j.client.network.error.outputFieNotWritable=Output file not writable
 duniter4j.client.network.executionTime=Execution time\: %s ms
-duniter4j.client.network.header=Head: block {%1$s} computed at %2$s (UTC time) validated by {%3$3.2f%%} of the peers
+duniter4j.client.network.header=Head\: block {%1$s} computed at %2$s (UTC time) validated by {%3$3.2f%%} of the peers
 duniter4j.client.network.loadingPeers=Reading network peers... (timeout\: %s ms)
 duniter4j.client.network.mirror=Mirror
 duniter4j.client.network.noPeers=No peers found
diff --git a/duniter4j-client/src/main/resources/i18n/duniter4j-client_fr_FR.properties b/duniter4j-client/src/main/resources/i18n/duniter4j-client_fr_FR.properties
index 374d0f59..27bb4419 100644
--- a/duniter4j-client/src/main/resources/i18n/duniter4j-client_fr_FR.properties
+++ b/duniter4j-client/src/main/resources/i18n/duniter4j-client_fr_FR.properties
@@ -4,7 +4,7 @@ duniter4j.client.network.action=Afficher les noeuds Duniter
 duniter4j.client.network.cesiumPlus=Cs+
 duniter4j.client.network.error.outputFieNotWritable=Fichier de sortie non inscriptible
 duniter4j.client.network.executionTime=Temps d'execution \: %s ms
-duniter4j.client.network.header=Branche principale: bloc {%1$s} calculé à %2$s (heure UTC) validé par {%3$3.2f%%} des noeuds
+duniter4j.client.network.header=Branche principale\: bloc {%1$s} calculé à %2$s (heure UTC) validé par {%3$3.2f%%} des noeuds
 duniter4j.client.network.loadingPeers=Lecture des noeuds du réseau... (Délai d'attente \: %s ms)
 duniter4j.client.network.mirror=Mirroir
 duniter4j.client.network.noPeers=Aucun noeud trouvé
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/NetworkRemoteServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/NetworkRemoteServiceImpl.java
index c05a640a..a1a62bcd 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/NetworkRemoteServiceImpl.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/NetworkRemoteServiceImpl.java
@@ -37,6 +37,7 @@ import org.duniter.core.client.config.Configuration;
 import org.duniter.core.client.model.bma.*;
 import org.duniter.core.client.model.bma.jackson.JacksonUtils;
 import org.duniter.core.client.model.local.Peer;
+import org.duniter.core.client.service.ServiceLocator;
 import org.duniter.core.exception.TechnicalException;
 import org.duniter.core.util.Preconditions;
 import org.duniter.core.util.websocket.WebsocketClientEndpoint;
@@ -68,11 +69,16 @@ public class NetworkRemoteServiceImpl extends BaseRemoteServiceImpl implements N
 
     public static final String URL_WS2P_HEADS = URL_WS2P + "/heads";
 
-    public final Configuration config;
+    private Configuration config;
 
     public NetworkRemoteServiceImpl() {
         super();
-        this.config = Configuration.instance();
+    }
+
+    @Override
+    public void afterPropertiesSet() {
+        super.afterPropertiesSet();
+        config = Configuration.instance();
     }
 
     public NetworkPeering getPeering(Peer peer) {
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteServiceImpl.java
index 19d86c77..a230da41 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteServiceImpl.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteServiceImpl.java
@@ -26,6 +26,7 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import org.apache.commons.collections4.MapUtils;
+import org.duniter.core.client.config.Configuration;
 import org.duniter.core.client.model.ModelUtils;
 import org.duniter.core.client.model.bma.*;
 import org.duniter.core.client.model.local.*;
@@ -76,6 +77,7 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe
     private CryptoService cryptoService;
     private BlockchainRemoteService bcService;
     private CurrencyService currencyService;
+    private Configuration config;
 
     public WotRemoteServiceImpl() {
         super();
@@ -87,6 +89,7 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe
         cryptoService = ServiceLocator.instance().getCryptoService();
         bcService = ServiceLocator.instance().getBlockchainRemoteService();
         currencyService = ServiceLocator.instance().getCurrencyService();
+        config = Configuration.instance();
     }
 
     public List<Identity> findIdentities(Set<String> currenciesIds, String uidOrPubKey) {
@@ -132,7 +135,7 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe
     @Override
     public Map<String, String> getMembersUids(Peer peer) {
         // get /wot/members
-        JsonNode json = httpService.executeRequest(peer, URL_MEMBERS, JsonNode.class);
+        JsonNode json = httpService.executeRequest(peer, URL_MEMBERS, JsonNode.class, config.getNetworkLargerTimeout());
 
         if (json == null || !json.has("results")) return null;
 
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkService.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkService.java
index c470273e..d7778db3 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkService.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkService.java
@@ -55,6 +55,7 @@ public interface NetworkService extends Service {
         public Boolean filterSsl;
         public List<String> filterEndpoints;
         public String currency;
+        public Integer minBlockNumber;
     }
 
 
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java
index fd240b4b..4dce8317 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java
@@ -102,11 +102,14 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network
     @Override
     public List<Peer> getPeers(Peer firstPeer) {
 
+        BlockchainBlock current = blockchainRemoteService.getCurrentBlock(firstPeer);
+
         // Default filter
         Filter filterDef = new Filter();
         filterDef.filterType = null;
         filterDef.filterStatus = Peer.PeerStatus.UP;
         filterDef.filterEndpoints = ImmutableList.of(EndpointApi.BASIC_MERKLED_API.name(), EndpointApi.BMAS.name(), EndpointApi.WS2P.name());
+        filterDef.minBlockNumber = current.getNumber().intValue() - 100;
 
         // Default sort
         Sort sortDef = new Sort();
@@ -125,7 +128,6 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network
 
         try {
             return getPeersAsync(mainPeer, (filter != null ? filter.filterEndpoints : null), executor)
-                //.thenComposeAsync(CompletableFutures::allOfToList)
                 .thenApplyAsync(this::fillPeerStatsConsensus)
                 .thenApplyAsync(peers -> peers.stream()
                         // Filter on currency
@@ -197,8 +199,11 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network
         // BMA or ES_CORE
         if (Peers.hasBmaEndpoint(peer) || Peers.hasEsCoreEndpoint(peer)) {
 
-            return CompletableFuture.supplyAsync(() -> fillNodeSummary(peer), pool)
-                .thenApplyAsync(this::fillCurrentBlock)
+            return CompletableFuture.allOf(
+                    CompletableFuture.supplyAsync(() -> fillNodeSummary(peer), pool),
+                    CompletableFuture.supplyAsync(() -> fillCurrentBlock(peer), pool)
+            )
+                .thenApply((v) -> peer)
                 .exceptionally(throwable -> {
                     peer.getStats().setStatus(Peer.PeerStatus.DOWN);
                     if(!(throwable instanceof HttpConnectException)) {
@@ -362,6 +367,7 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network
     public void addPeersChangeListener(final Peer mainPeer, final PeersChangeListener listener) {
 
         BlockchainParameters parameters = blockchainRemoteService.getParameters(mainPeer);
+        fillCurrentBlock(mainPeer);
 
         // Default filter
         Filter filterDef = new Filter();
@@ -370,6 +376,11 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network
         filterDef.filterEndpoints = ImmutableList.of(EndpointApi.BASIC_MERKLED_API.name(), EndpointApi.BMAS.name(), EndpointApi.WS2P.name());
         filterDef.currency = parameters.getCurrency();
 
+        // Skip node on an old fork
+        if (mainPeer.getStats().getBlockNumber() != null) {
+            filterDef.minBlockNumber = mainPeer.getStats().getBlockNumber() - 100;
+        }
+
         // Default sort
         Sort sortDef = new Sort();
         sortDef.sortType = null;
@@ -671,6 +682,11 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network
             return false;
         }
 
+        // Filter block number
+        if (filter.minBlockNumber != null && (stats.getBlockNumber() == null || stats.getBlockNumber().intValue() < filter.minBlockNumber.intValue())) {
+            return false;
+        }
+
         return true;
     }
 
-- 
GitLab