From 3a3f7f6a596e85ef373ebd1af0fb78c1b63468b7 Mon Sep 17 00:00:00 2001 From: Oliver Nitzschke Date: Fri, 23 Dec 2016 09:48:15 +0100 Subject: [PATCH 1/7] added getLatestInclusion (#14) * added getLatestInclusion * added findTransactionObjects * added documentation --- src/main/java/jota/IotaAPIProxy.java | 63 +++++++++++++++++++----- src/test/java/jota/IotaAPIProxyTest.java | 11 +++++ 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/main/java/jota/IotaAPIProxy.java b/src/main/java/jota/IotaAPIProxy.java index 1f9de61..7946d67 100644 --- a/src/main/java/jota/IotaAPIProxy.java +++ b/src/main/java/jota/IotaAPIProxy.java @@ -250,15 +250,15 @@ public class IotaAPIProxy { * sendTrytes * prepareTransfers * getInputs - + * getLatestInclusion + getTransfers sendTransfer getBundle getTransactionsObjects findTransactionObjects - getLatestInclusion - + replayBundle broadcastBundle getAccountData @@ -309,13 +309,7 @@ public class IotaAPIProxy { } return trx; } - - public List findAndGetTxs(final String addresses) { - final FindTransactionResponse res = findTransactionsByAddresses(addresses); - return getTransactionsObjects(res.getHashes()); - } - /** * Wrapper function for getTrytes and transactionObjects * gets the trytes and transaction object from a list of transaction hashes @@ -326,7 +320,7 @@ public class IotaAPIProxy { * @returns {function} callback * @returns {object} success **/ - public List getTransactionsObjects(String ... hashes) { + public List getTransactionsObjects(String[] hashes) { if (!InputValidator.isArrayOfHashes(hashes)) { throw new IllegalStateException("Not an Array of Hashes: " + Arrays.toString(hashes)); @@ -342,6 +336,26 @@ public class IotaAPIProxy { return trxs; } + /** + * Wrapper function for findTransactions, getTrytes and transactionObjects + * Returns the transactionObject of a transaction hash. The input can be a valid + * findTransactions input + * + * @param {object} input + * @method getTransactionsObjects + * @returns {function} callback + * @returns {object} success + **/ + public List findTransactionObjects(String[] input) { + FindTransactionResponse ftr = findTransactions(input, null, null, null); + if (ftr == null || ftr.getHashes() == null) + + return null; + + // get the transaction objects of the transactions + return getTransactionsObjects(ftr.getHashes()); + } + /** * Prepares transfer by generating bundle, finding and signing inputs * @@ -578,11 +592,36 @@ public class IotaAPIProxy { } throw new IllegalStateException("Not enough balance"); } - + + /** + * Gets the associated bundle transactions of a single transaction + * Does validation of signatures, total sum as well as bundle order + * + * @method getBundle + * @param {string} transaction Hash of a tail transaction + * @returns {list} bundle Transaction objects + **/ public GetBundleResponse getBundle(String transaction) { return null; //IotaAPIUtils.getBundle(transaction); } - + + /** + * Wrapper function for getNodeInfo and getInclusionStates + * + * @method getLatestInclusion + * @param {array} hashes + * @returns {function} callback + * @returns {array} state + **/ + public GetInclusionStateResponse getLatestInclusion(String[] hashes) { + GetNodeInfoResponse getNodeInfoResponse = getNodeInfo(); + if (getNodeInfoResponse == null) return null; + + String[] latestMilestone = {getNodeInfoResponse.getLatestSolidSubtangleMilestone()}; + + return getInclusionStates(hashes, latestMilestone); + } + public static class Builder { String protocol, host, port; diff --git a/src/test/java/jota/IotaAPIProxyTest.java b/src/test/java/jota/IotaAPIProxyTest.java index 43b4c94..ffb52ac 100644 --- a/src/test/java/jota/IotaAPIProxyTest.java +++ b/src/test/java/jota/IotaAPIProxyTest.java @@ -169,4 +169,15 @@ public class IotaAPIProxyTest { public void shouldSendTrytes() { proxy.sendTrytes(TEST_TRYTES, 18); } + + @Test + public void shouldGetLastInclusionState() { + GetInclusionStateResponse res = proxy.getLatestInclusion(new String[]{TEST_HASH}); + assertThat(res.getStates(), IsNull.notNullValue()); + } + + @Test + public void shouldFindTransactionObjects() { + assertThat(proxy.findTransactionObjects(new String[]{TEST_ADDRESS_WITH_CHECKSUM}), IsNull.notNullValue()); + } } \ No newline at end of file From 3f8922a089a64779df877b9d1c9993b5ed6b0844 Mon Sep 17 00:00:00 2001 From: pinpong Date: Thu, 22 Dec 2016 18:47:41 +0100 Subject: [PATCH 2/7] added findTransactionObjects --- src/main/java/jota/IotaAPIProxy.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/jota/IotaAPIProxy.java b/src/main/java/jota/IotaAPIProxy.java index 7946d67..7eabbf6 100644 --- a/src/main/java/jota/IotaAPIProxy.java +++ b/src/main/java/jota/IotaAPIProxy.java @@ -336,6 +336,16 @@ public class IotaAPIProxy { return trxs; } + public List findTransactionObjects(String[] input) { + FindTransactionResponse ftr = findTransactions(input, null, null, null); + if (ftr == null || ftr.getHashes() == null) + + return null; + + // get the transaction objects of the transactions + return getTransactionsObjects(ftr.getHashes()); + } + /** * Wrapper function for findTransactions, getTrytes and transactionObjects * Returns the transactionObject of a transaction hash. The input can be a valid From 5881879f7846163311b83292165879c1a98e43c7 Mon Sep 17 00:00:00 2001 From: pinpong Date: Thu, 22 Dec 2016 19:34:31 +0100 Subject: [PATCH 3/7] added documentation --- src/main/java/jota/IotaAPIProxy.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/jota/IotaAPIProxy.java b/src/main/java/jota/IotaAPIProxy.java index 7eabbf6..ef62bec 100644 --- a/src/main/java/jota/IotaAPIProxy.java +++ b/src/main/java/jota/IotaAPIProxy.java @@ -336,6 +336,16 @@ public class IotaAPIProxy { return trxs; } + /** + * Wrapper function for findTransactions, getTrytes and transactionObjects + * Returns the transactionObject of a transaction hash. The input can be a valid + * findTransactions input + * + * @param {object} input + * @method getTransactionsObjects + * @returns {function} callback + * @returns {object} success + **/ public List findTransactionObjects(String[] input) { FindTransactionResponse ftr = findTransactions(input, null, null, null); if (ftr == null || ftr.getHashes() == null) From b1c75bf0def18670b3ca52ce2b9dc01ea4e3dd94 Mon Sep 17 00:00:00 2001 From: pinpong Date: Fri, 23 Dec 2016 09:54:16 +0100 Subject: [PATCH 4/7] fixed NullPoointer --- src/main/java/jota/IotaAPIProxy.java | 8 +++-- src/main/java/jota/utils/Converter.java | 41 ++++++++++++++++++++----- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/main/java/jota/IotaAPIProxy.java b/src/main/java/jota/IotaAPIProxy.java index ef62bec..6ac88d2 100644 --- a/src/main/java/jota/IotaAPIProxy.java +++ b/src/main/java/jota/IotaAPIProxy.java @@ -577,10 +577,12 @@ public class IotaAPIProxy { // Calls getBalances and formats the output // returns the final inputsObject then - public GetBalancesAndFormatResponse getBalanceAndFormat(final List addresses, - final List balances, long threshold, int start, int end) { + public GetBalancesAndFormatResponse getBalanceAndFormat(final List addresses, List balances, long threshold, int start, int end) { - GetBalancesResponse bres = getBalances(100, addresses); + if (balances == null || balances.isEmpty()) { + GetBalancesResponse getBalancesResponse = getBalances(100, addresses); + balances = Arrays.asList(getBalancesResponse.getBalances()); + } // If threshold defined, keep track of whether reached or not // else set default to true diff --git a/src/main/java/jota/utils/Converter.java b/src/main/java/jota/utils/Converter.java index 90550e7..4276b08 100644 --- a/src/main/java/jota/utils/Converter.java +++ b/src/main/java/jota/utils/Converter.java @@ -2,14 +2,12 @@ package jota.utils; import jota.model.Transaction; import jota.pow.Curl; - -import java.util.Arrays; -import java.util.Optional; - import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Arrays; + public class Converter { private static final Logger log = LoggerFactory.getLogger(Converter.class); @@ -69,12 +67,39 @@ public class Converter { } public static int[] trits(final String trytes) { - final int[] trits = new int[trytes.length() * NUMBER_OF_TRITS_IN_A_TRYTE]; - for (int i = 0; i < trytes.length(); i++) { - System.arraycopy(TRYTE_TO_TRITS_MAPPINGS[Constants.TRYTE_ALPHABET.indexOf(trytes.charAt(i))], 0, trits, i * NUMBER_OF_TRITS_IN_A_TRYTE, NUMBER_OF_TRITS_IN_A_TRYTE); - } + if (InputValidator.isValue(trytes)) { + + int value = Integer.parseInt(trytes); + + long absoluteValue = value < 0 ? -value : value; + + while (absoluteValue > 0) { + + int remainder = (int) (absoluteValue % RADIX); + absoluteValue /= RADIX; + + if (remainder > MAX_TRIT_VALUE) { + remainder = MIN_TRIT_VALUE; + absoluteValue++; + } + + trits[trits.length] = remainder; + } + if (value < 0) { + + for (int i = 0; i < trits.length; i++) { + + trits[i] = -trits[i]; + } + } + } else { + + for (int i = 0; i < trytes.length(); i++) { + System.arraycopy(TRYTE_TO_TRITS_MAPPINGS[Constants.TRYTE_ALPHABET.indexOf(trytes.charAt(i))], 0, trits, i * NUMBER_OF_TRITS_IN_A_TRYTE, NUMBER_OF_TRITS_IN_A_TRYTE); + } + } return trits; } From a976e48f6b599b11737e184b08f01dce629340a1 Mon Sep 17 00:00:00 2001 From: pinpong Date: Fri, 23 Dec 2016 18:34:27 +0100 Subject: [PATCH 5/7] added replayTransfer --- src/main/java/jota/IotaAPIProxy.java | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/java/jota/IotaAPIProxy.java b/src/main/java/jota/IotaAPIProxy.java index 6ac88d2..6dceab3 100644 --- a/src/main/java/jota/IotaAPIProxy.java +++ b/src/main/java/jota/IotaAPIProxy.java @@ -285,7 +285,7 @@ public class IotaAPIProxy { * @param {array} trytes * @param {int} depth * @param {int} minWeightMagnitude - * @return + * @return */ public List sendTrytes(final String trytes, final int minWeightMagnitude) { @@ -627,6 +627,30 @@ public class IotaAPIProxy { return null; //IotaAPIUtils.getBundle(transaction); } + /** + * Replays a transfer by doing Proof of Work again + * + * @method replayBundle + * @param {string} tail + * @param {int} depth + * @param {int} minWeightMagnitude + * @param {function} callback + * @returns {object} analyzed Transaction objects + **/ + public List replayTransfer(String transaction, int depth, int minWeightMagnitude) { + + List bundleTrytes = new ArrayList<>(); + + GetBundleResponse bundle = getBundle(transaction); + + for (Transaction element : bundle.getTransactions()) { + + bundleTrytes.add(IotaAPIUtils.transactionTrytes(element)); + } + + return sendTrytes(bundleTrytes, minWeightMagnitude); + } + /** * Wrapper function for getNodeInfo and getInclusionStates * From 9a327a6a43fe1851e2a43e9489ce2a0f9d1e5b54 Mon Sep 17 00:00:00 2001 From: pinpong Date: Sat, 24 Dec 2016 10:38:07 +0100 Subject: [PATCH 6/7] extended InputValidatorTest --- src/test/java/jota/InputValidatorTest.java | 29 ++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/test/java/jota/InputValidatorTest.java b/src/test/java/jota/InputValidatorTest.java index 5f4795e..b898baf 100644 --- a/src/test/java/jota/InputValidatorTest.java +++ b/src/test/java/jota/InputValidatorTest.java @@ -1,8 +1,12 @@ package jota; +import jota.model.Transfer; import jota.utils.InputValidator; import org.junit.Test; +import java.util.ArrayList; +import java.util.List; + import static org.junit.Assert.assertEquals; /** @@ -11,8 +15,11 @@ import static org.junit.Assert.assertEquals; public class InputValidatorTest { private static final String TEST_ADDRESS_WITHOUT_CHECKSUM = "PNGMCSNRCTRHCHPXYTPKEJYPCOWKOMRXZFHH9N9VDIKMNVAZCMIYRHVJIAZARZTUETJVFDMBEBIQE9QTHBFWDAOEFA"; + private static final String TEST_ADDRESS_WITH_CHECKSUM = "PNGMCSNRCTRHCHPXYTPKEJYPCOWKOMRXZFHH9N9VDIKMNVAZCMIYRHVJIAZARZTUETJVFDMBEBIQE9QTHBFWDAOEFA"; private static final String TEST_TRYTES = "BYSWEAUTWXHXZ9YBZISEK9LUHWGMHXCGEVNZHRLUWQFCUSDXZHOFHWHL9MQPVJXXZLIXPXPXF9KYEREFSKCPKYIIKPZVLHUTDFQKKVVBBN9ATTLPCNPJDWDEVIYYLGPZGCWXOBDXMLJC9VO9QXTTBLAXTTBFUAROYEGQIVB9MJWJKXJMCUPTWAUGFZBTZCSJVRBGMYXTVBDDS9MYUJCPZ9YDWWQNIPUAIJXXSNLKUBSCOIJPCLEFPOXFJREXQCUVUMKSDOVQGGHRNILCO9GNCLWFM9APMNMWYASHXQAYBEXF9QRIHIBHYEJOYHRQJAOKAQ9AJJFQ9WEIWIJOTZATIBOXQLBMIJU9PCGBLVDDVFP9CFFSXTDUXMEGOOFXWRTLFGV9XXMYWEMGQEEEDBTIJ9OJOXFAPFQXCDAXOUDMLVYRMRLUDBETOLRJQAEDDLNVIRQJUBZBO9CCFDHIX9MSQCWYAXJVWHCUPTRSXJDESISQPRKZAFKFRULCGVRSBLVFOPEYLEE99JD9SEBALQINPDAZHFAB9RNBH9AZWIJOTLBZVIEJIAYGMC9AZGNFWGRSWAXTYSXVROVNKCOQQIWGPNQZKHUNODGYADPYLZZZUQRTJRTODOUKAOITNOMWNGHJBBA99QUMBHRENGBHTH9KHUAOXBVIVDVYYZMSEYSJWIOGGXZVRGN999EEGQMCOYVJQRIRROMPCQBLDYIGQO9AMORPYFSSUGACOJXGAQSPDY9YWRRPESNXXBDQ9OZOXVIOMLGTSWAMKMTDRSPGJKGBXQIVNRJRFRYEZ9VJDLHIKPSKMYC9YEGHFDS9SGVDHRIXBEMLFIINOHVPXIFAZCJKBHVMQZEVWCOSNWQRDYWVAIBLSCBGESJUIBWZECPUCAYAWMTQKRMCHONIPKJYYTEGZCJYCT9ABRWTJLRQXKMWY9GWZMHYZNWPXULNZAPVQLPMYQZCYNEPOCGOHBJUZLZDPIXVHLDMQYJUUBEDXXPXFLNRGIPWBRNQQZJSGSJTTYHIGGFAWJVXWL9THTPWOOHTNQWCNYOYZXALHAZXVMIZE9WMQUDCHDJMIBWKTYH9AC9AFOT9DPCADCV9ZWUTE9QNOMSZPTZDJLJZCJGHXUNBJFUBJWQUEZDMHXGBPTNSPZBR9TGSKVOHMOQSWPGFLSWNESFKSAZY9HHERAXALZCABFYPOVLAHMIHVDBGKUMDXC9WHHTIRYHZVWNXSVQUWCR9M9RAGMFEZZKZ9XEOQGOSLFQCHHOKLDSA9QCMDGCGMRYJZLBVIFOLBIJPROKMHOYTBTJIWUZWJMCTKCJKKTR9LCVYPVJI9AHGI9JOWMIWZAGMLDFJA9WU9QAMEFGABIBEZNNAL9OXSBFLOEHKDGHWFQSHMPLYFCNXAAZYJLMQDEYRGL9QKCEUEJ9LLVUOINVSZZQHCIKPAGMT9CAYIIMTTBCPKWTYHOJIIY9GYNPAJNUJ9BKYYXSV9JSPEXYMCFAIKTGNRSQGUNIYZCRT9FOWENSZQPD9ALUPYYAVICHVYELYFPUYDTWUSWNIYFXPX9MICCCOOZIWRNJIDALWGWRATGLJXNAYTNIZWQ9YTVDBOFZRKO9CFWRPAQQRXTPACOWCPRLYRYSJARRKSQPR9TCFXDVIXLP9XVL99ERRDSOHBFJDJQQGGGCZNDQ9NYCTQJWVZIAELCRBJJFDMCNZU9FIZRPGNURTXOCDSQGXTQHKHUECGWFUUYS9J9NYQ9U9P9UUP9YMZHWWWCIASCFLCMSKTELZWUGCDE9YOKVOVKTAYPHDF9ZCCQAYPJIJNGSHUIHHCOSSOOBUDOKE9CJZGYSSGNCQJVBEFTZFJ9SQUHOASKRRGBSHWKBCBWBTJHOGQ9WOMQFHWJVEG9NYX9KWBTCAIXNXHEBDIOFO9ALYMFGRICLCKKLG9FOBOX9PDWNQRGHBKHGKKRLWTBEQMCWQRLHAVYYZDIIPKVQTHYTWQMTOACXZOQCDTJTBAAUWXSGJF9PNQIJ9AJRUMUVCPWYVYVARKR9RKGOUHHNKNVGGPDDLGKPQNOYHNKAVVKCXWXOQPZNSLATUJT9AUWRMPPSWHSTTYDFAQDXOCYTZHOYYGAIM9CELMZ9AZPWB9MJXGHOKDNNSZVUDAGXTJJSSZCPZVPZBYNNTUQABSXQWZCHDQSLGK9UOHCFKBIBNETK999999999999999999999999999999999999999999999999999999999999999999999999999999999NOXDXXKUDWLOFJLIPQIBRBMGDYCPGDNLQOLQS99EQYKBIU9VHCJVIPFUYCQDNY9APGEVYLCENJIOBLWNB999999999XKBRHUD99C99999999NKZKEKWLDKMJCI9N9XQOLWEPAYWSH9999999999999999999999999KDDTGZLIPBNZKMLTOLOXQVNGLASESDQVPTXALEKRMIOHQLUHD9ELQDBQETS9QFGTYOYWLNTSKKMVJAUXSIROUICDOXKSYZTDPEDKOQENTJOWJONDEWROCEJIEWFWLUAACVSJFTMCHHXJBJRKAAPUDXXVXFWP9X9999IROUICDOXKSYZTDPEDKOQENTJOWJONDEWROCEJIEWFWLUAACVSJFTMCHHXJBJRKAAPUDXXVXFWP9X9999"; - + private static final String TEST_HASH = "OAATQS9VQLSXCLDJVJJVYUGONXAXOFMJOZNSYWRZSWECMXAQQURHQBJNLD9IOFEPGZEPEMPXCIVRX9999"; + private static final String TEST_MESSAGE = "JOTA"; + private static final String TEST_TAG = "JOTASPAM9999999999999999999"; @Test public void shouldIsAddress() { assertEquals(InputValidator.isAddress(TEST_ADDRESS_WITHOUT_CHECKSUM), true); @@ -27,4 +34,22 @@ public class InputValidatorTest { public void shouldIsTrytes() { assertEquals(InputValidator.isTrytes(TEST_TRYTES, TEST_TRYTES.length()), true); } -} + + @Test + public void shouldIsValue() { + assertEquals(InputValidator.isValue("1234"), true); + } + + @Test + public void shouldIsArrayOfHashes() { + assertEquals(InputValidator.isArrayOfHashes(new String[]{TEST_HASH, TEST_HASH}), true); + } + + @Test + public void shouldIsTransfersCollectionCorrect() { + List transfers = new ArrayList<>(); + transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITH_CHECKSUM, 0, TEST_MESSAGE, TEST_TAG)); + transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITH_CHECKSUM, 0, TEST_MESSAGE, TEST_TAG)); + assertEquals(InputValidator.isTransfersCollectionCorrect(transfers), true); + } +} \ No newline at end of file From ad486446ada716b240045e4dd7be568236dcfd76 Mon Sep 17 00:00:00 2001 From: pinpong Date: Sat, 24 Dec 2016 10:55:33 +0100 Subject: [PATCH 7/7] fixed merge conflict --- src/main/java/jota/IotaAPIProxy.java | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/main/java/jota/IotaAPIProxy.java b/src/main/java/jota/IotaAPIProxy.java index 6dceab3..173bda8 100644 --- a/src/main/java/jota/IotaAPIProxy.java +++ b/src/main/java/jota/IotaAPIProxy.java @@ -335,27 +335,7 @@ public class IotaAPIProxy { } return trxs; } - - /** - * Wrapper function for findTransactions, getTrytes and transactionObjects - * Returns the transactionObject of a transaction hash. The input can be a valid - * findTransactions input - * - * @param {object} input - * @method getTransactionsObjects - * @returns {function} callback - * @returns {object} success - **/ - public List findTransactionObjects(String[] input) { - FindTransactionResponse ftr = findTransactions(input, null, null, null); - if (ftr == null || ftr.getHashes() == null) - - return null; - - // get the transaction objects of the transactions - return getTransactionsObjects(ftr.getHashes()); - } - + /** * Wrapper function for findTransactions, getTrytes and transactionObjects * Returns the transactionObject of a transaction hash. The input can be a valid