From 5e9b74bbfeb7a890d50d9334bab447bb43062b94 Mon Sep 17 00:00:00 2001 From: gosticks Date: Wed, 24 Jan 2018 20:05:40 +0100 Subject: [PATCH] fixed problems with closing of channel --- src/main/java/iotaFlashWrapper/Helpers.java | 200 +++++++++++++----- .../iotaFlashWrapper/IotaFlashBridge.java | 2 +- src/main/java/iotaFlashWrapper/Main.java | 47 ++-- src/main/resources/iota.flash.js | 1 + 4 files changed, 165 insertions(+), 85 deletions(-) diff --git a/src/main/java/iotaFlashWrapper/Helpers.java b/src/main/java/iotaFlashWrapper/Helpers.java index b502894..86d3c2d 100644 --- a/src/main/java/iotaFlashWrapper/Helpers.java +++ b/src/main/java/iotaFlashWrapper/Helpers.java @@ -18,9 +18,9 @@ import java.util.Map; public class Helpers { private static boolean useTestnet = true; - private static String seedGeneratorURL = "https://seeedy.tangle.works"; + private static String seedGeneratorURL = "http://87.118.96.200:3000"; //"https://seeedy.tangle.works"; private static String testNetNodeURL = "https://testnet140.tangle.works:443"; - private static String netNodeURL = "http://node.iotawallet.info:14265"; + private static String netNodeURL = "http://node.iotawallet.info:14265"; // "http://87.118.96.200:14700";// private static IotaAPI iotaAPI = null; /** @@ -41,27 +41,22 @@ public class Helpers { * @param shouldClose * @return */ - public static ArrayList createTransaction(ArrayList transfers, CreateTransactionHelperObject toUse, UserObject user, boolean shouldClose) { + public static ArrayList createTransaction(ArrayList transfers, CreateTransactionHelperObject toUse, UserObject user) { // System.out.println("Creating a transaction of" + transfers.getValue() + " to " + transfers.getAddress()); System.out.println("[INFO]: using address " + toUse.getAddress().getAddress() + ", with boundle count" + toUse.getAddress().getBundles().size()); - ArrayList newTransfers; + FlashObject flash = user.getFlash(); - - if (shouldClose) { - newTransfers = IotaFlashBridge.close(flash.getSettlementAddresses(), flash.getDeposits()); - } else { - // Prepare a new transaction. - newTransfers = IotaFlashBridge.prepare( - flash.getSettlementAddresses(), - flash.getDeposits(), - user.getUserIndex(), - transfers - ); - } - + ArrayList bundles; + // Prepare a new transaction. + ArrayList newTransfers = IotaFlashBridge.prepare( + flash.getSettlementAddresses(), + flash.getDeposits(), + user.getUserIndex(), + transfers + ); // Compose the transaction. This may also add some management transactions (moving remainder tokens.) - ArrayList bundles = IotaFlashBridge.compose( + bundles = IotaFlashBridge.compose( flash.getBalance(), flash.getDeposits(), flash.getOutputs(), @@ -69,7 +64,7 @@ public class Helpers { flash.getRemainderAddress(), flash.getTransfers(), newTransfers, - shouldClose + false ); System.out.println("[SUCCESS] Created signatures for user" + user.getUserIndex()); @@ -81,6 +76,30 @@ public class Helpers { return IotaFlashBridge.appliedSignatures(bundles, signatures); } + public static ArrayList closeChannel(UserObject user) { + FlashObject flash = user.getFlash(); + ArrayList closeTransfers = IotaFlashBridge.close(flash.getSettlementAddresses(), flash.getDeposits()); + // Compose the transaction. This may also add some management transactions (moving remainder tokens.) + ArrayList bundles = IotaFlashBridge.compose( + flash.getBalance(), + flash.getDeposits(), + flash.getOutputs(), + flash.getRoot(), + flash.getRemainderAddress(), + flash.getTransfers(), + closeTransfers, + true + ); + + System.out.println("[SUCCESS] Created signatures for user" + user.getUserIndex()); + // Apply the signature of the transaction creater to the current transactions bundle. + ArrayList signatures = IotaFlashBridge.sign(flash.getRoot(), user.getSeed(), bundles); + + System.out.println("[SUCCESS] Parial applied Signature for user" + user.getUserIndex() + " on transfer bundle"); + // Sign bundle with your USER ONE'S signatures + return IotaFlashBridge.appliedSignatures(bundles, signatures); + } + /** * * Tree management. @@ -234,6 +253,11 @@ public class Helpers { return null; } + /** + * Apply transfers to a user flash state. + * @param signedBundles + * @param user + */ public static void applyTransfers(ArrayList signedBundles, UserObject user) { // Apply transfers to User ONE FlashObject newFlash = IotaFlashBridge.applyTransfersToUser(user, signedBundles); @@ -242,13 +266,20 @@ public class Helpers { user.setFlash(newFlash); } - - public static List sendTrytes(String[] trytes, IotaAPI api) { + /** + * Send trytes array to the node specified in the IotaAPI setup. + * @param trytes + * @param api + * @return returns the transactions applied to the node tangle. + */ + public static List sendTrytes(String[] trytes, IotaAPI api, int depth, int minWeightMagnitude) { try { System.out.println("[INFO] Sinding close bundle... This can take some time"); - List txs = api.sendTrytes(trytes, 5, 10); + List txs = api.sendTrytes(trytes, depth, minWeightMagnitude); return txs; + } catch (IllegalAccessError error) { + System.out.println("[ERROR] " + error.getLocalizedMessage()); } catch (Exception exception) { System.out.println("[ERROR]: could not send trytes " + exception.getLocalizedMessage()); } @@ -257,17 +288,70 @@ public class Helpers { } - public static List POWClosedBundle(List bundles) { + public static List POWClosedBundle(List bundles, int depth, int minWeightMagnitude) { List attachedBundles = new ArrayList<>(); for (Bundle b : bundles) { String[] trytes = b.toTrytesArray(); - attachedBundles.add(new Bundle(sendTrytes(trytes, getIotaAPI()))); + List txs = sendTrytes(trytes, getIotaAPI(), depth, minWeightMagnitude); + if (txs != null && txs.size() > 0) { + Bundle bundle = new Bundle(txs); + attachedBundles.add(bundle); + } } return attachedBundles; } + /** + * creates a new iota instace with the defined url and mode (testnet or not) + * if api instance available the just return it + * @return IotaAPI instance with setup url + */ + public static IotaAPI getIotaAPI() { + if (iotaAPI == null) { + return getNewIotaAPI(); + } + return iotaAPI; + } + + /** + * Creates a new instance of iota api and override the currently set one. + * Can be used to change url settings. + * @return IotaAPI instance with setup url + */ + public static IotaAPI getNewIotaAPI() { + URL nodeURL; + + try { + if (useTestnet) { + nodeURL = new URL(testNetNodeURL); + } else { + nodeURL = new URL(netNodeURL); + } + iotaAPI = new IotaAPI.Builder() + .protocol(nodeURL.getProtocol()) + .host(nodeURL.getHost()) + .port(String.valueOf(nodeURL.getPort())) + .build(); + } catch (Exception e) { + System.out.println("[ERROR] Failed to create IotaAPI instance." + e.getLocalizedMessage()); + return null; + } + + return iotaAPI; + } + + + /** + * + * Utilities + */ + + /** + * gives a new funded seed from a seedGeneratorURL + * @return + */ public static GeneratedSeed getNewSeed() { try { String seedData = readUrl(seedGeneratorURL); @@ -280,6 +364,41 @@ public class Helpers { } } + /** + * Get the total left in the flash channel. + * @param user + * @return + */ + public static double getFlashDeposits(UserObject user) { + double sum = 0; + for (double deposit : user.getFlash().getDeposits()) { + sum += deposit; + } + return sum; + } + + /** + * get current output of the flash channel. All transactions and remainder. + * @param user UserObject for which to compute amount + * @return amount of IOTA + */ + public static double getBalanceOfUser(UserObject user) { + double balance = user.getFlash().getDeposits().get(user.getUserIndex()); + Map transfers = user.getFlash().getOutputs(); + for (Map.Entry transfer : transfers.entrySet()) { + if (transfer.getKey().equals(user.getAddress())) { + balance += transfer.getValue(); + } + } + + return balance; + } + + /** + * Returns the amount of iota deposited in a selected address + * @param address + * @return + */ public static long getBalance(String address) { ArrayList addreses = new ArrayList<>(); addreses.add(address); @@ -288,11 +407,17 @@ public class Helpers { GetBalancesResponse resp = api.getBalances(100, addreses); return Long.parseLong(resp.getBalances()[0]); } catch (Exception e) { - System.out.println("[ERROR]: could not read balance for account " + address + " with error" + e.getLocalizedMessage()); + System.out.println("[ERROR]: could not read balance for account " + address + " with error " + e.getLocalizedMessage()); return -1; } } + /** + * Utility for reading date from a provided url string. + * @param urlString + * @return + * @throws Exception + */ private static String readUrl(String urlString) throws Exception { BufferedReader reader = null; try { @@ -311,31 +436,6 @@ public class Helpers { } } - private static IotaAPI getIotaAPI() { - if (iotaAPI == null) { - URL nodeURL; - - try { - if (useTestnet) { - nodeURL = new URL(testNetNodeURL); - } else { - nodeURL = new URL(netNodeURL); - } - iotaAPI = new IotaAPI.Builder() - .protocol(nodeURL.getProtocol()) - .host(nodeURL.getHost()) - .port(String.valueOf(nodeURL.getPort())) - .build(); - } catch (Exception e) { - System.out.println("[ERROR] Failed to create IotaAPI instance." + e.getLocalizedMessage()); - return null; - } - - } - return iotaAPI; - } - - public static Transaction cloneTransaction(jota.model.Transaction transaction) { return new Transaction( transaction.getSignatureFragments(), diff --git a/src/main/java/iotaFlashWrapper/IotaFlashBridge.java b/src/main/java/iotaFlashWrapper/IotaFlashBridge.java index 3404206..8acbf9a 100644 --- a/src/main/java/iotaFlashWrapper/IotaFlashBridge.java +++ b/src/main/java/iotaFlashWrapper/IotaFlashBridge.java @@ -181,7 +181,7 @@ public class IotaFlashBridge { params.add(V8Converter.multisigToV8Object(engine, remainderAddress)); params.add(V8Converter.bundleListToV8Array(engine, history)); params.add(V8Converter.transferListToV8Array(engine, transfers)); - + params.add(close); // Call js function. V8Array ret = transfer.executeArrayFunction("compose", V8ObjectUtils.toV8Array(engine, params)); diff --git a/src/main/java/iotaFlashWrapper/Main.java b/src/main/java/iotaFlashWrapper/Main.java index b881892..fc5a1fa 100644 --- a/src/main/java/iotaFlashWrapper/Main.java +++ b/src/main/java/iotaFlashWrapper/Main.java @@ -1,6 +1,8 @@ package iotaFlashWrapper; +import com.sun.xml.internal.ws.api.message.HeaderList; import iotaFlashWrapper.Model.*; +import jota.IotaAPI; import jota.model.Transaction; import jota.utils.Checksum; @@ -54,8 +56,6 @@ public class Main { allUserDigests.add(oneDigests); allUserDigests.add(twoDigests); - - /*************************************** User one setup. ***************************************/ @@ -128,6 +128,10 @@ public class Main { long rootBalance = Helpers.getBalance(multisgFulladdr); System.out.println("Funds in root address:" + rootBalance); + + IotaAPI api = Helpers.getIotaAPI(); + // api.sendTransfer(); + /*************************************** Create transactions. ***************************************/ @@ -140,7 +144,7 @@ public class Main { ArrayList confirmedTransfers; // Try to make 10 transfers. - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 4; i++) { // Create transaction helper and check if we need to add nodes CreateTransactionHelperObject helper = Helpers.getTransactionHelper(oneFlash.getFlash().getRoot()); @@ -173,7 +177,7 @@ public class Main { transfers.add(new Transfer(twoSettlement, 10)); // Create a transaction from a transfer. - suggestedTransfer = Helpers.createTransaction(transfers, helper, oneFlash, false); + suggestedTransfer = Helpers.createTransaction(transfers, helper, oneFlash); System.out.println("[INFO] Created transfer suggestion."); @@ -191,10 +195,10 @@ public class Main { Helpers.applyTransfers(signedBundlesOne, oneFlash); Helpers.applyTransfers(signedBundlesTwo, twoFlash); - System.out.println("Transaction Applied! Transactable tokens: " + getFlashDeposits(oneFlash)); + System.out.println("Transaction Applied! Transactable tokens: " + Helpers.getFlashDeposits(oneFlash)); - double oneBalance = getBalanceOfUser(oneFlash); - double twoBalance = getBalanceOfUser(twoFlash); + double oneBalance = Helpers.getBalanceOfUser(oneFlash); + double twoBalance = Helpers.getBalanceOfUser(twoFlash); System.out.println("Deposits"); System.out.println("User one:" + oneBalance + ", deposits: " + oneFlash.getFlash().getDeposits() ); @@ -230,11 +234,7 @@ public class Main { System.out.println("[INFO] Closing channel..."); - // Create transfers. - ArrayList closeTransfers = new ArrayList<>(); -// closeTransfers.add(new Transfer(oneSettlement, 5)); -// closeTransfers.add(new Transfer(twoSettlement, 5)); - suggestedTransfer = Helpers.createTransaction(closeTransfers, closeHelper, oneFlash, true); + suggestedTransfer = Helpers.closeChannel(oneFlash); System.out.println("[INFO] Created transfer suggestion."); @@ -258,29 +258,8 @@ public class Main { List closeBundles = new ArrayList<>(); closeBundles.add(signedBundlesOne.get(signedBundlesOne.size() - 1)); - List attachedBundles = Helpers.POWClosedBundle(closeBundles); + List attachedBundles = Helpers.POWClosedBundle(signedBundlesOne, 5, 10); System.out.println("[INFO] Attached bundles" + attachedBundles.toString()); } - - - public static double getFlashDeposits(UserObject user) { - double sum = 0; - for (double deposit : user.getFlash().getDeposits()) { - sum += deposit; - } - return sum; - } - - public static double getBalanceOfUser(UserObject user) { - double balance = user.getFlash().getDeposits().get(user.getUserIndex()); - Map transfers = user.getFlash().getOutputs(); - for (Map.Entry transfer : transfers.entrySet()) { - if (transfer.getKey().equals(user.getAddress())) { - balance += transfer.getValue(); - } - } - - return balance; - } } diff --git a/src/main/resources/iota.flash.js b/src/main/resources/iota.flash.js index 8d01a8e..cd67432 100644 --- a/src/main/resources/iota.flash.js +++ b/src/main/resources/iota.flash.js @@ -10374,6 +10374,7 @@ function getMultisigs(root, transfers) { node = node.children[node.children.length - 1]; } if(node.address != firstTransfer.address) { + console.log(firstTransfer.address) throw new Error(TransferErrors.ADDRESS_NOT_FOUND); } let multisigs = [];