diff --git a/node_config.properties b/node_config.properties index f3c3793..e5e5a5a 100644 --- a/node_config.properties +++ b/node_config.properties @@ -1,5 +1,5 @@ iota.node.protocol=http #iota.node.host=138.68.126.141 -iota.node.host=127.0.0.1 +iota.node.host=node.iotawallet.info iota.node.port=14265 diff --git a/src/main/java/jota/dto/response/AnalyzeTransactionResponse.java b/src/main/java/jota/dto/response/AnalyzeTransactionResponse.java index fdb7059..53081ff 100644 --- a/src/main/java/jota/dto/response/AnalyzeTransactionResponse.java +++ b/src/main/java/jota/dto/response/AnalyzeTransactionResponse.java @@ -1,86 +1,15 @@ package jota.dto.response; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; +import jota.model.Transaction; + +import java.util.ArrayList; +import java.util.List; public class AnalyzeTransactionResponse extends AbstractResponse { - private Transactions[] transactions; + private List transactions = new ArrayList(); - public Transactions[] getTransactions() { + public List getTransactions() { return transactions; } - - static class Transactions { - private String signatureMessageChunk; - private String index; - private String approvalNonce; - private String hash; - private String digest; - private String type; - private String timestamp; - private String trunkTransaction; - private String branchTransaction; - private String signatureNonce; - private String address; - private String value; - private String bundle; - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); - } - - public String getValue() { - return value; - } - - public String getDigest() { - return digest; - } - - public String getTrunkTransaction() { - return trunkTransaction; - } - - public String getTimestamp() { - return timestamp; - } - - public String getSignatureNonce() { - return signatureNonce; - } - - public String getType() { - return type; - } - - public String getAddress() { - return address; - } - - public String getApprovalNonce() { - return approvalNonce; - } - - public String getBranchTransaction() { - return branchTransaction; - } - - public String getBundle() { - return bundle; - } - - public String getHash() { - return hash; - } - - public String getIndex() { - return index; - } - - public String getSignatureMessageChunk() { - return signatureMessageChunk; - } - } } diff --git a/src/main/java/jota/dto/response/GetBundleResponse.java b/src/main/java/jota/dto/response/GetBundleResponse.java index c508f78..278631f 100644 --- a/src/main/java/jota/dto/response/GetBundleResponse.java +++ b/src/main/java/jota/dto/response/GetBundleResponse.java @@ -1,93 +1,15 @@ package jota.dto.response; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; +import jota.model.Transaction; + +import java.util.ArrayList; +import java.util.List; public class GetBundleResponse extends AbstractResponse { - public Transactions[] transactions; + private List transactions = new ArrayList<>(); - private String warning; - - public String getWarning() { - return warning; - } - - public Transactions[] getTransactions() { + public List getTransactions() { return transactions; } - - public static class Transactions { - private String signatureMessageChunk; - private String index; - private String approvalNonce; - private String hash; - private String digest; - private String type; - private String timestamp; - private String trunkTransaction; - private String branchTransaction; - private String signatureNonce; - private String address; - private String value; - private String bundle; - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); - } - - public String getAddress() { - return address; - } - - public String getApprovalNonce() { - return approvalNonce; - } - - public String getBranchTransaction() { - return branchTransaction; - } - - public String getBundle() { - return bundle; - } - - public String getDigest() { - return digest; - } - - public String getHash() { - return hash; - } - - public String getIndex() { - return index; - } - - public String getSignatureMessageChunk() { - return signatureMessageChunk; - } - - public String getSignatureNonce() { - return signatureNonce; - } - - public String getTimestamp() { - return timestamp; - } - - public String getType() { - return type; - } - - public String getTrunkTransaction() { - return trunkTransaction; - } - - public String getValue() { - return value; - } - - } } diff --git a/src/main/java/jota/dto/response/GetNeighborsResponse.java b/src/main/java/jota/dto/response/GetNeighborsResponse.java index 550a546..3740307 100644 --- a/src/main/java/jota/dto/response/GetNeighborsResponse.java +++ b/src/main/java/jota/dto/response/GetNeighborsResponse.java @@ -1,34 +1,15 @@ package jota.dto.response; +import jota.model.Neighbor; + +import java.util.ArrayList; +import java.util.List; + public class GetNeighborsResponse extends AbstractResponse { - public Neighbors[] neighbors; + private List neighbors = new ArrayList<>(); - public Neighbors[] getNeighbors() { + public List getNeighbors() { return neighbors; } - - public static class Neighbors { - - private String address; - private Integer numberOfAllTransactions; - private Integer numberOfInvalidTransactions; - private Integer numberOfNewTransactions; - - public String getAddress() { - return address; - } - - public Integer getNumberOfAllTransactions() { - return numberOfAllTransactions; - } - - public Integer getNumberOfInvalidTransactions() { - return numberOfInvalidTransactions; - } - - public Integer getNumberOfNewTransactions() { - return numberOfNewTransactions; - } - } } diff --git a/src/main/java/jota/dto/response/GetTransfersResponse.java b/src/main/java/jota/dto/response/GetTransfersResponse.java index 4046ad4..441ccea 100644 --- a/src/main/java/jota/dto/response/GetTransfersResponse.java +++ b/src/main/java/jota/dto/response/GetTransfersResponse.java @@ -1,46 +1,15 @@ package jota.dto.response; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; +import jota.model.Transfer; + +import java.util.ArrayList; +import java.util.List; public class GetTransfersResponse extends AbstractResponse { - private Transfers[] transfers; + private List transfers = new ArrayList<>(); - public Transfers[] getTransfers() { + public List getTransfers() { return transfers; } - - public static class Transfers { - private String timestamp; - private String address; - private String hash; - private Integer persistence; - private long value; - - public String getAddress() { - return address; - } - - public String getHash() { - return hash; - } - - public Integer getPersistence() { - return persistence; - } - - public String getTimestamp() { - return timestamp; - } - - public long getValue() { - return value; - } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); - } - } } diff --git a/src/main/java/jota/model/Neighbor.java b/src/main/java/jota/model/Neighbor.java new file mode 100644 index 0000000..2eee719 --- /dev/null +++ b/src/main/java/jota/model/Neighbor.java @@ -0,0 +1,36 @@ +package jota.model; + +/** + * Created by pinpong on 02.12.16. + */ +public class Neighbor { + + private String address; + private Integer numberOfAllTransactions; + private Integer numberOfInvalidTransactions; + private Integer numberOfNewTransactions; + + public Neighbor(String address, Integer numberOfAllTransactions, Integer numberOfInvalidTransactions, Integer numberOfNewTransactions) { + this.address = address; + this.numberOfAllTransactions = numberOfAllTransactions; + this.numberOfInvalidTransactions = numberOfInvalidTransactions; + this.numberOfNewTransactions = numberOfNewTransactions; + } + + public String getAddress() { + return address; + } + + public Integer getNumberOfAllTransactions() { + return numberOfAllTransactions; + } + + public Integer getNumberOfInvalidTransactions() { + return numberOfInvalidTransactions; + } + + public Integer getNumberOfNewTransactions() { + return numberOfNewTransactions; + } + +} diff --git a/src/main/java/jota/model/Transaction.java b/src/main/java/jota/model/Transaction.java new file mode 100644 index 0000000..4cf5e89 --- /dev/null +++ b/src/main/java/jota/model/Transaction.java @@ -0,0 +1,99 @@ +package jota.model; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * Created by pinpong on 02.12.16. + */ +public class Transaction { + + private String signatureMessageChunk; + private String index; + private String approvalNonce; + private String hash; + private String digest; + private String type; + private String timestamp; + private String trunkTransaction; + private String branchTransaction; + private String signatureNonce; + private String address; + private String value; + private String bundle; + + public Transaction(String signatureMessageChunk, String index, String approvalNonce, String hash, String digest, String type, String timestamp, String trunkTransaction, String branchTransaction, String signatureNonce, String address, String value, String bundle) { + + this.hash = hash; + this.type = type; + this.signatureMessageChunk = signatureMessageChunk; + this.digest = digest; + this.address = address; + this.value = value; + this.timestamp = timestamp; + this.index = index; + this.bundle = bundle; + this.signatureNonce = signatureNonce; + this.approvalNonce = approvalNonce; + this.trunkTransaction = trunkTransaction; + this.branchTransaction = branchTransaction; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); + } + + public String getValue() { + return value; + } + + public String getDigest() { + return digest; + } + + public String getTrunkTransaction() { + return trunkTransaction; + } + + public String getTimestamp() { + return timestamp; + } + + public String getSignatureNonce() { + return signatureNonce; + } + + public String getType() { + return type; + } + + public String getAddress() { + return address; + } + + public String getApprovalNonce() { + return approvalNonce; + } + + public String getBranchTransaction() { + return branchTransaction; + } + + public String getBundle() { + return bundle; + } + + public String getHash() { + return hash; + } + + public String getIndex() { + return index; + } + + public String getSignatureMessageChunk() { + return signatureMessageChunk; + } + +} diff --git a/src/main/java/jota/model/Transfer.java b/src/main/java/jota/model/Transfer.java new file mode 100644 index 0000000..fa149ee --- /dev/null +++ b/src/main/java/jota/model/Transfer.java @@ -0,0 +1,50 @@ +package jota.model; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * Created by pinpong on 02.12.16. + */ +public class Transfer { + + private String timestamp; + private String address; + private String hash; + private Integer persistence; + private long value; + + public Transfer(String timestamp, String address, String hash, Integer persistence, long value) { + + this.timestamp = timestamp; + this.address = address; + this.hash = hash; + this.persistence = persistence; + this.value = value; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); + } + + public String getAddress() { + return address; + } + + public String getHash() { + return hash; + } + + public Integer getPersistence() { + return persistence; + } + + public String getTimestamp() { + return timestamp; + } + + public long getValue() { + return value; + } +} diff --git a/src/main/java/jota/utils/Checksum.java b/src/main/java/jota/utils/Checksum.java new file mode 100644 index 0000000..0a303db --- /dev/null +++ b/src/main/java/jota/utils/Checksum.java @@ -0,0 +1,44 @@ +package jota.utils; + +import org.apache.commons.lang3.NotImplementedException; + +/** + * Created by pinpong on 02.12.16. + */ +public class Checksum { + + public static String addChecksum(String address) { + + InputValidator.checkAddress(address); + String addressWithChecksum = address; + addressWithChecksum += calculateChecksum(address); + return addressWithChecksum; + } + + public static String removeChecksum(String addressWithChecksum) { + if (isAddressWithChecksum(addressWithChecksum)) { + return getAddress(addressWithChecksum); + } + throw new RuntimeException("Invalid address: " + addressWithChecksum); + } + + private static String getAddress(String addressWithChecksum) { + return addressWithChecksum.substring(0, Constants.addressLengthWithoutChecksum); + } + + public static boolean isValidChecksum(String addressWithChecksum) { + String addressWithoutChecksum = removeChecksum(addressWithChecksum); + String adressWithRecalculateChecksum = calculateChecksum(addressWithoutChecksum); + + return adressWithRecalculateChecksum.equals(addressWithChecksum); + } + + private static boolean isAddressWithChecksum(String addressWithChecksum) { + return InputValidator.checkAddress(addressWithChecksum) && addressWithChecksum.length() == Constants.addressLengthWithChecksum; + } + + private static String calculateChecksum(String address) { + // TODO + throw new NotImplementedException(address); + } +} diff --git a/src/main/java/jota/utils/Constants.java b/src/main/java/jota/utils/Constants.java new file mode 100644 index 0000000..997b296 --- /dev/null +++ b/src/main/java/jota/utils/Constants.java @@ -0,0 +1,13 @@ +package jota.utils; + +/** + * Created by pinpong on 02.12.16. + */ +public class Constants { + + public static final String TRYTE_ALPHABET = "9ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + public static int addressLengthWithoutChecksum = 81; + public static int addressLengthWithChecksum = 90; + +} diff --git a/src/main/java/jota/utils/Converter.java b/src/main/java/jota/utils/Converter.java index be5313f..b9cccbd 100644 --- a/src/main/java/jota/utils/Converter.java +++ b/src/main/java/jota/utils/Converter.java @@ -9,7 +9,6 @@ public class Converter { public static final int NUMBER_OF_TRITS_IN_A_BYTE = 5; public static final int NUMBER_OF_TRITS_IN_A_TRYTE = 3; - public static final String TRYTE_ALPHABET = "9ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static final int[][] BYTE_TO_TRITS_MAPPINGS = new int[243][]; static final int[][] TRYTE_TO_TRITS_MAPPINGS = new int[27][]; @@ -63,7 +62,7 @@ public class Converter { 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[TRYTE_ALPHABET.indexOf(trytes.charAt(i))], 0, trits, i * NUMBER_OF_TRITS_IN_A_TRYTE, NUMBER_OF_TRITS_IN_A_TRYTE); + 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; @@ -100,9 +99,9 @@ public class Converter { int j = trits[offset + i * 3] + trits[offset + i * 3 + 1] * 3 + trits[offset + i * 3 + 2] * 9; if (j < 0) { - j += TRYTE_ALPHABET.length(); + j += Constants.TRYTE_ALPHABET.length(); } - trytes.append(TRYTE_ALPHABET.charAt(j)); + trytes.append(Constants.TRYTE_ALPHABET.charAt(j)); } return trytes.toString(); } diff --git a/src/main/java/jota/utils/InputValidator.java b/src/main/java/jota/utils/InputValidator.java new file mode 100644 index 0000000..327812a --- /dev/null +++ b/src/main/java/jota/utils/InputValidator.java @@ -0,0 +1,35 @@ +package jota.utils; + +import jdk.nashorn.internal.runtime.regexp.joni.Regex; +import jota.model.Transfer; +import org.apache.commons.lang3.NotImplementedException; + +import java.util.Arrays; + +/** + * Created by pinpong on 02.12.16. + */ +public class InputValidator { + + public static boolean isAddress(String address) { + // TODO: In the future check checksum + // Check if address with checksum + return (address.length() == Constants.addressLengthWithoutChecksum || + address.length() == Constants.addressLengthWithChecksum) && isTrytes(address, address.length()); + } + + + public static boolean checkAddress(String address) { + if (!isAddress(address)) + throw new RuntimeException("Invalid address: " + address); + return true; + } + + public static boolean isTrytes(String trytes, int length) { + + // If no length specified, just validate the trytes + + Regex regexTrytes = new Regex("^[9A-Z]{" + (length == 0 ? "0," : length) + "}$"); + return trytes.matches(regexTrytes.toString()); + } +} diff --git a/src/main/java/jota/utils/TrytesConverter.java b/src/main/java/jota/utils/TrytesConverter.java index 3f90cbd..4751b4a 100644 --- a/src/main/java/jota/utils/TrytesConverter.java +++ b/src/main/java/jota/utils/TrytesConverter.java @@ -5,8 +5,6 @@ package jota.utils; */ public class TrytesConverter { - private static final String TRYTE_ALPHABET = "9ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - /** * Conversion of ascii encoded bytes to trytes. * Input is a string (can be stringified JSON object), return value is Trytes @@ -52,7 +50,7 @@ public class TrytesConverter { int firstValue = asciiValue % 27; int secondValue = (asciiValue - firstValue) / 27; - String trytesValue = String.valueOf(TRYTE_ALPHABET.charAt(firstValue) + String.valueOf(TRYTE_ALPHABET.charAt(secondValue))); + String trytesValue = String.valueOf(Constants.TRYTE_ALPHABET.charAt(firstValue) + String.valueOf(Constants.TRYTE_ALPHABET.charAt(secondValue))); trytes += trytesValue; } @@ -77,8 +75,8 @@ public class TrytesConverter { for (int i = 0; i < inputTrytes.length(); i += 2) { // get a trytes pair - int firstValue = TRYTE_ALPHABET.indexOf(inputTrytes.charAt(i)); - int secondValue = TRYTE_ALPHABET.indexOf(inputTrytes.charAt(i + 1)); + int firstValue = Constants.TRYTE_ALPHABET.indexOf(inputTrytes.charAt(i)); + int secondValue = Constants.TRYTE_ALPHABET.indexOf(inputTrytes.charAt(i + 1)); int decimalValue = firstValue + secondValue * 27; diff --git a/src/test/java/jota/ChecksumTest.java b/src/test/java/jota/ChecksumTest.java new file mode 100644 index 0000000..d67afef --- /dev/null +++ b/src/test/java/jota/ChecksumTest.java @@ -0,0 +1,25 @@ +package jota; + +import jota.utils.Checksum; +import jota.utils.InputValidator; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Created by pinpong on 02.12.16. + */ +public class ChecksumTest { + + private static final String TEST_ADDRESS = "RVORZ9SIIP9RCYMREUIXXVPQIPHVCNPQ9HZWYKFWYWZRE9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVAZETAIRPTM"; + + @Test + public void shouldAddChecksum() { + assertEquals(Checksum.addChecksum(TEST_ADDRESS), true); + } + + @Test + public void shouldRemoveChecksum() { + assertEquals(Checksum.addChecksum(TEST_ADDRESS), Checksum.isValidChecksum(Checksum.addChecksum(TEST_ADDRESS))); + } +} diff --git a/src/test/java/jota/InputValidatorTest.java b/src/test/java/jota/InputValidatorTest.java new file mode 100644 index 0000000..2ee0a10 --- /dev/null +++ b/src/test/java/jota/InputValidatorTest.java @@ -0,0 +1,29 @@ +package jota; + +import jota.utils.InputValidator; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Created by pinpong on 02.12.16. + */ +public class InputValidatorTest { + + private static final String TEST_ADDRESS = "RVORZ9SIIP9RCYMREUIXXVPQIPHVCNPQ9HZWYKFWYWZRE9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVAZETAIRPTM"; + + @Test + public void shouldIsAddress() { + assertEquals(InputValidator.isAddress(TEST_ADDRESS), true); + } + + @Test + public void shouldCheckAddress() { + assertEquals(InputValidator.checkAddress(TEST_ADDRESS), true); + } + + @Test + public void shouldIsTrytes() { + assertEquals(InputValidator.isTrytes(TEST_ADDRESS, TEST_ADDRESS.length()), true); + } +}