From 6176b0d5569bc9a370da9897bde523f4229979b6 Mon Sep 17 00:00:00 2001 From: AZ Date: Sun, 29 Jan 2017 20:23:23 +0100 Subject: [PATCH] refactored --- src/main/java/jota/IotaAPI.java | 26 +++--- ...IotaAPICoreProxy.java => IotaAPICore.java} | 17 ++-- src/main/java/jota/model/Bundle.java | 2 +- src/main/java/jota/model/Transaction.java | 89 ++++++++++++++++++- src/main/java/jota/utils/Converter.java | 25 ------ src/main/java/jota/utils/IotaAPIUtils.java | 2 +- .../java/jota/utils/TransactionConverter.java | 69 -------------- src/test/java/jota/IotaCoreApiTest.java | 10 ++- 8 files changed, 116 insertions(+), 124 deletions(-) rename src/main/java/jota/{IotaAPICoreProxy.java => IotaAPICore.java} (94%) delete mode 100644 src/main/java/jota/utils/TransactionConverter.java diff --git a/src/main/java/jota/IotaAPI.java b/src/main/java/jota/IotaAPI.java index dbfd86b..8bd00fd 100644 --- a/src/main/java/jota/IotaAPI.java +++ b/src/main/java/jota/IotaAPI.java @@ -25,7 +25,7 @@ import java.util.*; * * @author davassi */ -public class IotaAPI extends IotaAPICoreProxy { +public class IotaAPI extends IotaAPICore { private static final Logger log = LoggerFactory.getLogger(IotaAPI.class); private ICurl customCurl; @@ -216,7 +216,7 @@ public class IotaAPI extends IotaAPICoreProxy { * @param {int} minWeightMagnitude * @return */ - public List sendTrytes(final String[] trytes, final int depth, final int minWeightMagnitude) { + public List sendTrytes(final String[] trytes, final int depth, final int minWeightMagnitude) { final GetTransactionsToApproveResponse txs = getTransactionsToApprove(depth); // attach to tangle - do pow @@ -230,8 +230,8 @@ public class IotaAPI extends IotaAPICoreProxy { final List trx = new ArrayList<>(); - for (final String tx : Arrays.asList(res.getTrytes())) { - trx.add(new TransactionConverter(customCurl).transactionObject(tx)); + for (final String tryte : Arrays.asList(res.getTrytes())) { + trx.add(new Transaction(tryte, customCurl)); } return trx; } @@ -257,7 +257,7 @@ public class IotaAPI extends IotaAPICoreProxy { final List trxs = new ArrayList<>(); for (final String tryte : trytesResponse.getTrytes()) { - trxs.add(new TransactionConverter(customCurl).transactionObject(tryte)); + trxs.add(new Transaction(tryte, customCurl)); } return trxs; } @@ -440,8 +440,8 @@ public class IotaAPI extends IotaAPICoreProxy { List trxb = bundle.getTransactions(); List bundleTrytes = new ArrayList<>(); - for (Transaction tx : trxb) { - bundleTrytes.add(Converter.transactionTrytes(tx)); + for (Transaction trx : trxb) { + bundleTrytes.add(trx.toTrytes()); } Collections.reverse(bundleTrytes); return bundleTrytes; @@ -577,7 +577,7 @@ public class IotaAPI extends IotaAPICoreProxy { throw new ArgumentException("Invalid Bundle"); } - String trxTrytes = Converter.transactionTrytes(trx).substring(2187, 2187 + 162); + String trxTrytes = trx.toTrytes().substring(2187, 2187 + 162); //System.out.println("Bundlesize "+bundle.getTransactions().size()+" "+trxTrytes); // Absorb bundle hash + value + timestamp + lastIndex + currentIndex trytes. curl.absorb(Converter.trits(trxTrytes)); @@ -644,9 +644,9 @@ public class IotaAPI extends IotaAPICoreProxy { GetBundleResponse bundleResponse = getBundle(transaction); Bundle bundle = new Bundle(bundleResponse.getTransactions(), bundleResponse.getTransactions().size()); - for (Transaction element : bundle.getTransactions()) { + for (Transaction trx : bundle.getTransactions()) { - bundleTrytes.add(Converter.transactionTrytes(element)); + bundleTrytes.add(trx.toTrytes()); } List trxs = sendTrytes(bundleTrytes.toArray(new String[bundleTrytes.size()]), depth, minWeightMagnitude); @@ -719,7 +719,7 @@ public class IotaAPI extends IotaAPICoreProxy { throw new ArgumentException("Bundle transactions not visible"); } - Transaction trx = new TransactionConverter(customCurl).transactionObject(gtr.getTrytes()[0]); + Transaction trx = new Transaction(gtr.getTrytes()[0], customCurl); if (trx == null || trx.getBundle() == null) { throw new ArgumentException("Invalid trytes, could not create object"); } @@ -760,7 +760,7 @@ public class IotaAPI extends IotaAPICoreProxy { throw new ArgumentException("Bundle transactions not visible"); } - Transaction trx = new TransactionConverter(customCurl).transactionObject(gtr.getTrytes()[0]); + Transaction trx = new Transaction(gtr.getTrytes()[0], customCurl); if (trx == null || trx.getBundle() == null) { throw new ArgumentException("Invalid trytes, could not create object"); } @@ -821,7 +821,7 @@ public class IotaAPI extends IotaAPICoreProxy { throw new NotEnoughBalanceException(); } - public static class Builder extends IotaAPICoreProxy.Builder { + public static class Builder extends IotaAPICore.Builder { private ICurl customCurl; public Builder withCustomCurl(ICurl curl) { diff --git a/src/main/java/jota/IotaAPICoreProxy.java b/src/main/java/jota/IotaAPICore.java similarity index 94% rename from src/main/java/jota/IotaAPICoreProxy.java rename to src/main/java/jota/IotaAPICore.java index e87e052..1004eb6 100644 --- a/src/main/java/jota/IotaAPICoreProxy.java +++ b/src/main/java/jota/IotaAPICore.java @@ -13,7 +13,6 @@ import retrofit2.converter.gson.GsonConverterFactory; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; -import java.util.Collection; import java.util.List; import java.util.Properties; import java.util.concurrent.TimeUnit; @@ -21,14 +20,14 @@ import java.util.concurrent.TimeUnit; /** * Created by Adrian on 15.01.2017. */ -public class IotaAPICoreProxy { +public class IotaAPICore { - private static final Logger log = LoggerFactory.getLogger(IotaAPICoreProxy.class); + private static final Logger log = LoggerFactory.getLogger(IotaAPICore.class); private IotaAPIService service; private String protocol, host, port; - protected IotaAPICoreProxy(final Builder builder) { + protected IotaAPICore(final Builder builder) { protocol = builder.protocol; host = builder.host; port = builder.port; @@ -142,12 +141,6 @@ public class IotaAPICoreProxy { return wrapCheckedException(res).body(); } - public GetInclusionStateResponse getInclusionStates(Collection transactions, Collection tips) { - final Call res = service.getInclusionStates(IotaGetInclusionStateRequest - .createGetInclusionStateRequest(transactions, tips)); - return wrapCheckedException(res).body(); - } - public GetTrytesResponse getTrytes(String... hashes) { final Call res = service.getTrytes(IotaGetTrytesRequest.createGetTrytesRequest(hashes)); return wrapCheckedException(res).body(); @@ -192,7 +185,7 @@ public class IotaAPICoreProxy { String protocol, host, port; - public IotaAPICoreProxy build() { + public IotaAPICore build() { if (protocol == null || host == null || port == null) { @@ -205,7 +198,7 @@ public class IotaAPICoreProxy { } } - return new IotaAPICoreProxy(this); + return new IotaAPICore(this); } private boolean checkPropertiesFiles() { diff --git a/src/main/java/jota/model/Bundle.java b/src/main/java/jota/model/Bundle.java index 548251c..93acfae 100644 --- a/src/main/java/jota/model/Bundle.java +++ b/src/main/java/jota/model/Bundle.java @@ -142,6 +142,6 @@ public class Bundle implements Comparable { @Override public int compareTo(Bundle o) { - return this.getTransactions().get(0).getTimestamp().compareTo(o.getTransactions().get(0).getTimestamp()); + return Long.compare(Long.parseLong(this.getTransactions().get(0).getTimestamp()), Long.parseLong(o.getTransactions().get(0).getTimestamp())); } } \ 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 aa6c35f..dbe0506 100644 --- a/src/main/java/jota/model/Transaction.java +++ b/src/main/java/jota/model/Transaction.java @@ -1,12 +1,23 @@ package jota.model; +import jota.pow.ICurl; +import jota.pow.JCurl; +import jota.utils.Converter; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; /** * Created by pinpong on 02.12.16. */ public class Transaction { + private static final Logger log = LoggerFactory.getLogger(Transaction.class); + private ICurl customCurl; + private String hash; private String signatureFragments; private String address; @@ -21,8 +32,21 @@ public class Transaction { private String nonce; private Boolean persistence; - public Transaction() { + public Transaction(ICurl curl) { + customCurl = curl; + } + public Transaction() { + customCurl = null; + } + + public Transaction(String trytes) { + transactionObject(trytes); + } + + public Transaction(String trytes, ICurl customCurl) { + transactionObject(trytes); + this.customCurl = customCurl; } public Transaction(String signatureFragments, String currentIndex, String lastIndex, String nonce, String hash, String tag, String timestamp, String trunkTransaction, String branchTransaction, String address, String value, String bundle) { @@ -162,4 +186,67 @@ public class Transaction { return obj != null && ((Transaction) obj).getHash().equals(this.getHash()); } + public String toTrytes() { + int[] valueTrits = Converter.trits(this.getValue(), 81); + + int[] timestampTrits = Converter.trits(this.getTimestamp(), 27); + + + int[] currentIndexTrits = Converter.trits(this.getCurrentIndex(), 27); + + + int[] lastIndexTrits = Converter.trits(this.getLastIndex(), 27); + + + return this.getSignatureFragments() + + this.getAddress() + + Converter.trytes(valueTrits) + + this.getTag() + + Converter.trytes(timestampTrits) + + Converter.trytes(currentIndexTrits) + + Converter.trytes(lastIndexTrits) + + this.getBundle() + + this.getTrunkTransaction() + + this.getBranchTransaction() + + this.getNonce(); + } + + public void transactionObject(final String trytes) { + + if (StringUtils.isEmpty(trytes)) { + log.warn("Warning: empty trytes in input for transactionObject"); + return; + } + + // validity check + for (int i = 2279; i < 2295; i++) { + if (trytes.charAt(i) != '9') { + log.warn("Trytes {} does not seem a valid tryte", trytes); + return; + } + } + + int[] transactionTrits = Converter.trits(trytes); + int[] hash = new int[243]; + + final ICurl curl = customCurl == null ? new JCurl() : customCurl; // we need a fluent JCurl. + + // generate the correct transaction hash + curl.reset(); + curl.absorb(transactionTrits, 0, transactionTrits.length); + curl.squeeze(hash, 0, hash.length); + + this.setHash(Converter.trytes(hash)); + 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.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)); + } } \ No newline at end of file diff --git a/src/main/java/jota/utils/Converter.java b/src/main/java/jota/utils/Converter.java index 8a50475..a5f5802 100644 --- a/src/main/java/jota/utils/Converter.java +++ b/src/main/java/jota/utils/Converter.java @@ -219,29 +219,4 @@ public class Converter { } } - public static String transactionTrytes(Transaction trx) { - int[] valueTrits = Converter.trits(trx.getValue(), 81); - - int[] timestampTrits = Converter.trits(trx.getTimestamp(), 27); - - - int[] currentIndexTrits = Converter.trits(trx.getCurrentIndex(), 27); - - - int[] lastIndexTrits = Converter.trits(trx.getLastIndex(), 27); - - - return trx.getSignatureFragments() - + trx.getAddress() - + Converter.trytes(valueTrits) - + trx.getTag() - + Converter.trytes(timestampTrits) - + Converter.trytes(currentIndexTrits) - + Converter.trytes(lastIndexTrits) - + trx.getBundle() - + trx.getTrunkTransaction() - + trx.getBranchTransaction() - + trx.getNonce(); - } - } diff --git a/src/main/java/jota/utils/IotaAPIUtils.java b/src/main/java/jota/utils/IotaAPIUtils.java index b3c8b00..dfc869b 100644 --- a/src/main/java/jota/utils/IotaAPIUtils.java +++ b/src/main/java/jota/utils/IotaAPIUtils.java @@ -111,7 +111,7 @@ public class IotaAPIUtils { // Convert all bundle entries into trytes for (Transaction tx : bundle.getTransactions()) { - bundleTrytes.add(Converter.transactionTrytes(tx)); + bundleTrytes.add(tx.toTrytes()); } Collections.reverse(bundleTrytes); return bundleTrytes; diff --git a/src/main/java/jota/utils/TransactionConverter.java b/src/main/java/jota/utils/TransactionConverter.java deleted file mode 100644 index 27c5882..0000000 --- a/src/main/java/jota/utils/TransactionConverter.java +++ /dev/null @@ -1,69 +0,0 @@ -package jota.utils; - -import jota.model.Transaction; -import jota.pow.ICurl; -import jota.pow.JCurl; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Arrays; - -/** - * Created by Adrian on 15.01.2017. - */ -public class TransactionConverter { - private static final Logger log = LoggerFactory.getLogger(TransactionConverter.class); - private ICurl customCurl; - - public TransactionConverter(ICurl curl) { - customCurl = curl; - } - - public TransactionConverter() { - customCurl = null; - } - - public Transaction transactionObject(final String trytes) { - - if (StringUtils.isEmpty(trytes)) { - log.warn("Warning: empty trytes in input for transactionObject"); - return null; - } - - // validity check - for (int i = 2279; i < 2295; i++) { - if (trytes.charAt(i) != '9') { - log.warn("Trytes {} does not seem a valid tryte", trytes); - return null; - } - } - - int[] transactionTrits = Converter.trits(trytes); - int[] hash = new int[243]; - - final JCurl curl = new JCurl(); // we need a fluent JCurl. - - // generate the correct transaction hash - curl.reset(); - curl.absorb(transactionTrits, 0, transactionTrits.length); - curl.squeeze(hash, 0, hash.length); - - Transaction trx = new Transaction(); - - trx.setHash(Converter.trytes(hash)); - trx.setSignatureFragments(trytes.substring(0, 2187)); - trx.setAddress(trytes.substring(2187, 2268)); - trx.setValue("" + Converter.longValue(Arrays.copyOfRange(transactionTrits, 6804, 6837))); - trx.setTag(trytes.substring(2295, 2322)); - trx.setTimestamp("" + Converter.longValue(Arrays.copyOfRange(transactionTrits, 6966, 6993))); - trx.setCurrentIndex("" + Converter.longValue(Arrays.copyOfRange(transactionTrits, 6993, 7020))); - trx.setLastIndex("" + Converter.longValue(Arrays.copyOfRange(transactionTrits, 7020, 7047))); - trx.setBundle(trytes.substring(2349, 2430)); - trx.setTrunkTransaction(trytes.substring(2430, 2511)); - trx.setBranchTransaction(trytes.substring(2511, 2592)); - trx.setNonce(trytes.substring(2592, 2673)); - - return trx; - } -} diff --git a/src/test/java/jota/IotaCoreApiTest.java b/src/test/java/jota/IotaCoreApiTest.java index 66918d4..8913816 100644 --- a/src/test/java/jota/IotaCoreApiTest.java +++ b/src/test/java/jota/IotaCoreApiTest.java @@ -16,11 +16,11 @@ 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 IotaAPICoreProxy proxy; + private static IotaAPICore proxy; @Before public void createProxyInstance() { - proxy = new IotaAPICoreProxy.Builder().build(); + proxy = new IotaAPICore.Builder().build(); } @Test @@ -102,6 +102,12 @@ public class IotaCoreApiTest { @Test public void shouldGetInclusionStates() { + GetInclusionStateResponse res = proxy.getInclusionStates(new String[]{"DBPECSH9YLSSTQDGERUHJBBJTKVUDBMTJLG9WPHBINGHIFOSJMDJLARTVOXXWEFQJLLBINOHCZGYFSMUEXWPPMTOFW"}, new String[]{"EJDQOQHMLJGBMFWB9WJSPRCYIGNPO9WRHDCEQXIMPVPIJ9JV9RJGVHNX9EPGXFOOKBABCVMMAAX999999"}); + assertThat(res.getStates(), IsNull.notNullValue()); + } + + @Test(expected = IllegalAccessError.class) + public void shouldNotGetInclusionStates() { GetInclusionStateResponse res = proxy.getInclusionStates(new String[]{TEST_ADDRESS_WITH_CHECKSUM}, new String[]{"DNSBRJWNOVUCQPILOQIFDKBFJMVOTGHLIMLLRXOHFTJZGRHJUEDAOWXQRYGDI9KHYFGYDWQJZKX999999"}); assertThat(res.getStates(), IsNull.notNullValue()); }