diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 1ca7d784..85fa2464 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -4,7 +4,7 @@ org.iota jota JOTA - 0.9.0-RC1 + 0.9.2 JOTA library is a simple Java wrapper around IOTA Node's JSON-REST HTTP interface. @@ -41,7 +41,7 @@ maven-surefire-plugin 2.12.4 - true + ${skipTests} @@ -53,7 +53,6 @@ maven-source-plugin - 3.0.1 attach-sources @@ -72,11 +71,6 @@ jar - - private - true - -Xdoclint:none - @@ -121,6 +115,7 @@ + true 1.7 UTF-8 diff --git a/pom.xml b/pom.xml index edb84885..4c200978 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.iota jota - 0.9.1 + 0.9.2 JOTA JOTA library is a simple Java wrapper around IOTA Node's JSON-REST HTTP interface. @@ -24,6 +24,13 @@ + + + org.bouncycastle + bcprov-jdk15on + 1.57 + + com.squareup.retrofit2 diff --git a/src/main/java/jota/IotaAPI.java b/src/main/java/jota/IotaAPI.java index 9bc1f5a4..a5a4663f 100644 --- a/src/main/java/jota/IotaAPI.java +++ b/src/main/java/jota/IotaAPI.java @@ -1,10 +1,11 @@ package jota; +import com.google.gson.Gson; import jota.dto.response.*; import jota.error.*; import jota.model.*; import jota.pow.ICurl; -import jota.pow.JCurl; +import jota.pow.SpongeFactory; import jota.utils.*; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -252,6 +253,7 @@ public List sendTrytes(final String[] trytes, final int depth, fina final GetTransactionsToApproveResponse txs = getTransactionsToApprove(depth); // attach to tangle - do pow + System.out.println(new Gson().toJson(txs)); final GetAttachToTangleResponse res = attachToTangle(txs.getTrunkTransaction(), txs.getBranchTransaction(), minWeightMagnitude, trytes); try { @@ -641,7 +643,7 @@ public GetBundleResponse getBundle(String transaction) throws ArgumentException, long totalSum = 0; String bundleHash = bundle.getTransactions().get(0).getBundle(); - ICurl curl = new JCurl(); + ICurl curl = SpongeFactory.create(SpongeFactory.Mode.KERL); curl.reset(); List signaturesToValidate = new ArrayList<>(); @@ -1108,7 +1110,7 @@ public List addRemainder(final String seed, } public static class Builder extends IotaAPICore.Builder { - private ICurl customCurl = new JCurl(); + private ICurl customCurl = SpongeFactory.create(SpongeFactory.Mode.KERL); public Builder withCustomCurl(ICurl curl) { customCurl = curl; diff --git a/src/main/java/jota/model/Bundle.java b/src/main/java/jota/model/Bundle.java index 1de54f64..5c4844a7 100644 --- a/src/main/java/jota/model/Bundle.java +++ b/src/main/java/jota/model/Bundle.java @@ -1,7 +1,7 @@ package jota.model; import jota.pow.ICurl; -import jota.pow.JCurl; +import jota.pow.SpongeFactory; import jota.utils.Converter; import org.apache.commons.lang3.StringUtils; @@ -90,7 +90,7 @@ public void addEntry(int signatureMessageLength, String address, long value, Str */ public void finalize(ICurl customCurl) { - ICurl curl = customCurl == null ? new JCurl() : customCurl; + ICurl curl = customCurl == null ? SpongeFactory.create(SpongeFactory.Mode.KERL) : customCurl; curl.reset(); for (int i = 0; i < this.getTransactions().size(); i++) { diff --git a/src/main/java/jota/model/Transaction.java b/src/main/java/jota/model/Transaction.java index 4b706839..b064188e 100644 --- a/src/main/java/jota/model/Transaction.java +++ b/src/main/java/jota/model/Transaction.java @@ -1,7 +1,7 @@ package jota.model; import jota.pow.ICurl; -import jota.pow.JCurl; +import jota.pow.SpongeFactory; import jota.utils.Converter; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -18,8 +18,9 @@ */ public class Transaction { - private static final Logger log = LoggerFactory.getLogger(Transaction.class); - private ICurl customCurl; + private static final transient Logger log = LoggerFactory.getLogger(Transaction.class); + + private transient ICurl customCurl; private String hash; private String signatureFragments; @@ -391,7 +392,7 @@ public void transactionObject(final String trytes) { int[] transactionTrits = Converter.trits(trytes); int[] hash = new int[243]; - final ICurl curl = customCurl == null ? new JCurl() : customCurl; // we need a fluent JCurl. + final ICurl curl = customCurl == null ? SpongeFactory.create(SpongeFactory.Mode.KERL) : customCurl; // we need a fluent JCurl. // generate the correct transaction hash curl.reset(); diff --git a/src/main/java/jota/pow/JCurl.java b/src/main/java/jota/pow/JCurl.java index 3a80848c..ea7640c1 100644 --- a/src/main/java/jota/pow/JCurl.java +++ b/src/main/java/jota/pow/JCurl.java @@ -1,5 +1,10 @@ package jota.pow; +import jota.utils.Converter; +import jota.utils.Pair; + +import java.util.Arrays; + /** * (c) 2016 Come-from-Beyond *

@@ -14,10 +19,30 @@ public class JCurl implements ICurl { private static final int STATE_LENGTH = 3 * HASH_LENGTH; private static final int NUMBER_OF_ROUNDS = 27; - private static final int[] TRUTH_TABLE = {1, 0, -1, 1, -1, 0, -1, 1, 0}; - - private int[] state = new int[STATE_LENGTH]; + 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; + if (pair) { + stateHigh = new long[STATE_LENGTH]; + stateLow = new long[STATE_LENGTH]; + state = null; + set(); + } else { + state = new int[STATE_LENGTH]; + stateHigh = null; + stateLow = null; + } + } /** * Absorbs the specified trits. * @@ -54,14 +79,21 @@ public JCurl absorb(final int[] trits) { */ public JCurl transform() { - final int[] scratchpad = new int[STATE_LENGTH]; int scratchpadIndex = 0; + int prev_scratchpadIndex = 0; for (int round = 0; round < NUMBER_OF_ROUNDS; round++) { System.arraycopy(state, 0, scratchpad, 0, STATE_LENGTH); for (int stateIndex = 0; stateIndex < STATE_LENGTH; stateIndex++) { - state[stateIndex] = TRUTH_TABLE[scratchpad[scratchpadIndex] + scratchpad[scratchpadIndex += (scratchpadIndex < 365 ? 364 : -365)] * 3 + 4]; + prev_scratchpadIndex = scratchpadIndex; + if (scratchpadIndex < 365) { + scratchpadIndex += 364; + } else { + scratchpadIndex += -365; + } + state[stateIndex] = TRUTH_TABLE[scratchpad[prev_scratchpadIndex] + (scratchpad[scratchpadIndex] << 2) + 5]; } } + return this; } @@ -124,6 +156,52 @@ public void setState(int[] state) { this.state = state; } + private void set() { + Arrays.fill(stateLow, Converter.HIGH_LONG_BITS); + Arrays.fill(stateHigh, Converter.HIGH_LONG_BITS); + } + + private void pairTransform() { + final long[] curlScratchpadLow = new long[STATE_LENGTH]; + final long[] curlScratchpadHigh = new long[STATE_LENGTH]; + int curlScratchpadIndex = 0; + for (int round = 27; 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++) { + final long alpha = curlScratchpadLow[curlScratchpadIndex]; + final long beta = curlScratchpadHigh[curlScratchpadIndex]; + final long gamma = curlScratchpadHigh[curlScratchpadIndex += (curlScratchpadIndex < 365 ? 364 : -365)]; + final long delta = (alpha | (~gamma)) & (curlScratchpadLow[curlScratchpadIndex] ^ beta); + stateLow[curlStateIndex] = ~delta; + stateHigh[curlStateIndex] = (alpha ^ gamma) | delta; + } + } + } + + public void absorb(final Pair pair, int offset, int length) { + int o = offset, l = length, i = 0; + do { + System.arraycopy(pair.low, o, stateLow, 0, l < HASH_LENGTH ? l : HASH_LENGTH); + System.arraycopy(pair.hi, o, stateHigh, 0, l < HASH_LENGTH ? l : HASH_LENGTH); + pairTransform(); + o += HASH_LENGTH; + } while ((l -= HASH_LENGTH) > 0); + } + + public Pair squeeze(Pair pair, int offset, int length) { + int o = offset, l = length, i = 0; + long[] low = pair.low; + long[] hi = pair.hi; + do { + System.arraycopy(stateLow, 0, low, o, l < HASH_LENGTH ? l : HASH_LENGTH); + System.arraycopy(stateHigh, 0, hi, o, l < HASH_LENGTH ? l : HASH_LENGTH); + pairTransform(); + o += HASH_LENGTH; + } while ((l -= HASH_LENGTH) > 0); + return new Pair<>(low, hi); + } + /** * Clones this instance. * @@ -131,6 +209,6 @@ public void setState(int[] state) { */ @Override public ICurl clone() { - return new JCurl(); + return new JCurl(pair); } } diff --git a/src/main/java/jota/pow/Kerl.java b/src/main/java/jota/pow/Kerl.java new file mode 100644 index 00000000..fad11632 --- /dev/null +++ b/src/main/java/jota/pow/Kerl.java @@ -0,0 +1,169 @@ +package jota.pow; + +import org.bouncycastle.jcajce.provider.digest.Keccak; + +import java.math.BigInteger; +import java.util.Arrays; + +public class Kerl extends JCurl { + + private static final int HASH_LENGTH = 243; + private static final int BIT_HASH_LENGTH = 384; + private static final int BYTE_HASH_LENGTH = BIT_HASH_LENGTH / 8; + + private static final int RADIX = 3; + private static final int MAX_TRIT_VALUE = (RADIX - 1) / 2, MIN_TRIT_VALUE = -MAX_TRIT_VALUE; + private final Keccak.Digest384 keccak; + private byte[] byte_state; + private int[] trit_state; + + public Kerl() { + super(); + this.keccak = new Keccak.Digest384(); + this.byte_state = new byte[BYTE_HASH_LENGTH]; + this.trit_state = new int[HASH_LENGTH]; + } + + public static BigInteger convertTritsToBigint(final int[] trits, final int offset, final int size) { + + BigInteger value = BigInteger.ZERO; + + for (int i = size; i-- > 0; ) { + + value = value.multiply(BigInteger.valueOf(RADIX)).add(BigInteger.valueOf(trits[offset + i])); + } + + return value; + } + + private static BigInteger convertBytesToBigInt(final byte[] bytes, final int offset, final int size) { + + return new BigInteger(Arrays.copyOfRange(bytes, offset, offset + size)); + } + + private static int[] convertBigintToTrits(final BigInteger value, int size) { + + int[] destination = new int[size]; + BigInteger absoluteValue = value.compareTo(BigInteger.ZERO) < 0 ? value.negate() : value; + for (int i = 0; i < size; i++) { + + BigInteger[] divRemainder = absoluteValue.divideAndRemainder(BigInteger.valueOf(RADIX)); + int remainder = divRemainder[1].intValue(); + absoluteValue = divRemainder[0]; + + if (remainder > MAX_TRIT_VALUE) { + + remainder = MIN_TRIT_VALUE; + absoluteValue = absoluteValue.add(BigInteger.ONE); + } + destination[i] = remainder; + } + + if (value.compareTo(BigInteger.ZERO) < 0) { + + for (int i = 0; i < size; i++) { + + destination[i] = -destination[i]; + } + } + + return destination; + } + + private static byte[] convertBigintToBytes(final BigInteger value, int size) { + + final byte[] result = new byte[BYTE_HASH_LENGTH]; + + final byte[] bytes = value.toByteArray(); + int i = 0; + while (i + bytes.length < BYTE_HASH_LENGTH) { + + result[i++] = (byte) (bytes[0] < 0 ? -1 : 0); + } + for (int j = bytes.length; j-- > 0; ) { + + result[i++] = bytes[bytes.length - 1 - j]; + } + + return result; + } + + @Override + public Kerl reset() { + + this.keccak.reset(); + + return this; + } + + @Override + public Kerl absorb(final int[] trits, int offset, int length) { + + if (length % 243 != 0) throw new RuntimeException("Illegal length: " + length); + + do { + + //copy trits[offset:offset+length] + System.arraycopy(trits, offset, trit_state, 0, HASH_LENGTH); + + //convert to bits + trit_state[HASH_LENGTH - 1] = 0; + byte[] bytes = convertBigintToBytes(convertTritsToBigint(trit_state, 0, HASH_LENGTH), BYTE_HASH_LENGTH); + + //run keccak + keccak.update(bytes); + offset += HASH_LENGTH; + + } while ((length -= HASH_LENGTH) > 0); + + return this; + } + + @Override + public int[] squeeze(final int[] trits, int offset, int length) { + + if (length % 243 != 0) throw new RuntimeException("Illegal length: " + length); + + do { + + byte_state = this.keccak.digest(); + //convert to trits + trit_state = convertBigintToTrits(convertBytesToBigInt(byte_state, 0, BYTE_HASH_LENGTH), HASH_LENGTH); + + //copy with offset + trit_state[HASH_LENGTH - 1] = 0; + System.arraycopy(trit_state, 0, trits, offset, HASH_LENGTH); + + //calculate hash again + for (int i = byte_state.length; i-- > 0; ) { + + byte_state[i] = (byte) (byte_state[i] ^ 0xFF); + } + keccak.update(byte_state); + offset += HASH_LENGTH; + + } while ((length -= HASH_LENGTH) > 0); + + return trits; + } + + /** + * Squeezes the specified trits. + * + * @param trits The trits. + * @return The squeezes trits. + */ + public int[] squeeze(final int[] trits) { + return squeeze(trits, 0, trits.length); + } + + /** + * Clones this instance. + * + * @return A new instance. + */ + @Override + public Kerl clone() { + return new Kerl(); + } +} \ No newline at end of file diff --git a/src/main/java/jota/pow/SpongeFactory.java b/src/main/java/jota/pow/SpongeFactory.java new file mode 100644 index 00000000..ca37b288 --- /dev/null +++ b/src/main/java/jota/pow/SpongeFactory.java @@ -0,0 +1,25 @@ +package jota.pow; + +/** + * Created by paul on 7/27/17. + */ +public abstract class SpongeFactory { + public static ICurl create(Mode mode) { + switch (mode) { + case CURL: + return new JCurl(); + case KERL: + return new Kerl(); + case BCURLT: + return new JCurl(true); + default: + return null; + } + } + + public enum Mode { + CURL, + KERL, + BCURLT + } +} \ No newline at end of file diff --git a/src/main/java/jota/utils/Checksum.java b/src/main/java/jota/utils/Checksum.java index a69c3f93..08107ca2 100644 --- a/src/main/java/jota/utils/Checksum.java +++ b/src/main/java/jota/utils/Checksum.java @@ -1,7 +1,9 @@ package jota.utils; import jota.error.InvalidAddressException; +import jota.pow.ICurl; import jota.pow.JCurl; +import jota.pow.SpongeFactory; /** * This class defines utility methods to add/remove the checksum to/from an address. @@ -53,7 +55,7 @@ private static String removeChecksumFromAddress(String addressWithChecksum) { **/ public static boolean isValidChecksum(String addressWithChecksum) throws InvalidAddressException { String addressWithoutChecksum = removeChecksum(addressWithChecksum); - String addressWithRecalculateChecksum = addressWithChecksum += calculateChecksum(addressWithoutChecksum); + String addressWithRecalculateChecksum = addressWithoutChecksum += calculateChecksum(addressWithoutChecksum); return addressWithRecalculateChecksum.equals(addressWithChecksum); } @@ -82,10 +84,13 @@ public static boolean isAddressWithoutChecksum(String address) throws InvalidAdd } private static String calculateChecksum(String address) { - JCurl curl = new JCurl(); + ICurl curl = SpongeFactory.create(SpongeFactory.Mode.KERL); curl.reset(); - curl.setState(Converter.copyTrits(address, curl.getState())); - curl.transform(); - return Converter.trytes(curl.getState()).substring(0, 9); + curl.absorb(Converter.trits(address)); + int[] checksumTrits = new int[JCurl.HASH_LENGTH]; + curl.squeeze(checksumTrits); + String checksum = Converter.trytes(checksumTrits); + String checksumPrt = checksum.substring(72, 81); + return checksumPrt; } } diff --git a/src/main/java/jota/utils/Converter.java b/src/main/java/jota/utils/Converter.java index 4410962d..69f4a334 100644 --- a/src/main/java/jota/utils/Converter.java +++ b/src/main/java/jota/utils/Converter.java @@ -31,6 +31,9 @@ public class Converter { private static final int[][] BYTE_TO_TRITS_MAPPINGS = new int[243][]; private static final int[][] TRYTE_TO_TRITS_MAPPINGS = new int[27][]; + public static final int HIGH_INTEGER_BITS = 0xFFFFFFFF; + public static final long HIGH_LONG_BITS = 0xFFFFFFFFFFFFFFFFL; + static { final int[] trits = new int[NUMBER_OF_TRITS_IN_A_BYTE]; diff --git a/src/main/java/jota/utils/Multisig.java b/src/main/java/jota/utils/Multisig.java index 3ce4795d..35a8cf21 100644 --- a/src/main/java/jota/utils/Multisig.java +++ b/src/main/java/jota/utils/Multisig.java @@ -2,7 +2,7 @@ import jota.model.Bundle; import jota.pow.ICurl; -import jota.pow.JCurl; +import jota.pow.SpongeFactory; import java.util.Arrays; @@ -27,7 +27,7 @@ public Multisig(ICurl customCurl) { * Initializes a new instance of the Multisig class. */ public Multisig() { - this(new JCurl()); + this(SpongeFactory.create(SpongeFactory.Mode.KERL)); } /** diff --git a/src/main/java/jota/utils/Pair.java b/src/main/java/jota/utils/Pair.java new file mode 100644 index 00000000..8fec666c --- /dev/null +++ b/src/main/java/jota/utils/Pair.java @@ -0,0 +1,14 @@ +package jota.utils; + +/** + * Created by paul on 4/15/17. + */ +public class Pair { + public S low; + public T hi; + + public Pair(S k, T v) { + low = k; + hi = v; + } +} \ No newline at end of file diff --git a/src/main/java/jota/utils/Signing.java b/src/main/java/jota/utils/Signing.java index bd4b6a55..a1e3cdf2 100644 --- a/src/main/java/jota/utils/Signing.java +++ b/src/main/java/jota/utils/Signing.java @@ -3,7 +3,7 @@ import jota.model.Bundle; import jota.model.Transaction; import jota.pow.ICurl; -import jota.pow.JCurl; +import jota.pow.SpongeFactory; import java.util.ArrayList; import java.util.Arrays; @@ -27,7 +27,7 @@ public class Signing { * @param curl */ public Signing(ICurl curl) { - this.curl = curl == null ? new JCurl() : curl; + this.curl = curl == null ? SpongeFactory.create(SpongeFactory.Mode.KERL) : curl; } /** @@ -146,7 +146,7 @@ public int[] digest(int[] normalizedBundleFragment, int[] signatureFragment) { for (int j = normalizedBundleFragment[i] + 13; j-- > 0; ) { - ICurl jCurl = new JCurl(); + ICurl jCurl = SpongeFactory.create(SpongeFactory.Mode.KERL); jCurl.reset(); jCurl.absorb(buffer); jCurl.squeeze(buffer); diff --git a/src/test/java/jota/ChecksumTest.java b/src/test/java/jota/ChecksumTest.java index 12ec896b..d247ff38 100644 --- a/src/test/java/jota/ChecksumTest.java +++ b/src/test/java/jota/ChecksumTest.java @@ -11,21 +11,23 @@ */ public class ChecksumTest { - private static final String TEST_ADDRESS_WITHOUT_CHECKSUM = "RVORZ9SIIP9RCYMREUIXXVPQIPHVCNPQ9HZWYKFWYWZRE9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVA"; - private static final String TEST_ADDRESS_WITH_CHECKSUM = "RVORZ9SIIP9RCYMREUIXXVPQIPHVCNPQ9HZWYKFWYWZRE9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVAFOXM9MUBX"; + private static final String TEST_ADDRESS_WITHOUT_CHECKSUM = "EUHMAFIYBYZOXAVQQYRQ9RCNMTYX9KNEZFWXYMQIYPSRZRVDOLXDPUEARYPTWSZCAXJLXRYUUQKSHIJYZ"; + private static final String TEST_ADDRESS_WITHOUT_CHECKSUM2 = "P9UDUZMN9DEXCRQEKLJYSBSBZFCHOBPJSDKMLCCVJDOVOFDWMNBZRIRRZJGINOUMPJBMYYZEGRTIDUABD"; + private static final String TEST_ADDRESS_WITH_CHECKSUM = "EUHMAFIYBYZOXAVQQYRQ9RCNMTYX9KNEZFWXYMQIYPSRZRVDOLXDPUEARYPTWSZCAXJLXRYUUQKSHIJYZICCXCXUHX"; + private static final String TEST_ADDRESS_WITH_CHECKSUM2 = "P9UDUZMN9DEXCRQEKLJYSBSBZFCHOBPJSDKMLCCVJDOVOFDWMNBZRIRRZJGINOUMPJBMYYZEGRTIDUABDODCNSCYJD"; @Test public void shouldAddChecksum() throws InvalidAddressException { - assertEquals(Checksum.addChecksum(TEST_ADDRESS_WITHOUT_CHECKSUM), TEST_ADDRESS_WITH_CHECKSUM); + assertEquals(Checksum.addChecksum(TEST_ADDRESS_WITHOUT_CHECKSUM2), TEST_ADDRESS_WITH_CHECKSUM2); } - + @Test public void shouldRemoveChecksum() throws InvalidAddressException { - assertEquals(Checksum.removeChecksum(TEST_ADDRESS_WITH_CHECKSUM), TEST_ADDRESS_WITHOUT_CHECKSUM); + assertEquals(Checksum.removeChecksum(TEST_ADDRESS_WITH_CHECKSUM2), TEST_ADDRESS_WITHOUT_CHECKSUM2); } @Test public void shouldIsValidChecksum() throws InvalidAddressException { - assertEquals(Checksum.isValidChecksum(TEST_ADDRESS_WITH_CHECKSUM), true); + assertEquals(Checksum.isValidChecksum(TEST_ADDRESS_WITH_CHECKSUM2), true); } } diff --git a/src/test/java/jota/IotaAPITest.java b/src/test/java/jota/IotaAPITest.java index 11dd2dda..7bb7f64c 100644 --- a/src/test/java/jota/IotaAPITest.java +++ b/src/test/java/jota/IotaAPITest.java @@ -14,6 +14,7 @@ import org.junit.Ignore; import org.junit.Test; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; @@ -26,21 +27,22 @@ */ public class IotaAPITest { - private static final String TEST_SEED1 = "AAA999999999999999999999999999999999999999999999999999999999999999999999999999999"; + private static final String TEST_SEED1 = "IHDEENZYITYVYSPKAURUZAQKGVJEREFDJMYTANNXXGPZ9GJWTEOJJ9IPMXOGZNQLSNMFDSQOTZAEETUEA"; private static final String TEST_SEED2 = "IHDEENZYITYVYSPKAURUZAQKGVJEREFDJMYTANNXXGPZ9GJWTEOJJ9IPMXOGZNQLSNMFDSQOTZAEETUEA"; - private static final String TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_1 = "NINSZRAKWBERQBBN9KGIRNXQDNENLBUBAYRZPUXFJSWRWVADEOGGOWMLQWSHA9NEOLASWRGOQJXAVRMFY"; - private static final String TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2 = "PNGMCSNRCTRHCHPXYTPKEJYPCOWKOMRXZFHH9N9VDIKMNVAZCMIYRHVJIAZARZTUETJVFDMBEBIQE9QTH"; - private static final String TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_3 = "NOHBJKARAS9DZBFTRVIFY99STSQPSGTHMGMDYXLYIYKFYZISJUOGYWMZXDB9XEXFSSP9GYAIEHUQHLQ9C"; - private static final String TEST_HASH = "CKZ9TYPLUWH9FUSYJMPIZBVHWFZXTZMVOJLC9KOICSTBBQWXYTOTMCVPSPMYNDONTXHRULRFAWD999999"; + 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_3 = "ASCZZOBQDMNHLELQKWJBMRETMHBTF9V9TNKYDIFW9PDXPUHPVVGHMSWPVMNJHSJF99QFCMNTPCPGS9DT9"; + private static final String TEST_HASH = "AKOEBGNW9BVIDWLXIYFIVQMEOTELGKMKWDCMEVRBPSYQZC9UIRYNKHPEQRGQKTBYVQCIQMWMZFXA99999"; private static final String TEST_INVALID_TRYTES = "BYSWEAUTWXHXZ9YBZISEK9LUHWGMHXCGEVNZHRLUWQFCUSDXZHOFHWHL9MQPVJXXZLIXPXPXF9KYEREFSKCPKYIIKPZVLHUTDFQKKVVBBN9ATTLPCNPJDWDEVIYYLGPZGCWXOBDXMLJC9VO9QXTTBLAXTTBFUAROYEGQIVB9MJWJKXJMCUPTWAUGFZBTZCSJVRBGMYXTVBDDS9MYUJCPZ9YDWWQNIPUAIJXXSNLKUBSCOIJPCLEFPOXFJREXQCUVUMKSDOVQGGHRNILCO9GNCLWFM9APMNMWYASHXQAYBEXF9QRIHIBHYEJOYHRQJAOKAQ9AJJFQ9WEIWIJOTZATIBOXQLBMIJU9PCGBLVDDVFP9CFFSXTDUXMEGOOFXWRTLFGV9XXMYWEMGQEEEDBTIJ9OJOXFAPFQXCDAXOUDMLVYRMRLUDBETOLRJQAEDDLNVIRQJUBZBO9CCFDHIX9MSQCWYAXJVWHCUPTRSXJDESISQPRKZAFKFRULCGVRSBLVFOPEYLEE99JD9SEBALQINPDAZHFAB9RNBH9AZWIJOTLBZVIEJIAYGMC9AZGNFWGRSWAXTYSXVROVNKCOQQIWGPNQZKHUNODGYADPYLZZZUQRTJRTODOUKAOITNOMWNGHJBBA99QUMBHRENGBHTH9KHUAOXBVIVDVYYZMSEYSJWIOGGXZVRGN999EEGQMCOYVJQRIRROMPCQBLDYIGQO9AMORPYFSSUGACOJXGAQSPDY9YWRRPESNXXBDQ9OZOXVIOMLGTSWAMKMTDRSPGJKGBXQIVNRJRFRYEZ9VJDLHIKPSKMYC9YEGHFDS9SGVDHRIXBEMLFIINOHVPXIFAZCJKBHVMQZEVWCOSNWQRDYWVAIBLSCBGESJUIBWZECPUCAYAWMTQKRMCHONIPKJYYTEGZCJYCT9ABRWTJLRQXKMWY9GWZMHYZNWPXULNZAPVQLPMYQZCYNEPOCGOHBJUZLZDPIXVHLDMQYJUUBEDXXPXFLNRGIPWBRNQQZJSGSJTTYHIGGFAWJVXWL9THTPWOOHTNQWCNYOYZXALHAZXVMIZE9WMQUDCHDJMIBWKTYH9AC9AFOT9DPCADCV9ZWUTE9QNOMSZPTZDJLJZCJGHXUNBJFUBJWQUEZDMHXGBPTNSPZBR9TGSKVOHMOQSWPGFLSWNESFKSAZY9HHERAXALZCABFYPOVLAHMIHVDBGKUMDXC9WHHTIRYHZVWNXSVQUWCR9M9RAGMFEZZKZ9XEOQGOSLFQCHHOKLDSA9QCMDGCGMRYJZLBVIFOLBIJPROKMHOYTBTJIWUZWJMCTKCJKKTR9LCVYPVJI9AHGI9JOWMIWZAGMLDFJA9WU9QAMEFGABIBEZNNAL9OXSBFLOEHKDGHWFQSHMPLYFCNXAAZYJLMQDEYRGL9QKCEUEJ9LLVUOINVSZZQHCIKPAGMT9CAYIIMTTBCPKWTYHOJIIY9GYNPAJNUJ9BKYYXSV9JSPEXYMCFAIKTGNRSQGUNIYZCRT9FOWENSZQPD9ALUPYYAVICHVYELYFPUYDTWUSWNIYFXPX9MICCCOOZIWRNJIDALWGWRATGLJXNAYTNIZWQ9YTVDBOFZRKO9CFWRPAQQRXTPACOWCPRLYRYSJARRKSQPR9TCFXDVIXLP9XVL99ERRDSOHBFJDJQQGGGCZNDQ9NYCTQJWVZIAELCRBJJFDMCNZU9FIZRPGNURTXOCDSQGXTQHKHUECGWFUUYS9J9NYQ9U9P9UUP9YMZHWWWCIASCFLCMSKTELZWUGCDE9YOKVOVKTAYPHDF9ZCCQAYPJIJNGSHUIHHCOSSOOBUDOKE9CJZGYSSGNCQJVBEFTZFJ9SQUHOASKRRGBSHWKBCBWBTJHOGQ9WOMQFHWJVEG9NYX9KWBTCAIXNXHEBDIOFO9ALYMFGRICLCKKLG9FOBOX9PDWNQRGHBKHGKKRLWTBEQMCWQRLHAVYYZDIIPKVQTHYTWQMTOACXZOQCDTJTBAAUWXSGJF9PNQIJ9AJRUMUVCPWYVYVARKR9RKGOUHHNKNVGGPDDLGKPQNOYHNKAVVKCXWXOQPZNSLATUJT9AUWRMPPSWHSTTYDFAQDXOCYTZHOYYGAIM9CELMZ9AZPWB9MJXGHOKDNNSZVUDAGXTJJSSZCPZVPZBYNNTUQABSXQWZCHDQSLGK9UOHCFKBIBNETK999999999999999999999999999999999999999999999999999999999999999999999999999999999NOXDXXKUDWLOFJLIPQIBRBMGDYCPGDNLQOLQS99EQYKBIU9VHCJVIPFUYCQDNY9APGEVYLCENJIOBLWNB999999999XKBRHUD99C99999999NKZKEKWLDKMJCI9N9XQOLWEPAYWSH9999999999999999999999999KDDTGZLIPBNZKMLTOLOXQVNGLASESDQVPTXALEKRMIOHQLUHD9ELQDBQETS9QFGTYOYWLNTSKKMVJAUXSIROUICDOXKSYZTDPEDKOQENTJOWJONDEWROCEJIEWFWLUAACVSJFTMCHHXJBJRKAAPUDXXVXFWP9X9999IROUICDOXKSYZTDPEDKOQENTJOWJONDEWROCEJIEWFWLUAACVSJFTMCHHXJBJRKAAPUDXXVXFWP9X9999"; private static final String TEST_TRYTES = "JUSTANOTHERTEST999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999PNGMCSNRCTRHCHPXYTPKEJYPCOWKOMRXZFHH9N9VDIKMNVAZCMIYRHVJIAZARZTUETJVFDMBEBIQE9QTH999999999999999999999999999JOTASPAM9999999999999999999VADPPWD99999999999999999999AQKWPYWBUEPGRZAVQUKYAVRPPNEIZZFHHLBESBBINMZCDU9GYMQAUKXSDLAHCB9XCFEPACLJGLHFUSTWJ999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"; private static final String TEST_MILESTONE = "SMYMAKKPSUKCKDRUEYCGZJTYCZ9HHDMDUWBAPXARGURPQRHTAJDASRWMIDTPTBNDKDEFBUTBGGAFX9999"; private static final Integer TEST_MILESTONE_INDEX = 8059; private static final String TEST_MESSAGE = "JOTA"; private static final String TEST_TAG = "JOTASPAM9999999999999999999"; - private static final String[] TEST_ADDRESSES = new String[]{"KHJXD9XKXPIVQRGREUIPVJTMEY9L9MXZAAKBBRYNINTIOXWBRMNLLW9MLGAXMGQWDBZLCOGFCBNKTDLDC" - , "MQSAAEDPMKIAJPPGNLIHPQIVFGLHNEGG9JNMSHOQSVQHBQBMLNHY9WVRTCOYUOWOIJHBQXIQVFPDF9YRW" - , "RGYOHMECRNVPYYPIAKEWHSOLBYOQPRFRPOJGHUMEGLICCUIPTZEXLWDLLPBNRXONUTQGLSAJSLHRXFVQD" + private static final String[] TEST_ADDRESSES = new String[]{"LXQHWNY9CQOHPNMKFJFIJHGEPAENAOVFRDIBF99PPHDTWJDCGHLYETXT9NPUVSNKT9XDTDYNJKJCPQMZCCOZVXMTXC" + , "P9UDUZMN9DEXCRQEKLJYSBSBZFCHOBPJSDKMLCCVJDOVOFDWMNBZRIRRZJGINOUMPJBMYYZEGRTIDUABD" + , "MIMVJEYREIIZLXOXQROMPJFCIX9NFVXD9ZQMNZERPI9OJIJFUWQ9WCTMKXEEPHYPWEZPHLJBJOFH9YTRB" , "FOJHXRVJRFMJTFDUWJYYZXCZIJXKQALLXMLKHZFDMHWTIBBXUKSNSUYJLKYRQBNXKRSUXZHDTPWXYD9YF" , "B9YNPQO9EXID9RDEEGLCBJBYKBLWHTOQOZKTLJDFPJZOPKJJTNUYUVVTDJPBCBYIWGPSCMNRZFGFHFSXH" , "NQEFOAFIYKZOUXDFQ9X9PHCNSDETRTJZINZ9EYGKU99QJLDSTSC9VTBAA9FHLNLNYQXWLTNPRJDWCGIPP" @@ -59,7 +61,9 @@ public class IotaAPITest { , "WDTFFXHBHMFQQVXQLBFJFVVHVIIAVYM9PFAZCHMKET9ESMHIRHSMVDJBZTXPTAFVIASMSXRDCIYVWVQNO" , "XCCPS9GMTSUB9DXPVKLTBDHOFX9PJMBYZQYQEXMRQDPGQPLWRGZGXODYJKGVFOHHYUJRCSXAIDGYSAWRB" , "KVEBCGMEOPDPRCQBPIEMZTTXYBURGZVNH9PLHKPMM9D9FUKWIGLKZROGNSYIFHULLWQWXCNAW9HKKVIDC"}; - private static Gson gson = new GsonBuilder().create(); + private static int MWM = 15; + + private static Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).create(); private IotaAPI iotaClient; @Before @@ -96,6 +100,7 @@ public void shouldCreateANewAddressWithoutChecksum() throws InvalidSecurityLevel assertThat(res3.getAddresses().get(0), Is.is(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_3)); } + @Test public void shouldPrepareTransfer() throws InvalidSecurityLevelException, NotEnoughBalanceException, InvalidAddressException, InvalidTransferException { List transfers = new ArrayList<>(); @@ -115,18 +120,20 @@ public void shouldGetLastInclusionState() throws NoNodeInfoException { @Test public void shouldFindTransactionObjects() { List ftr = iotaClient.findTransactionObjects(TEST_ADDRESSES); + System.out.println(ftr); assertThat(ftr, IsNull.notNullValue()); } - @Test(expected = ArgumentException.class) + @Test(expected = IllegalAccessError.class) public void shouldNotGetBundle() throws InvalidBundleException, ArgumentException, InvalidSignatureException { - GetBundleResponse gbr = iotaClient.getBundle(TEST_HASH); + GetBundleResponse gbr = iotaClient.getBundle("SADASD"); assertThat(gbr, IsNull.notNullValue()); } - @Test(expected = ArgumentException.class) + @Test public void shouldGetBundle() throws InvalidBundleException, ArgumentException, InvalidSignatureException { GetBundleResponse gbr = iotaClient.getBundle(TEST_HASH); + System.out.println(gbr); assertThat(gbr, IsNull.notNullValue()); } @@ -145,20 +152,20 @@ public void shouldGetTransfers() throws InvalidBundleException, ArgumentExceptio @Ignore @Test public void shouldReplayBundle() throws InvalidTrytesException, InvalidBundleException, InvalidSignatureException, ArgumentException { - ReplayBundleResponse rbr = iotaClient.replayBundle(TEST_TRYTES, 9, 18); + ReplayBundleResponse rbr = iotaClient.replayBundle(TEST_TRYTES, 9, MWM); assertThat(rbr, IsNull.notNullValue()); } @Ignore @Test(expected = InvalidTrytesException.class) public void shouldNotSendTrytes() throws InvalidTrytesException { - iotaClient.sendTrytes(new String[]{TEST_INVALID_TRYTES}, 9, 18); + iotaClient.sendTrytes(new String[]{TEST_INVALID_TRYTES}, 9, MWM); } @Ignore @Test public void shouldSendTrytes() throws InvalidTrytesException { - iotaClient.sendTrytes(new String[]{TEST_TRYTES}, 9, 18); + iotaClient.sendTrytes(new String[]{TEST_TRYTES}, 9, MWM); } @Ignore @@ -166,7 +173,7 @@ public void shouldSendTrytes() throws InvalidTrytesException { 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)); - SendTransferResponse str = iotaClient.sendTransfer(TEST_SEED2, 2, 9, 18, transfers, null, null); + SendTransferResponse str = iotaClient.sendTransfer(TEST_SEED2, 2, 9, MWM, transfers, null, null); assertThat(str.getSuccessfully(), IsNull.notNullValue()); } @@ -174,8 +181,8 @@ public void shouldNotSendTransfer() throws ArgumentException, InvalidSignatureEx @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, 0, "JUSTANOTHERTEST", TEST_TAG)); - SendTransferResponse str = iotaClient.sendTransfer(TEST_SEED2, 2, 9, 18, transfers, null, null); + transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2_2, 100, "JUSTANOTHERTEST", TEST_TAG)); + SendTransferResponse str = iotaClient.sendTransfer(TEST_SEED1, 2, 9, MWM, transfers, null, null); assertThat(str.getSuccessfully(), IsNull.notNullValue()); } } \ No newline at end of file diff --git a/src/test/java/jota/IotaCoreApiTest.java b/src/test/java/jota/IotaCoreApiTest.java index 7e3ed965..a75f7fe0 100644 --- a/src/test/java/jota/IotaCoreApiTest.java +++ b/src/test/java/jota/IotaCoreApiTest.java @@ -15,7 +15,7 @@ public class IotaCoreApiTest { private static final String TEST_BUNDLE = "XZKJUUMQOYUQFKMWQZNTFMSS9FKJLOEV9DXXXWPMQRTNCOUSUQNTBIJTVORLOQPLYZOTMLFRHYKMTGZZU"; private static final String TEST_ADDRESS_WITH_CHECKSUM = "PNGMCSNRCTRHCHPXYTPKEJYPCOWKOMRXZFHH9N9VDIKMNVAZCMIYRHVJIAZARZTUETJVFDMBEBIQE9QTHBFWDAOEFA"; - private static final String TEST_HASH = "OAATQS9VQLSXCLDJVJJVYUGONXAXOFMJOZNSYWRZSWECMXAQQURHQBJNLD9IOFEPGZEPEMPXCIVRX9999"; + private static final String TEST_HASH = "OOAARHCXXCPMNZPUEYOOUIUCTWZSQGKNIECIKRBNUUJEVMLJAWGCXREXEQGNJUJKUXXQAWWAZYKB99999"; private static IotaAPICore proxy; @Before