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();