From 6c2df379596eb3c9791badea1cfb98a583c6e84d Mon Sep 17 00:00:00 2001 From: pinpong Date: Mon, 11 Dec 2017 13:27:41 +0100 Subject: [PATCH] extended sendTransfers --- jota/src/main/java/jota/IotaAPI.java | 29 +++++++++++++++++-- jota/src/main/java/jota/utils/Constants.java | 3 ++ jota/src/test/java/jota/IotaAPITest.java | 6 ++-- jota/src/test/java/jota/IotaLocalPoWTest.java | 2 +- jota/src/test/java/jota/SendMessageTest.java | 2 +- 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/jota/src/main/java/jota/IotaAPI.java b/jota/src/main/java/jota/IotaAPI.java index cf85f74..227d035 100644 --- a/jota/src/main/java/jota/IotaAPI.java +++ b/jota/src/main/java/jota/IotaAPI.java @@ -807,15 +807,40 @@ public class IotaAPI extends IotaAPICore { * @param transfers Array of transfer objects. * @param inputs List of inputs used for funding the transfer. * @param remainderAddress If defined, this remainderAddress will be used for sending the remainder value (of the inputs) to. - * @param validateInputs Whether or not to validate the balances of the provided inputs + * @param validateInputs Whether or not to validate the balances of the provided inputs. + * @param validateAddresses Whether or not to validate if the destination address is already used and if a key reuse is detect. * @return Array of valid Transaction objects. * @throws ArgumentException is thrown when the specified input is not valid. */ - public SendTransferResponse sendTransfer(String seed, int security, int depth, int minWeightMagnitude, final List transfers, List inputs, String remainderAddress, boolean validateInputs) throws ArgumentException { + public SendTransferResponse sendTransfer(String seed, int security, int depth, int minWeightMagnitude, final List transfers, List inputs, String remainderAddress, boolean validateInputs, boolean validateAddresses) throws ArgumentException { StopWatch stopWatch = new StopWatch(); List trytes = prepareTransfers(seed, security, transfers, remainderAddress, inputs, validateInputs); + + if (validateAddresses) { + + HashSet addresses = new HashSet<>(); + + for (String trx : trytes) { + addresses.add(new Transaction(trx, customCurl.clone()).getAddress()); + } + + String[] hashes = findTransactionsByAddresses(addresses.toArray(new String[addresses.size()])).getHashes(); + List transactions = findTransactionsObjectsByHashes(hashes); + List gna = getNewAddress(seed, security, 0, false, 0, true).getAddresses(); + + for (Transaction trx : transactions) { + if (trx.getValue() < 0 && gna.contains(trx.getAddress())) { + throw new ArgumentException(Constants.PRIVATE_KEY_REUSE_ERROR); + } + + if (trx.getValue() < 0) { + throw new ArgumentException(Constants.SENDING_TO_USED_ADDRESS_ERROR); + } + } + } + List trxs = sendTrytes(trytes.toArray(new String[trytes.size()]), depth, minWeightMagnitude); Boolean[] successful = new Boolean[trxs.size()]; diff --git a/jota/src/main/java/jota/utils/Constants.java b/jota/src/main/java/jota/utils/Constants.java index 8fcf759..9f4a920 100644 --- a/jota/src/main/java/jota/utils/Constants.java +++ b/jota/src/main/java/jota/utils/Constants.java @@ -59,4 +59,7 @@ public class Constants { public static final String GET_TRYTES_RESPONSE_ERROR = "Get trytes response was null."; public static final String GET_BUNDLE_RESPONSE_ERROR = "Get bundle response was null."; public static final String GET_INCLUSION_STATE_RESPONSE_ERROR = "Get inclusion state response was null."; + + public static final String SENDING_TO_USED_ADDRESS_ERROR = "Sending to a used address."; + public static final String PRIVATE_KEY_REUSE_ERROR = "Private key reuse detect!"; } diff --git a/jota/src/test/java/jota/IotaAPITest.java b/jota/src/test/java/jota/IotaAPITest.java index 3aa2304..8953515 100644 --- a/jota/src/test/java/jota/IotaAPITest.java +++ b/jota/src/test/java/jota/IotaAPITest.java @@ -259,7 +259,7 @@ public class IotaAPITest { public void shouldNotSendTransfer() throws ArgumentException { List transfers = new ArrayList<>(); transfers.add(new Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2, 2, TEST_MESSAGE, TEST_TAG)); - SendTransferResponse str = iotaAPI.sendTransfer(TEST_SEED1, 2, DEPTH, MIN_WEIGHT_MAGNITUDE, transfers, null, null, false); + SendTransferResponse str = iotaAPI.sendTransfer(TEST_SEED1, 2, DEPTH, MIN_WEIGHT_MAGNITUDE, transfers, null, null, false, true); assertThat(str.getTransactions(), IsNull.notNullValue()); assertThat(str.getSuccessfully(), IsNull.notNullValue()); } @@ -269,7 +269,7 @@ public class IotaAPITest { public void shouldSendTransferWithoutInputs() throws ArgumentException { List transfers = new ArrayList<>(); transfers.add(new Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2, 1, TEST_MESSAGE, TEST_TAG)); - SendTransferResponse str = iotaAPI.sendTransfer(TEST_SEED1, 2, DEPTH, MIN_WEIGHT_MAGNITUDE, transfers, null, null, false); + SendTransferResponse str = iotaAPI.sendTransfer(TEST_SEED1, 2, DEPTH, MIN_WEIGHT_MAGNITUDE, transfers, null, null, false, true); assertThat(str.getTransactions(), IsNull.notNullValue()); assertThat(str.getSuccessfully(), IsNull.notNullValue()); } @@ -286,7 +286,7 @@ public class IotaAPITest { transfers.add(new Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2, 1, TEST_MESSAGE, TEST_TAG)); - SendTransferResponse str = iotaAPI.sendTransfer(TEST_SEED1, 2, DEPTH, MIN_WEIGHT_MAGNITUDE, transfers, inputlist, null, true); + SendTransferResponse str = iotaAPI.sendTransfer(TEST_SEED1, 2, DEPTH, MIN_WEIGHT_MAGNITUDE, transfers, inputlist, null, true, true); assertThat(str.getTransactions(), IsNull.notNullValue()); assertThat(str.getSuccessfully(), IsNull.notNullValue()); } diff --git a/jota/src/test/java/jota/IotaLocalPoWTest.java b/jota/src/test/java/jota/IotaLocalPoWTest.java index 93ffdf4..44fbb15 100644 --- a/jota/src/test/java/jota/IotaLocalPoWTest.java +++ b/jota/src/test/java/jota/IotaLocalPoWTest.java @@ -38,7 +38,7 @@ public class IotaLocalPoWTest { public void shouldSendTransfer() throws ArgumentException { List transfers = new ArrayList<>(); transfers.add(new Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2, 0, TEST_MESSAGE, TEST_TAG)); - SendTransferResponse str = iotaClient.sendTransfer(TEST_SEED1, 2, DEPTH, MIN_WEIGHT_MAGNITUDE, transfers, null, null, false); + SendTransferResponse str = iotaClient.sendTransfer(TEST_SEED1, 2, DEPTH, MIN_WEIGHT_MAGNITUDE, transfers, null, null, false, false); assertThat(str.getSuccessfully(), IsNull.notNullValue()); } } diff --git a/jota/src/test/java/jota/SendMessageTest.java b/jota/src/test/java/jota/SendMessageTest.java index 642d148..a8e920a 100644 --- a/jota/src/test/java/jota/SendMessageTest.java +++ b/jota/src/test/java/jota/SendMessageTest.java @@ -39,7 +39,7 @@ public class SendMessageTest { // for each 2187 trytes in a message one transfer is necessary transfers.add(new Transfer(TEST_ADDRESS_WITH_CHECKSUM_SECURITY_LEVEL_2, 0, StringUtils.rightPad(TEST_MESSAGE, 2188, '9'), TEST_TAG)); - SendTransferResponse str = iotaClient.sendTransfer(TEST_SEED1, 2, DEPTH, MIN_WEIGHT_MAGNITUDE, transfers, null, null, false); + SendTransferResponse str = iotaClient.sendTransfer(TEST_SEED1, 2, DEPTH, MIN_WEIGHT_MAGNITUDE, transfers, null, null, false, false); assertEquals(str.getTransactions().size(), 2); assertThat(str.getTransactions(), IsNull.notNullValue()); assertThat(str.getSuccessfully(), IsNull.notNullValue());