diff --git a/.travis.yml b/.travis.yml index f9e9cd3..ac57f5b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ deploy: file_glob: true file: - "/home/travis/build/iotaledger/iota.lib.java/target/jota*.jar" + - "/home/travis/build/iotaledger/iota.lib.java/target/jota*.jar-with-dependencies" - "/home/travis/build/iotaledger/iota.lib.java/target/jota*.jar.asc" - "/home/travis/build/iotaledger/iota.lib.java/target/jota*-sources.jar" - "/home/travis/build/iotaledger/iota.lib.java/target/jota*-sources.jar.asc" diff --git a/README.md b/README.md index 39742f7..50badda 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,11 @@ The JOTA library is a simple Java wrapper around [[IOTA]](http://www.iotatoken.c It allows to connect easily using java directly to a local or a remote [[IOTA node]](https://iota.readme.io/docs/syncing-to-the-network). -* **Latest release:** 0.9.1 -* **Compatibility:** fully compatible with IOTA IRI v1.2.6 +* **Latest release:** 0.9.3 +* **Compatibility:** fully compatible with IOTA IRI v1.4.0 * **API coverage:** 14 of 14 commands fully implemented * **License:** Apache License 2.0 -* **Readme updated:** 2016-01-19 21:05:02 (UTC) +* **Readme updated:** 2017-09-23 21:05:02 (UTC) A list of all *IOTA* JSON-REST API commands currently supported by jota wrapper can be found in the `Commands` enum (see [here](https://github.com/davassi/JOTA/blob/master/src/main/java/jota/IotaAPICommands.java) for more details). diff --git a/pom.xml b/pom.xml index f080178..c40a778 100644 --- a/pom.xml +++ b/pom.xml @@ -115,6 +115,28 @@ + + maven-assembly-plugin + + + + + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + org.apache.maven.plugins maven-source-plugin diff --git a/src/main/java/jota/IotaAPI.java b/src/main/java/jota/IotaAPI.java index 6f2df1e..9a66a73 100644 --- a/src/main/java/jota/IotaAPI.java +++ b/src/main/java/jota/IotaAPI.java @@ -805,16 +805,16 @@ public class IotaAPI extends IotaAPICore { * @param minWeightMagnitude The minimum weight magnitude. * @param transfers Array of transfer objects. * @param inputs List of inputs used for funding the transfer. - * @param address If defined, this address will be used for sending the remainder value (of the inputs) to. + * @param remainderAddress If defined, this remainderAddress will be used for sending the remainder value (of the inputs) to. * @return Array of Transaction objects. - * @throws InvalidAddressException is thrown when the specified address is not an valid address. + * @throws InvalidAddressException is thrown when the specified remainderAddress is not an valid remainderAddress. * @throws NotEnoughBalanceException is thrown when a transfer fails because their is not enough balance to perform the transfer. * @throws InvalidSecurityLevelException is thrown when the specified security level is not valid. * @throws InvalidTrytesException is thrown when invalid trytes is provided. - * @throws InvalidAddressException is thrown when the specified address is not an valid address. + * @throws InvalidAddressException is thrown when the specified remainderAddress is not an valid remainderAddress. * @throws InvalidTransferException is thrown when an invalid transfer is provided. */ - public SendTransferResponse sendTransfer(String seed, int security, int depth, int minWeightMagnitude, final List transfers, Input[] inputs, String address) throws NotEnoughBalanceException, InvalidSecurityLevelException, InvalidTrytesException, InvalidAddressException, InvalidTransferException { + public SendTransferResponse sendTransfer(String seed, int security, int depth, int minWeightMagnitude, final List transfers, Input[] inputs, String remainderAddress) throws NotEnoughBalanceException, InvalidSecurityLevelException, InvalidTrytesException, InvalidAddressException, InvalidTransferException { if (security < 1 || security > 3) { throw new InvalidSecurityLevelException(); @@ -822,7 +822,7 @@ public class IotaAPI extends IotaAPICore { StopWatch stopWatch = new StopWatch(); - List trytes = prepareTransfers(seed, security, transfers, address, inputs == null ? null : Arrays.asList(inputs)); + List trytes = prepareTransfers(seed, security, transfers, remainderAddress, inputs == null ? null : Arrays.asList(inputs)); List trxs = sendTrytes(trytes.toArray(new String[trytes.size()]), depth, minWeightMagnitude); Boolean[] successful = new Boolean[trxs.size()]; @@ -1044,7 +1044,7 @@ public class IotaAPI extends IotaAPICore { bundle.addEntry(1, remainderAddress, remainder, tag, timestamp); } - bundle.finalize(customCurl.clone()); + bundle.finalize(SpongeFactory.create(SpongeFactory.Mode.CURLP81)); bundle.addTrytes(signatureFragments); return bundle.getTransactions(); diff --git a/src/main/java/jota/IotaAPICore.java b/src/main/java/jota/IotaAPICore.java index e1305ab..ee77038 100644 --- a/src/main/java/jota/IotaAPICore.java +++ b/src/main/java/jota/IotaAPICore.java @@ -14,7 +14,6 @@ import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; import java.io.BufferedReader; -import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.List; diff --git a/src/main/java/jota/IotaLocalPoW.java b/src/main/java/jota/IotaLocalPoW.java index 7a7ae7d..d679564 100644 --- a/src/main/java/jota/IotaLocalPoW.java +++ b/src/main/java/jota/IotaLocalPoW.java @@ -4,5 +4,5 @@ package jota; * Interface for an implementation to perform local PoW. */ public interface IotaLocalPoW { - public String performPoW(String trytes, int minWeightMagnitude); + String performPoW(String trytes, int minWeightMagnitude); } diff --git a/src/main/java/jota/model/Bundle.java b/src/main/java/jota/model/Bundle.java index 5c4844a..9155821 100644 --- a/src/main/java/jota/model/Bundle.java +++ b/src/main/java/jota/model/Bundle.java @@ -107,7 +107,8 @@ public class Bundle implements Comparable { int[] lastIndexTrits = Converter.trits(this.getTransactions().get(i).getLastIndex(), 27); - int[] t = Converter.trits(this.getTransactions().get(i).getAddress() + Converter.trytes(valueTrits) + this.getTransactions().get(i).getTag() + Converter.trytes(timestampTrits) + Converter.trytes(currentIndexTrits) + Converter.trytes(lastIndexTrits)); + int[] t = Converter.trits(this.getTransactions().get(i).getAddress() + Converter.trytes(valueTrits) + this.getTransactions().get(i).getObsoleteTag() + Converter.trytes(timestampTrits) + Converter.trytes(currentIndexTrits) + Converter.trytes(lastIndexTrits)); + curl.absorb(t, 0, t.length); } @@ -128,6 +129,7 @@ public class Bundle implements Comparable { public void addTrytes(List signatureFragments) { String emptySignatureFragment = ""; String emptyHash = EMPTY_HASH; + long emptyTimestamp = 999999999l; emptySignatureFragment = StringUtils.rightPad(emptySignatureFragment, 2187, '9'); @@ -141,8 +143,14 @@ public class Bundle implements Comparable { // Fill empty branchTransaction this.getTransactions().get(i).setBranchTransaction(emptyHash); + + this.getTransactions().get(i).setAttachmentTimestamp(emptyTimestamp); + this.getTransactions().get(i).setAttachmentTimestampLowerBound(emptyTimestamp); + this.getTransactions().get(i).setAttachmentTimestampUpperBound(emptyTimestamp); + // Fill empty nonce - this.getTransactions().get(i).setNonce(emptyHash); + this.getTransactions().get(i).setNonce(StringUtils.rightPad("", 27, "9")); + } } @@ -200,6 +208,6 @@ public class Bundle implements Comparable { */ @Override public int compareTo(Bundle o) { - return Long.compare(this.getTransactions().get(0).getTimestamp(), o.getTransactions().get(0).getTimestamp()); + return Long.compare(this.getTransactions().get(0).getAttachmentTimestamp(), o.getTransactions().get(0).getAttachmentTimestamp()); } } \ No newline at end of file diff --git a/src/main/java/jota/model/Transaction.java b/src/main/java/jota/model/Transaction.java index d0d4b50..29c5cae 100644 --- a/src/main/java/jota/model/Transaction.java +++ b/src/main/java/jota/model/Transaction.java @@ -26,7 +26,7 @@ public class Transaction { private String signatureFragments; private String address; private long value; - private String tag; + private String obsoleteTag; private long timestamp; private long currentIndex; private long lastIndex; @@ -35,6 +35,51 @@ public class Transaction { private String branchTransaction; private String nonce; private Boolean persistence; + private long attachmentTimestamp; + private String tag; + private long attachmentTimestampLowerBound; + private long attachmentTimestampUpperBound; + + /** + * Initializes a new instance of the Signature class. + */ + public Transaction(String signatureFragments, long currentIndex, long lastIndex, String nonce, String hash, String obsoleteTag, long timestamp, String trunkTransaction, String branchTransaction, String address, long value, String bundle, String tag, long attachmentTimestamp, long attachmentTimestampLowerBound, long attachmentTimestampUpperBound) { + + this.hash = hash; + this.obsoleteTag = obsoleteTag; + this.signatureFragments = signatureFragments; + this.address = address; + this.value = value; + this.timestamp = timestamp; + this.currentIndex = currentIndex; + this.lastIndex = lastIndex; + this.bundle = bundle; + this.trunkTransaction = trunkTransaction; + this.branchTransaction = branchTransaction; + this.tag = tag; + this.attachmentTimestamp = attachmentTimestamp; + this.attachmentTimestampLowerBound = attachmentTimestampLowerBound; + this.attachmentTimestampUpperBound = attachmentTimestampUpperBound; + this.nonce = nonce; + } + + /** + * Initializes a new instance of the Signature class. + */ + public Transaction(String address, long value, String tag, long timestamp) { + this.address = address; + this.value = value; + this.obsoleteTag = tag; + this.timestamp = timestamp; + } + + public long getAttachmentTimestampLowerBound() { + return attachmentTimestampLowerBound; + } + + public void setAttachmentTimestampLowerBound(long attachmentTimestampLowerBound) { + this.attachmentTimestampLowerBound = attachmentTimestampLowerBound; + } /** * Initializes a new instance of the Signature class. @@ -65,33 +110,12 @@ public class Transaction { this.customCurl = customCurl; } - /** - * Initializes a new instance of the Signature class. - */ - public Transaction(String signatureFragments, long currentIndex, long lastIndex, String nonce, String hash, String tag, long timestamp, String trunkTransaction, String branchTransaction, String address, long value, String bundle) { - - this.hash = hash; - this.tag = tag; - this.signatureFragments = signatureFragments; - this.address = address; - this.value = value; - this.timestamp = timestamp; - this.currentIndex = currentIndex; - this.lastIndex = lastIndex; - this.bundle = bundle; - this.trunkTransaction = trunkTransaction; - this.branchTransaction = branchTransaction; - this.nonce = nonce; + public long getAttachmentTimestampUpperBound() { + return attachmentTimestampUpperBound; } - /** - * Initializes a new instance of the Signature class. - */ - public Transaction(String address, long value, String tag, long timestamp) { - this.address = address; - this.value = value; - this.tag = tag; - this.timestamp = timestamp; + public void setAttachmentTimestampUpperBound(long attachmentTimestampUpperBound) { + this.attachmentTimestampUpperBound = attachmentTimestampUpperBound; } /** @@ -338,6 +362,42 @@ public class Transaction { this.persistence = persistence; } + /** + * Get the obsoleteTag. + * + * @return The obsoleteTag. + */ + public String getObsoleteTag() { + return obsoleteTag; + } + + /** + * Set the obsoleteTag. + * + * @param obsoleteTag The persistence. + */ + public void setObsoleteTag(String obsoleteTag) { + this.obsoleteTag = obsoleteTag; + } + + /** + * Get the attachmentTimestamp. + * + * @return The attachmentTimestamp. + */ + public long getAttachmentTimestamp() { + return attachmentTimestamp; + } + + /** + * Set the attachmentTimestamp. + * + * @param attachmentTimestamp The persistence. + */ + public void setAttachmentTimestamp(long attachmentTimestamp) { + this.attachmentTimestamp = attachmentTimestamp; + } + public boolean equals(Object obj) { return obj != null && ((Transaction) obj).getHash().equals(this.getHash()); } @@ -351,24 +411,34 @@ public class Transaction { int[] timestampTrits = Converter.trits(this.getTimestamp(), 27); - int[] currentIndexTrits = Converter.trits(this.getCurrentIndex(), 27); - int[] lastIndexTrits = Converter.trits(this.getLastIndex(), 27); + int[] attachmentTimestampTrits = Converter.trits(this.getAttachmentTimestamp(), 27); - return this.getSignatureFragments() + int[] attachmentTimestampLowerBoundTrits = Converter.trits(this.getAttachmentTimestampLowerBound(), 27); + + int[] attachmentTimestampUpperBoundTrits = Converter.trits(this.getAttachmentTimestampUpperBound(), 27); + + this.tag = this.tag != null && !this.tag.isEmpty() ? this.tag : this.obsoleteTag; + + String trx = this.getSignatureFragments() + this.getAddress() + Converter.trytes(valueTrits) - + this.getTag() + + this.getObsoleteTag() + Converter.trytes(timestampTrits) + Converter.trytes(currentIndexTrits) + Converter.trytes(lastIndexTrits) + this.getBundle() + this.getTrunkTransaction() + this.getBranchTransaction() + + this.getTag() + + Converter.trytes(attachmentTimestampTrits) + + Converter.trytes(attachmentTimestampLowerBoundTrits) + + Converter.trytes(attachmentTimestampUpperBoundTrits) + this.getNonce(); + return trx; } /** @@ -392,7 +462,7 @@ public class Transaction { int[] transactionTrits = Converter.trits(trytes); int[] hash = new int[243]; - ICurl curl = SpongeFactory.create(SpongeFactory.Mode.CURL); + ICurl curl = SpongeFactory.create(SpongeFactory.Mode.CURLP81); // generate the correct transaction hash curl.reset(); curl.absorb(transactionTrits, 0, transactionTrits.length); @@ -402,13 +472,17 @@ public class Transaction { this.setSignatureFragments(trytes.substring(0, 2187)); this.setAddress(trytes.substring(2187, 2268)); this.setValue(Converter.longValue(Arrays.copyOfRange(transactionTrits, 6804, 6837))); - this.setTag(trytes.substring(2295, 2322)); + this.setObsoleteTag(trytes.substring(2295, 2322)); this.setTimestamp(Converter.longValue(Arrays.copyOfRange(transactionTrits, 6966, 6993))); this.setCurrentIndex(Converter.longValue(Arrays.copyOfRange(transactionTrits, 6993, 7020))); this.setLastIndex(Converter.longValue(Arrays.copyOfRange(transactionTrits, 7020, 7047))); this.setBundle(trytes.substring(2349, 2430)); this.setTrunkTransaction(trytes.substring(2430, 2511)); this.setBranchTransaction(trytes.substring(2511, 2592)); - this.setNonce(trytes.substring(2592, 2673)); + this.setTag(trytes.substring(2592, 2619)); + this.setAttachmentTimestamp(Converter.longValue(Arrays.copyOfRange(transactionTrits, 7857, 7884)) / 1000); + this.setAttachmentTimestampLowerBound(Converter.longValue(Arrays.copyOfRange(transactionTrits, 7884, 7911))); + this.setAttachmentTimestampUpperBound(Converter.longValue(Arrays.copyOfRange(transactionTrits, 7911, 7938))); + this.setNonce(trytes.substring(2646, 2673)); } } \ No newline at end of file diff --git a/src/main/java/jota/pow/JCurl.java b/src/main/java/jota/pow/JCurl.java index e242fed..4096ec8 100644 --- a/src/main/java/jota/pow/JCurl.java +++ b/src/main/java/jota/pow/JCurl.java @@ -4,6 +4,7 @@ import jota.utils.Converter; import jota.utils.Pair; import java.util.Arrays; +import java.util.NoSuchElementException; /** * (c) 2016 Come-from-Beyond @@ -18,20 +19,29 @@ public class JCurl implements ICurl { public static final int HASH_LENGTH = 243; private static final int STATE_LENGTH = 3 * HASH_LENGTH; - private static final int NUMBER_OF_ROUNDS = 27; + public static final int NUMBER_OF_ROUNDSP81 = 81; + public static final int NUMBER_OF_ROUNDSP27 = 27; + private final int numberOfRounds; + private static final int[] TRUTH_TABLE = {1, 0, -1, 2, 1, -1, 0, 2, -1, 1, 0}; private final long[] stateLow; private final long[] stateHigh; private final int[] scratchpad = new int[STATE_LENGTH]; private int[] state; - private boolean pair; - public JCurl() { - this(false); - } - - public JCurl(boolean pair) { - this.pair = pair; + public JCurl(boolean pair, SpongeFactory.Mode mode) { + switch (mode) { + case CURLP27: { + numberOfRounds = NUMBER_OF_ROUNDSP27; + } + break; + case CURLP81: { + numberOfRounds = NUMBER_OF_ROUNDSP81; + } + break; + default: + throw new NoSuchElementException("Only Curl-P-27 and Curl-P-81 are supported."); + } if (pair) { stateHigh = new long[STATE_LENGTH]; stateLow = new long[STATE_LENGTH]; @@ -44,6 +54,24 @@ public class JCurl implements ICurl { } } + public JCurl(SpongeFactory.Mode mode) { + switch (mode) { + case CURLP27: { + numberOfRounds = NUMBER_OF_ROUNDSP27; + } + break; + case CURLP81: { + numberOfRounds = NUMBER_OF_ROUNDSP81; + } + break; + default: + throw new NoSuchElementException("Only Curl-P-27 and Curl-P-81 are supported."); + } + state = new int[STATE_LENGTH]; + stateHigh = null; + stateLow = null; + } + /** * Absorbs the specified trits. * @@ -82,7 +110,7 @@ public class JCurl implements ICurl { int scratchpadIndex = 0; int prev_scratchpadIndex = 0; - for (int round = 0; round < NUMBER_OF_ROUNDS; round++) { + for (int round = 0; round < numberOfRounds; round++) { System.arraycopy(state, 0, scratchpad, 0, STATE_LENGTH); for (int stateIndex = 0; stateIndex < STATE_LENGTH; stateIndex++) { prev_scratchpadIndex = scratchpadIndex; @@ -104,8 +132,15 @@ public class JCurl implements ICurl { * @return The ICurl instance (used for method chaining). */ public JCurl reset() { - for (int stateIndex = 0; stateIndex < STATE_LENGTH; stateIndex++) { - state[stateIndex] = 0; + Arrays.fill(state, 0); + return this; + } + + public JCurl reset(boolean pair) { + if (pair) { + set(); + } else { + reset(); } return this; } @@ -166,7 +201,7 @@ public class JCurl implements ICurl { final long[] curlScratchpadLow = new long[STATE_LENGTH]; final long[] curlScratchpadHigh = new long[STATE_LENGTH]; int curlScratchpadIndex = 0; - for (int round = 27; round-- > 0; ) { + for (int round = numberOfRounds; round-- > 0; ) { System.arraycopy(stateLow, 0, curlScratchpadLow, 0, STATE_LENGTH); System.arraycopy(stateHigh, 0, curlScratchpadHigh, 0, STATE_LENGTH); for (int curlStateIndex = 0; curlStateIndex < STATE_LENGTH; curlStateIndex++) { @@ -180,6 +215,7 @@ public class JCurl implements ICurl { } } + public void absorb(final Pair pair, int offset, int length) { int o = offset, l = length, i = 0; do { @@ -210,6 +246,6 @@ public class JCurl implements ICurl { */ @Override public ICurl clone() { - return new JCurl(pair); + return new JCurl(SpongeFactory.Mode.CURLP81); } } diff --git a/src/main/java/jota/pow/Kerl.java b/src/main/java/jota/pow/Kerl.java index dd8c01c..c916060 100644 --- a/src/main/java/jota/pow/Kerl.java +++ b/src/main/java/jota/pow/Kerl.java @@ -24,7 +24,7 @@ public class Kerl extends JCurl { private static int INT_LENGTH = BYTE_LENGTH / 4; Kerl() { - super(); + super(SpongeFactory.Mode.CURLP81); this.keccak = new Keccak.Digest384(); this.byte_state = new byte[BYTE_HASH_LENGTH]; this.trit_state = new int[HASH_LENGTH]; @@ -52,7 +52,7 @@ public class Kerl extends JCurl { } int[] base = new int[INT_LENGTH]; - Set setUniqueNumbers = new LinkedHashSet(); + Set setUniqueNumbers = new LinkedHashSet<>(); for (int x : trits) { setUniqueNumbers.add(x); } diff --git a/src/main/java/jota/pow/SpongeFactory.java b/src/main/java/jota/pow/SpongeFactory.java index ca37b28..c8e133f 100644 --- a/src/main/java/jota/pow/SpongeFactory.java +++ b/src/main/java/jota/pow/SpongeFactory.java @@ -6,20 +6,21 @@ package jota.pow; public abstract class SpongeFactory { public static ICurl create(Mode mode) { switch (mode) { - case CURL: - return new JCurl(); + case CURLP81: + return new JCurl(mode); + case CURLP27: + return new JCurl(mode); case KERL: return new Kerl(); - case BCURLT: - return new JCurl(true); default: return null; } } public enum Mode { - CURL, + CURLP81, + CURLP27, KERL, - BCURLT + //BCURLT } } \ No newline at end of file diff --git a/src/test/java/jota/IotaAPITest.java b/src/test/java/jota/IotaAPITest.java index 18db7e2..fa37edf 100644 --- a/src/test/java/jota/IotaAPITest.java +++ b/src/test/java/jota/IotaAPITest.java @@ -33,11 +33,11 @@ public class IotaAPITest { private static final String TEST_SEED2 = "IHDEENZYITYVYSPKAURUZAQKGVJEREFDJMYTANNXXGPZ9GJWTEOJJ9IPMXOGZNQLSNMFDSQOTZAEETUEA"; private static final String TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_1 = "MALAZGDVZIAQQRTNYJDSZMY9VE9LAHQKTVCUOAGZUCX9IBUMODFFTMGUIUAXGLWZQ9CYRSLYBM9QBIBYA"; private static final String TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2 = "LXQHWNY9CQOHPNMKFJFIJHGEPAENAOVFRDIBF99PPHDTWJDCGHLYETXT9NPUVSNKT9XDTDYNJKJCPQMZC"; - private static final String TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2_2 = "LXQHWNY9CQOHPNMKFJFIJHGEPAENAOVFRDIBF99PPHDTWJDCGHLYETXT9NPUVSNKT9XDTDYNJKJCPQMZCCOZVXMTXC"; + private static final String TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2_2 = "RXTLHYQWBSJUZQXUS9LMLBE9RLAQFNDWBMZUGYJRJRHYRQQKVXBXJKEZOJDCVKFXM9GXYNMKTESEEILAYFCTLW9DQD"; private static final String TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_3 = "ASCZZOBQDMNHLELQKWJBMRETMHBTF9V9TNKYDIFW9PDXPUHPVVGHMSWPVMNJHSJF99QFCMNTPCPGS9DT9"; - private static final String TEST_HASH = "KIGLIYTQCLTGLQZXUTGJKXVNOGDLBXXGLEWDBNNFNBJHQFHZ9KOCZVTPV9WYLL9WHZEYBGHAWDRD99999"; + private static final String TEST_HASH = "EVCNKLXUTEKHSQKYKBSBACP9SCPTCBLLYLB9IDBMNQ9HAYANSUBZOCAAIPSGIMDAYLICTGWJAFFAA9999"; private static final String TEST_INVALID_TRYTES = "BYSWEAUTWXHXZ9YBZISEK9LUHWGMHXCGEVNZHRLUWQFCUSDXZHOFHWHL9MQPVJXXZLIXPXPXF9KYEREFSKCPKYIIKPZVLHUTDFQKKVVBBN9ATTLPCNPJDWDEVIYYLGPZGCWXOBDXMLJC9VO9QXTTBLAXTTBFUAROYEGQIVB9MJWJKXJMCUPTWAUGFZBTZCSJVRBGMYXTVBDDS9MYUJCPZ9YDWWQNIPUAIJXXSNLKUBSCOIJPCLEFPOXFJREXQCUVUMKSDOVQGGHRNILCO9GNCLWFM9APMNMWYASHXQAYBEXF9QRIHIBHYEJOYHRQJAOKAQ9AJJFQ9WEIWIJOTZATIBOXQLBMIJU9PCGBLVDDVFP9CFFSXTDUXMEGOOFXWRTLFGV9XXMYWEMGQEEEDBTIJ9OJOXFAPFQXCDAXOUDMLVYRMRLUDBETOLRJQAEDDLNVIRQJUBZBO9CCFDHIX9MSQCWYAXJVWHCUPTRSXJDESISQPRKZAFKFRULCGVRSBLVFOPEYLEE99JD9SEBALQINPDAZHFAB9RNBH9AZWIJOTLBZVIEJIAYGMC9AZGNFWGRSWAXTYSXVROVNKCOQQIWGPNQZKHUNODGYADPYLZZZUQRTJRTODOUKAOITNOMWNGHJBBA99QUMBHRENGBHTH9KHUAOXBVIVDVYYZMSEYSJWIOGGXZVRGN999EEGQMCOYVJQRIRROMPCQBLDYIGQO9AMORPYFSSUGACOJXGAQSPDY9YWRRPESNXXBDQ9OZOXVIOMLGTSWAMKMTDRSPGJKGBXQIVNRJRFRYEZ9VJDLHIKPSKMYC9YEGHFDS9SGVDHRIXBEMLFIINOHVPXIFAZCJKBHVMQZEVWCOSNWQRDYWVAIBLSCBGESJUIBWZECPUCAYAWMTQKRMCHONIPKJYYTEGZCJYCT9ABRWTJLRQXKMWY9GWZMHYZNWPXULNZAPVQLPMYQZCYNEPOCGOHBJUZLZDPIXVHLDMQYJUUBEDXXPXFLNRGIPWBRNQQZJSGSJTTYHIGGFAWJVXWL9THTPWOOHTNQWCNYOYZXALHAZXVMIZE9WMQUDCHDJMIBWKTYH9AC9AFOT9DPCADCV9ZWUTE9QNOMSZPTZDJLJZCJGHXUNBJFUBJWQUEZDMHXGBPTNSPZBR9TGSKVOHMOQSWPGFLSWNESFKSAZY9HHERAXALZCABFYPOVLAHMIHVDBGKUMDXC9WHHTIRYHZVWNXSVQUWCR9M9RAGMFEZZKZ9XEOQGOSLFQCHHOKLDSA9QCMDGCGMRYJZLBVIFOLBIJPROKMHOYTBTJIWUZWJMCTKCJKKTR9LCVYPVJI9AHGI9JOWMIWZAGMLDFJA9WU9QAMEFGABIBEZNNAL9OXSBFLOEHKDGHWFQSHMPLYFCNXAAZYJLMQDEYRGL9QKCEUEJ9LLVUOINVSZZQHCIKPAGMT9CAYIIMTTBCPKWTYHOJIIY9GYNPAJNUJ9BKYYXSV9JSPEXYMCFAIKTGNRSQGUNIYZCRT9FOWENSZQPD9ALUPYYAVICHVYELYFPUYDTWUSWNIYFXPX9MICCCOOZIWRNJIDALWGWRATGLJXNAYTNIZWQ9YTVDBOFZRKO9CFWRPAQQRXTPACOWCPRLYRYSJARRKSQPR9TCFXDVIXLP9XVL99ERRDSOHBFJDJQQGGGCZNDQ9NYCTQJWVZIAELCRBJJFDMCNZU9FIZRPGNURTXOCDSQGXTQHKHUECGWFUUYS9J9NYQ9U9P9UUP9YMZHWWWCIASCFLCMSKTELZWUGCDE9YOKVOVKTAYPHDF9ZCCQAYPJIJNGSHUIHHCOSSOOBUDOKE9CJZGYSSGNCQJVBEFTZFJ9SQUHOASKRRGBSHWKBCBWBTJHOGQ9WOMQFHWJVEG9NYX9KWBTCAIXNXHEBDIOFO9ALYMFGRICLCKKLG9FOBOX9PDWNQRGHBKHGKKRLWTBEQMCWQRLHAVYYZDIIPKVQTHYTWQMTOACXZOQCDTJTBAAUWXSGJF9PNQIJ9AJRUMUVCPWYVYVARKR9RKGOUHHNKNVGGPDDLGKPQNOYHNKAVVKCXWXOQPZNSLATUJT9AUWRMPPSWHSTTYDFAQDXOCYTZHOYYGAIM9CELMZ9AZPWB9MJXGHOKDNNSZVUDAGXTJJSSZCPZVPZBYNNTUQABSXQWZCHDQSLGK9UOHCFKBIBNETK999999999999999999999999999999999999999999999999999999999999999999999999999999999NOXDXXKUDWLOFJLIPQIBRBMGDYCPGDNLQOLQS99EQYKBIU9VHCJVIPFUYCQDNY9APGEVYLCENJIOBLWNB999999999XKBRHUD99C99999999NKZKEKWLDKMJCI9N9XQOLWEPAYWSH9999999999999999999999999KDDTGZLIPBNZKMLTOLOXQVNGLASESDQVPTXALEKRMIOHQLUHD9ELQDBQETS9QFGTYOYWLNTSKKMVJAUXSIROUICDOXKSYZTDPEDKOQENTJOWJONDEWROCEJIEWFWLUAACVSJFTMCHHXJBJRKAAPUDXXVXFWP9X9999IROUICDOXKSYZTDPEDKOQENTJOWJONDEWROCEJIEWFWLUAACVSJFTMCHHXJBJRKAAPUDXXVXFWP9X9999"; - private static final String TEST_TRYTES = "JUSTANOTHERTEST999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999PNGMCSNRCTRHCHPXYTPKEJYPCOWKOMRXZFHH9N9VDIKMNVAZCMIYRHVJIAZARZTUETJVFDMBEBIQE9QTH999999999999999999999999999JOTASPAM9999999999999999999VADPPWD99999999999999999999AQKWPYWBUEPGRZAVQUKYAVRPPNEIZZFHHLBESBBINMZCDU9GYMQAUKXSDLAHCB9XCFEPACLJGLHFUSTWJ999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"; + private static final String TEST_TRYTES = "9RYSLXACOTYQZAQIAMCULCVKMBIPMKINPFJCZFIZOOZMTCTKIXQHQTUTVGZMVHGKLRZGWOT9UGYQFNCGNRJWDETRKWUFIAFA9M9ZPZKVJWKOJENHFWMFBDVOLEVCGQTKCTOPNGRYQURVQPFJAZFUKCXAOORIYCVDKDINDXRFAFRSFVRXCTPETGIJULBYGXUHQMBGHAKGJLMNZUQE9EVOGTFVJ9EVSDNUYPGQLZBAJNWG9XXXDHETVT9XBBCQZEWJXFLVHEXHEQARCOSRKQQVEQKK9APNBRBJHHUWRGAWUIMLY9AFCULX9ITRJBYU9BNQPZBJKJDNHDAKIGDMNUOFCWAEDSBDRUTORPZQCHCSQRVIERZNGPYBPEOQXGFAKANGXPE9MA9ZZCLKDQANOKIAV9QDDUZILVMEIHXDSHDISEJMLQGVEUJWMCKCMIQTRRGJKJFSVMZWYNQJCFCPOEGOTJULGPFTM9GQGEONOXSYXYPQZHVFYHKYREHQMYWHYUTZE999HRWIQTOENSRFPB9NXDVFSUA9NLAKOELYAAHTFDDAYBHPKNAXXTJIPYOKXTEMYUIOKXORYUFEIIAZCFGCCINBPTXFNTGPKFOQNGEODMSCVOZKRJYLECZB9VDZJCLPMTY9UPLTLH9GVDBALFNBLQXI9ADJJXCSPQJXHNNZUOJCMFJKZZ9ZTJRQMNLDSTZYTFNXQPZKMQJLZBHF9URFHNX9MQVMTIHEMROFCCPDLUOTRCAURYL9IJ9IGTRFVIJXSFLYBJOQOASBNVRFQGVIGKA9UJUDHWUSBFFKDHDVRGLOZQYADXGS9IOGCPCVCFPNUDFTUKXCOEEUMNDZCZGUXIECIYCKL9XCPEIQMYV9VCP9JJMSREJFQB9IVXUAXWCURUADEPBIVIGERXIMFZAGQPRC9KSYYLHBZVZGQJVTZVBGMRBWYJCYRHMJWPIKJYAYTALAAZROZYCMQKWBSFUGHFSOGGTCQDHWJU9VJGCAHJLHSORFKVJKV9RSZHLJZTDJJGOXTRLKNJORWYPW9UKRZROJONZQWJNUEPBZZJYBJJNCAQOEYTHFWVUBACCFTREABOZKQEKSMDAFECVGMGELNZUFZJHWHNXLBOSHLNBPGSQDVLZLBUXWINABWYBDMZNIYNVPYLRKUULTMNNKZUFNQOQKROJSXWYTBRDSJQKTOUXLMXVCVIXEYPZWBSMEXMBGUIVACRTGKDEIYZKP9KQCQXPWRXNLGQOATRHCXJFQINXFYQIDTPUJVXKUYVRYHWDHWSNLWUFPNNJZVNMRFWPZBJCRRSHMHUG9NKKH9SOXTUJUAXBF9MHYWHJ9ZTJRUQFKRLHMNVPWX9XFXLMVJAGASMWMIFYUZFAUCEIOOYMEYWOIZTNEWFVZKOQFECWEPSMOYFSJJKEJQMPSXGE9WTYRQJVMHUQZFD9MJUFFCNSGAZCTXYPIJFNSXAUCYPGZMNWMQWSWCKAQYKXJTWINSGPPZG9HLDLEAWUWEVCTVRCBDFOXKUROXH9HXXAXVPEJFRSLOGRVGYZASTEBAQNXJJROCYRTDPYFUIQJVDHAKEG9YACV9HCPJUEUKOYFNWDXCCJBIFQKYOXGRDHVTHEQUMHO999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999DNVEZXD99A99999999A99999999BULMKQXROXEBHPBYGKQINYJTHPTL9OGKUFBFAVRHPZSNXBUDMNRJFYIIGWOFVCXSVFQRZMPGCZMZUNKCDDRWDLKTKCZXZFMIZ9CZBWNOJGSXHBKEXCFQPBNFAE9QAVRX9SWGEZQRSYAYNW9TPWVWCJXAUPQHYZ9999NBDPASDXMXDCHLMZJIBHAZREUBOTZZAYGKCWTBSBKKETULAPABDTY9AMPBSXO9KJOLCWJMJSZFKU999999999999999999999999999999999999999999999999999999999999CWJQRPBIJGTWQTCMDUVOCBUAMH"; private static final String TEST_MILESTONE = "SMYMAKKPSUKCKDRUEYCGZJTYCZ9HHDMDUWBAPXARGURPQRHTAJDASRWMIDTPTBNDKDEFBUTBGGAFX9999"; private static final Integer TEST_MILESTONE_INDEX = 8059; private static final String TEST_MESSAGE = "JOTA"; @@ -63,7 +63,7 @@ public class IotaAPITest { , "WDTFFXHBHMFQQVXQLBFJFVVHVIIAVYM9PFAZCHMKET9ESMHIRHSMVDJBZTXPTAFVIASMSXRDCIYVWVQNO" , "XCCPS9GMTSUB9DXPVKLTBDHOFX9PJMBYZQYQEXMRQDPGQPLWRGZGXODYJKGVFOHHYUJRCSXAIDGYSAWRB" , "KVEBCGMEOPDPRCQBPIEMZTTXYBURGZVNH9PLHKPMM9D9FUKWIGLKZROGNSYIFHULLWQWXCNAW9HKKVIDC"}; - private static int MWM = 15; + private static int MWM = 14; private static Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).create(); private IotaAPI iotaClient; @@ -144,7 +144,7 @@ public class IotaAPITest { public void shouldPrepareTransfer() throws InvalidSecurityLevelException, NotEnoughBalanceException, InvalidAddressException, InvalidTransferException { List transfers = new ArrayList<>(); transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2, 0, TEST_MESSAGE, TEST_TAG)); - transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2, 1, TEST_MESSAGE, TEST_TAG)); + transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2, 0, TEST_MESSAGE, TEST_TAG)); List trytes = iotaClient.prepareTransfers(TEST_SEED1, 2, transfers, null, null); Assert.assertNotNull(trytes); assertThat(trytes.isEmpty(), Is.is(false)); @@ -224,7 +224,7 @@ public class IotaAPITest { @Test(expected = IllegalStateException.class) public void shouldNotSendTransfer() throws ArgumentException, InvalidSignatureException, InvalidBundleException, NotEnoughBalanceException, InvalidSecurityLevelException, InvalidTrytesException, InvalidAddressException, InvalidTransferException { List transfers = new ArrayList<>(); - transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2, 10000990, "JUSTANOTHERTEST", TEST_TAG)); + transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2, 0, "JUSTANOTHERTEST", TEST_TAG)); SendTransferResponse str = iotaClient.sendTransfer(TEST_SEED2, 2, 9, MWM, transfers, null, null); assertThat(str.getSuccessfully(), IsNull.notNullValue()); } @@ -233,7 +233,7 @@ public class IotaAPITest { @Test public void shouldSendTransfer() throws ArgumentException, InvalidSignatureException, InvalidBundleException, NotEnoughBalanceException, InvalidSecurityLevelException, InvalidTrytesException, InvalidAddressException, InvalidTransferException { List transfers = new ArrayList<>(); - transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2_2, 100, "JUSTANOTHERTEST", TEST_TAG)); + transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2_2, 0, "JUSTANOTHERTEST", TEST_TAG)); SendTransferResponse str = iotaClient.sendTransfer(TEST_SEED1, 2, 9, MWM, transfers, null, null); assertThat(str.getSuccessfully(), IsNull.notNullValue()); } diff --git a/src/test/java/jota/IotaMultisigTest.java b/src/test/java/jota/IotaMultisigTest.java index dbb7147..927b5b8 100644 --- a/src/test/java/jota/IotaMultisigTest.java +++ b/src/test/java/jota/IotaMultisigTest.java @@ -8,7 +8,7 @@ import jota.error.InvalidTransferException; import jota.model.Bundle; import jota.model.Transaction; import jota.model.Transfer; -import jota.pow.JCurl; +import jota.pow.SpongeFactory; import jota.utils.Converter; import jota.utils.Multisig; import jota.utils.Signing; @@ -78,7 +78,7 @@ public class IotaMultisigTest { bundle = ms.addSignature(bundle, multiSigAddress, ms.getKey(TEST_SEED2, 0, 3)); - Signing sgn = new Signing(new JCurl()); + Signing sgn = new Signing(SpongeFactory.create(SpongeFactory.Mode.KERL)); boolean isValidSignature = sgn.validateSignatures(bundle, multiSigAddress); assertTrue("MultiSignature not valid", isValidSignature); diff --git a/src/test/java/jota/SigningTest.java b/src/test/java/jota/SigningTest.java index 1b4a5a6..6d69703 100644 --- a/src/test/java/jota/SigningTest.java +++ b/src/test/java/jota/SigningTest.java @@ -2,21 +2,14 @@ package jota; import jota.error.InvalidAddressException; import jota.model.Bundle; -import jota.utils.Checksum; -import jota.utils.Constants; -import jota.utils.Converter; -import jota.utils.InputValidator; -import jota.utils.IotaAPIUtils; -import jota.utils.SeedRandomGenerator; -import jota.utils.Signing; - +import jota.utils.*; import org.junit.Test; +import java.util.Arrays; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import java.util.Arrays; - /** * @author schierlm@gmx.de */