From 3d618c63703df25622346f3ee3548440a75a6ae9 Mon Sep 17 00:00:00 2001 From: blavenie <benoit.lavenier@e-is.pro> Date: Mon, 27 Mar 2017 18:21:18 +0200 Subject: [PATCH] - Update command line client - Client: could now broadcast TX sent --- .../src/main/java/fr/duniter/cmd/Main.java | 19 +- .../fr/duniter/cmd/actions/NetworkAction.java | 159 +++++++++---- .../duniter/cmd/actions/SentMoneyAction.java | 76 ------- .../cmd/actions/TransactionAction.java | 213 ++++++++++++++++++ .../cmd/actions/params/AuthParameters.java | 67 ++++++ .../cmd/actions/params/PeerParameters.java | 67 ++++++ .../cmd/actions/params/WalletParameters.java | 14 -- .../src/main/resources/log4j.properties | 32 +-- .../duniter/core/client/model/local/Peer.java | 6 + .../service/bma/TransactionRemoteService.java | 22 ++ .../bma/TransactionRemoteServiceImpl.java | 44 +++- .../src/main/resources/log4j.properties | 2 +- .../duniter/core/service/CryptoService.java | 9 + .../service/Ed25519CryptoServiceImpl.java | 17 +- .../org/duniter/core/util/StringUtils.java | 7 + .../main/filtered-resources/log4j.properties | 1 + .../org/duniter/elasticsearch/PluginInit.java | 2 +- .../service/BlockchainService.java | 13 -- .../service/EndpointService.java | 81 ++----- 19 files changed, 607 insertions(+), 244 deletions(-) delete mode 100644 duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/SentMoneyAction.java create mode 100644 duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/TransactionAction.java create mode 100644 duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/params/AuthParameters.java create mode 100644 duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/params/PeerParameters.java delete mode 100644 duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/params/WalletParameters.java diff --git a/duniter4j-cmd/src/main/java/fr/duniter/cmd/Main.java b/duniter4j-cmd/src/main/java/fr/duniter/cmd/Main.java index 7208a3dc..8dca2049 100644 --- a/duniter4j-cmd/src/main/java/fr/duniter/cmd/Main.java +++ b/duniter4j-cmd/src/main/java/fr/duniter/cmd/Main.java @@ -2,10 +2,11 @@ package fr.duniter.cmd; import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; +import com.beust.jcommander.ParameterDescription; import com.beust.jcommander.ParameterException; import com.google.common.collect.Lists; import fr.duniter.cmd.actions.NetworkAction; -import fr.duniter.cmd.actions.SentMoneyAction; +import fr.duniter.cmd.actions.TransactionAction; import org.apache.commons.io.FileUtils; import org.duniter.core.client.config.Configuration; import org.duniter.core.client.service.ServiceLocator; @@ -13,8 +14,6 @@ import org.duniter.core.util.StringUtils; import org.nuiton.i18n.I18n; import org.nuiton.i18n.init.DefaultI18nInitializer; import org.nuiton.i18n.init.UserI18nInitializer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; @@ -34,6 +33,7 @@ public class Main { @Parameter(names = "-config", description = "Configuration file path") private String configFilename = "duniter-cmd.config"; + public static void main(String ... args) { Main main = new Main(); main.run(args); @@ -43,13 +43,24 @@ public class Main { Map<String, Runnable> actions = new HashMap<>(); actions.put("network", new NetworkAction()); - actions.put("send", new SentMoneyAction()); + actions.put("transaction", new TransactionAction()); // Parsing args JCommander jc = new JCommander(this); actions.entrySet().stream().forEach(entry -> jc.addCommand(entry.getKey(), entry.getValue())); try { jc.parse(args); + + jc.getParameters().stream().forEach(param -> { + if (param.getParameter().password() + && param.getParameter().required() + && param.getParameter().echoInput() + && !param.isAssigned()) { + System.out.print(param.getParameter().getParameter().description()); + //var17.addValue(new String(var11)); + } + }); + //jc.parse(args); } catch(ParameterException e) { System.err.println(e.getMessage()); diff --git a/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/NetworkAction.java b/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/NetworkAction.java index ac10b861..2da6b804 100644 --- a/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/NetworkAction.java +++ b/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/NetworkAction.java @@ -1,15 +1,23 @@ package fr.duniter.cmd.actions; +import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; +import com.beust.jcommander.ParametersDelegate; +import com.beust.jcommander.internal.Lists; +import dnl.utils.text.table.SeparatorPolicy; import dnl.utils.text.table.TextTable; +import fr.duniter.cmd.actions.params.PeerParameters; import fr.duniter.cmd.actions.utils.Formatters; import org.duniter.core.client.model.local.Peer; import org.duniter.core.client.service.ServiceLocator; import org.duniter.core.client.service.local.NetworkService; import org.duniter.core.util.CollectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; /** @@ -17,64 +25,127 @@ import java.util.stream.Collectors; */ @Parameters(commandDescription = "Display network peers") public class NetworkAction implements Runnable { + private static Logger log = LoggerFactory.getLogger(NetworkAction.class); - @Parameter(names = "-host", description = "Duniter host") - private String host = "g1.duniter.org"; + @ParametersDelegate + public PeerParameters peerParameters = new PeerParameters(); - @Parameter(names = "-port", description = "Duniter port") - private int port = 10901; + @Parameter(names = "--continue", description = "Continue scanning ?") + private boolean autoRefresh = false; + + private int previousRowDisplayed = 0; @Override public void run() { - NetworkService service = ServiceLocator.instance().getNetworkService(); - Peer mainPeer = Peer.newBuilder().setHost(host).setPort(port).build(); + peerParameters.parse(); + Peer mainPeer = peerParameters.getPeer(); + + log.info("Loading peers..."); + NetworkService service = ServiceLocator.instance().getNetworkService(); List<Peer> peers = service.getPeers(mainPeer); + showPeersTable(peers, autoRefresh); + + if (autoRefresh) { + final List<String> knownBlocks = Lists.newArrayList(); + peers.stream().forEach(peer -> { + String buid = peer.getStats().getBlockNumber() + "-" + peer.getStats().getBlockHash(); + if (!knownBlocks.contains(buid)) { + knownBlocks.add(buid); + } + }); + + // Start listening for new block... + CompletableFuture.runAsync(() -> + ServiceLocator.instance().getBlockchainRemoteService().addPeerListener(mainPeer, message -> { + List<Peer> updatedPeers = service.getPeers(mainPeer); + + int knowBlockSize = knownBlocks.size(); + updatedPeers.stream().forEach(peer -> { + String buid = peer.getStats().getBlockNumber() + "-" + peer.getStats().getBlockHash(); + if (!knownBlocks.contains(buid)) { + knownBlocks.add(buid); + } + }); + + // new block received: refresh console + if (knowBlockSize < knownBlocks.size()) { + showPeersTable(updatedPeers, true); + } + + })); + + try { + while(true) { + Thread.sleep(10000); // 10 s + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + + } + + /* -- protected methods -- */ + + public void showPeersTable(List<Peer> peers, boolean clearConsole) { + + // Clearing console + if (clearConsole) { + clearConsole(); + } if (CollectionUtils.isEmpty(peers)) { - System.out.println("No peers found"); + JCommander.getConsole().println("No peers found"); + return; + } + String[] columnNames = { + "Uid", + "Pubkey", + "Address", + "Status", + "API", + "Version", + "Difficulty", + "Block #"}; + + List<Object[]> data = peers.stream().map(peer -> { + boolean isUp = peer.getStats().getStatus() == Peer.PeerStatus.UP; + return new Object[] { + Formatters.formatUid(peer.getStats().getUid()), + Formatters.formatPubkey(peer.getPubkey()), + peer.getHost() + ":" + peer.getPort(), + peer.getStats().getStatus().name(), + isUp && peer.isUseSsl() ? "SSL" : null, + isUp ? peer.getStats().getVersion() : null, + (isUp && peer.getStats().getHardshipLevel() != null) ? peer.getStats().getHardshipLevel() : "Mirror", + isUp ? peer.getStats().getBlockNumber() : null + }; + }) + .collect(Collectors.toList()); + + Object[][] rows = new Object[data.size()][]; + int i = 0; + for (Object[] row : data) { + rows[i++] = row; } - else { - - String[] columnNames = { - "Uid", - "Pubkey", - "Address", - "Status", - "API", - "Version", - "Difficulty", - "Block #"}; - - List<Object[]> data = peers.stream().map(peer -> { - boolean isUp = peer.getStats().getStatus() == Peer.PeerStatus.UP; - return new Object[] { - Formatters.formatUid(peer.getStats().getUid()), - Formatters.formatPubkey(peer.getPubkey()), - peer.getHost() + ":" + peer.getPort(), - peer.getStats().getStatus().name(), - isUp && peer.isUseSsl() ? "SSL" : null, - isUp ? peer.getStats().getVersion() : null, - isUp ? peer.getStats().getHardshipLevel() : "Mirror", - isUp ? peer.getStats().getBlockNumber() : null - }; - }) - .collect(Collectors.toList()); - - Object[][] rows = new Object[data.size()][]; - int i = 0; - for (Object[] row : data) { - rows[i++] = row; - } - TextTable tt = new TextTable(columnNames, rows); - // this adds the numbering on the left - tt.setAddRowNumbering(true); - tt.printTable(); - } + TextTable tt = new TextTable(columnNames, rows); + // this adds the numbering on the left + tt.setAddRowNumbering(true); + tt.printTable(); + previousRowDisplayed = 3/*header rows*/ + rows.length; } + protected void moveCursor(int nbLinesUp) { + System.out.print(String.format("\033[%dA",nbLinesUp)); // Move up + System.out.print("\033[2K"); // Erase line content + } + protected void clearConsole() { + System.out.print(String.format("\033[2J")); + } } diff --git a/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/SentMoneyAction.java b/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/SentMoneyAction.java deleted file mode 100644 index 9b64dcf8..00000000 --- a/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/SentMoneyAction.java +++ /dev/null @@ -1,76 +0,0 @@ -package fr.duniter.cmd.actions; - -import com.beust.jcommander.Parameter; -import com.beust.jcommander.ParametersDelegate; -import fr.duniter.cmd.actions.params.WalletParameters; -import fr.duniter.cmd.actions.utils.Formatters; -import org.duniter.core.client.config.Configuration; -import org.duniter.core.client.model.bma.BlockchainParameters; -import org.duniter.core.client.model.local.Currency; -import org.duniter.core.client.model.local.Peer; -import org.duniter.core.client.model.local.Wallet; -import org.duniter.core.client.service.ServiceLocator; -import org.duniter.core.client.service.bma.BlockchainRemoteService; -import org.duniter.core.client.service.bma.TransactionRemoteService; -import org.duniter.core.service.CryptoService; -import org.duniter.core.util.crypto.CryptoUtils; -import org.duniter.core.util.crypto.KeyPair; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Created by blavenie on 22/03/17. - */ -public class SentMoneyAction implements Runnable { - - private static final Logger log = LoggerFactory.getLogger(SentMoneyAction.class); - - @ParametersDelegate - private WalletParameters walletParams = new WalletParameters(); - - @Parameter(names = "--amount", description = "Amount", required = true) - public int amount; - - @Parameter(names = "--dest", description = "Destination pubkey", required = true) - public String destPubkey; - - @Parameter(names = "--comment", description = "TX Comment") - public String comment; - - @Override - public void run() { - - CryptoService cryptoService = ServiceLocator.instance().getCryptoService(); - TransactionRemoteService txService = ServiceLocator.instance().getTransactionRemoteService(); - Configuration config = Configuration.instance(); - - Peer peer = Peer.newBuilder().setHost(config.getNodeHost()) - .setPort(config.getNodePort()) - .build(); - - Currency currency = ServiceLocator.instance().getBlockchainRemoteService().getCurrencyFromPeer(peer); - ServiceLocator.instance().getCurrencyService().save(currency); - peer.setCurrencyId(currency.getId()); - peer.setCurrency(currency.getCurrencyName()); - ServiceLocator.instance().getPeerService().save(peer); - - // Compute keypair and wallet - KeyPair keypair = cryptoService.getKeyPair(walletParams.salt, walletParams.password); - Wallet wallet = new Wallet( - currency.getCurrencyName(), - null, - keypair.getPubKey(), - keypair.getSecKey()); - wallet.setCurrencyId(currency.getId()); - - System.out.println("Connected to wallet: " + wallet.getPubKeyHash()); - - txService.transfer(wallet, destPubkey, amount, comment); - - - System.out.println(String.format("Successfully sent [%d %s] to [%s]", - amount, - Formatters.currencySymbol(currency.getCurrencyName()), - Formatters.formatPubkey(destPubkey))); - } -} diff --git a/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/TransactionAction.java b/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/TransactionAction.java new file mode 100644 index 00000000..c738c0df --- /dev/null +++ b/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/TransactionAction.java @@ -0,0 +1,213 @@ +package fr.duniter.cmd.actions; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.ParametersDelegate; +import com.beust.jcommander.validators.PositiveInteger; +import com.google.common.collect.ImmutableList; +import fr.duniter.cmd.actions.params.AuthParameters; +import fr.duniter.cmd.actions.params.PeerParameters; +import fr.duniter.cmd.actions.utils.Formatters; +import org.duniter.core.client.model.bma.EndpointApi; +import org.duniter.core.client.model.local.Currency; +import org.duniter.core.client.model.local.Peer; +import org.duniter.core.client.model.local.Wallet; +import org.duniter.core.client.service.ServiceLocator; +import org.duniter.core.client.service.bma.TransactionRemoteService; +import org.duniter.core.client.service.local.NetworkService; +import org.duniter.core.client.service.local.PeerService; +import org.duniter.core.exception.BusinessException; +import org.duniter.core.exception.TechnicalException; +import org.duniter.core.service.CryptoService; +import org.duniter.core.util.CollectionUtils; +import org.duniter.core.util.crypto.KeyPair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * Created by blavenie on 22/03/17. + */ +public class TransactionAction implements Runnable { + + private static Logger log = LoggerFactory.getLogger(TransactionAction.class); + + @ParametersDelegate + public AuthParameters authParameters = new AuthParameters(); + + @ParametersDelegate + public PeerParameters peerParameters = new PeerParameters(); + + @Parameter(names = "--amount", description = "Amount", required = true, validateWith = PositiveInteger.class) + public int amount; + + @Parameter(names = "--output", description = "Output pubkey", required = true) + public String output; + + @Parameter(names = "--comment", description = "TX Comment") + public String comment; + + private int mainConsensusPeerCount = 0; + private int forkConsensusPeerCount = 0; + + @Override + public void run() { + try { + + // Make sure auth parameters are filled + authParameters.parse(); + peerParameters.parse(); + + // Reducing node timeout when broadcast + + + Peer peer = peerParameters.getPeer(); + + Currency currency = ServiceLocator.instance().getBlockchainRemoteService().getCurrencyFromPeer(peer); + ServiceLocator.instance().getCurrencyService().save(currency); + peer.setCurrencyId(currency.getId()); + peer.setCurrency(currency.getCurrencyName()); + ServiceLocator.instance().getPeerService().save(peer); + + + // Compute keypair and wallet + KeyPair keypair = null; + if (authParameters.authScrypt) { + CryptoService cryptoService = ServiceLocator.instance().getCryptoService(); + keypair = cryptoService.getKeyPairFromSeed( + cryptoService.getSeed( + new String(authParameters.salt), + new String(authParameters.password), + authParameters.scryptPArams.get(0), // N + authParameters.scryptPArams.get(1), // p + authParameters.scryptPArams.get(2) // r + )); + } + else { + fail("Unknwon authentification type"); + return; + } + + Wallet wallet = new Wallet( + currency.getCurrencyName(), + null, + keypair.getPubKey(), + keypair.getSecKey()); + wallet.setCurrencyId(currency.getId()); + + // Send TX document to ONE peer + if (!peerParameters.broadcast) { + sendToPeer(peer, wallet); + } + + // Sent TX using broadcast + else { + sendBroadcast(peer, currency, wallet, peerParameters.useSsl); + } + } + catch(BusinessException | TechnicalException e) { + fail(e); + } + } + + protected void fail(String message) { + log.error(message); + System.exit(-1); + } + + protected void sendToPeer(Peer peer, Wallet wallet) { + TransactionRemoteService txService = ServiceLocator.instance().getTransactionRemoteService(); + + logTxSummary(wallet); + + txService.transfer(peer, wallet, output, amount, comment); + JCommander.getConsole().println("Transaction successfully sent."); + } + + protected void sendBroadcast(Peer mainPeer, Currency currency, Wallet wallet, boolean useSsl) { + + TransactionRemoteService txService = ServiceLocator.instance().getTransactionRemoteService(); + PeerService peerService = ServiceLocator.instance().getPeerService(); + + log.info("Loading member peers..."); + + // Filter to [member + UP] peers + NetworkService.Filter peersFilter = new NetworkService.Filter(); + peersFilter.filterType = NetworkService.FilterType.MEMBER; + peersFilter.filterStatus = Peer.PeerStatus.UP; + if (useSsl) { + peersFilter.filterEndpoints = ImmutableList.of(EndpointApi.BMAS.name()); + } + else { + peersFilter.filterEndpoints = ImmutableList.of(EndpointApi.BASIC_MERKLED_API.name()); + } + // Sort by [lesser difficulty first] + NetworkService.Sort sortLesserDifficulty = new NetworkService.Sort(); + sortLesserDifficulty.sortType = NetworkService.SortType.HARDSHIP; + sortLesserDifficulty.sortAsc = true; + + // Get the peers list + List<Peer> peers = ServiceLocator.instance().getNetworkService().getPeers(mainPeer, peersFilter, sortLesserDifficulty); + + if (CollectionUtils.isEmpty(peers)) { + log.warn("No members peers found! Skipping --broadcast option."); + sendToPeer(mainPeer, wallet); + return; + } + + log.info(String.format("%d member peers found for broadcast", peers.size())); + + logTxSummary(wallet); + + peers.stream().forEach(peer -> { + peer.setCurrencyId(currency.getId()); + peer.setCurrency(currency.getCurrencyName()); + peerService.save(peer); + + log.debug(String.format("Send TX to [%s]...", peer)); + try { + txService.transfer(peer, wallet, output, amount, comment); + + log.warn(String.format("Successfully sent to [%s]", peer)); + + if (peer.getStats() != null) { + if (peer.getStats().isMainConsensus()) { + mainConsensusPeerCount++; + } else if (peer.getStats().isForkConsensus()) { + forkConsensusPeerCount++; + } + } + + } + catch (Exception e) { + log.warn(String.format("Could not send transaction to [%s]: %s", peer, e.getMessage())); + } + }); + + if (mainConsensusPeerCount > 0) { + JCommander.getConsole().println(String.format("Transaction successfully sent (to %d nodes on the main blockchain consensus).", mainConsensusPeerCount)); + } + else if (forkConsensusPeerCount > 0){ + fail(String.format("Transaction has NOT been sent to the main consensus BlockChain, but ONLY to %d peers on a fork of the blockchain.", forkConsensusPeerCount)); + } + else { + fail(String.format("Transaction has NOT been sent. Not a single peer has accepted the transaction.")); + } + + } + + + protected void logTxSummary(Wallet wallet) { + // Log TX summary + JCommander.getConsole().println(String.format("Generate Transation:\n\t- From: %s\n\t- To: %s\n\t- Amount: %s %s", + Formatters.formatPubkey(wallet.getPubKeyHash()), + Formatters.formatPubkey(output), + amount, + Formatters.currencySymbol(wallet.getCurrency()))); + } + + protected void fail(Exception e) { + fail(e.getMessage()); + } +} diff --git a/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/params/AuthParameters.java b/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/params/AuthParameters.java new file mode 100644 index 00000000..17fd1f99 --- /dev/null +++ b/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/params/AuthParameters.java @@ -0,0 +1,67 @@ +package fr.duniter.cmd.actions.params; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.ParameterException; +import com.beust.jcommander.converters.CommaParameterSplitter; +import com.beust.jcommander.validators.PositiveInteger; +import com.google.common.collect.ImmutableList; +import org.duniter.core.service.Ed25519CryptoServiceImpl; +import org.duniter.core.util.StringUtils; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Created by blavenie on 22/03/17. + */ +public class AuthParameters { + + @Parameter(names = "--auth-scrypt", description = "Authenticate using Scrypt ?") + public boolean authScrypt = true; + + @Parameter(names = "--salt", description = "Salt (to generate the keypair)", password = true) + public char[] salt; + + @Parameter(names = "--passwd", description = "Password (to generate the keypair)", password = true) + public char[] password; + + @Parameter(names = "--scrypt-params", description = "Scrypt parameters (N,r,p)", + splitter = CommaParameterSplitter.class, + validateWith = PositiveInteger.class) + public List<Integer> scryptPArams; + + public void parse() { + // Compute keypair and wallet + if (StringUtils.isBlank(salt) && authScrypt) { + JCommander.getConsole().print("Please enter your Scrypt Salt (Secret identifier): "); + salt = JCommander.getConsole().readPassword(true); + } + if (StringUtils.isBlank(password) && authScrypt){ + JCommander.getConsole().print("Please enter your Scrypt password (masked): "); + password = JCommander.getConsole().readPassword(true); + } + if (scryptPArams == null && authScrypt) { + JCommander.getConsole().print(String.format("Please enter your Scrypt parameters (N,r,p): [%d,%d,%d] ", + Ed25519CryptoServiceImpl.SCRYPT_PARAMS_N, + Ed25519CryptoServiceImpl.SCRYPT_PARAMS_r, + Ed25519CryptoServiceImpl.SCRYPT_PARAMS_p)); + char[] scryptsParamsStr = JCommander.getConsole().readPassword(false); + if (StringUtils.isNotBlank(scryptsParamsStr)) { + String[] parts = new String(scryptsParamsStr).split(","); + if (parts.length != 3) { + throw new ParameterException("Invalid Scrypt parameters (expected 3 values)"); + } + scryptPArams = Arrays.asList(parts).stream().map(part -> Integer.parseInt(part)).collect(Collectors.toList()); + } + else { + scryptPArams = ImmutableList.of( + Ed25519CryptoServiceImpl.SCRYPT_PARAMS_N, + Ed25519CryptoServiceImpl.SCRYPT_PARAMS_r, + Ed25519CryptoServiceImpl.SCRYPT_PARAMS_p); + } + } + } + +} diff --git a/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/params/PeerParameters.java b/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/params/PeerParameters.java new file mode 100644 index 00000000..a08a8a67 --- /dev/null +++ b/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/params/PeerParameters.java @@ -0,0 +1,67 @@ +package fr.duniter.cmd.actions.params; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.ParameterException; +import org.duniter.core.client.config.Configuration; +import org.duniter.core.client.model.local.Peer; +import org.duniter.core.util.Preconditions; +import org.duniter.core.util.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by blavenie on 22/03/17. + */ +public class PeerParameters { + + private static Logger log = LoggerFactory.getLogger(PeerParameters.class); + + @Parameter(names = {"-p", "--peer"}, description = "Peer address (use format: 'host:port')") + public String peerStr; + + @Parameter(names = "--broadcast", description = "Broadcast document sent to all nodes") + public boolean broadcast = false; + + @Parameter(names = "--ssl", description = "Using SSL connection to node") + public boolean useSsl = false; + + @Parameter(names = "--timeout", description = "HTTP request timeout, in millisecond") + public Long timeout = null; + + private Peer peer = null; + + public void parse() { + if (StringUtils.isNotBlank(peerStr)) { + String[] parts = peerStr.split(":"); + if (parts.length > 2) { + throw new ParameterException("Invalid --peer parameter"); + } + String host = parts[0]; + Integer port = parts.length == 2 ? Integer.parseInt(parts[1]) : null; + + Peer.Builder peerBuilder = Peer.newBuilder().setHost(host); + if (port != null) { + peerBuilder.setPort(port); + } + if (useSsl){ + peerBuilder.setUseSsl(useSsl); + } + peer = peerBuilder.build(); + + log.info(String.format("Duniter node: [%s:%s]", peer.getHost(), peer.getPort())); + } + else { + Configuration config = Configuration.instance(); + peer = Peer.newBuilder().setHost(config.getNodeHost()) + .setPort(config.getNodePort()) + .build(); + log.info(String.format("Fallback to default Duniter node: [%s:%d]", peer.getHost(), peer.getPort())); + } + } + + public Peer getPeer() { + Preconditions.checkNotNull(peer, "Please call parse() before getPeer()."); + return peer; + } +} diff --git a/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/params/WalletParameters.java b/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/params/WalletParameters.java deleted file mode 100644 index 2694cafc..00000000 --- a/duniter4j-cmd/src/main/java/fr/duniter/cmd/actions/params/WalletParameters.java +++ /dev/null @@ -1,14 +0,0 @@ -package fr.duniter.cmd.actions.params; - -import com.beust.jcommander.Parameter; - -/** - * Created by blavenie on 22/03/17. - */ -public class WalletParameters { - @Parameter(names = "--salt", description = "Salt (to generate the keypair)", required = true) - public String salt; - - @Parameter(names = "--passwd", description = "Password (to generate the keypair)", required = true) - public String password; -} diff --git a/duniter4j-cmd/src/main/resources/log4j.properties b/duniter4j-cmd/src/main/resources/log4j.properties index f31940a1..d8de0e03 100644 --- a/duniter4j-cmd/src/main/resources/log4j.properties +++ b/duniter4j-cmd/src/main/resources/log4j.properties @@ -1,27 +1,33 @@ ### # Global logging configuration -log4j.rootLogger=ERROR, stdout, file +log4j.rootLogger=INFO, stdout, file -# Console output +# Console appender log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %5p - %m%n - -# duniter4j levels -log4j.logger.org.duniter=INFO -log4j.logger.org.duniter.cmd=INFO -#log4j.logger.org.duniter.core.client.service=DEBUG -log4j.logger.org.duniter.core.client.service.local=DEBUG -#log4j.logger.org.duniter.core.client.service.bma=DEBUG -log4j.logger.org.duniter.core.beans=WARN -#log4j.logger.org.duniter.core.client.service=TRACE +log4j.appender.stdout.layout.ConversionPattern=%p - %m%n +# File appender log4j.appender.file=org.apache.log4j.RollingFileAppender -log4j.appender.file.file=ucoin-client.log +log4j.appender.file.file=duniter4j-client.log log4j.appender.file.MaxFileSize=10MB log4j.appender.file.MaxBackupIndex=4 log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ISO8601} %5p %c - %m%n +# Duniter4j levels +log4j.logger.org.duniter=INFO +#log4j.logger.org.duniter.cmd=INFO +#log4j.logger.org.duniter.core.client.service=DEBUG +#log4j.logger.org.duniter.core.client.service.local=DEBUG +#log4j.logger.org.duniter.core.client.service.bma=DEBUG +log4j.logger.org.duniter.core.beans=WARN +#log4j.logger.org.duniter.core.client.service=TRACE +# Other frameworks levels +log4j.logger.org.apache.http=ERROR +log4j.logger.org.nuiton.util=WARN +log4j.logger.org.nuiton.config=WARN +log4j.logger.org.nuiton.converter=WARN +log4j.logger.org.nuiton.i18n=ERROR \ No newline at end of file diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peer.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peer.java index 02eb05cc..d31a8496 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peer.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peer.java @@ -24,6 +24,7 @@ package org.duniter.core.client.model.local; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.google.common.base.Joiner; import org.duniter.core.client.model.bma.EndpointApi; import org.duniter.core.client.model.bma.NetworkPeering; import org.duniter.core.util.Preconditions; @@ -343,6 +344,11 @@ public class Peer implements LocalEntity, Serializable { this.stats = stats; } + @JsonIgnore + public String computeKey() { + return Joiner.on('-').skipNulls().join(pubkey, dns, ipv4, ipv6, port, useSsl); + } + public String toString() { StringJoiner joiner = new StringJoiner(" "); if (api != null) { 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 76242225..882f4c54 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 @@ -33,6 +33,28 @@ import org.duniter.core.client.service.exception.InsufficientCreditException; public interface TransactionRemoteService extends Service { + /** + * Transfer TX to the given peer, or if null to currency's default peer + * @param peer + * @param wallet + * @param destPubKey + * @param amount + * @param comment + * @return + * @throws InsufficientCreditException + */ + String transfer(Peer peer, Wallet wallet, String destPubKey, long amount, + String comment) throws InsufficientCreditException; + + /** + * Same, using the default currency's peer + * @param wallet + * @param destPubKey + * @param amount + * @param comment + * @return + * @throws InsufficientCreditException + */ String transfer(Wallet wallet, String destPubKey, long amount, String comment) throws InsufficientCreditException; 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 a6ad175c..4c8e869f 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 @@ -77,24 +77,38 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen cryptoService = ServiceLocator.instance().getCryptoService(); } + public String transfer(Wallet wallet, String destPubKey, long amount, String comment) throws InsufficientCreditException { + Preconditions.checkNotNull(wallet); + Preconditions.checkNotNull(wallet.getCurrencyId()); + + return transfer(null, wallet, destPubKey, amount, comment); + } + + public String transfer(Peer peer, Wallet wallet, String destPubKey, long amount, + String comment) throws InsufficientCreditException { + Preconditions.checkNotNull(wallet); + Preconditions.checkArgument(peer != null || wallet.getCurrencyId() != null); // Get current block - BlockchainBlock currentBlock = executeRequest(wallet.getCurrencyId(), BlockchainRemoteServiceImpl.URL_BLOCK_CURRENT, BlockchainBlock.class); + BlockchainBlock currentBlock = peer != null ? + executeRequest(peer, BlockchainRemoteServiceImpl.URL_BLOCK_CURRENT, BlockchainBlock.class) : + executeRequest(wallet.getCurrencyId(), BlockchainRemoteServiceImpl.URL_BLOCK_CURRENT, BlockchainBlock.class); // http post /tx/process - HttpPost httpPost = new HttpPost( - getPath(wallet.getCurrencyId(), URL_TX_PROCESS)); + HttpPost httpPost = peer != null ? + new HttpPost(getPath(peer, URL_TX_PROCESS)) : + new HttpPost(getPath(wallet.getCurrencyId(), URL_TX_PROCESS)); // compute transaction - String transaction = getSignedTransaction(wallet, currentBlock, destPubKey, 0, amount, - comment); + String transaction = getSignedTransaction(peer, wallet, currentBlock, destPubKey, 0, amount, + comment); if (log.isDebugEnabled()) { log.debug(String.format( - "Will send transaction document: \n------\n%s------", - transaction)); + "Will send transaction document: \n------\n%s------", + transaction)); } List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); @@ -107,16 +121,19 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen } String selfResult = executeRequest(httpPost, String.class); - log.info("received from /tx/process: " + selfResult); + if (log.isDebugEnabled()) { + log.debug("Received from /tx/process: " + selfResult); + } - String fingerprint = DigestUtils.sha1Hex(transaction); + String fingerprint = DigestUtils.sha1Hex(transaction); if (log.isDebugEnabled()) { log.debug(String.format( "Fingerprint: %s", fingerprint)); } - return fingerprint; + return fingerprint; + } public TxSource getSources(long currencyId, String pubKey) { @@ -217,7 +234,8 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen /* -- internal methods -- */ - public String getSignedTransaction(Wallet wallet, + protected String getSignedTransaction(Peer peer, + Wallet wallet, BlockchainBlock block, String destPubKey, int locktime, @@ -228,7 +246,9 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen Preconditions.checkArgument(StringUtils.isNotBlank(wallet.getPubKeyHash())); // Retrieve the wallet sources - TxSource sourceResults = getSources(wallet.getCurrencyId(), wallet.getPubKeyHash()); + TxSource sourceResults = peer != null ? + getSources(peer, wallet.getPubKeyHash()) : + getSources(wallet.getCurrencyId(), wallet.getPubKeyHash()); if (sourceResults == null) { throw new TechnicalException("Unable to load user sources."); } diff --git a/duniter4j-core-client/src/main/resources/log4j.properties b/duniter4j-core-client/src/main/resources/log4j.properties index d5aafd24..554a25b8 100644 --- a/duniter4j-core-client/src/main/resources/log4j.properties +++ b/duniter4j-core-client/src/main/resources/log4j.properties @@ -7,7 +7,7 @@ log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %5p (%c:%L) - %m%n -# ucoin levels +# Duniter4j levels log4j.logger.org.duniter=DEBUG log4j.logger.org.duniter.core.client.service.bma.AbstractNetworkService=WARN diff --git a/duniter4j-core-shared/src/main/java/org/duniter/core/service/CryptoService.java b/duniter4j-core-shared/src/main/java/org/duniter/core/service/CryptoService.java index 0fcf80a0..4702a46c 100644 --- a/duniter4j-core-shared/src/main/java/org/duniter/core/service/CryptoService.java +++ b/duniter4j-core-shared/src/main/java/org/duniter/core/service/CryptoService.java @@ -32,8 +32,17 @@ import org.duniter.core.util.crypto.KeyPair; * Created by eis on 10/01/15. */ public interface CryptoService extends Bean { + + /** + * generate a crypto seed, using default N,r,p parameters (4096,16,1) + * @param salt + * @param password + * @return + */ byte[] getSeed(String salt, String password); + byte[] getSeed(String salt, String password, int N, int r, int p); + /** * Returns a new signing key pair generated from salt and password. * The salt and password must contain enough entropy to be secure. diff --git a/duniter4j-core-shared/src/main/java/org/duniter/core/service/Ed25519CryptoServiceImpl.java b/duniter4j-core-shared/src/main/java/org/duniter/core/service/Ed25519CryptoServiceImpl.java index f822e004..6448f79a 100644 --- a/duniter4j-core-shared/src/main/java/org/duniter/core/service/Ed25519CryptoServiceImpl.java +++ b/duniter4j-core-shared/src/main/java/org/duniter/core/service/Ed25519CryptoServiceImpl.java @@ -50,10 +50,10 @@ public class Ed25519CryptoServiceImpl implements CryptoService { // Length of a secret key private static int SECRETKEY_BYTES = 64; - // Scrypt parameter - private static int SCRYPT_PARAMS_N = 4096; - private static int SCRYPT_PARAMS_r = 16; - private static int SCRYPT_PARAMS_p = 1; + // Scrypt default parameters + public static int SCRYPT_PARAMS_N = 4096; + public static int SCRYPT_PARAMS_r = 16; + public static int SCRYPT_PARAMS_p = 1; protected final static char[] HEX_CHARS = "0123456789ABCDEF".toCharArray(); @@ -68,12 +68,16 @@ public class Ed25519CryptoServiceImpl implements CryptoService { @Override public byte[] getSeed(String salt, String password) { + return getSeed(salt, password, SCRYPT_PARAMS_N, SCRYPT_PARAMS_r, SCRYPT_PARAMS_p); + } + + @Override + public byte[] getSeed(String salt, String password, int N, int r, int p) { try { byte[] seed = SCrypt.scrypt( CryptoUtils.decodeAscii(password), CryptoUtils.decodeAscii(salt), - SCRYPT_PARAMS_N, SCRYPT_PARAMS_r, - SCRYPT_PARAMS_p, SEED_BYTES); + N, r, p, SEED_BYTES); return seed; } catch (GeneralSecurityException e) { throw new TechnicalException( @@ -86,7 +90,6 @@ public class Ed25519CryptoServiceImpl implements CryptoService { return getKeyPairFromSeed(getSeed(salt, password)); } - @Override public KeyPair getKeyPairFromSeed(byte[] seed) { byte[] secretKey = CryptoUtils.zeros(SECRETKEY_BYTES); diff --git a/duniter4j-core-shared/src/main/java/org/duniter/core/util/StringUtils.java b/duniter4j-core-shared/src/main/java/org/duniter/core/util/StringUtils.java index 944a5633..f1ba86d0 100644 --- a/duniter4j-core-shared/src/main/java/org/duniter/core/util/StringUtils.java +++ b/duniter4j-core-shared/src/main/java/org/duniter/core/util/StringUtils.java @@ -33,11 +33,18 @@ public class StringUtils { public static boolean isNotBlank(String value) { return value != null && value.trim().length() > 0; } + public static boolean isNotBlank(char[] value) { + return value != null && value.length > 0; + } public static boolean isBlank(String value) { return value == null || value.trim().length() == 0; } + public static boolean isBlank(char[] value) { + return value == null || value.length == 0; + } + public static boolean isNotEmpty(String value) { return value != null && value.length() > 0; } diff --git a/duniter4j-es-core/src/main/filtered-resources/log4j.properties b/duniter4j-es-core/src/main/filtered-resources/log4j.properties index 7b6667b1..a730face 100644 --- a/duniter4j-es-core/src/main/filtered-resources/log4j.properties +++ b/duniter4j-es-core/src/main/filtered-resources/log4j.properties @@ -15,6 +15,7 @@ log4j.logger.org.duniter=INFO log4j.logger.org.duniter.elasticsearch=DEBUG # Other frameworks levels +log4j.logger.org.apache.http=ERROR log4j.logger.org.nuiton.util=WARN log4j.logger.org.nuiton.config=WARN log4j.logger.org.nuiton.converter=WARN diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/PluginInit.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/PluginInit.java index 5d6cde48..0468f586 100644 --- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/PluginInit.java +++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/PluginInit.java @@ -139,7 +139,7 @@ public class PluginInit extends AbstractLifecycleComponent<PluginInit> { // Index peers (and listen if new peer appear) injector.getInstance(EndpointService.class) - .indexLastPeers(peer)/* + .indexAllEndpoints(peer)/* .listenAndIndexNewPeer(peer)*/; } } diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java index 968b77bf..b4b67c3c 100644 --- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java +++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java @@ -298,19 +298,6 @@ public class BlockchainService extends AbstractService { createIndexRequestBuilder.execute().actionGet(); } - public void createBlock(BlockchainBlock block) throws org.duniter.elasticsearch.exception.DuplicateIndexIdException { - Preconditions.checkNotNull(block, "block could not be null") ; - Preconditions.checkNotNull(block.getCurrency(), "block attribute 'blockchain' could not be null"); - Preconditions.checkNotNull(block.getNumber(), "block attribute 'number' could not be null"); - - BlockchainBlock existingBlock = getBlockById(block.getCurrency(), block.getNumber()); - if (existingBlock != null) { - throw new DuplicateIndexIdException(String.format("Block with number [%s] already exists.", block.getNumber())); - } - - indexBlock(block, false); - } - /** * Create or update a block, depending on its existence and hash * @param block diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/EndpointService.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/EndpointService.java index 8df83239..1fb2eb9f 100644 --- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/EndpointService.java +++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/EndpointService.java @@ -119,12 +119,12 @@ public class EndpointService extends AbstractService { } } - public EndpointService indexLastPeers(Peer peer) { - indexLastPeers(peer, nullProgressionModel); + public EndpointService indexAllEndpoints(Peer peer) { + indexAllEndpoints(peer, nullProgressionModel); return this; } - public EndpointService indexLastPeers(Peer peer, ProgressionModel progressionModel) { + public EndpointService indexAllEndpoints(Peer peer, ProgressionModel progressionModel) { try { // Get the blockchain name from node @@ -139,7 +139,7 @@ public class EndpointService extends AbstractService { indexPeers(currencyName, peer, progressionModel); } catch(Exception e) { - logger.error("Error during indexLastPeers: " + e.getMessage(), e); + logger.error("Error during indexAllEndpoints: " + e.getMessage(), e); progressionModel.setStatus(ProgressionModel.Status.FAILED); } @@ -243,32 +243,33 @@ public class EndpointService extends AbstractService { public Peer savePeer(final Peer peer, boolean wait) throws DuplicateIndexIdException { Preconditions.checkNotNull(peer, "peer could not be null") ; Preconditions.checkNotNull(peer.getCurrency(), "peer attribute 'currency' could not be null"); - //Preconditions.checkNotNull(peer.getHash(), "peer attribute 'hash' could not be null"); Preconditions.checkNotNull(peer.getPubkey(), "peer attribute 'pubkey' could not be null"); Preconditions.checkNotNull(peer.getHost(), "peer attribute 'host' could not be null"); Preconditions.checkNotNull(peer.getApi(), "peer 'api' could not be null"); - Peer existingPeer = getPeerByHash(peer.getCurrency(), peer.getHash()); + String id = cryptoService.hash(peer.computeKey()); + + boolean exists = isDocumentExists(peer.getCurrency(), ENDPOINT_TYPE, id); // Currency not exists, or has changed, so create it - if (existingPeer == null) { + if (!exists) { if (logger.isTraceEnabled()) { logger.trace(String.format("Insert new peer [%s]", peer)); } // Index new peer - indexPeer(peer, wait); + indexPeer(peer, id, wait); } // Update existing peer else { logger.trace(String.format("Update peer [%s]", peer)); - updatePeer(peer, wait); + updatePeer(peer, id, wait); } return peer; } - public void indexPeer(Peer peer, boolean wait) { + public void indexPeer(Peer peer, String id, boolean wait) { Preconditions.checkNotNull(peer); Preconditions.checkArgument(StringUtils.isNotBlank(peer.getCurrency())); Preconditions.checkNotNull(peer.getHash()); @@ -282,7 +283,7 @@ public class EndpointService extends AbstractService { // Preparing indexBlocksFromNode IndexRequestBuilder indexRequest = client.prepareIndex(peer.getCurrency(), ENDPOINT_TYPE) - .setId(peer.getHash()) + .setId(id) .setSource(json); // Execute indexBlocksFromNode @@ -299,7 +300,7 @@ public class EndpointService extends AbstractService { } } - public void updatePeer(Peer peer, boolean wait) { + public void updatePeer(Peer peer, String id, boolean wait) { Preconditions.checkNotNull(peer); Preconditions.checkArgument(StringUtils.isNotBlank(peer.getCurrency())); Preconditions.checkNotNull(peer.getHash()); @@ -312,7 +313,7 @@ public class EndpointService extends AbstractService { String json = objectMapper.writeValueAsString(peer); // Preparing indexBlocksFromNode - UpdateRequestBuilder updateRequest = client.prepareUpdate(peer.getCurrency(), ENDPOINT_TYPE, peer.getHash()) + UpdateRequestBuilder updateRequest = client.prepareUpdate(peer.getCurrency(), ENDPOINT_TYPE, id) .setDoc(json); // Execute indexBlocksFromNode @@ -329,33 +330,6 @@ public class EndpointService extends AbstractService { } } - /** - * - * @param currencyName - * @param number the peer hash - * @param json block as JSON - */ - public EndpointService indexPeerFromJson(String currencyName, int number, byte[] json, boolean refresh, boolean wait) { - Preconditions.checkNotNull(json); - Preconditions.checkArgument(json.length > 0); - - // Preparing indexBlocksFromNode - IndexRequestBuilder indexRequest = client.prepareIndex(currencyName, ENDPOINT_TYPE) - .setId(String.valueOf(number)) - .setRefresh(refresh) - .setSource(json); - - // Execute indexBlocksFromNode - if (!wait) { - indexRequest.execute(); - } - else { - indexRequest.execute().actionGet(); - } - - return this; - } - /** * Index the given block, as the last (current) block. This will check is a fork has occur, and apply a rollback so. */ @@ -432,7 +406,7 @@ public class EndpointService extends AbstractService { SearchResponse searchResponse = searchRequest.execute().actionGet(); // Read query result - return toBlocks(searchResponse, true); + return toPeers(searchResponse, true); } /* -- Internal methods -- */ @@ -491,7 +465,7 @@ public class EndpointService extends AbstractService { } } - public Peer getPeerByHash(String currencyName, String hash) { + public Peer getPeerByHash(String currencyName, String id) { // Prepare request SearchRequestBuilder searchRequest = client @@ -500,26 +474,26 @@ public class EndpointService extends AbstractService { .setSearchType(SearchType.DFS_QUERY_THEN_FETCH); // If more than a word, search on terms match - searchRequest.setQuery(QueryBuilders.matchQuery("_id", hash)); + searchRequest.setQuery(QueryBuilders.matchQuery("_id", id)); // Execute query try { SearchResponse searchResponse = searchRequest.execute().actionGet(); - List<Peer> blocks = toBlocks(searchResponse, false); - if (CollectionUtils.isEmpty(blocks)) { + List<Peer> peers = toPeers(searchResponse, false); + if (CollectionUtils.isEmpty(peers)) { return null; } // Return the unique result - return CollectionUtils.extractSingleton(blocks); + return CollectionUtils.extractSingleton(peers); } catch(JsonSyntaxException e) { - throw new TechnicalException(String.format("Error while getting indexed peer #%s for [%s]", hash, currencyName), e); + throw new TechnicalException(String.format("Error while getting indexed peer #%s for [%s]", id, currencyName), e); } } - protected List<Peer> toBlocks(SearchResponse response, boolean withHighlight) { + protected List<Peer> toPeers(SearchResponse response, boolean withHighlight) { // Read query result List<Peer> result = Lists.newArrayList(); response.getHits().forEach(searchHit -> { @@ -556,15 +530,4 @@ public class EndpointService extends AbstractService { } - protected void reportIndexPeersProgress(ProgressionModel progressionModel, String currencyName, Peer peer, int offset, int total) { - int pct = offset * 100 / total; - progressionModel.setCurrent(pct); - - progressionModel.setMessage(I18n.t("duniter4j.es.networkService.indexPeers.progress", currencyName, peer, offset, pct)); - if (logger.isInfoEnabled()) { - logger.info(I18n.t("duniter4j.es.networkService.indexPeers.progress", currencyName, peer, offset, pct)); - } - - } - } -- GitLab