diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/CurrencyDao.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/CurrencyDao.java
index ee7c5d4c2c17796a15317b28fede4b64ef5bad85..d43a899637902913061c0aeed91d12f29159c45d 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/CurrencyDao.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/CurrencyDao.java
@@ -34,18 +34,18 @@ import java.util.Set;
  */
 public interface CurrencyDao extends Bean, EntityDao<String, Currency> {
 
-    Currency create(final Currency currency);
-
-    Currency update(final Currency currency);
-
-    void remove(final Currency currency);
-
     Set<String> getAllIds();
 
     List<Currency> getAll();
 
     List<Currency> getAllByAccount(long accountId);
 
+    Currency create(final Currency currency);
+
+    Currency update(final Currency currency);
+
+    void remove(final Currency currency);
+
     /**
      * Return the value of the last universal dividend
      * @param currencyId
@@ -62,4 +62,6 @@ public interface CurrencyDao extends Bean, EntityDao<String, Currency> {
      void insertUDs(String currencyId,  Map<Integer, Long> newUDs);
 
     boolean isExists(String currencyId);
+
+
 }
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryCurrencyDaoImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryCurrencyDaoImpl.java
index 1daf584458a35cc02c41d43b862d10dbedadcd62..89a0c1b33e083e3fd7e5a24eaeeb38c61592bd4b 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryCurrencyDaoImpl.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryCurrencyDaoImpl.java
@@ -25,6 +25,7 @@ package org.duniter.core.client.dao.mem;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import org.duniter.core.client.dao.CurrencyDao;
+import org.duniter.core.client.model.local.Currency;
 
 import java.util.*;
 
@@ -43,7 +44,7 @@ public class MemoryCurrencyDaoImpl implements CurrencyDao {
     }
 
     @Override
-    public org.duniter.core.client.model.local.Currency create(final org.duniter.core.client.model.local.Currency entity) {
+    public Currency create(final org.duniter.core.client.model.local.Currency entity) {
 
         currencies.put(entity.getId(), entity);
 
@@ -51,13 +52,13 @@ public class MemoryCurrencyDaoImpl implements CurrencyDao {
     }
 
     @Override
-    public org.duniter.core.client.model.local.Currency update(final org.duniter.core.client.model.local.Currency currency) {
+    public Currency update(final Currency currency) {
         currencies.put(currency.getId(), currency);
         return currency;
     }
 
     @Override
-    public void remove(final org.duniter.core.client.model.local.Currency currency) {
+    public void remove(final Currency currency) {
         currencies.remove(currency.getId());
     }
 
@@ -67,23 +68,23 @@ public class MemoryCurrencyDaoImpl implements CurrencyDao {
     }
 
     @Override
-    public List<org.duniter.core.client.model.local.Currency> getAll() {
+    public List<Currency> getAll() {
         return ImmutableList.copyOf(currencies.values());
     }
 
     @Override
-    public List<org.duniter.core.client.model.local.Currency> getAllByAccount(long accountId) {
+    public List<Currency> getAllByAccount(long accountId) {
         return ImmutableList.copyOf(currencies.values());
     }
 
     @Override
-    public org.duniter.core.client.model.local.Currency getById(String id) {
+    public Currency getById(String id) {
         return currencies.get(id);
     }
 
     @Override
     public long getLastUD(String id) {
-        org.duniter.core.client.model.local.Currency currency = getById(id);
+        Currency currency = getById(id);
         if (currency == null) {
             return -1;
         }
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryPeerDaoImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryPeerDaoImpl.java
index 0234378ea81f221d76a3c20d453a3d2207de78c9..e284fcb84d4a9e630422b18b0a84505a6f16ae88 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryPeerDaoImpl.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryPeerDaoImpl.java
@@ -160,14 +160,22 @@ public class MemoryPeerDaoImpl implements PeerDao {
     @Override
     public void updatePeersAsDown(String currencyId, long upTimeLimitInSec, Collection<String> endpointApis) {
 
+        long firstDownTime = System.currentTimeMillis();
+
         getPeersByCurrencyId(currencyId).stream()
                 .filter(peer ->
                         peer.getStats() != null
-                        && peer.getStats().getLastUpTime() < upTimeLimitInSec
+                        && peer.getStats().isReacheable()
+                        && (
+                                peer.getStats().getLastUpTime() == null
+                                || peer.getStats().getLastUpTime() < upTimeLimitInSec
+                        )
                         && (endpointApis == null || endpointApis.contains(peer.getApi()))
                 )
-                .forEach(peer -> peer.getStats().setStatus(Peer.PeerStatus.DOWN));
-
+                .forEach(peer -> {
+                    peer.getStats().setStatus(Peer.PeerStatus.DOWN);
+                    peer.getStats().setFirstDownTime(firstDownTime);
+                });
     }
 
     @Override
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeering.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeering.java
index 6ca031f8267792c5471460cd3bfa3cccd6063864..9d5b972fb66c83a128cabbb5939d563f9f8d9d0a 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeering.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeering.java
@@ -27,6 +27,7 @@ import org.duniter.core.util.CollectionUtils;
 import org.duniter.core.util.StringUtils;
 
 import java.io.Serializable;
+import java.util.Objects;
 
 /**
  * Created by eis on 05/02/15.
@@ -91,7 +92,6 @@ public class NetworkPeering implements Serializable {
         this.status = status;
     }
 
-    @JsonIgnore
     public String getRaw() {
         return raw;
     }
@@ -231,6 +231,20 @@ public class NetworkPeering implements Serializable {
             }
             return sb.toString();
         }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof Endpoint) {
+                return Objects.equals(((Endpoint) obj).api, api)
+                        && Objects.equals(((Endpoint) obj).id, id)
+                        && Objects.equals(((Endpoint) obj).dns, dns)
+                        && Objects.equals(((Endpoint) obj).ipv4, ipv4)
+                        && Objects.equals(((Endpoint) obj).ipv6, ipv6)
+                        && Objects.equals(((Endpoint) obj).port, port)
+                        && Objects.equals(((Endpoint) obj).path, path);
+            }
+            return super.equals(obj);
+        }
     }
 
 
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java
index fef4b095e0d787f43afc723177f78e66f5e157b7..77420cdb154f458ae33cc65883286dd9a85ad827 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java
@@ -41,12 +41,15 @@ public class NetworkPeerings {
     }
 
     public static NetworkPeering parse(String document) throws IOException {
+        NetworkPeering result = new NetworkPeering();
+        return parse(document, result);
+    }
+
+    public static NetworkPeering parse(String document, NetworkPeering result) throws IOException {
         Preconditions.checkNotNull(document);
 
         try {
 
-            NetworkPeering result = new NetworkPeering();
-
             String[] lines = document.trim().split("\n");
 
             Preconditions.checkArgument(lines.length >= 7, "Invalid document");
@@ -89,24 +92,4 @@ public class NetworkPeerings {
             throw new IOException(e.getMessage(), e);
         }
     }
-
-    public static void parseDefaultFormatEndPoint(Matcher matcher, NetworkPeering.Endpoint endpoint, int startGroup) {
-        for(int i=startGroup; i<=matcher.groupCount(); i++) {
-            String word = matcher.group(i);
-
-            if (StringUtils.isNotBlank(word)) {
-                if (InetAddressUtils.isIPv4Address(word)) {
-                    endpoint.ipv4 = word;
-                } else if (InetAddressUtils.isIPv6Address(word)) {
-                    endpoint.ipv6 = word;
-                } else if (i == matcher.groupCount() || (i == matcher.groupCount() -1) && word.matches("\\d+")){
-                    endpoint.port = Integer.parseInt(word);
-                } else if (word.startsWith("/")) {
-                    endpoint.path = word;
-                } else {
-                    endpoint.dns = word;
-                }
-            }
-        }
-    }
 }
\ No newline at end of file
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Currency.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Currency.java
index d4b64004bd6ce37e9a8fc327d0b471c94e59609e..cc76e8b9f8f7c222caf45f0754fc02cbe5f44553 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Currency.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Currency.java
@@ -32,24 +32,22 @@ import org.duniter.core.client.model.bma.BlockchainParameters;
  */
 public class Currency implements LocalEntity<String>, Serializable {
 
+    public static final String PROPERTY_FIRST_BLOCK_SIGNATURE = "firstBlockSignature";
+    public static final String PROPERTY_MEMBER_COUNT = "membersCount";
+    public static final String PROPERTY_LAST_UD = "lastUD";
+    public static final String PROPERTY_PARAMETERS = "parameters";
+    public static final String PROPERTY_UNITBASE = "unitbase";
+
     private String id;
-    private Integer membersCount;
+    private BlockchainParameters parameters;
     private String firstBlockSignature;
+    private Integer membersCount;
     private Long lastUD;
-    private BlockchainParameters parameters;
+    private Integer unitbase;
 
     public Currency() {
     }
 
-    public Currency(String id,
-                    String firstBlockSignature,
-                    int membersCount,
-                    BlockchainParameters parameters) {
-        this.id = id;
-        this.firstBlockSignature = firstBlockSignature;
-        this.membersCount = membersCount;
-        this.parameters = parameters;
-    }
 
     @JsonIgnore
     public String getId() {
@@ -68,7 +66,6 @@ public class Currency implements LocalEntity<String>, Serializable {
         return firstBlockSignature;
     }
 
-
     public void setMembersCount(Integer membersCount) {
         this.membersCount = membersCount;
     }
@@ -85,6 +82,14 @@ public class Currency implements LocalEntity<String>, Serializable {
         this.lastUD = lastUD;
     }
 
+    public Integer getUnitbase() {
+        return unitbase;
+    }
+
+    public void setUnitbase(Integer unitbase) {
+        this.unitbase = unitbase;
+    }
+
     public BlockchainParameters getParameters() {
         return parameters;
     }
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peer.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peer.java
index c00902e7210f563b4081a4ebd20121156c0a52b4..955d8f273c9bb57493d8de078abd624daf44eacd 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peer.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peer.java
@@ -27,7 +27,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.google.common.base.Joiner;
 import org.duniter.core.client.model.bma.EndpointApi;
 import org.duniter.core.client.model.bma.NetworkPeering;
-import org.duniter.core.client.model.bma.NetworkPeers;
+import org.duniter.core.client.model.bma.NetworkPeerings;
 import org.duniter.core.util.Preconditions;
 import org.duniter.core.util.StringUtils;
 import org.duniter.core.util.http.InetAddressUtils;
@@ -56,6 +56,7 @@ public class Peer implements LocalEntity<String>, Serializable {
         private String path;
 
         private Peering peering;
+        private Stats stats;
 
         public Builder() {
 
@@ -160,6 +161,12 @@ public class Peer implements LocalEntity<String>, Serializable {
             this.peering.setVersion(remotePeering.getVersion());
             this.peering.setSignature(remotePeering.getSignature());
 
+            String raw = remotePeering.getRaw();
+            if (StringUtils.isBlank(raw)) {
+                raw = remotePeering.toString();
+            }
+            this.peering.setRaw(raw);
+
             // Block number+hash
             if (remotePeering.getBlock() != null) {
                 String[] blockParts = remotePeering.getBlock().split("-");
@@ -172,6 +179,34 @@ public class Peer implements LocalEntity<String>, Serializable {
             return this;
         }
 
+        public Builder setStats(NetworkPeering remotePeering) {
+            this.stats = this.stats != null ? this.stats : new Stats();
+
+            // Block number+hash
+            if (remotePeering.getBlock() != null) {
+                String[] blockParts = remotePeering.getBlock().split("-");
+                if (blockParts.length == 2) {
+                    this.stats.setBlockNumber(Integer.parseInt(blockParts[0]));
+                    this.stats.setBlockHash(blockParts[1]);
+                }
+            }
+
+            // Update peer status UP/DOWN
+            if ("UP".equalsIgnoreCase(remotePeering.getStatus())) {
+                stats.setStatus(Peer.PeerStatus.UP);
+
+                // FIXME: Duniter 1.7 return lastUpTime in ms. Check if this a bug or not
+                stats.setLastUpTime(System.currentTimeMillis());
+                //stats.setLastUpTime((long)Math.round(System.currentTimeMillis() / 1000));
+            }
+            else {
+                stats.setStatus(Peer.PeerStatus.DOWN);
+            }
+
+            return this;
+        }
+
+
         public void setPath(String path) {
             this.path = path;
         }
@@ -201,6 +236,10 @@ public class Peer implements LocalEntity<String>, Serializable {
             if (this.peering != null) {
                 ep.setPeering(this.peering);
             }
+            // Stats
+            if (this.stats != null) {
+                ep.setStats(this.stats);
+            }
             return ep;
         }
 
@@ -518,8 +557,9 @@ public class Peer implements LocalEntity<String>, Serializable {
         public static final String PROPERTY_SOFTWARE = "software";
         public static final String PROPERTY_VERSION = "version";
         public static final String PROPERTY_STATUS = "status";
-        public static final String PROPERTY_LAST_UP_TIME = "lastUpTime";
         public static final String PROPERTY_UID = "uid";
+        public static final String PROPERTY_LAST_UP_TIME = "lastUpTime";
+        public static final String PROPERTY_FIRST_DOWN_TIME = "firstDownTime";
 
         private String software;
         private String version;
@@ -534,6 +574,7 @@ public class Peer implements LocalEntity<String>, Serializable {
         private Double consensusPct = 0d;
         private String uid;
         private Long lastUpTime;
+        private Long firstDownTime;
 
         public Stats() {
 
@@ -647,5 +688,13 @@ public class Peer implements LocalEntity<String>, Serializable {
         public void setLastUpTime(Long lastUpTime) {
             this.lastUpTime = lastUpTime;
         }
+
+        public Long getFirstDownTime() {
+            return firstDownTime;
+        }
+
+        public void setFirstDownTime(Long firstDownTime) {
+            this.firstDownTime = firstDownTime;
+        }
     }
 }
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peers.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peers.java
index a30b8636444bcf3a37e330e77dca4eded63430c8..b3da103f441d40f26ab6e4ddd242ee4ddbc82291 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peers.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peers.java
@@ -22,16 +22,19 @@ package org.duniter.core.client.model.local;
  * #L%
  */
 
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
 import org.duniter.core.client.model.bma.*;
 import org.duniter.core.util.CollectionUtils;
 import org.duniter.core.util.Preconditions;
 import org.duniter.core.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.io.IOException;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -39,6 +42,8 @@ import java.util.stream.Collectors;
  */
 public final class Peers {
 
+    private static final Logger log = LoggerFactory.getLogger(Peers.class);
+
     private Peers() {
         // helper class
     }
@@ -79,66 +84,65 @@ public final class Peers {
         return peer.getStats() != null && peer.getStats().isReacheable();
     }
 
-    public static List<NetworkPeers.Peer> toBmaPeers(List<Peer> peers) {
-        if (CollectionUtils.isEmpty(peers)) return null;
-
-        // Group endpoint by pubkey
-        Map<String, List<Peer>> epByPubkeys = Maps.newHashMap();
-        peers.stream().forEach(peer -> {
-            String pubkey = peer.getPubkey();
-            if (StringUtils.isNotBlank(pubkey)) {
-                List<Peer> endpoints = epByPubkeys.get(pubkey);
-                if (endpoints == null) {
-                    endpoints = Lists.newArrayList();
-                    epByPubkeys.put(pubkey, endpoints);
-                }
-                endpoints.add(peer);
-            }
-        });
-
-        return epByPubkeys.values().stream().map(endpoints -> {
-            Peer firstEp = endpoints.get(0);
-            NetworkPeers.Peer result = new NetworkPeers.Peer();
-            result.setCurrency(firstEp.getCurrency());
-            result.setPubkey(firstEp.getPubkey());
-
-            if (firstEp.getPeering() != null) {
-                result.setBlock(getPeeringBlockStamp(firstEp));
-                result.setSignature(firstEp.getPeering().getSignature());
-                result.setVersion(firstEp.getPeering().getVersion());
-            }
-            else {
-                result.setVersion(Protocol.VERSION);
-                result.setBlock(getStatsBlockStamp(firstEp));
-                result.setSignature(null);
-            }
-
-            // Compute status (=UP is at least one endpoint is UP)
-            String status = endpoints.stream()
-                    .map(Peers::getStatus)
-                    .filter(s -> s == Peer.PeerStatus.UP)
-                    .findAny()
-                    .orElse(Peer.PeerStatus.DOWN).name();
-            result.setStatus(status);
-
-            // Compute endpoints list
-            List<NetworkPeering.Endpoint> bmaEps = endpoints.stream()
-                    .map(Peers::toBmaEndpoint)
-                    .collect(Collectors.toList());
-            result.setEndpoints(bmaEps.toArray(new NetworkPeering.Endpoint[bmaEps.size()]));
-
-            // Compute last try
-            Long lastUpTime =  endpoints.stream()
-                    .map(Peers::getLastUpTime)
-                    .filter(Objects::nonNull)
-                    .max(Long::compare)
-                    .orElse(null);
-
-            // Compute last try
-            result.setLastTry(lastUpTime);
-
-            return result;
-        }).collect(Collectors.toList());
+    public static List<NetworkPeers.Peer> toBmaPeers(List<Peer> endpointAsPeers) {
+        if (CollectionUtils.isEmpty(endpointAsPeers)) return null;
+
+        Joiner keyJoiner = Joiner.on(':');
+
+        // Group by peering document
+        Multimap<String, Peer> groupByPeering = ArrayListMultimap.create();
+        endpointAsPeers.stream()
+                .filter(endpointAsPeer ->
+                        endpointAsPeer.getPeering() != null
+                        && endpointAsPeer.getPubkey() != null
+                        && endpointAsPeer.getPeering().getSignature() != null
+                        && endpointAsPeer.getPeering().getRaw() != null
+                )
+                .forEach(endpointAsPeer ->  {
+                    String peeringKey = String.format("%s:%s:%s",
+                                    endpointAsPeer.getPubkey(),
+                                    endpointAsPeer.getPeering().getBlockNumber(),
+                                    endpointAsPeer.getPeering().getSignature());
+                    groupByPeering.put(peeringKey, endpointAsPeer);
+                });
+
+        // Sort keys, to select only first peering doc, by pubkey (by block number)
+        Set<String> processedPubkeys = Sets.newHashSet();
+        return groupByPeering.keySet().stream()
+                .sorted(Comparator.naturalOrder())
+                .map(peeringKey -> {
+                    String pubkey = peeringKey.substring(0, peeringKey.indexOf(':'));
+                    // Skip if already processed
+                    if (processedPubkeys.contains(pubkey)) return null;
+                    // Remember the pubkey, to skip it next time
+                    processedPubkeys.add(pubkey);
+
+                    // Get the first endpoint found for this pubkey
+                    Peer peer = groupByPeering.get(peeringKey).iterator().next();
+                    NetworkPeers.Peer result = new NetworkPeers.Peer();
+
+                    // Fill BMA peer, using the raw document
+                    try {
+                        NetworkPeerings.parse(peer.getPeering().getRaw(), result);
+                    } catch (IOException e) {
+                        log.error("Unable to parse raw document found in: " + peer.toString());
+                        return null;
+                    }
+
+                    // Override the status, last_try and first_down, using stats
+                    Peer.PeerStatus status = getStatus(peer).orElse(Peer.PeerStatus.DOWN);
+                    result.setStatus(status.name());
+                    if (status == Peer.PeerStatus.UP) {
+                        result.setLastTry(getLastUpTime(peer).get());
+                    }
+                    else {
+                        result.setFirstDown(getFirstDownTime(peer).get());
+                    }
+                    return result;
+                })
+                // Remove skipped items
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
     }
 
     public static NetworkWs2pHeads.Head toWs2pHead(Peer peer) {
@@ -149,18 +153,23 @@ public final class Peers {
         return result;
     }
 
-    public static  Peer.PeerStatus getStatus(final Peer peer) {
-        return peer.getStats() != null &&
-                peer.getStats().getStatus() != null ?
-                peer.getStats().getStatus() : null;
+    public static Optional<Peer.PeerStatus> getStatus(final Peer peer) {
+        return peer.getStats() != null ?
+                Optional.ofNullable(peer.getStats().getStatus()) :
+                Optional.empty();
     }
 
-    public static Long getLastUpTime(final Peer peer) {
-        return peer.getStats() != null &&
-                peer.getStats().getLastUpTime() != null ?
-                peer.getStats().getLastUpTime() : null;
+    public static Optional<Long> getLastUpTime(final Peer peer) {
+        return peer.getStats() != null ?
+                Optional.ofNullable(peer.getStats().getLastUpTime()) :
+                Optional.empty();
     }
 
+    public static Optional<Long> getFirstDownTime(final Peer peer) {
+        return peer.getStats() != null ?
+                Optional.ofNullable(peer.getStats().getFirstDownTime()) :
+                Optional.empty();
+    }
 
     public static String getPeeringBlockStamp(final Peer peer) {
         return peer.getPeering() != null &&
@@ -188,11 +197,26 @@ public final class Peers {
         return bmaEp;
     }
 
-    public static Peer setPeeringAndStats(Peer peer, NetworkPeering peeringDocument)  {
+    public static NetworkPeers.Peer toBmaPeer(NetworkPeering peeringDocument) {
+        NetworkPeers.Peer result = new NetworkPeers.Peer();
+
+        result.setCurrency(peeringDocument.getCurrency());
+        result.setPubkey(peeringDocument.getPubkey());
+        result.setBlock(peeringDocument.getBlock());
+        result.setSignature(peeringDocument.getSignature());
+        result.setVersion(peeringDocument.getVersion());
+        result.setEndpoints(peeringDocument.getEndpoints());
+        result.setStatus(peeringDocument.getStatus());
+
+        result.setRaw(peeringDocument.getRaw());
+
+        return result;
+    }
+
+    public static Peer setPeering(Peer peer, NetworkPeering peeringDocument)  {
         Preconditions.checkNotNull(peer);
         Preconditions.checkNotNull(peeringDocument);
 
-        Peer.Stats stats = peer.getStats() != null ? peer.getStats() : new Peer.Stats();
         Peer.Peering peering = (peer.getPeering() != null) ? peer.getPeering() : new Peer.Peering();
 
         // Copy some fields
@@ -203,29 +227,39 @@ public final class Peers {
         peering.setSignature(peeringDocument.getSignature());
 
         // Copy block infos
-        String blockstamp = peeringDocument.getBlock();
-        if (StringUtils.isNotBlank(blockstamp)) {
-            String[] blockParts = blockstamp.split("-");
+        if (StringUtils.isNotBlank(peeringDocument.getBlock())) {
+            String[] blockParts = peeringDocument.getBlock().split("-");
+            if (blockParts.length == 2) {
+                peering.setBlockNumber(Integer.parseInt(blockParts[0]));
+                peering.setBlockHash(blockParts[1]);
+            }
+        }
+
+        return peer;
+    }
+
+    public static Peer setStats(Peer peer, NetworkPeering peeringDocument)  {
+        Preconditions.checkNotNull(peer);
+        Preconditions.checkNotNull(peeringDocument);
+
+        Peer.Stats stats = peer.getStats() != null ? peer.getStats() : new Peer.Stats();
+
+        // Copy block infos
+        if (StringUtils.isNotBlank(peeringDocument.getBlock())) {
+            String[] blockParts = peeringDocument.getBlock().split("-");
             if (blockParts.length == 2) {
-                int blockNumber = Integer.parseInt(blockParts[0]);
-                String blockHash = blockParts[1];
-
-                // Fill peering block
-                peering.setBlockNumber(blockNumber);
-                peering.setBlockHash(blockHash);
-
-                // use peering block as default stats (if empty)
-                if (stats.getBlockNumber() == null) {
-                    stats.setBlockNumber(blockNumber);
-                    stats.setBlockHash(blockHash);
-                }
+                stats.setBlockNumber(Integer.parseInt(blockParts[0]));
+                stats.setBlockHash(blockParts[1]);
             }
         }
 
         // Update peer status UP/DOWN
         if ("UP".equalsIgnoreCase(peeringDocument.getStatus())) {
             stats.setStatus(Peer.PeerStatus.UP);
-            stats.setLastUpTime((long)Math.round(System.currentTimeMillis() / 1000));
+
+            // FIXME: Duniter 1.7 return lastUpTime in ms. Check if this a bug or not
+            stats.setLastUpTime(System.currentTimeMillis());
+            //stats.setLastUpTime((long)Math.round(System.currentTimeMillis() / 1000));
         }
         else {
             stats.setStatus(Peer.PeerStatus.DOWN);
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/PeerServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/PeerServiceImpl.java
index a459e0b14551c2f096c23f85eda2241b95a7ddf6..a58d5723595a573a1ee0965961a4e9f2791723e6 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/PeerServiceImpl.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/PeerServiceImpl.java
@@ -191,12 +191,15 @@ public class PeerServiceImpl implements PeerService, InitializingBean {
                 log.debug(String.format("[%s] Updating peers (%s endpoints found)", currencyId, peers.size()));
             }
 
-            final long upTime = System.currentTimeMillis() / 1000;
+            // FIXME: Duniter 1.7 return lastUpTime in ms. Check if this a bug or not
+            final long upTime = System.currentTimeMillis();
+            //final long upTime = System.currentTimeMillis() / 1000;
 
             peers.forEach(peer -> {
                 // On each UP peers: set last UP time
                 if (peer.getStats() != null && peer.getStats().isReacheable()) {
                     peer.getStats().setLastUpTime(upTime);
+                    peer.getStats().setFirstDownTime(null);
                 }
                 // Save
                 save(peer);
@@ -209,7 +212,6 @@ public class PeerServiceImpl implements PeerService, InitializingBean {
         return peerDao.isExists(currencyId, peerId);
     }
 
-
     @Override
     public void updatePeersAsDown(String currencyId, Collection<String> filterApis) {
         int peerDownTimeoutMs = config.getPeerUpMaxAge();