diff --git a/duniter4j-client/src/main/java/org/duniter/client/actions/TransactionAction.java b/duniter4j-client/src/main/java/org/duniter/client/actions/TransactionAction.java index 8415a1f2ba3e7c31e61bfa8f7654e95314ad6b2d..8060100c0db8d13757408f3e7c29c4483f4313a1 100644 --- a/duniter4j-client/src/main/java/org/duniter/client/actions/TransactionAction.java +++ b/duniter4j-client/src/main/java/org/duniter/client/actions/TransactionAction.java @@ -100,7 +100,7 @@ public class TransactionAction extends AbstractAction { Currency currency = ServiceLocator.instance().getBlockchainRemoteService().getCurrencyFromPeer(peer); ServiceLocator.instance().getCurrencyService().save(currency); - peer.setCurrency(currency.getCurrencyName()); + peer.setCurrency(currency.getId()); ServiceLocator.instance().getPeerService().save(peer); @@ -123,7 +123,7 @@ public class TransactionAction extends AbstractAction { } Wallet wallet = new Wallet( - currency.getCurrencyName(), + currency.getId(), null, keypair.getPubKey(), keypair.getSecKey()); @@ -219,7 +219,7 @@ public class TransactionAction extends AbstractAction { logTxSummary(wallet); peers.stream().forEach(peer -> { - peer.setCurrency(currency.getCurrencyName()); + peer.setCurrency(currency.getId()); peerService.save(peer); log.debug(String.format("Send TX to [%s]...", peer)); diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/config/Configuration.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/config/Configuration.java index 7bb45477b84d9f900371713799579b01b6a663d4..0b7cc4f274e40bd38050a6185cfd550665ca49b0 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/config/Configuration.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/config/Configuration.java @@ -251,6 +251,10 @@ public class Configuration { return applicationConfig.getOptionAsInt(ConfigurationOption.NETWORK_TIMEOUT.getKey()); } + public int getNetworkLargerTimeout() { + return Math.max(30000, getNetworkTimeout()); + } + public int getNetworkMaxTotalConnections() { return applicationConfig.getOptionAsInt(ConfigurationOption.NETWORK_MAX_CONNECTIONS.getKey()); } 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 e33b06762b700065cebb5d28c4578ae0f1e10e03..ee7c5d4c2c17796a15317b28fede4b64ef5bad85 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 @@ -40,9 +40,11 @@ public interface CurrencyDao extends Bean, EntityDao<String, Currency> { void remove(final Currency currency); - List<String> getCurrencyIds(); + Set<String> getAllIds(); - List<Currency> getCurrencies(long accountId); + List<Currency> getAll(); + + List<Currency> getAllByAccount(long accountId); /** * Return the value of the last universal dividend diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/PeerDao.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/PeerDao.java index 1a9ade97b36494d46f8881b53fd0ea24d2f5fbe5..d12e7013bfc9817767d328385cbe45eae875d188 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/PeerDao.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/PeerDao.java @@ -24,6 +24,7 @@ package org.duniter.core.client.dao; import org.duniter.core.client.model.bma.EndpointApi; import org.duniter.core.client.model.bma.NetworkPeers; +import org.duniter.core.client.model.bma.NetworkWs2pHeads; import org.duniter.core.client.model.local.Peer; import java.util.Collection; @@ -56,6 +57,14 @@ public interface PeerDao extends EntityDao<String, Peer> { */ List<NetworkPeers.Peer> getBmaPeersByCurrencyId(String currencyId, String[] pubkeys); + /** + * Get WS2p heads as BMA /network/ws2p/head format + * @param currencyId + * @param pubkeys use to filter on specific pubkeys. If null, not filtering + * @return + */ + List<NetworkWs2pHeads.Head> getWs2pPeersByCurrencyId(String currencyId, String[] pubkeys); + boolean isExists(String currencyId, String peerId); Long getMaxLastUpTime(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 82ed699debfcb7ce094cbf12056d7b0e378f4a33..1daf584458a35cc02c41d43b862d10dbedadcd62 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 @@ -23,6 +23,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 java.util.*; @@ -61,15 +62,18 @@ public class MemoryCurrencyDaoImpl implements CurrencyDao { } @Override - public List<String> getCurrencyIds() { - return ImmutableList.copyOf(currencies.keySet()); + public Set<String> getAllIds() { + return ImmutableSet.copyOf(currencies.keySet()); } @Override - public List<org.duniter.core.client.model.local.Currency> getCurrencies(long accountId) { - List<org.duniter.core.client.model.local.Currency> result = new ArrayList<>(); - result.addAll(currencies.values()); - return result; + public List<org.duniter.core.client.model.local.Currency> getAll() { + return ImmutableList.copyOf(currencies.values()); + } + + @Override + public List<org.duniter.core.client.model.local.Currency> getAllByAccount(long accountId) { + return ImmutableList.copyOf(currencies.values()); } @Override 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 9fd7dbe0919457331596f13197d15ef7ea02c6c3..44cd11b4c4f7a6978472789797ef3ef75ca6f999 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 @@ -26,6 +26,7 @@ import com.google.common.collect.ImmutableList; import org.duniter.core.client.dao.PeerDao; import org.duniter.core.client.model.bma.EndpointApi; import org.duniter.core.client.model.bma.NetworkPeers; +import org.duniter.core.client.model.bma.NetworkWs2pHeads; import org.duniter.core.client.model.local.Peer; import org.duniter.core.client.model.local.Peers; import org.duniter.core.util.Preconditions; @@ -121,6 +122,17 @@ public class MemoryPeerDaoImpl implements PeerDao { return Peers.toBmaPeers(getPeersByCurrencyIdAndApiAndPubkeys(currencyId, null, pubkeys)); } + @Override + public List<NetworkWs2pHeads.Head> getWs2pPeersByCurrencyId(String currencyId, String[] pubkeys) { + Preconditions.checkNotNull(currencyId); + + return getPeersByCurrencyIdAndApiAndPubkeys(currencyId, null, pubkeys) + .stream() + .map(Peers::toWs2pHead) + // Skip if no message + .filter(head -> head.getMessage() != null) + .collect(Collectors.toList()); + } @Override public boolean isExists(final String currencyId, final String peerId) { diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/BasicIdentity.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/BasicIdentity.java index 389673adacc066b5869838030a12b93cb4ccb2b2..20456b52dbf9a5f9a0e38a6bdde3ffeb091bb058 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/BasicIdentity.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/BasicIdentity.java @@ -23,6 +23,9 @@ package org.duniter.core.client.model; */ +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.duniter.core.client.model.local.LocalEntity; + import java.io.Serializable; /** @@ -36,6 +39,10 @@ public class BasicIdentity implements Serializable { private static final long serialVersionUID = 8080689271400316984L; + public static final String PROPERTY_UID = "uid"; + public static final String PROPERTY_PUBKEY = "pubkey"; + public static final String PROPERTY_SIGNATURE = "signature"; + private String pubkey; private String signature; @@ -58,10 +65,14 @@ public class BasicIdentity implements Serializable { this.signature = signature; } + @JsonIgnore + @Deprecated public String getSelf() { return signature; } + @JsonIgnore + @Deprecated public void setSelf(String signature) { this.signature = signature; } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/BlockchainBlock.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/BlockchainBlock.java index 4724fadd821c27b2e7fa951b302f78e3e144108d..57e707f3199edd7d83e113884b2a6d621d8b3a2f 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/BlockchainBlock.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/BlockchainBlock.java @@ -51,6 +51,7 @@ public class BlockchainBlock implements Serializable { public static final String PROPERTY_REVOKED = "revoked"; public static final String PROPERTY_EXCLUDED = "excluded"; public static final String PROPERTY_MEDIAN_TIME = "medianTime"; + public static final String PROPERTY_ISSUER = "issuer"; private static final long serialVersionUID = -5598140972293452669L; diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/BlockchainDifficulties.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/BlockchainDifficulties.java new file mode 100644 index 0000000000000000000000000000000000000000..82617b53475bf74120b200a4ac41a347d6755ec3 --- /dev/null +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/BlockchainDifficulties.java @@ -0,0 +1,68 @@ +package org.duniter.core.client.model.bma; + +/* + * #%L + * UCoin Java :: Core Client API + * %% + * Copyright (C) 2014 - 2016 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import java.io.Serializable; + +public class BlockchainDifficulties implements Serializable { + private static final long serialVersionUID = -5631089862715942431L; + + private Long block; + private DifficultyLevel[] levels; + + public Long getBlock() { + return block; + } + public void setBlock(Long block) { + this.block = block; + } + public DifficultyLevel[] getLevels() { + return levels; + } + public void setLevels(DifficultyLevel[] levels) { + this.levels = levels; + } + + public static class DifficultyLevel implements Serializable { + private static final long serialVersionUID = 1L; + + private String uid; + private int level; + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + } +} diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/BlockchainMemberships.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/BlockchainMemberships.java index 1f2c36b59bb5453822b4eeb37ef4777f6dc78917..99f896b78e573a6851dac580fc2acbac1ec1d929 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/BlockchainMemberships.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/BlockchainMemberships.java @@ -45,7 +45,7 @@ public class BlockchainMemberships extends BasicIdentity { this.memberships = memberships; } - public class Membership implements Serializable { + public static class Membership implements Serializable { private static final long serialVersionUID = 1L; private String version; diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Protocol.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Protocol.java index 0c854f39abcef621b6b7f697135115548e03007f..07cf3a2cbcd8499fa55f4aa67e415b2ef25be42c 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Protocol.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Protocol.java @@ -35,6 +35,8 @@ public interface Protocol { String TYPE_MEMBERSHIP = "Membership"; + String TYPE_CERTIFICATION = "Certification"; + String TYPE_TRANSACTION = "Transaction"; String TYPE_PEER = "Peer"; diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Contact.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Contact.java index 6d95919e9c812ae80c7939b0ef617b7d714ee834..f9fa2715bebe6e3d97c617d30c4d25ab5a0223e6 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Contact.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Contact.java @@ -113,7 +113,7 @@ public class Contact implements LocalEntity<Long>, Serializable { public boolean hasIdentityForCurrency(String currencyId) { return identities.stream() - .anyMatch(identity -> identity.getCurrencyId() != null - && currencyId.equals(identity.getCurrencyId())); + .anyMatch(identity -> identity.getCurrency() != null + && currencyId.equals(identity.getCurrency())); } } 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 04770f58f5b0a07a1315706d2c0d430976bddf8b..d4b64004bd6ce37e9a8fc327d0b471c94e59609e 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 @@ -25,7 +25,6 @@ package org.duniter.core.client.model.local; import java.io.Serializable; import com.fasterxml.jackson.annotation.JsonIgnore; -import org.duniter.core.client.model.Account; import org.duniter.core.client.model.bma.BlockchainParameters; /** @@ -33,7 +32,7 @@ import org.duniter.core.client.model.bma.BlockchainParameters; */ public class Currency implements LocalEntity<String>, Serializable { - private String currencyName; + private String id; private Integer membersCount; private String firstBlockSignature; private Long lastUD; @@ -42,11 +41,11 @@ public class Currency implements LocalEntity<String>, Serializable { public Currency() { } - public Currency(String currencyName, + public Currency(String id, String firstBlockSignature, int membersCount, BlockchainParameters parameters) { - this.currencyName = currencyName; + this.id = id; this.firstBlockSignature = firstBlockSignature; this.membersCount = membersCount; this.parameters = parameters; @@ -54,12 +53,11 @@ public class Currency implements LocalEntity<String>, Serializable { @JsonIgnore public String getId() { - return currencyName; + return id; } - public String getCurrencyName() - { - return currencyName; + public void setId(String id) { + this.id = id; } public Integer getMembersCount() { @@ -70,13 +68,6 @@ public class Currency implements LocalEntity<String>, Serializable { return firstBlockSignature; } - public void setId(String id) { - this.currencyName = id; - } - - public void setCurrencyName(String currencyName) { - this.currencyName = currencyName; - } public void setMembersCount(Integer membersCount) { this.membersCount = membersCount; @@ -103,6 +94,6 @@ public class Currency implements LocalEntity<String>, Serializable { } public String toString() { - return currencyName; + return id; } } \ No newline at end of file diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Identity.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Identity.java index dbe29e999ad2fbf895c579c309a41c27271e5aac..3b82915b523585a9a6fe94f173a2b483d5579d83 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Identity.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Identity.java @@ -23,29 +23,23 @@ package org.duniter.core.client.model.local; */ +import com.fasterxml.jackson.annotation.JsonIgnore; import org.duniter.core.client.model.BasicIdentity; public class Identity extends BasicIdentity { private static final long serialVersionUID = -7451079677730158794L; + public static final String PROPERTY_IS_MEMBER = "isMember"; + public static final String PROPERTY_WAS_MEMBER = "wasMember"; + private String timestamp = null; private Boolean isMember = null; - private String currencyId; - - /** - * The timestamp value of the signature date (a BLOCK_UID) - * @return - */ - public String getTimestamp() { - return timestamp; - } + private Boolean wasMember = null; - public void setTimestamp(String timestamp) { - this.timestamp = timestamp; - } + private String currency; /** * Indicate whether the certification is written in the blockchain or not. @@ -58,11 +52,35 @@ public class Identity extends BasicIdentity { this.isMember = isMember; } - public String getCurrencyId() { - return currencyId; + public Boolean getWasMember() { + return wasMember; + } + + public void setWasMember(Boolean wasMember) { + this.wasMember = wasMember; + } + + /** + * The timestamp value of the signature date (a BLOCK_UID) + * @return + */ + @JsonIgnore + public String getTimestamp() { + return timestamp; + } + + @JsonIgnore + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + @JsonIgnore + public String getCurrency() { + return currency; } - public void setCurrencyId(String currencyId) { - this.currencyId = currencyId; + @JsonIgnore + public void setCurrency(String currency) { + this.currency = currency; } } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/Member.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Member.java similarity index 65% rename from duniter4j-core-client/src/main/java/org/duniter/core/client/model/Member.java rename to duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Member.java index fb6a9ad81fa42ce0acb13a2eb6b2e0237aee17a4..2ed02c89b53667503bfee47c556f61792061335d 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/Member.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Member.java @@ -1,4 +1,4 @@ -package org.duniter.core.client.model; +package org.duniter.core.client.model.local; /* * #%L @@ -23,29 +23,20 @@ package org.duniter.core.client.model; */ -import org.duniter.core.client.model.local.Identity; +import com.fasterxml.jackson.annotation.JsonIgnore; -public class Member extends Identity { +public class Member extends Identity implements LocalEntity<String> { private static final long serialVersionUID = 8448049949323699700L; - private String number; - - private String hash; - - public String getNumber() { - return number; + @JsonIgnore + public String getId() { + return getPubkey(); } - public void setNumber(String number) { - this.number = number; + @JsonIgnore + public void setId(String pubkey) { + setPubkey(pubkey); } - public String getHash() { - return hash; - } - - public void setHash(String hash) { - this.hash = hash; - } } 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 3648143ab417e00d83a80bef6e420971ef703b7c..deb2d801dde378bd46434d7a788f21382fd933b4 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 @@ -24,10 +24,7 @@ package org.duniter.core.client.model.local; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -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.Protocol; +import org.duniter.core.client.model.bma.*; import org.duniter.core.util.CollectionUtils; import org.duniter.core.util.StringUtils; @@ -147,6 +144,13 @@ public final class Peers { }).collect(Collectors.toList()); } + public static NetworkWs2pHeads.Head toWs2pHead(Peer peer) { + NetworkWs2pHeads.Head result = new NetworkWs2pHeads.Head(); + + // TODO : add implementation + + return result; + } public static Peer.PeerStatus getStatus(final Peer peer) { return peer.getStats() != null && diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpService.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpService.java index b1a02dee360510d05168ca6f7faa9ef50fa9893f..366bdd167c447e1ee6e8059ced38706841748640 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpService.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpService.java @@ -50,6 +50,8 @@ public interface HttpService extends Service { <T> T executeRequest(Peer peer, String absolutePath, Class<? extends T> resultClass); + <T> T executeRequest(Peer peer, String absolutePath, Class<? extends T> resultClass, int timeout) ; + String getPath(Peer peer, String... absolutePath); String getPath(String... absolutePath); diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpServiceImpl.java index 9f74e06722e6f3d6af333ef7cfb83e833a3cc21c..c7516b4332bbb418576b3d03eaf1c2e3f06725a2 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpServiceImpl.java @@ -152,8 +152,12 @@ public class HttpServiceImpl implements HttpService, Closeable, InitializingBean } public <T> T executeRequest(Peer peer, String absolutePath, Class<? extends T> resultClass) { + return executeRequest(peer, absolutePath, resultClass, 0); + } + + public <T> T executeRequest(Peer peer, String absolutePath, Class<? extends T> resultClass, int timeout) { HttpGet httpGet = new HttpGet(peer.getUrl() + absolutePath); - return executeRequest(HttpClients.getThreadHttpClient(0), httpGet, resultClass); + return executeRequest(HttpClients.getThreadHttpClient(timeout), httpGet, resultClass); } public String getPath(Peer peer, String... absolutePath) { diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BaseRemoteServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BaseRemoteServiceImpl.java index b1cfc667e3614188b9425aaca6985d758cf14000..f051ea609653e7119078cb8b50fdec9855248bb7 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BaseRemoteServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BaseRemoteServiceImpl.java @@ -58,15 +58,29 @@ public abstract class BaseRemoteServiceImpl implements Service, InitializingBean peerService = null; } + @Deprecated public <T> T executeRequest(Peer peer, String absolutePath, Class<? extends T> resultClass) { return httpService.executeRequest(peer, absolutePath, resultClass); } + @Deprecated + public <T> T executeRequest(Peer peer, String absolutePath, Class<? extends T> resultClass, int timeout) { + return httpService.executeRequest(peer, absolutePath, resultClass, timeout); + } + + @Deprecated public <T> T executeRequest(String currencyId, String absolutePath, Class<? extends T> resultClass) { Peer peer = peerService.getActivePeerByCurrencyId(currencyId); return httpService.executeRequest(peer, absolutePath, resultClass); } + @Deprecated + public <T> T executeRequest(String currencyId, String absolutePath, Class<? extends T> resultClass, int timeout) { + Peer peer = peerService.getActivePeerByCurrencyId(currencyId); + return httpService.executeRequest(peer, absolutePath, resultClass, timeout); + } + + @Deprecated public <T> T executeRequest(HttpUriRequest request, Class<? extends T> resultClass) { return httpService.executeRequest(request, resultClass); } @@ -76,14 +90,17 @@ public abstract class BaseRemoteServiceImpl implements Service, InitializingBean return httpService.getPath(peer, aPath); } + @Deprecated public String getPath(Peer peer, String aPath) { return httpService.getPath(peer, aPath); } + @Deprecated public URIBuilder getURIBuilder(URI baseUri, String... path) { return httpService.getURIBuilder(baseUri, path); } + @Deprecated public URIBuilder getURIBuilder(URL baseUrl, String... path) { try { return httpService.getURIBuilder(baseUrl.toURI(), path); diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BlockchainRemoteService.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BlockchainRemoteService.java index eaac3b408694040101a197afee66b7505285259a..f93313a0c36e4b26131e1b190e8e8052a1f93998 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BlockchainRemoteService.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BlockchainRemoteService.java @@ -23,6 +23,7 @@ package org.duniter.core.client.service.bma; */ import org.duniter.core.beans.Service; +import org.duniter.core.client.model.bma.BlockchainDifficulties; import org.duniter.core.client.model.local.Identity; import org.duniter.core.client.model.bma.BlockchainBlock; import org.duniter.core.client.model.bma.BlockchainMemberships; @@ -49,6 +50,8 @@ public interface BlockchainRemoteService extends Service { */ BlockchainParameters getParameters(String currencyId, boolean useCache); + BlockchainParameters getParameters(Peer peer, boolean useCache); + /** * get the blockchain parameters (currency parameters) * @@ -84,6 +87,8 @@ public interface BlockchainRemoteService extends Service { */ Long getBlockDividend(String currencyId, long number) throws BlockNotFoundException; + Long getBlockDividend(Peer peer, long number) throws BlockNotFoundException; + /** * Retrieve a block, by id (from 0 to current) * @@ -124,6 +129,7 @@ public interface BlockchainRemoteService extends Service { * * @return */ + BlockchainBlock getCurrentBlock(Peer peer, boolean useCache); BlockchainBlock getCurrentBlock(String currencyId, boolean useCache); /** @@ -131,15 +137,8 @@ public interface BlockchainRemoteService extends Service { * * @return */ - BlockchainBlock getCurrentBlock(String currencyId); - - /** - * Retrieve the current block - * - * @param peer the peer to use for request - * @return the last block - */ BlockchainBlock getCurrentBlock(Peer peer); + BlockchainBlock getCurrentBlock(String currencyId); /** * Retrieve the currency data, from peer @@ -149,23 +148,20 @@ public interface BlockchainRemoteService extends Service { */ Currency getCurrencyFromPeer(Peer peer); - BlockchainParameters getBlockchainParametersFromPeer(Peer peer); - /** - * Retrieve the last emitted UD (or ud0 if not UD emitted yet) - * - * @param currencyId id of currency + * Retrieve personal difficulties (level, uid) * @return */ - long getLastUD(String currencyId); + BlockchainDifficulties getDifficulties(Peer peer); + BlockchainDifficulties getDifficulties(String currencyId); /** - * Retrieve the last emitted UD, from a peer (or ud0 if not UD emitted yet) + * Retrieve the last emitted UD (or ud0 if not UD emitted yet) * - * @param currencyId id of currency * @return */ long getLastUD(Peer peer); + long getLastUD(String currencyId); /** * Check is a identity is not already used by a existing member @@ -193,7 +189,6 @@ public interface BlockchainRemoteService extends Service { */ void loadMembership(String currencyId, Identity identity, boolean checkLookupForNonMember); - BlockchainMemberships getMembershipByUid(String currencyId, String uid); BlockchainMemberships getMembershipByPublicKey(String currencyId, String pubkey); @@ -220,18 +215,18 @@ public interface BlockchainRemoteService extends Service { * @param startOffset * @return */ + Map<Integer, Long> getUDs(Peer peer, long startOffset); Map<Integer, Long> getUDs(String currencyId, long startOffset); /** * Listening new block event - * @param currencyId * @param listener * @param autoReconnect * @return */ + WebsocketClientEndpoint addBlockListener(Peer peer, WebsocketClientEndpoint.MessageListener listener, boolean autoReconnect); WebsocketClientEndpoint addBlockListener(String currencyId, WebsocketClientEndpoint.MessageListener listener, boolean autoReconnect); - WebsocketClientEndpoint addBlockListener(Peer peer, WebsocketClientEndpoint.MessageListener listener, boolean autoReconnect); } \ No newline at end of file diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceImpl.java index c577dbc8b5bc982b9c135f1ccdb8fddcbd6079d3..ed3fc30e7f451a2277b141861b56bd0d444bca12 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceImpl.java @@ -22,6 +22,7 @@ package org.duniter.core.client.service.bma; * #L% */ +import com.google.common.collect.Maps; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; @@ -75,6 +76,8 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement public static final String URL_MEMBERSHIP_SEARCH = URL_BASE + "/memberships/%s"; + public static final String URL_DIFFICULTIES = URL_BASE + "/difficulties"; + public static final String URL_WS_BLOCK = "/ws/block"; private Configuration config; @@ -114,44 +117,56 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement } @Override - public BlockchainParameters getParameters(String currencyId, boolean useCache) { - if (!useCache) { - return getParameters(currencyId); + public BlockchainParameters getParameters(Peer peer, boolean useCache) { + if (!useCache || peer.getCurrency() == null) { + return getParameters(peer); } else { - return mParametersCache.get(currencyId); + BlockchainParameters result = mParametersCache.getIfPresent(peer.getCurrency()); + if (result == null) { + result = getParameters(peer); + if (result != null) { + mParametersCache.put(peer.getCurrency(), result); + } + } + return result; } } @Override - public BlockchainParameters getParameters(String currencyId) { - // get blockchain parameter - BlockchainParameters result = executeRequest(currencyId, URL_PARAMETERS, BlockchainParameters.class); - return result; + public BlockchainParameters getParameters(String currencyId, boolean useCache) { + return getParameters(peerService.getActivePeerByCurrencyId(currencyId), useCache); } @Override public BlockchainParameters getParameters(Peer peer) { - // get blockchain parameter - BlockchainParameters result = executeRequest(peer, URL_PARAMETERS, BlockchainParameters.class); - return result; + return httpService.executeRequest(peer, URL_PARAMETERS, BlockchainParameters.class); } @Override - public BlockchainBlock getBlock(String currencyId, long number) throws BlockNotFoundException { - String path = String.format(URL_BLOCK, number); + public BlockchainParameters getParameters(String currencyId) { + return getParameters(peerService.getActivePeerByCurrencyId(currencyId)); + } + + @Override + public BlockchainBlock getBlock(Peer peer, long number) throws BlockNotFoundException { try { - return executeRequest(currencyId, path, BlockchainBlock.class); + return httpService.executeRequest(peer, String.format(URL_BLOCK, number), BlockchainBlock.class); } catch(HttpNotFoundException e) { - throw new BlockNotFoundException(String.format("Block #%s not found", number)); + throw new BlockNotFoundException(String.format("Block #%s not found on peer [%s]", number, peer)); } } @Override - public Long getBlockDividend(String currencyId, long number) throws BlockNotFoundException { + public BlockchainBlock getBlock(String currencyId, long number) throws BlockNotFoundException { + return getBlock(peerService.getActivePeerByCurrencyId(currencyId), number); + } + + @Override + public Long getBlockDividend(Peer peer, long number) throws BlockNotFoundException { String path = String.format(URL_BLOCK, number); try { - String json = executeRequest(currencyId, path, String.class); + String json = httpService.executeRequest(peer, path, String.class); return getDividendFromBlockJson(json); } catch(HttpNotFoundException e) { @@ -159,23 +174,17 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement } } - @Override - public BlockchainBlock getBlock(Peer peer, long number) throws BlockNotFoundException { - // Get block from number - String path = String.format(URL_BLOCK, number); - try { - return executeRequest(peer, path, BlockchainBlock.class); - } - catch(HttpNotFoundException e) { - throw new BlockNotFoundException(String.format("Block #%s not found on peer [%s]", number, peer)); - } + public Long getBlockDividend(String currencyId, long number) throws BlockNotFoundException { + return getBlockDividend(peerService.getActivePeerByCurrencyId(currencyId), number); } + + @Override public long[] getBlocksWithTx(Peer peer) { try { - Blocks blocks = executeRequest(peer, URL_BLOCK_WITH_TX, Blocks.class); + Blocks blocks = httpService.executeRequest(peer, URL_BLOCK_WITH_TX, Blocks.class); return (blocks == null || blocks.getResult() == null) ? new long[0] : blocks.getResult().getBlocks(); } catch(HttpNotFoundException e) { @@ -189,7 +198,7 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement // get blockchain parameter String path = String.format(URL_BLOCK, number); try { - return executeRequest(peer, path, String.class); + return httpService.executeRequest(peer, path, String.class); } catch(HttpNotFoundException e) { throw new BlockNotFoundException(String.format("Block #%s not found on peer [%s]", number, peer)); @@ -200,7 +209,7 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement public String[] getBlocksAsJson(Peer peer, int count, int from) { // get blockchain parameter String path = String.format(URL_BLOCKS_FROM, count, from); - String jsonBlocksStr = executeRequest(peer, path, String.class); + String jsonBlocksStr = httpService.executeRequest(peer, path, String.class); // Parse only array content, but deserialize array item JsonArrayParser parser = new JsonArrayParser(); @@ -212,25 +221,35 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement * * @return */ - public BlockchainBlock getCurrentBlock(String currencyId, boolean useCache) { - if (!useCache) { - return getCurrentBlock(currencyId); + @Override + public BlockchainBlock getCurrentBlock(Peer peer, boolean useCache) { + if (!useCache || peer.getCurrency() == null) { + return getCurrentBlock(peer); } else { - return mCurrentBlockCache.get(currencyId); + BlockchainBlock result = mCurrentBlockCache.getIfPresent(peer.getCurrency()); + if (result == null) { + result = getCurrentBlock(peer); + if (result != null) { + mCurrentBlockCache.put(peer.getCurrency(), result); + } + } + return result; } } + public BlockchainBlock getCurrentBlock(String currencyId, boolean useCache) { + return getCurrentBlock(peerService.getActivePeerByCurrencyId(currencyId), useCache); + } + @Override public BlockchainBlock getCurrentBlock(String currencyId) { - // get blockchain parameter - BlockchainBlock result = executeRequest(currencyId, URL_BLOCK_CURRENT, BlockchainBlock.class); - return result; + return getCurrentBlock(peerService.getActivePeerByCurrencyId(currencyId)); } @Override public BlockchainBlock getCurrentBlock(Peer peer) { // get blockchain parameter - BlockchainBlock result = executeRequest(peer, URL_BLOCK_CURRENT, BlockchainBlock.class); + BlockchainBlock result = httpService.executeRequest(peer, URL_BLOCK_CURRENT, BlockchainBlock.class); return result; } @@ -241,7 +260,7 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement BlockchainBlock lastBlock = getCurrentBlock(peer); org.duniter.core.client.model.local.Currency result = new org.duniter.core.client.model.local.Currency(); - result.setCurrencyName(parameter.getCurrency()); + result.setId(parameter.getCurrency()); result.setFirstBlockSignature(firstBlock.getSignature()); result.setMembersCount(lastBlock.getMembersCount()); result.setLastUD(parameter.getUd0()); @@ -249,38 +268,10 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement return result; } - @Override - public BlockchainParameters getBlockchainParametersFromPeer(Peer peer){ - return getParameters(peer); - } - - @Override - public long getLastUD(String currencyId) { - // get block number with UD - String blocksWithUdResponse = executeRequest(currencyId, URL_BLOCK_WITH_UD, String.class); - Integer blockNumber = getLastBlockNumberFromJson(blocksWithUdResponse); - - // If no result (this could happen when no UD has been send - if (blockNumber == null) { - // get the first UD from currency parameter - BlockchainParameters parameter = getParameters(currencyId); - return parameter.getUd0(); - } - - // Get the UD from the last block with UD - Long lastUD = getBlockDividend(currencyId, blockNumber); - - // Check not null (should never append) - if (lastUD == null) { - throw new TechnicalException("Unable to get last UD from server"); - } - return lastUD.longValue(); - } - @Override public long getLastUD(Peer peer) { // get block number with UD - String blocksWithUdResponse = executeRequest(peer, URL_BLOCK_WITH_UD, String.class); + String blocksWithUdResponse = httpService.executeRequest(peer, URL_BLOCK_WITH_UD, String.class); int[] blocksWithUD = getBlockNumbersFromJson(blocksWithUdResponse); @@ -293,7 +284,7 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement try { // Get the UD from the last block with UD String path = String.format(URL_BLOCK, blocksWithUD[index]); - String json = executeRequest(peer, path, String.class); + String json = httpService.executeRequest(peer, path, String.class); Long lastUD = getDividendFromBlockJson(json); // Check not null (should never append) @@ -312,6 +303,11 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement return parameter.getUd0(); } + @Override + public long getLastUD(String currencyId) { + return getLastUD(peerService.getActivePeerByCurrencyId(currencyId)); + } + /** * Check is a identity is not already used by a existing member * @@ -414,25 +410,23 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); urlParameters.add(new BasicNameValuePair("membership", membership)); - HttpPost httpPost = new HttpPost(getPath(wallet.getCurrencyId(), URL_MEMBERSHIP)); + HttpPost httpPost = new HttpPost(httpService.getPath(wallet.getCurrencyId(), URL_MEMBERSHIP)); try { httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); } catch (UnsupportedEncodingException e) { throw new TechnicalException(e); } - String membershipResult = executeRequest(httpPost, String.class); + String membershipResult = httpService.executeRequest(httpPost, String.class); if (log.isDebugEnabled()) { log.debug("received from /tx/process: " + membershipResult); } - - executeRequest(httpPost, String.class); } public void requestMembership(Peer peer, String currency, byte[] pubKey, byte[] secKey, String uid, String membershipBlockUid, String selfBlockUid) { // http post /blockchain/membership - HttpPost httpPost = new HttpPost(getPath(peer, URL_MEMBERSHIP)); + HttpPost httpPost = new HttpPost(httpService.getPath(peer, URL_MEMBERSHIP)); // compute the self-certification String membership = getSignedMembership(currency, pubKey, secKey, uid, membershipBlockUid, selfBlockUid, true/*side in*/); @@ -448,32 +442,20 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement } // Execute the request - executeRequest(httpPost, String.class); + httpService.executeRequest(httpPost, String.class); } - public BlockchainMemberships getMembershipByPubkeyOrUid(String currencyId, String uidOrPubkey) { - String path = String.format(URL_MEMBERSHIP_SEARCH, uidOrPubkey); - - // search blockchain membership + public BlockchainMemberships getMembershipByPubkeyOrUid(Peer peer, String uidOrPubkey) { try { - return executeRequest(currencyId, path, BlockchainMemberships.class); + return httpService.executeRequest(peer, String.format(URL_MEMBERSHIP_SEARCH, uidOrPubkey), BlockchainMemberships.class); } catch (HttpBadRequestException e) { log.debug("No member matching this pubkey or uid: " + uidOrPubkey); return null; } } - public BlockchainMemberships getMembershipByPubkeyOrUid(Peer peer, String uidOrPubkey) { - String path = String.format(URL_MEMBERSHIP_SEARCH, uidOrPubkey); - - // search blockchain membership - try { - BlockchainMemberships result = executeRequest(peer, path, BlockchainMemberships.class); - return result; - } catch (HttpBadRequestException e) { - log.debug("No member matching this pubkey or uid: " + uidOrPubkey); - return null; - } + public BlockchainMemberships getMembershipByPubkeyOrUid(String currencyId, String uidOrPubkey) { + return getMembershipByPubkeyOrUid(peerService.getActivePeerByCurrencyId(currencyId), uidOrPubkey); } public String getMembership(Wallet wallet, @@ -501,22 +483,16 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement /** * Get UD, by block number * - * @param currencyId + * @param peer * @param startOffset * @return */ - public Map<Integer, Long> getUDs(String currencyId, long startOffset) { + public Map<Integer, Long> getUDs(Peer peer, long startOffset) { log.debug(String.format("Getting block's UD from block [%s]", startOffset)); - int[] blockNumbersWithUD = getBlocksWithUD(currencyId); - - Map<Integer, Long> result = new LinkedHashMap<Integer,Long>(); + int[] blockNumbersWithUD = getBlocksWithUD(peer); -// Insert the UD0 (if need) -// if (startOffset <= 0) { -// BlockchainParameters parameters = getParameters(currencyId, true/*with cache*/); -// result.put(0, parameters.getUd0()); -// } + Map<Integer, Long> result = Maps.newLinkedHashMap(); boolean previousBlockInsert = false; if (blockNumbersWithUD != null && blockNumbersWithUD.length != 0) { @@ -524,10 +500,10 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement for (Integer blockNumber : blockNumbersWithUD) { if (blockNumber >= startOffset) { if(!previousBlockInsert){ - Long previousUd = getParameters(currencyId, true/*with cache*/).getUd0(); + Long previousUd = getParameters(peer, true/*with cache*/).getUd0(); Integer previousBlockNumber = 0; if(previousBlockNumberWithUd!=null){ - previousUd = getBlockDividend(currencyId, previousBlockNumberWithUd); + previousUd = getBlockDividend(peer, previousBlockNumberWithUd); if (previousUd == null) { throw new TechnicalException( String.format("Unable to get UD from server block [%s]", @@ -539,7 +515,7 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement result.put(previousBlockNumber, previousUd); previousBlockInsert = true; } - Long ud = getBlockDividend(currencyId, blockNumber); + Long ud = getBlockDividend(peer, blockNumber); // Check not null (should never append) if (ud == null) { throw new TechnicalException(String.format("Unable to get UD from server block [%s]", blockNumber)); @@ -550,15 +526,21 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement } } }else{ - result.put(0, getParameters(currencyId, true/*with cache*/).getUd0()); + result.put(0, getParameters(peer, true/*with cache*/).getUd0()); } return result; } - @Override - public WebsocketClientEndpoint addBlockListener(String currencyId, WebsocketClientEndpoint.MessageListener listener, boolean autoReconnect) { - return addBlockListener(peerService.getActivePeerByCurrencyId(currencyId), listener, autoReconnect); + /** + * Get UD, by block number + * + * @param currencyId + * @param startOffset + * @return + */ + public Map<Integer, Long> getUDs(String currencyId, long startOffset) { + return getUDs(peerService.getActivePeerByCurrencyId(currencyId), startOffset); } @Override @@ -575,6 +557,20 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement return wsClientEndPoint; } + @Override + public WebsocketClientEndpoint addBlockListener(String currencyId, WebsocketClientEndpoint.MessageListener listener, boolean autoReconnect) { + return addBlockListener(peerService.getActivePeerByCurrencyId(currencyId), listener, autoReconnect); + } + + @Override + public BlockchainDifficulties getDifficulties(Peer peer) { + return httpService.executeRequest(peer, URL_DIFFICULTIES, BlockchainDifficulties.class, config.getNetworkLargerTimeout()); + } + + @Override + public BlockchainDifficulties getDifficulties(String currencyId) { + return getDifficulties(peerService.getActivePeerByCurrencyId(currencyId)); + } /* -- Internal methods -- */ @@ -646,12 +642,10 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement } - private int[] getBlocksWithUD(String currencyId) { + private int[] getBlocksWithUD(Peer peer) { log.debug("Getting blocks with UD"); - String json = executeRequest(currencyId, URL_BLOCK_WITH_UD, String.class); - - + String json = httpService.executeRequest(peer, URL_BLOCK_WITH_UD, String.class); int startIndex = json.indexOf("["); int endIndex = json.lastIndexOf(']'); @@ -685,6 +679,11 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement return result; } + private int[] getBlocksWithUD(String currencyId) { + Peer peer = peerService.getActivePeerByCurrencyId(currencyId); + return getBlocksWithUD(peer); + } + protected String getSignedMembership(String currency, byte[] pubKey, byte[] secKey, 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 a7c0e63eb3f24853a511e50919242f8beb4aac26..c05a640ae802332a1429e96839fd58cfcfd3e4a4 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 @@ -24,8 +24,6 @@ package org.duniter.core.client.service.bma; import java.io.IOException; import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.net.URISyntaxException; import java.util.*; import com.fasterxml.jackson.databind.JsonNode; @@ -35,13 +33,12 @@ import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.message.BasicNameValuePair; +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.model.local.Wallet; import org.duniter.core.exception.TechnicalException; import org.duniter.core.util.Preconditions; -import org.duniter.core.util.StringUtils; import org.duniter.core.util.websocket.WebsocketClientEndpoint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,13 +68,15 @@ public class NetworkRemoteServiceImpl extends BaseRemoteServiceImpl implements N public static final String URL_WS2P_HEADS = URL_WS2P + "/heads"; + public final Configuration config; + public NetworkRemoteServiceImpl() { super(); + this.config = Configuration.instance(); } public NetworkPeering getPeering(Peer peer) { - NetworkPeering result = httpService.executeRequest(peer, URL_PEERING, NetworkPeering.class); - return result; + return httpService.executeRequest(peer, URL_PEERING, NetworkPeering.class); } @Override @@ -125,9 +124,9 @@ public class NetworkRemoteServiceImpl extends BaseRemoteServiceImpl implements N public List<Peer> findPeers(Peer peer, String status, EndpointApi endpointApi, Integer currentBlockNumber, String currentBlockHash) { Preconditions.checkNotNull(peer); - List<Peer> result = new ArrayList<Peer>(); + List<Peer> result = Lists.newArrayList(); - NetworkPeers remoteResult = httpService.executeRequest(peer, URL_PEERS, NetworkPeers.class); + NetworkPeers remoteResult = httpService.executeRequest(peer, URL_PEERS, NetworkPeers.class, config.getNetworkLargerTimeout()); for (NetworkPeers.Peer remotePeer: remoteResult.peers) { boolean match = (status == null || status.equalsIgnoreCase(remotePeer.status)) @@ -161,7 +160,7 @@ public class NetworkRemoteServiceImpl extends BaseRemoteServiceImpl implements N public List<Ws2pHead> getWs2pHeads(Peer peer) { Preconditions.checkNotNull(peer); - NetworkWs2pHeads remoteResult = httpService.executeRequest(peer, URL_WS2P_HEADS, NetworkWs2pHeads.class); + NetworkWs2pHeads remoteResult = httpService.executeRequest(peer, URL_WS2P_HEADS, NetworkWs2pHeads.class, config.getNetworkLargerTimeout()); List<Ws2pHead> result = Lists.newArrayList(); @@ -210,7 +209,7 @@ public class NetworkRemoteServiceImpl extends BaseRemoteServiceImpl implements N Preconditions.checkNotNull(peeringDocument); // http post /tx/process - HttpPost httpPost = new HttpPost(getPath(peer, URL_PEERING_PEERS)); + HttpPost httpPost = new HttpPost(httpService.getPath(peer, URL_PEERING_PEERS)); if (log.isDebugEnabled()) { log.debug(String.format( @@ -227,7 +226,7 @@ public class NetworkRemoteServiceImpl extends BaseRemoteServiceImpl implements N throw new TechnicalException(e); } - String result = executeRequest(httpPost, String.class); + String result = httpService.executeRequest(httpPost, String.class); if (log.isDebugEnabled()) { log.debug("Received from " + URL_PEERING_PEERS + " (POST): " + result); } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/TransactionRemoteService.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/TransactionRemoteService.java index 0e5ab18a7569748dcce3f1229db76b93685d905f..e6d48bb839ac93950ec375578900d35292ef52dc 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/TransactionRemoteService.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/TransactionRemoteService.java @@ -58,17 +58,17 @@ public interface TransactionRemoteService extends Service { String transfer(Wallet wallet, String destPubKey, long amount, String comment) throws InsufficientCreditException; - TxSource getSources(String currencyId, String pubKey); - TxSource getSources(Peer peer, String pubKey); + TxSource getSources(String currencyId, String pubKey); + long getCreditOrZero(Peer peer, String pubKey); long getCreditOrZero(String currencyId, String pubKey); - Long getCredit(String currencyId, String pubKey); - Long getCredit(Peer peer, String pubKey); + Long getCredit(String currencyId, String pubKey); long computeCredit(TxSource.Source[] sources); + TxHistory getTxHistory(Peer peer, String pubKey, long fromBlockNumber, long toBlockNumber); TxHistory getTxHistory(String currencyId, String pubKey, long fromBlockNumber, long toBlockNumber); } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/TransactionRemoteServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/TransactionRemoteServiceImpl.java index 47c91a51dab46017ec0d4aa9f6e00bc25e35437e..7b02b75a48327ace8ad8a700ff8a07411cdc0dbe 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/TransactionRemoteServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/TransactionRemoteServiceImpl.java @@ -91,15 +91,12 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen Preconditions.checkNotNull(wallet); Preconditions.checkArgument(peer != null || wallet.getCurrencyId() != null); + peer = peer != null ? peer : peerService.getActivePeerByCurrencyId(wallet.getCurrencyId()); // Get current block - BlockchainBlock currentBlock = peer != null ? - executeRequest(peer, BlockchainRemoteServiceImpl.URL_BLOCK_CURRENT, BlockchainBlock.class) : - executeRequest(wallet.getCurrencyId(), BlockchainRemoteServiceImpl.URL_BLOCK_CURRENT, BlockchainBlock.class); + BlockchainBlock currentBlock = httpService.executeRequest(peer, BlockchainRemoteServiceImpl.URL_BLOCK_CURRENT, BlockchainBlock.class); // http post /tx/process - HttpPost httpPost = peer != null ? - new HttpPost(getPath(peer, URL_TX_PROCESS)) : - new HttpPost(getPath(wallet.getCurrencyId(), URL_TX_PROCESS)); + HttpPost httpPost = new HttpPost(httpService.getPath(peer, URL_TX_PROCESS)); // compute transaction String transaction = getSignedTransaction(peer, wallet, currentBlock, destPubKey, 0, amount, @@ -120,7 +117,7 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen throw new TechnicalException(e); } - String selfResult = executeRequest(httpPost, String.class); + String selfResult = httpService.executeRequest(httpPost, String.class); if (log.isDebugEnabled()) { log.debug("Received from /tx/process: " + selfResult); } @@ -136,17 +133,6 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen } - public TxSource getSources(String currencyId, String pubKey) { - if (log.isDebugEnabled()) { - log.debug(String.format("Get sources by pubKey: %s", pubKey)); - } - - // get parameter - String path = String.format(URL_TX_SOURCES, pubKey); - TxSource result = executeRequest(currencyId, path, TxSource.class); - - return result; - } public TxSource getSources(Peer peer, String pubKey) { if (log.isDebugEnabled()) { @@ -155,13 +141,17 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen // get parameter String path = String.format(URL_TX_SOURCES, pubKey); - TxSource result = executeRequest(peer, path, TxSource.class); + TxSource result = httpService.executeRequest(peer, path, TxSource.class); return result; } - public long getCreditOrZero(String currencyId, String pubKey) { - Long credit = getCredit(currencyId, pubKey); + public TxSource getSources(String currencyId, String pubKey) { + return getSources(peerService.getActivePeerByCurrencyId(currencyId), pubKey); + } + + public long getCreditOrZero(Peer peer, String pubKey) { + Long credit = getCredit(peer, pubKey); if (credit == null) { return 0; @@ -169,22 +159,9 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen return credit.longValue(); } - public Long getCredit(String currencyId, String pubKey) { - if (log.isDebugEnabled()) { - log.debug(String.format("Get credit by pubKey [%s] for currency [id=%s]", pubKey, currencyId)); - } - - // get parameter - String path = String.format(URL_TX_SOURCES, pubKey); - TxSource result = executeRequest(currencyId, path, TxSource.class); - - if (result == null) { - return null; - } - - // Compute the credit - return computeCredit(result.getSources()); - } + public long getCreditOrZero(String currencyId, String pubKey) { + return getCreditOrZero(peerService.getActivePeerByCurrencyId(currencyId), pubKey); + } public Long getCredit(Peer peer, String pubKey) { if (log.isDebugEnabled()) { @@ -193,7 +170,7 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen // get parameter String path = String.format(URL_TX_SOURCES, pubKey); - TxSource result = executeRequest(peer, path, TxSource.class); + TxSource result = httpService.executeRequest(peer, path, TxSource.class); if (result == null) { return null; @@ -203,8 +180,11 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen return computeCredit(result.getSources()); } + public Long getCredit(String currencyId, String pubKey) { + return getCredit(peerService.getActivePeerByCurrencyId(currencyId), pubKey); + } - public long computeCredit(TxSource.Source[] sources) { + public long computeCredit(TxSource.Source[] sources) { if (CollectionUtils.isEmpty(sources)) { return 0; } @@ -216,22 +196,26 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen return credit; } - public TxHistory getTxHistory(String currencyId, String pubKey, long fromBlockNumber, long toBlockNumber) { + public TxHistory getTxHistory(Peer peer, String pubKey, long start, long end) { Preconditions.checkNotNull(pubKey); - Preconditions.checkArgument(fromBlockNumber >= 0); - Preconditions.checkArgument(fromBlockNumber <= toBlockNumber); + Preconditions.checkArgument(start >= 0); + Preconditions.checkArgument(start <= end); if (log.isDebugEnabled()) { - log.debug(String.format("Get TX history by pubKey [%s], from block [%s -> %s]", pubKey, fromBlockNumber, toBlockNumber)); + log.debug(String.format("Get TX history by pubKey [%s], from block [%s -> %s]", pubKey, start, end)); } // get parameter - String path = String.format(URL_TX_HISTORY, pubKey, fromBlockNumber, toBlockNumber); - TxHistory result = executeRequest(currencyId, path, TxHistory.class); + String path = String.format(URL_TX_HISTORY, pubKey, start, end); + TxHistory result = httpService.executeRequest(peer, path, TxHistory.class); return result; } + public TxHistory getTxHistory(String currencyId, String pubKey, long start, long end) { + return getTxHistory(peerService.getActivePeerByCurrencyId(currencyId), pubKey, start, end); + } + /* -- internal methods -- */ protected String getSignedTransaction(Peer peer, diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteService.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteService.java index f89c399f433c277eed28ec2a95cac30bb5587f06..4cc37b8c4cfa2534577f1ec6943ff9387c79c242 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteService.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteService.java @@ -25,10 +25,7 @@ package org.duniter.core.client.service.bma; import org.duniter.core.beans.Service; import org.duniter.core.client.model.bma.WotCertification; import org.duniter.core.client.model.bma.WotLookup; -import org.duniter.core.client.model.local.Certification; -import org.duniter.core.client.model.local.Identity; -import org.duniter.core.client.model.local.Peer; -import org.duniter.core.client.model.local.Wallet; +import org.duniter.core.client.model.local.*; import java.util.Collection; import java.util.List; @@ -39,50 +36,54 @@ public interface WotRemoteService extends Service { List<Identity> findIdentities(Set<String> currenciesIds, String uidOrPubKey); + WotLookup.Uid find(Peer peer, String uidOrPubKey); WotLookup.Uid find(String currencyId, String uidOrPubKey); - void getRequirments(String currencyId, String pubKey); + void getRequirements(String currencyId, String pubKey); + WotLookup.Uid findByUid(Peer peer, String uid); WotLookup.Uid findByUid(String currencyId, String uid); - WotLookup.Uid findByUidAndPublicKey(String currencyId, String uid, String pubKey); - WotLookup.Uid findByUidAndPublicKey(Peer peer, String uid, String pubKey); + WotLookup.Uid findByUidAndPublicKey(String currencyId, String uid, String pubKey); + Identity getIdentity(Peer peer, String uid, String pubKey); Identity getIdentity(String currencyId, String uid, String pubKey); + Identity getIdentity(Peer peer, String pubKey); Identity getIdentity(String currencyId, String pubKey); - Identity getIdentity(Peer peer, String uid, String pubKey); - + Collection<Certification> getCertifications(Peer peer, String uid, String pubkey, boolean isMember); Collection<Certification> getCertifications(String currencyId, String uid, String pubkey, boolean isMember); + WotCertification getCertifiedBy(Peer peer, String uid); WotCertification getCertifiedBy(String currencyId, String uid); - int countValidCertifiers(String currencyId, String pubkey); - - WotCertification getCertifiersOf(String currencyId, String uid); + long countValidCertifiers(Peer peer, String pubkey); + long countValidCertifiers(String currencyId, String pubkey); - String getSignedIdentity(String currency, byte[] pubKey, byte[] secKey, String uid, String blockUid); + WotCertification getCertifiersOf(Peer peer, String uid); + WotCertification getCertifiersOf(String currencyId, String uid); - Map<String, String> getMembersUids(String currencyId); + String getSignedIdentity(String currencyId, byte[] pubKey, byte[] secKey, String uid, String blockUid); Map<String, String> getMembersUids(Peer peer); - - void sendIdentity(String currencyId, byte[] pubKey, byte[] secKey, String uid, String blockUid); + List<Member> getMembers(Peer peer); + List<Member> getMembers(String currencyId); void sendIdentity(Peer peer, String currency, byte[] pubKey, byte[] secKey, String uid, String blockUid); - - String getCertification(byte[] pubKey, byte[] secKey, String userUid, - String userTimestamp, - String userSignature); + void sendIdentity(String currencyId, byte[] pubKey, byte[] secKey, String uid, String blockUid); String sendCertification(Wallet wallet, Identity identity); + String sendCertification(Peer peer, + byte[] pubKey, byte[] secKey, + String userUid, String userPubKeyHash, + String userTimestamp, String userSignature); + String sendCertification(String currencyId, - byte[] pubKey, byte[] secKey, - String uid, String timestamp, - String userUid, String userPubKeyHash, + byte[] pubKey, byte[] secKey, + String userUid, String userPubKeyHash, String userTimestamp, String userSignature); } 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 f2869f899cf87c58ddee69ee2d8746fc8f6bfbda..19d86c775cdf63156c7c79f123ea960bc842976a 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 @@ -23,18 +23,17 @@ package org.duniter.core.client.service.bma; */ 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.model.ModelUtils; import org.duniter.core.client.model.bma.*; -import org.duniter.core.client.model.local.Certification; -import org.duniter.core.client.model.local.Identity; -import org.duniter.core.client.model.local.Peer; -import org.duniter.core.client.model.local.Wallet; +import org.duniter.core.client.model.local.*; import org.duniter.core.client.service.ServiceLocator; import org.duniter.core.client.service.local.CurrencyService; import org.duniter.core.exception.TechnicalException; import org.duniter.core.service.CryptoService; import org.duniter.core.util.CollectionUtils; -import org.duniter.core.util.ObjectUtils; import org.duniter.core.util.Preconditions; import org.duniter.core.util.crypto.CryptoUtils; import org.apache.http.NameValuePair; @@ -46,6 +45,7 @@ import org.slf4j.LoggerFactory; import java.io.UnsupportedEncodingException; import java.util.*; +import java.util.stream.Collectors; public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRemoteService { @@ -55,6 +55,8 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe public static final String URL_ADD = URL_BASE + "/add"; + public static final String URL_CERTIFY = URL_BASE + "/certify"; + public static final String URL_MEMBERS = URL_BASE + "/members"; public static final String URL_LOOKUP = URL_BASE + "/lookup/%s"; @@ -88,13 +90,14 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe } public List<Identity> findIdentities(Set<String> currenciesIds, String uidOrPubKey) { - List<Identity> result = new ArrayList<Identity>(); + List<Identity> result = Lists.newArrayList(); String path = String.format(URL_LOOKUP, uidOrPubKey); for (String currencyId: currenciesIds) { - WotLookup lookupResult = executeRequest(currencyId, path, WotLookup.class); + Peer peer = peerService.getActivePeerByCurrencyId(currencyId); + WotLookup lookupResult = httpService.executeRequest(peer, path, WotLookup.class); addAllIdentities(result, lookupResult, currencyId); } @@ -102,14 +105,14 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe return result; } - public WotLookup.Uid find(String currencyId, String uidOrPubKey) { + public WotLookup.Uid find(Peer peer, String uidOrPubKey) { if (log.isDebugEnabled()) { log.debug(String.format("Try to find user by looking up on [%s]", uidOrPubKey)); } // get parameter String path = String.format(URL_LOOKUP, uidOrPubKey); - WotLookup lookupResults = executeRequest(currencyId, path, WotLookup.class); + WotLookup lookupResults = httpService.executeRequest(peer, path, WotLookup.class); for (WotLookup.Result result : lookupResults.getResults()) { if (CollectionUtils.isNotEmpty(result.getUids())) { @@ -122,38 +125,50 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe } - public Map<String, String> getMembersUids(String currencyId) { - // get /wot/members - JsonNode json = executeRequest(currencyId, URL_MEMBERS, JsonNode.class); + public WotLookup.Uid find(String currencyId, String uidOrPubKey) { + return find(peerService.getActivePeerByCurrencyId(currencyId), uidOrPubKey); + } - if (json == null || !json.has("results")) return null; + @Override + public Map<String, String> getMembersUids(Peer peer) { + // get /wot/members + JsonNode json = httpService.executeRequest(peer, URL_MEMBERS, JsonNode.class); - Map<String, String> result = new HashMap<>(); + if (json == null || !json.has("results")) return null; + Map<String, String> result = Maps.newHashMap(); json.get("results").forEach(entry -> { - result.put(entry.get("pubkey").asText(), entry.get("uid").asText()); + result.put( + entry.get("pubkey").asText(), + entry.get("uid").asText() + ); }); return result; } - public Map<String, String> getMembersUids(Peer peer) { - // get /wot/members - JsonNode json = executeRequest(peer, URL_MEMBERS, JsonNode.class); + public List<Member> getMembers(Peer peer) { - if (json == null || !json.has("results")) return null; + Map<String, String> map = getMembersUids(peer); + if (MapUtils.isEmpty(map)) return null; - Map<String, String> result = new HashMap<>(); + return map.entrySet().stream().map(entry -> { + Member member = new Member(); + member.setPubkey(entry.getKey()); + member.setUid(entry.getValue()); + member.setMember(true); + return member; + }).collect(Collectors.toList()); + } - json.get("results").forEach(entry -> { - result.put(entry.get("pubkey").asText(), entry.get("uid").asText()); - }); + public List<Member> getMembers(String currencyId) { + List<Member> result = getMembers(peerService.getActivePeerByCurrencyId(currencyId)); + result.forEach(m -> m.setCurrency(currencyId)); return result; } - - public void getRequirments(String currencyId, String pubKey) { + public void getRequirements(String currencyId, String pubKey) { if (log.isDebugEnabled()) { - log.debug(String.format("Try to find user requirements on [%s]", pubKey)); + log.debug(String.format("TODO: implement /wot/requirements on [%s]", pubKey)); } // get parameter String path = String.format(URL_REQUIREMENT, pubKey); @@ -162,14 +177,14 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe } - public WotLookup.Uid findByUid(String currencyId, String uid) { + public WotLookup.Uid findByUid(Peer peer, String uid) { if (log.isDebugEnabled()) { log.debug(String.format("Try to find user info by uid: %s", uid)); } // call lookup String path = String.format(URL_LOOKUP, uid); - WotLookup lookupResults = executeRequest(currencyId, path, WotLookup.class); + WotLookup lookupResults = httpService.executeRequest(peer, path, WotLookup.class); // Retrieve the exact uid WotLookup.Uid uniqueResult = getUid(lookupResults, uid); @@ -180,22 +195,12 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe return uniqueResult; } - public WotLookup.Uid findByUidAndPublicKey(String currencyId, String uid, String pubKey) { - if (log.isDebugEnabled()) { - log.debug(String.format("Try to find user info by uid [%s] and pubKey [%s]", uid, pubKey)); - } - - // call lookup - String path = String.format(URL_LOOKUP, uid); - WotLookup lookupResults = executeRequest(currencyId, path, WotLookup.class); - - // Retrieve the exact uid - WotLookup.Uid uniqueResult = getUidByUidAndPublicKey(lookupResults, uid, pubKey); - if (uniqueResult == null) { - return null; - } + public WotLookup.Uid findByUid(String currencyId, String uid) { + return findByUid(peerService.getActivePeerByCurrencyId(currencyId), uid); + } - return uniqueResult; + public WotLookup.Uid findByUidAndPublicKey(String currencyId, String uid, String pubKey) { + return findByUidAndPublicKey(peerService.getActivePeerByCurrencyId(currencyId), uid, pubKey); } public WotLookup.Uid findByUidAndPublicKey(Peer peer, String uid, String pubKey) { @@ -205,7 +210,7 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe // call lookup String path = String.format(URL_LOOKUP, uid); - WotLookup lookupResults = executeRequest(peer, path, WotLookup.class); + WotLookup lookupResults = httpService.executeRequest(peer, path, WotLookup.class); // Retrieve the exact uid WotLookup.Uid uniqueResult = getUidByUidAndPublicKey(lookupResults, uid, pubKey); @@ -217,130 +222,113 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe } public Identity getIdentity(String currencyId, String uid, String pubKey) { + return getIdentity(peerService.getActivePeerByCurrencyId(currencyId), uid, pubKey); + } + + public Identity getIdentity(Peer peer, String uid, String pubKey) { if (log.isDebugEnabled()) { log.debug(String.format("Get identity by uid [%s] and pubKey [%s]", uid, pubKey)); } - WotLookup.Uid lookupUid = findByUidAndPublicKey(currencyId, uid, pubKey); + WotLookup.Uid lookupUid = findByUidAndPublicKey(peer, uid, pubKey); if (lookupUid == null) { return null; } - return toIdentity(lookupUid); - } - public Identity getIdentity(String currencyId, String pubKey) { -// Log.d(TAG, String.format("Get identity by uid [%s] and pubKey [%s]", uid, pubKey)); - - WotLookup.Uid lookupUid = find(currencyId, pubKey); - if (lookupUid == null) { - return null; - } Identity result = toIdentity(lookupUid); result.setPubkey(pubKey); - result.setCurrencyId(currencyId); return result; } - public Identity getIdentity(Peer peer, String uid, String pubKey) { + public Identity getIdentity(String currencyId, String pubKey) { + return getIdentity(peerService.getActivePeerByCurrencyId(currencyId), pubKey); + } + + @Override + public Identity getIdentity(Peer peer, String pubKey) { if (log.isDebugEnabled()) { - log.debug(String.format("Get identity by uid [%s] and pubKey [%s]", uid, pubKey)); + log.debug(String.format("Get identity by pubKey [%s]", pubKey)); } - WotLookup.Uid lookupUid = findByUidAndPublicKey(peer, uid, pubKey); + WotLookup.Uid lookupUid = find(peer, pubKey); if (lookupUid == null) { return null; } - return toIdentity(lookupUid); + Identity result = toIdentity(lookupUid); + result.setPubkey(pubKey); + result.setCurrency(peer.getCurrency()); + return result; } - public Collection<Certification> getCertifications(String currencyId, String uid, String pubkey, boolean isMember) { + + public Collection<Certification> getCertifications(Peer peer, String uid, String pubkey, boolean isMember) { Preconditions.checkNotNull(uid); Preconditions.checkNotNull(pubkey); if (isMember) { - return getCertificationsByPubkeyForMember(currencyId, pubkey, true); + return getCertificationsByPubkeyForMember(peer, pubkey, true); } else { - return getCertificationsByPubkeyForNonMember(currencyId, uid, pubkey); + return getCertificationsByPubkeyForNonMember(peer, uid, pubkey); } } + public Collection<Certification> getCertifications(String currencyId, String uid, String pubkey, boolean isMember) { + return getCertifications(peerService.getActivePeerByCurrencyId(currencyId), uid, pubkey, isMember); + } - public WotCertification getCertifiedBy(String currencyId, String uid) { + public WotCertification getCertifiedBy(Peer peer, String uid) { if (log.isDebugEnabled()) { log.debug(String.format("Try to get certifications done by uid: %s", uid)); } // call certified-by String path = String.format(URL_CERTIFIED_BY, uid); - WotCertification result = executeRequest(currencyId, path, WotCertification.class); + WotCertification result = httpService.executeRequest(peer, path, WotCertification.class); return result; + } + + public WotCertification getCertifiedBy(String currencyId, String uid) { + return getCertifiedBy(peerService.getActivePeerByCurrencyId(currencyId), uid); } - public int countValidCertifiers(String currencyId, String pubkey) { + public long countValidCertifiers(Peer peer, String pubkey) { if (log.isDebugEnabled()) { log.debug(String.format("Try to count valid certifications done by pubkey: %s", pubkey)); } - int count =0; - // call certified-by - Collection<Certification> certifiersOf = getCertificationsByPubkeyForMember(currencyId, pubkey, false/*only certifiers of*/); - if (CollectionUtils.isEmpty(certifiersOf)) { - return 0; - } - - for(Certification certifier : certifiersOf){ - if(certifier.isValid()){ - count++; - } - } + Collection<Certification> certifiersOf = getCertificationsByPubkeyForMember(peer, pubkey, false/*only certifiers of*/); + if (CollectionUtils.isEmpty(certifiersOf)) return 0; - return count; + return certifiersOf.stream().filter(Certification::isValid).count(); + } + public long countValidCertifiers(String currencyId, String pubkey) { + return countValidCertifiers(peerService.getActivePeerByCurrencyId(currencyId), pubkey); } - public WotCertification getCertifiersOf(String currencyId, String uid) { + public WotCertification getCertifiersOf(Peer peer, String uid) { if (log.isDebugEnabled()) { log.debug(String.format("Try to get certifications done to uid: %s", uid)); } // call certifiers-of String path = String.format(URL_CERTIFIERS_OF, uid); - WotCertification result = executeRequest(currencyId, path, WotCertification.class); + WotCertification result = httpService.executeRequest(peer, path, WotCertification.class); return result; } - - public void sendIdentity(String currencyId, byte[] pubKey, byte[] secKey, String userId, String blockUid) { - // http post /wot/add - HttpPost httpPost = new HttpPost(getPath(currencyId, URL_ADD)); - - String currency = currencyService.getCurrencyNameById(currencyId); - - // compute the self-certification - String identity = getSignedIdentity(currency, pubKey, secKey, userId, blockUid); - - List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); - urlParameters.add(new BasicNameValuePair("identity", identity)); - - try { - httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); - } - catch(UnsupportedEncodingException e) { - throw new TechnicalException(e); - } - - // Execute the request - executeRequest(httpPost, String.class); + public WotCertification getCertifiersOf(String currencyId, String uid) { + return getCertifiersOf(peerService.getActivePeerByCurrencyId(currencyId), uid); } public void sendIdentity(Peer peer, String currency, byte[] pubKey, byte[] secKey, String uid, String blockUid) { // http post /wot/add - HttpPost httpPost = new HttpPost(getPath(peer, URL_ADD)); + HttpPost httpPost = new HttpPost(httpService.getPath(peer, URL_ADD)); // compute the self-certification String identity = getSignedIdentity(currency, pubKey, secKey, uid, blockUid); @@ -356,34 +344,27 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe } // Execute the request - executeRequest(httpPost, String.class); + httpService.executeRequest(httpPost, String.class); } - public String sendCertification(Wallet wallet, - Identity identity) { - return sendCertification( - wallet.getCurrencyId(), - wallet.getPubKey(), - wallet.getSecKey(), - wallet.getIdentity().getUid(), - wallet.getIdentity().getTimestamp(), - identity.getUid(), - identity.getPubkey(), - identity.getTimestamp(), - identity.getSignature()); + public void sendIdentity(String currencyId, byte[] pubKey, byte[] secKey, String uid, String blockUid) { + String currency = currencyService.getNameById(currencyId); + sendIdentity(peerService.getActivePeerByCurrencyId(currencyId), currency, pubKey, secKey, uid, blockUid); } - public String sendCertification(String currencyId, - byte[] pubKey, byte[] secKey, - String uid, String timestamp, - String userUid, String userPubKeyHash, - String userBlockUid, String userSignature) { + public String sendCertification(Peer peer, + byte[] pubKey, + byte[] secKey, + String idtyUid, + String idtyIssuer, + String idtyBlockUid, + String idtySignature) { // http post /wot/add - HttpPost httpPost = new HttpPost(getPath(currencyId, URL_ADD)); + HttpPost httpPost = new HttpPost(httpService.getPath(peer, URL_CERTIFY)); // Read the current block (number and hash) BlockchainRemoteService blockchainService = ServiceLocator.instance().getBlockchainRemoteService(); - BlockchainBlock currentBlock = blockchainService.getCurrentBlock(currencyId); + BlockchainBlock currentBlock = blockchainService.getCurrentBlock(peer); int blockNumber = currentBlock.getNumber(); String blockHash = (blockNumber != 0) ? currentBlock.getHash() @@ -392,20 +373,16 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe // Compute the pub key hash String pubKeyHash = CryptoUtils.encodeBase58(pubKey); - // compute signed identity - String identity = getIdentity(currentBlock.getCurrency(), - pubKeyHash, userUid, userBlockUid, userSignature); - // Compute the certification - String certification = null; /* FIXME getCertification(pubKey, secKey, - userUid, userBlockUid, userSignature, - blockNumber, blockHash);*/ - String inlineCertification = toInlineCertification(pubKeyHash, userPubKeyHash, certification); + String certification = getCertification( + currentBlock.getCurrency(), + pubKeyHash, + secKey, + idtyIssuer, idtyUid, idtyBlockUid, idtySignature, + blockNumber, blockHash); List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); - urlParameters.add(new BasicNameValuePair("identity", identity)); - urlParameters.add(new BasicNameValuePair("self", identity)); - urlParameters.add(new BasicNameValuePair("other", inlineCertification)); + urlParameters.add(new BasicNameValuePair("cert", certification)); try { httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); @@ -413,12 +390,35 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe catch(UnsupportedEncodingException e) { throw new TechnicalException(e); } - String selfResult = executeRequest(httpPost, String.class); - log.debug("received from /add: " + selfResult); + String selfResult = httpService.executeRequest(httpPost, String.class); + log.debug("received from /wot/certify: " + selfResult); return selfResult; } + public String sendCertification(String currencyId, + byte[] pubKey, byte[] secKey, + String idtyIssuer, + String idtyUid, + String idtyBlockUid, + String idtySignature) { + return sendCertification( + peerService.getActivePeerByCurrencyId(currencyId), + pubKey, secKey, idtyIssuer, idtyUid,idtyBlockUid, idtySignature); + } + + public String sendCertification(Wallet wallet, + Identity identity) { + return sendCertification( + wallet.getCurrencyId(), + wallet.getPubKey(), + wallet.getSecKey(), + identity.getUid(), + identity.getPubkey(), + identity.getTimestamp(), + identity.getSignature()); + } + public void addAllIdentities(List<Identity> result, WotLookup lookupResults, String currencyName) { for (WotLookup.Result lookupResult: lookupResults.getResults()) { @@ -433,7 +433,7 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe // Fill currency id and name // TODO - target.setCurrencyId(currencyName); + target.setCurrency(currencyName); result.add(target); } @@ -471,10 +471,10 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe /* -- Internal methods -- */ - protected Collection<Certification> getCertificationsByPubkeyForMember(String currencyId, String pubkey, boolean onlyCertifiersOf) { + protected Collection<Certification> getCertificationsByPubkeyForMember(Peer peer, String pubkey, boolean onlyCertifiersOf) { - BlockchainParameters bcParameter = bcService.getParameters(currencyId, true); - BlockchainBlock currentBlock = bcService.getCurrentBlock(currencyId, true); + BlockchainParameters bcParameter = bcService.getParameters(peer, true); + BlockchainBlock currentBlock = bcService.getCurrentBlock(peer, true); long medianTime = currentBlock.getMedianTime(); int sigValidity = bcParameter.getSigValidity(); int sigQty = bcParameter.getSigQty(); @@ -482,14 +482,14 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe Collection<Certification> result = new TreeSet<Certification>(ModelUtils.newWotCertificationComparatorByUid()); // Certifiers of - WotCertification certifiersOfList = getCertifiersOf(currencyId, pubkey); + WotCertification certifiersOfList = getCertifiersOf(peer, pubkey); boolean certifiersOfIsEmpty = (certifiersOfList == null || certifiersOfList.getCertifications() == null); int validWrittenCertifiersCount = 0; if (!certifiersOfIsEmpty) { for (WotCertification.Certification certifier : certifiersOfList.getCertifications()) { - Certification cert = toCertification(certifier, currencyId); + Certification cert = toCertification(certifier); cert.setCertifiedBy(false); result.add(cert); @@ -521,14 +521,14 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe if (!onlyCertifiersOf) { // Certified by - WotCertification certifiedByList = getCertifiedBy(currencyId, pubkey); + WotCertification certifiedByList = getCertifiedBy(peer, pubkey); boolean certifiedByIsEmpty = (certifiedByList == null || certifiedByList.getCertifications() == null); if (!certifiedByIsEmpty) { for (WotCertification.Certification certifiedBy : certifiedByList.getCertifications()) { - Certification cert = toCertification(certifiedBy, currencyId); + Certification cert = toCertification(certifiedBy); cert.setCertifiedBy(true); result.add(cert); @@ -552,7 +552,14 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe return result; } - protected Collection<Certification> getCertificationsByPubkeyForNonMember(String currencyId, final String uid, final String pubkey) { + protected Collection<Certification> getCertificationsByPubkeyForMember(final String currencyId, String pubkey, boolean onlyCertifiersOf) { + Collection<Certification> result = getCertificationsByPubkeyForMember(peerService.getActivePeerByCurrencyId(currencyId), pubkey, onlyCertifiersOf); + result.forEach(c -> c.setCurrencyId(currencyId)); + return result; + } + + + protected Collection<Certification> getCertificationsByPubkeyForNonMember(Peer peer, final String uid, final String pubkey) { // Ordered list, by uid/pubkey/cert time Collection<Certification> result = new TreeSet<>(ModelUtils.newWotCertificationComparatorByUid()); @@ -563,7 +570,7 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe // call lookup String path = String.format(URL_LOOKUP, pubkey); - WotLookup lookupResults = executeRequest(currencyId, path, WotLookup.class); + WotLookup lookupResults = httpService.executeRequest(peer, path, WotLookup.class); // Retrieve the exact uid WotLookup.Uid lookupUId = getUidByUidAndPublicKey(lookupResults, uid, pubkey); @@ -572,7 +579,7 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe Map<String, Certification> certifierByPubkeys = new HashMap<>(); if (lookupUId != null && lookupUId.getOthers() != null) { for(WotLookup.OtherSignature lookupSignature: lookupUId.getOthers()) { - Collection<Certification> certifiers = toCertifierCertifications(lookupSignature, currencyId); + Collection<Certification> certifiers = toCertifierCertifications(lookupSignature); result.addAll(certifiers); } } @@ -584,9 +591,6 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe for(WotLookup.SignedSignature lookupSignature : lookupResult.getSigned()) { Certification certifiedBy = toCertifiedByCerticication(lookupSignature); - // Set the currency Id - certifiedBy.setCurrencyId(currencyId); - // If exists, link to other side certification String certifiedByPubkey = certifiedBy.getPubkey(); if (certifierByPubkeys.containsKey(certifiedByPubkey)) { @@ -609,6 +613,12 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe return result; } + protected Collection<Certification> getCertificationsByPubkeyForNonMember(String currencyId, final String uid, final String pubkey) { + Collection<Certification> result = getCertificationsByPubkeyForNonMember(peerService.getActivePeerByCurrencyId(currencyId), uid, pubkey); + result.forEach(c -> c.setCurrencyId(currencyId)); + return result; + } + protected String toInlineCertification(String pubKeyHash, String userPubKeyHash, String certification) { @@ -642,12 +652,26 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe .toString(); } - public String getCertification(byte[] pubKey, byte[] secKey, String userUid, - String userTimestamp, - String userSignature) { + public String getCertification(String currency, + String issuer, + byte[] secKey, + String idtyIssuer, + String idtyUid, + String idtyTimestamp, + String idtySignature, + int certBlockNumber, + String certBlockHash) { + // Create the self part to sign String unsignedCertification = getCertificationUnsigned( - userUid, userTimestamp, userSignature); + currency, + issuer, + idtyIssuer, + idtyUid, + idtyTimestamp, + idtySignature, + certBlockNumber, + certBlockHash); // Compute the signature String signature = cryptoService.sign(unsignedCertification, secKey); @@ -660,21 +684,25 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe .toString(); } - protected String getCertificationUnsigned(String userUid, - String userTimestamp, - String userSignature) { + protected String getCertificationUnsigned(String currency, + String issuer, + String idtyPubkey, + String idtyUid, + String idtyTimestamp, + String idtySignature, + int certBlockNumber, + String certBlockHash) { // Create the self part to sign return new StringBuilder() - .append("UID:") - .append(userUid) - .append("\nMETA:TS:") - .append(userTimestamp) - .append('\n') - .append(userSignature) - /*.append("\nMETA:TS:") - .append(blockNumber) - .append('-') - .append(blockHash)*/ + .append("Version: ").append(Protocol.VERSION) + .append("\nType: ").append(Protocol.TYPE_CERTIFICATION) + .append("\nCurrency: ").append(currency) + .append("\nIssuer: ").append(issuer) + .append("\nIdtyIssuer: ").append(idtyPubkey) + .append("\nIdtyUniqueID: ").append(idtyUid) + .append("\nIdtyTimestamp: ").append(idtyTimestamp) + .append("\nIdtySignature: ").append(idtySignature) + .append("\nCertTimestamp: ").append(certBlockNumber).append('-').append(certBlockHash) .append('\n').toString(); } @@ -724,6 +752,9 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe protected WotLookup.Uid getUidByUidAndPublicKey(WotLookup lookupResults, String filterUid, String filterPublicKey) { + Preconditions.checkNotNull(filterUid); + Preconditions.checkNotNull(filterPublicKey); + if (lookupResults.getResults() == null || lookupResults.getResults().length == 0) { return null; } @@ -744,17 +775,16 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe return null; } - private Certification toCertification(final WotCertification.Certification source, final String currencyId) { + private Certification toCertification(final WotCertification.Certification source) { Certification target = new Certification(); target.setPubkey(source.getPubkey()); target.setUid(source.getUid()); target.setMember(source.getIsMember()); - target.setCurrencyId(currencyId); return target; } - private Collection<Certification> toCertifierCertifications(final WotLookup.OtherSignature source, final String currencyId) { + private Collection<Certification> toCertifierCertifications(final WotLookup.OtherSignature source) { List<Certification> result = new ArrayList<Certification>(); // If only one uid if (source.getUids().length == 1) { @@ -772,8 +802,6 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe // Is member target.setMember(source.isMember()); - // Set currency Id - target.setCurrencyId(currencyId); result.add(target); } @@ -793,9 +821,6 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe // Is member target.setMember(source.isMember()); - // Set currency Id - target.setCurrencyId(currencyId); - result.add(target); } } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceImpl.java index bfc93ec1b05a0f43056da194333df5052c3b4c1e..8ea61b6acb2920430d46ca0987f009e779cfcc2d 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceImpl.java @@ -101,8 +101,8 @@ public class CurrencyRegistryRemoteServiceImpl extends BaseRemoteServiceImpl imp } // get currency - String path = getPath(peer, URL_ALL_CURRENCY_NAMES); - String jsonResponse = executeRequest(new HttpGet(path), String.class); + String path = httpService.getPath(peer, URL_ALL_CURRENCY_NAMES); + String jsonResponse = httpService.executeRequest(new HttpGet(path), String.class); List<String> currencyNames = new JsonAttributeParser<>("currencyName", String.class).getValues(jsonResponse); diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/CurrencyService.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/CurrencyService.java index 45b2e7916a66befe2b2640d4ec964ec19db1b2f8..3f9809c4d386f10c8fc5ecd9de6c07939d2af841 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/CurrencyService.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/CurrencyService.java @@ -36,41 +36,37 @@ public interface CurrencyService extends Service { Currency save(final Currency currency); - List<Currency> getCurrencies(long accountId); + List<Currency> getAll(); - Currency getCurrencyById(String currencyId); + List<Currency> getAllByAccount(long accountId); + + Currency getById(String currencyId); /** * Return a (cached) currency name, by id * @param currencyId * @return */ - String getCurrencyNameById(String currencyId); + String getNameById(String currencyId); /** * Return a currency id, by name * @param currencyName * @return */ - String getCurrencyIdByName(String currencyName); + String getIdByName(String currencyName); /** * Return a (cached) list of currency ids * @return */ - Set<String> getCurrencyIds(); + Set<String> getAllIds(); /** * Return a (cached) number of registered currencies * @return */ - int getCurrencyCount(); - - /** - * Fill allOfToList cache need for currencies - * @param context - */ - void loadCache(long accountId); + int count(); /** * Return the value of the last universal dividend diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/CurrencyServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/CurrencyServiceImpl.java index 50fcb9b14daf3c10cd75f02516a400a06fc54f44..ccee8dee01762ac540e16852a5ec20ec91b184b4 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/CurrencyServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/CurrencyServiceImpl.java @@ -27,6 +27,7 @@ import org.duniter.core.client.dao.CurrencyDao; import org.duniter.core.client.model.local.Currency; import org.duniter.core.client.service.ServiceLocator; import org.duniter.core.client.service.bma.BlockchainRemoteService; +import org.duniter.core.util.CollectionUtils; import org.duniter.core.util.ObjectUtils; import org.duniter.core.util.Preconditions; import org.duniter.core.util.StringUtils; @@ -37,6 +38,7 @@ import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; /** @@ -62,11 +64,8 @@ public class CurrencyServiceImpl implements CurrencyService, InitializingBean { blockchainRemoteService = ServiceLocator.instance().getBlockchainRemoteService(); currencyDao = ServiceLocator.instance().getBean(CurrencyDao.class); - // Load cache from account - long accountId = ServiceLocator.instance().getDataContext().getAccountId(); - if (accountId != -1) { - loadCache(accountId); - } + // Load cache + initCaches(); } @Override @@ -76,13 +75,13 @@ public class CurrencyServiceImpl implements CurrencyService, InitializingBean { } public Currency save(final Currency currency) { - ObjectUtils.checkNotNull(currency); - ObjectUtils.checkArgument(StringUtils.isNotBlank(currency.getCurrencyName())); - ObjectUtils.checkArgument(StringUtils.isNotBlank(currency.getFirstBlockSignature())); - ObjectUtils.checkNotNull(currency.getMembersCount()); - ObjectUtils.checkArgument(currency.getMembersCount().intValue() >= 0); - ObjectUtils.checkNotNull(currency.getLastUD()); - ObjectUtils.checkArgument(currency.getLastUD().longValue() > 0); + Preconditions.checkNotNull(currency); + Preconditions.checkArgument(StringUtils.isNotBlank(currency.getId())); + Preconditions.checkArgument(StringUtils.isNotBlank(currency.getFirstBlockSignature())); + Preconditions.checkNotNull(currency.getMembersCount()); + Preconditions.checkArgument(currency.getMembersCount().intValue() >= 0); + Preconditions.checkNotNull(currency.getLastUD()); + Preconditions.checkArgument(currency.getLastUD().longValue() > 0); Currency result; @@ -106,12 +105,18 @@ public class CurrencyServiceImpl implements CurrencyService, InitializingBean { return result; } - public List<Currency> getCurrencies(long accountId) { - return currencyDao.getCurrencies(accountId); + public List<Currency> getAllByAccount(long accountId) { + return currencyDao.getAllByAccount(accountId); } + public List<Currency> getAll() { + Set<String> ids = currencyDao.getAllIds(); + return ids.stream() + .map(id -> getById(id)) + .collect(Collectors.toList()); + } - public Currency getCurrencyById(String currencyId) { + public Currency getById(String currencyId) { return mCurrencyCache.get(currencyId); } @@ -120,12 +125,12 @@ public class CurrencyServiceImpl implements CurrencyService, InitializingBean { * @param currencyId * @return */ - public String getCurrencyNameById(String currencyId) { - Currency currency = mCurrencyCache.getIfPresent(currencyId); + public String getNameById(String currencyId) { + Currency currency = mCurrencyCache != null ? mCurrencyCache.getIfPresent(currencyId) : null; if (currency == null) { return null; } - return currency.getCurrencyName(); + return currency.getId(); } /** @@ -133,13 +138,13 @@ public class CurrencyServiceImpl implements CurrencyService, InitializingBean { * @param currencyName * @return */ - public String getCurrencyIdByName(String currencyName) { + public String getIdByName(String currencyName) { Preconditions.checkArgument(StringUtils.isNotBlank(currencyName)); // Search from currencies for (Map.Entry<String, Currency> entry : mCurrencyCache.entrySet()) { Currency currency = entry.getValue(); - if (ObjectUtils.equals(currencyName, currency.getCurrencyName())) { + if (ObjectUtils.equals(currencyName, currency.getId())) { return entry.getKey(); } } @@ -150,62 +155,65 @@ public class CurrencyServiceImpl implements CurrencyService, InitializingBean { * Return a (cached) list of currency ids * @return */ - public Set<String> getCurrencyIds() { - return mCurrencyCache.keySet(); + public Set<String> getAllIds() { + Set<String> ids = mCurrencyCache.keySet(); + if (CollectionUtils.isEmpty(ids)) { + ids = currencyDao.getAllIds(); + } + return ids; } /** * Return a (cached) number of registered currencies * @return */ - public int getCurrencyCount() { + public int count() { return mCurrencyCache.entrySet().size(); } - /** * Fill allOfToList cache need for currencies - * @param accountId */ - public void loadCache(long accountId) { - if (mCurrencyCache == null || mUDCache == null) { - // Create and fill the currency cache - List<Currency> currencies = getCurrencies(accountId); - if (mCurrencyCache == null) { - - mCurrencyCache = new SimpleCache<String, Currency>() { - @Override - public Currency load(String currencyId) { - return currencyDao.getById(currencyId); - } - }; + public void initCaches() { + if (mCurrencyCache != null && mUDCache != null) return; + + // Create and fill the currency cache + if (mCurrencyCache == null) { - // Fill the cache - for (Currency currency : currencies) { - mCurrencyCache.put(currency.getId(), currency); + mCurrencyCache = new SimpleCache<String, Currency>() { + @Override + public Currency load(String currencyId) { + return currencyDao.getById(currencyId); } - } + }; - // Create the UD cache - if (mUDCache == null) { + // Fill cache for the configured account + long accountId = ServiceLocator.instance().getDataContext().getAccountId(); + List<Currency> currencies = (accountId != -1) ? getAllByAccount(accountId) : getAll(); + for (Currency currency : currencies) { + mCurrencyCache.put(currency.getId(), currency); + } + } - mUDCache = new SimpleCache<String, Long>(UD_CACHE_TIME_MILLIS) { - @Override - public Long load(final String currencyId) { - // Retrieve the last UD from the blockchain - final Long lastUD = blockchainRemoteService.getLastUD(currencyId); + // Create the UD cache + if (mUDCache == null) { - // Update currency - Currency currency = getCurrencyById(currencyId); - if (!ObjectUtils.equals(currency.getLastUD(), lastUD)) { - currency.setLastUD(lastUD); - currencyDao.update(currency); - } + mUDCache = new SimpleCache<String, Long>(UD_CACHE_TIME_MILLIS) { + @Override + public Long load(final String currencyId) { + // Retrieve the last UD from the blockchain + final Long lastUD = blockchainRemoteService.getLastUD(currencyId); - return lastUD; + // Update currency + Currency currency = getById(currencyId); + if (!ObjectUtils.equals(currency.getLastUD(), lastUD)) { + currency.setLastUD(lastUD); + currencyDao.update(currency); } - }; - } + + return lastUD; + } + }; } } 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 d61105851966400ec56f3b8cd9c52c9db4701da7..8df91db7ac21c2ab6a4a1127dc0dc9289d374cf7 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 @@ -25,6 +25,7 @@ package org.duniter.core.client.service.local; import com.fasterxml.jackson.databind.JsonNode; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import org.duniter.core.client.config.Configuration; import org.duniter.core.client.model.bma.*; import org.duniter.core.client.model.local.Peer; @@ -370,7 +371,7 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network final String currency = filter != null && filter.currency != null ? filter.currency : blockchainRemoteService.getParameters(mainPeer).getCurrency(); - final List<String> knownBlocks = new ArrayList<>(); + final Set<String> knownBlocks = Sets.newHashSet(); final Predicate<Peer> peerFilter = peerFilter(filter); final Comparator<Peer> peerComparator = peerComparator(sort); final ExecutorService pool = (executor != null) ? executor : ForkJoinPool.commonPool(); @@ -378,12 +379,8 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network // Refreshing one peer (e.g. received from WS) Consumer<List<Peer>> updateKnownBlocks = (updatedPeers) -> - updatedPeers.forEach(peer -> { - String buid = Peers.buid(peer); - if (!knownBlocks.contains(buid)) { - knownBlocks.add(buid); - } - }); + knownBlocks.addAll(updatedPeers.stream().map(Peers::buid).collect(Collectors.toSet())) + ; // Load all peers Runnable loadAllPeers = () -> { 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 a39e51f241382daa6fa4e8a6189d3dbea5bcffac..a459e0b14551c2f096c23f85eda2241b95a7ddf6 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 @@ -31,7 +31,6 @@ import org.duniter.core.client.service.ServiceLocator; import org.duniter.core.exception.TechnicalException; import org.duniter.core.service.CryptoService; import org.duniter.core.util.CollectionUtils; -import org.duniter.core.util.ObjectUtils; import org.duniter.core.util.Preconditions; import org.duniter.core.util.StringUtils; import org.duniter.core.util.cache.Cache; @@ -170,7 +169,7 @@ public class PeerServiceImpl implements PeerService, InitializingBean { } }; - List<Currency> currencies = ServiceLocator.instance().getCurrencyService().getCurrencies(accountId); + List<Currency> currencies = ServiceLocator.instance().getCurrencyService().getAllByAccount(accountId); for (Currency currency: currencies) { // Get peers from DB @@ -232,13 +231,23 @@ public class PeerServiceImpl implements PeerService, InitializingBean { protected Peer loadDefaultPeer(String currencyId) { List<Peer> peers = peerDao.getPeersByCurrencyId(currencyId); if (CollectionUtils.isEmpty(peers)) { - String currencyName = currencyService.getCurrencyNameById(currencyId); throw new TechnicalException(String.format( "No peers configure for currency [%s]", - currencyName != null ? currencyName : currencyId)); + currencyId)); } - return peers.get(0); + Peer defaultPeer = peers.stream() + .filter(peer -> peer.getStats() == null || peer.getStats().getStatus() == null || peer.getStats().getStatus() == Peer.PeerStatus.UP) + .findFirst().orElse(null); + if (defaultPeer != null) { + // Make sure currency is filled + defaultPeer.setCurrency(currencyId); + } + else { + log.warn(String.format("[%s] No default peer found. Unable to send remote request.", currencyId)); + } + + return defaultPeer; } } diff --git a/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceTest.java b/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceTest.java index cc92dee0c8d2fcabba1e677144dd3a0b2847463f..dc539d76f84b5112195304eb83f5993e625baf73 100644 --- a/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceTest.java +++ b/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceTest.java @@ -28,6 +28,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.duniter.core.client.TestResource; import org.duniter.core.client.config.Configuration; import org.duniter.core.client.model.bma.BlockchainBlock; +import org.duniter.core.client.model.bma.BlockchainDifficulties; import org.duniter.core.client.model.bma.BlockchainParameters; import org.duniter.core.client.model.bma.ErrorCode; import org.duniter.core.client.model.bma.jackson.JacksonUtils; @@ -189,6 +190,18 @@ public class BlockchainRemoteServiceTest { } } + @Test + public void getDifficulties() { + Peer peer = createTestPeer(); + + BlockchainDifficulties result = service.getDifficulties(peer); + Assert.assertNotNull(result); + Assert.assertNotNull(result.getBlock()); + + Assert.assertNotNull(result.getLevels()); + Assert.assertTrue(result.getLevels().length > 0); + } + /* -- Internal methods -- */ protected Peer createTestPeer() { diff --git a/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/WotRemoteServiceTest.java b/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/WotRemoteServiceTest.java index 7d781c16963f590f914f92aca6ca1ba584272e35..a58bb52facc118a5efdde80da40460c93dc0cb8c 100644 --- a/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/WotRemoteServiceTest.java +++ b/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/WotRemoteServiceTest.java @@ -27,6 +27,7 @@ import org.duniter.core.client.TestResource; import org.duniter.core.client.config.Configuration; import org.duniter.core.client.model.bma.ErrorCode; import org.duniter.core.client.model.local.Identity; +import org.duniter.core.client.model.local.Member; import org.duniter.core.client.model.local.Peer; import org.duniter.core.client.model.local.Wallet; import org.duniter.core.client.service.ServiceLocator; @@ -156,6 +157,33 @@ public class WotRemoteServiceTest { } } + @Test + public void sendCertification() { + Peer peer = createTestPeer(); + Wallet wallet = createTestWallet(); + WotRemoteService service = ServiceLocator.instance().getWotRemoteService(); + + Identity result = service.getIdentity(peer, "kimamila", "5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of"); + Assert.assertNotNull(result); + Assert.assertNotNull(result.getUid()); + Assert.assertNotNull(result.getPubkey()); + + try { + service.sendCertification(wallet, result); + } catch (BmaTechnicalException e) { + // Test user is not a member: an 1002 should be return + Assert.assertTrue(e.getCode() == 1002); + } + } + + @Test + public void getMembers() { + Peer peer = createTestPeer(); + List<Member> result = service.getMembers(peer); + Assert.assertNotNull(result); + Assert.assertTrue(result.size() > 0); + } + /* -- internal methods */ protected Wallet createTestWallet() {