fixed transactions not updating flash channel state

This commit is contained in:
gosticks
2018-01-15 17:51:50 +01:00
parent a874805353
commit 9191ac181c
20 changed files with 240 additions and 101 deletions

View File

@@ -12,7 +12,7 @@ If you have any ideas please submit a request (I am totally not a Java guy so...
- [x] updateLeafToRoot
- [x] getDigest
#### Model.Transfer
#### com.flashwifi.flashwrapper.Model.Transfer
- [x] prepare
- [x] compose
- [x] close (needs testing)
@@ -28,7 +28,7 @@ If you have any ideas please submit a request (I am totally not a Java guy so...
1. Clone repo
2. Update maven ressources
3. That's it.
4. You can run a test transaction by running the main func in the Main Class.
4. You can run a test transaction by running the main func in the com.flashwifi.flashwrapper.Main Class.

View File

@@ -12,7 +12,7 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0" level="project" />
<orderEntry type="library" name="Maven: com.github.iotaledger:iota~lib~java:v0.9.10" level="project" />
<orderEntry type="library" name="Maven: com.github.iotaledger:iota~lib~java:0.9.10" level="project" />
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.2" level="project" />
</component>
</module>

View File

@@ -21,11 +21,13 @@
<artifactId>j2v8_macosx_x86_64</artifactId>
<version>4.6.0</version>
</dependency>
<dependency>
<groupId>com.github.iotaledger</groupId>
<artifactId>iota~lib~java</artifactId>
<version>v0.9.10</version>
<version>0.9.10</version>
</dependency>
<!-- Gson: Java to Json conversion -->
<dependency>
<groupId>com.google.code.gson</groupId>
@@ -37,13 +39,10 @@
<!-- https://maven.apache.org/settings.html#Properties -->
<properties>
<!-- <encoding>UTF-8</encoding> -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
</project>

13
res/iota.flash.helper.js Normal file
View File

@@ -0,0 +1,13 @@
var Helper = {
applyTransfers: function(flash, bundles) {
iotaFlash.transfer.applyTransfers(
flash.root,
flash.deposits,
flash.outputs,
flash.remainderAddress,
flash.transfers,
bundles
)
return flash
}
}

View File

@@ -10297,6 +10297,7 @@ function close(settlement, deposits) {
* @param {array} transfers
*/
function applyTransfers(root, deposit, outputs, remainder, history, transfers) {
if (transfers.filter(transfer =>
transfer.filter(tx => tx.value < 0)
.filter(tx => !IOTACrypto.utils.validateSignatures(transfer, tx.address))

View File

@@ -1,4 +1,7 @@
import Model.*;
package com.flashwifi.flashwrapper;
import com.flashwifi.flashwrapper.Model.*;
import java.util.ArrayList;
import java.util.List;
@@ -7,7 +10,6 @@ import java.util.stream.Collectors;
public class Helpers {
public static ArrayList<Bundle> createTransaction(UserObject user, ArrayList<Transfer> transfers, boolean shouldClose) {
CreateTransactionHelperObject toUse = IotaFlashBridge.updateLeafToRoot(user.getFlash().getRoot());
if (toUse.getGenerate() != 0) {
// TODO: tell the server to gen new address.
System.out.println("No more addresses in channel.");
@@ -72,14 +74,16 @@ public class Helpers {
}
public static void applyTransfers(UserObject user, ArrayList<Bundle> bundles) {
IotaFlashBridge.applayTransfers(
user.getFlash().getRoot(),
user.getFlash().getDeposits(),
user.getFlash().getOutputs(),
user.getFlash().getRemainderAddress(),
user.getFlash().getTransfers(),
bundles
);
FlashObject flash = IotaFlashBridge.applyTransfersToUser(user, bundles);
user.setFlash(flash);
// com.flashwifi.flashwrapper.IotaFlashBridge.applyTransfers(
// user.getFlash().getRoot(),
// user.getFlash().getDeposits(),
// user.getFlash().getOutputs(),
// user.getFlash().getRemainderAddress(),
// user.getFlash().getTransfers(),
// bundles
// );
}
public static ArrayList<Bundle> clone(ArrayList<Bundle> bundles) {

View File

@@ -1,4 +1,6 @@
import Model.*;
package com.flashwifi.flashwrapper;
import com.flashwifi.flashwrapper.Model.*;
import com.eclipsesource.v8.*;
import com.eclipsesource.v8.utils.V8ObjectUtils;
@@ -13,9 +15,11 @@ import java.util.Map;
public class IotaFlashBridge {
private static String iotaLibPath = "res/iota.flash.js";
private static String iotaHelperLibPath = "res/iota.flash.helper.js";
private static V8 engine;
private static V8Object transfer;
private static V8Object multisig;
private static V8Object helper;
public static void boot() throws IOException {
String file = readFile(iotaLibPath, Charset.defaultCharset());
@@ -23,10 +27,12 @@ public class IotaFlashBridge {
engine = V8.createV8Runtime();
// Eval lib into current v8 context.
engine.executeVoidScript(file);
engine.executeVoidScript(readFile(iotaHelperLibPath, Charset.defaultCharset()));
multisig = (V8Object) engine.executeScript("iotaFlash.multisig");
transfer = (V8Object) engine.executeScript("iotaFlash.transfer");
helper = (V8Object) engine.executeScript("Helper");
Model.Console console = new Model.Console();
com.flashwifi.flashwrapper.Model.Console console = new com.flashwifi.flashwrapper.Model.Console();
V8Object v8Console = new V8Object(engine);
engine.add("console", v8Console);
v8Console.registerJavaMethod(console, "log", "log", new Class<?>[] { String.class });
@@ -61,6 +67,8 @@ public class IotaFlashBridge {
int secSum = (Integer) resultMap.get("securitySum");
MultisigAddress ret = new MultisigAddress(addr, secSum);
params.release();
retV8.release();
return ret;
}
@@ -250,7 +258,7 @@ public class IotaFlashBridge {
* @param signedBundles
* @return
*/
public static void applayTransfers(MultisigAddress root,
public static void applyTransfers(MultisigAddress root,
ArrayList<Integer> deposits,
ArrayList<Bundle> outputs,
MultisigAddress remainderAddress,
@@ -268,6 +276,20 @@ public class IotaFlashBridge {
transfer.executeFunction("applyTransfers", V8ObjectUtils.toV8Array(engine, params));
}
public static FlashObject applyTransfersToUser(UserObject user, ArrayList<Bundle> signedBundles) {
List<Object> params = new ArrayList<>();
params.add(V8Converter.flashObjectToV8Object(engine, user.getFlash()));
params.add(V8Converter.bundleListToV8Array(engine, signedBundles));
V8Array paramV8 = V8ObjectUtils.toV8Array(engine, params);
V8Object ret = helper.executeObjectFunction("applyTransfers", paramV8);
Map<String, Object> obj = V8ObjectUtils.toMap(ret);
paramV8.release();
FlashObject flash = V8Converter.flashObjectFromV8Object(ret);
ret.release();
return flash;
}
/// Utils
/**

View File

@@ -1,7 +1,9 @@
import Model.Bundle;
import Model.Digest;
import Model.MultisigAddress;
import Model.Transfer;
package com.flashwifi.flashwrapper;
import com.flashwifi.flashwrapper.Model.Bundle;
import com.flashwifi.flashwrapper.Model.Digest;
import com.flashwifi.flashwrapper.Model.MultisigAddress;
import com.flashwifi.flashwrapper.Model.Transfer;
import java.util.ArrayList;
import java.util.List;
@@ -12,7 +14,7 @@ public interface IotaFlashInterface {
public void updateLeafToRoot(MultisigAddress root);
// Model.Transfer
// com.flashwifi.flashwrapper.Model.Transfer
public Object prepare(ArrayList<String> settlementAddresses, ArrayList<Integer> deposits, int index, ArrayList<Transfer> transfers);
public List<Object> compose(int balance, ArrayList<Integer> deposits, ArrayList<Transfer> outputs, MultisigAddress root, String remainderAddress, ArrayList<Bundle> history, ArrayList<Transfer> transfers, boolean close);

View File

@@ -1,5 +1,6 @@
package com.flashwifi.flashwrapper;
import Model.*;
import com.flashwifi.flashwrapper.Model.*;
import java.io.IOException;
import java.util.ArrayList;
@@ -96,38 +97,17 @@ public class Main {
System.out.println("Channel Setup!");
ArrayList<Transfer> transfers = new ArrayList<>();
transfers.add(new Transfer(twoSettlement, 200));
transfers.add(new Transfer(twoSettlement, 1));
transfers.add(new Transfer(twoSettlement, 400));
System.out.println(oneFlash);
System.out.println("Creating a transaction: 200 to " + twoSettlement);
ArrayList<Bundle> bundles = Helpers.createTransaction(oneFlash, transfers, false);
System.out.println("[SUCCESS] createTransaction completed");
// Sign the bundles.
// Get signatures for the bundles
ArrayList<Signature> oneSignatures = Helpers.signTransaction(oneFlash, bundles);
// Generate USER TWO'S Singatures
ArrayList<Signature> twoSignatures = Helpers.signTransaction(twoFlash, bundles);
System.out.println("[SUCCESS] Created signatures for users.");
// Sign bundle with your USER ONE'S signatures
ArrayList<Bundle> signedBundles = IotaFlashBridge.appliedSignatures(bundles, oneSignatures);
System.out.println("[SUCCESS] Parial applied Signature for User one on transfer bundle");
// ADD USER TWOS'S signatures to the partially signed bundles
signedBundles = IotaFlashBridge.appliedSignatures(signedBundles, twoSignatures);
System.out.println("[SUCCESS] Signed bundle bu second user. Bundle ready.");
ArrayList<Bundle> partialSignedBundles = signTransfer(bundles, oneFlash);
ArrayList<Bundle> signedBundles = signTransfer(partialSignedBundles, twoFlash);
/////////////////////////////////
/// APPLY SIGNED BUNDLES
@@ -154,7 +134,7 @@ public class Main {
/*
// Supplying the CORRECT varibles to create a closing bundle
bundles = Helpers.createTransaction(
bundles = com.flashwifi.flashwrapper.Helpers.createTransaction(
oneFlash,
oneFlash.getFlash().getSettlementAddresses(),
true
@@ -164,10 +144,10 @@ public class Main {
/// SIGN BUNDLES
// Get signatures for the bundles
oneSignatures = Helpers.signTransaction(oneFlash, bundles)
oneSignatures = com.flashwifi.flashwrapper.Helpers.signTransaction(oneFlash, bundles)
// Generate USER TWO'S Singatures
twoSignatures = Helpers.signTransaction(twoFlash, bundles)
twoSignatures = com.flashwifi.flashwrapper.Helpers.signTransaction(twoFlash, bundles)
// Sign bundle with your USER ONE'S signatures
signedBundles = transfer.appliedSignatures(bundles, oneSignatures)
@@ -179,12 +159,12 @@ public class Main {
/// APPLY SIGNED BUNDLES
// Apply transfers to User ONE
oneFlash = Helpers.applyTransfers(oneFlash, signedBundles)
oneFlash = com.flashwifi.flashwrapper.Helpers.applyTransfers(oneFlash, signedBundles)
// Save latest channel bundles
oneFlash.bundles = signedBundles
// Apply transfers to User TWO
twoFlash = Helpers.applyTransfers(twoFlash, signedBundles)
twoFlash = com.flashwifi.flashwrapper.Helpers.applyTransfers(twoFlash, signedBundles)
// Save latest channel bundles
twoFlash.bundles = signedBundles
@@ -192,6 +172,17 @@ public class Main {
console.log("Final Bundle to be attached: ")*/
}
private static ArrayList<Bundle> signTransfer(ArrayList<Bundle> bundles, UserObject user) {
System.out.println("[SUCCESS] Created signatures for users.");
ArrayList<Signature> oneSignatures = Helpers.signTransaction(user, bundles);
System.out.println("[SUCCESS] Parial applied Signature for User one on transfer bundle");
// Sign bundle with your USER ONE'S signatures
ArrayList<Bundle> signedBundles = IotaFlashBridge.appliedSignatures(bundles, oneSignatures);
return signedBundles;
}
private static void setupUser(UserObject user, int TREE_DEPTH) {
// Create digests for the start of the channel
for (int i = 0; i < TREE_DEPTH + 1; i++) {

View File

@@ -1,7 +1,4 @@
package Model;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Array;
package com.flashwifi.flashwrapper.Model;
import java.util.ArrayList;
import java.util.HashMap;

View File

@@ -1,4 +1,4 @@
package Model;
package com.flashwifi.flashwrapper.Model;
public class Console {

View File

@@ -1,4 +1,4 @@
package Model;
package com.flashwifi.flashwrapper.Model;
public class CreateTransactionHelperObject {
private int generate = 0;

View File

@@ -1,4 +1,4 @@
package Model;
package com.flashwifi.flashwrapper.Model;
import java.util.HashMap;
import java.util.Map;

View File

@@ -1,6 +1,8 @@
package Model;
package com.flashwifi.flashwrapper.Model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class FlashObject {
int signersCount = 2;
@@ -19,6 +21,17 @@ public class FlashObject {
this.deposits = deposits;
}
public FlashObject(int signersCount, int balance, ArrayList<String> settlementAddresses, ArrayList<Integer> deposits, ArrayList<Bundle> outputs, ArrayList<Bundle> transfers, MultisigAddress root, MultisigAddress remainderAddress) {
this.signersCount = signersCount;
this.balance = balance;
this.settlementAddresses = settlementAddresses;
this.deposits = deposits;
this.outputs = outputs;
this.transfers = transfers;
this.root = root;
this.remainderAddress = remainderAddress;
}
@Override
public String toString() {
String out = "";
@@ -48,6 +61,31 @@ public class FlashObject {
return out;
}
public Map<String, Object> toMap() {
Map<String, Object> objectMap = new HashMap<>();
objectMap.put("signersCount", signersCount);
objectMap.put("balance", getBalance());
objectMap.put("root", root.toMap());
objectMap.put("remainderAddress", remainderAddress.toMap());
objectMap.put("settlementAddresses", getSettlementAddresses());
ArrayList<Object> outputMap = new ArrayList<>();
for (Bundle b: outputs) {
outputMap.add(b.toMap());
}
objectMap.put("outputs", outputMap);
objectMap.put("deposits", getDeposits());
ArrayList<Object> transfersMap = new ArrayList<>();
for (Bundle b: transfers) {
outputMap.add(b.toMap());
}
objectMap.put("transfers", transfersMap);
return objectMap;
}
public int getSignersCount() {
return signersCount;
}

View File

@@ -1,4 +1,4 @@
package Model;
package com.flashwifi.flashwrapper.Model;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Object;

View File

@@ -1,10 +1,10 @@
package Model;
package com.flashwifi.flashwrapper.Model;
import java.util.ArrayList;
import java.util.List;
/**
* This class represents an Model.Signature.
* This class represents an com.flashwifi.flashwrapper.Model.Signature.
*
* @author Adrian
**/
@@ -15,7 +15,7 @@ public class Signature {
private List<String> signatureFragments;
/**
* Initializes a new instance of the Model.Signature class.
* Initializes a new instance of the com.flashwifi.flashwrapper.Model.Signature class.
*/
public Signature() {
this.signatureFragments = new ArrayList<>();

View File

@@ -1,4 +1,4 @@
package Model;
package com.flashwifi.flashwrapper.Model;
import java.util.HashMap;
import java.util.Map;

View File

@@ -1,4 +1,4 @@
package Model;
package com.flashwifi.flashwrapper.Model;
import com.google.gson.Gson;

View File

@@ -1,7 +1,8 @@
package Model;
package com.flashwifi.flashwrapper.Model;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class UserObject {
private int userIndex = 1;
@@ -55,17 +56,48 @@ public class UserObject {
return out;
}
public Map<String, Object> toMap() {
Map<String, Object> objectMap = new HashMap<>();
objectMap.put("userIndex", getUserIndex());
objectMap.put("seed", getSeed());
objectMap.put("index", getIndex());
objectMap.put("security", getSecurity());
objectMap.put("depth", depth);
ArrayList<Object> bundleMaps = new ArrayList<>();
for (Bundle b: bundles) {
bundleMaps.add(b.toMap());
}
objectMap.put("bundles", bundleMaps);
ArrayList<Object> partialDigestMaps = new ArrayList<>();
for (Bundle b: bundles) {
partialDigestMaps.add(b.toMap());
}
objectMap.put("partialDigests", partialDigestMaps);
ArrayList<Object> multisigDigestsMaps = new ArrayList<>();
for (Bundle b: bundles) {
partialDigestMaps.add(b.toMap());
}
objectMap.put("multisigDigests", multisigDigestsMaps);
objectMap.put("flash", flash.toMap());
return objectMap;
}
/**
*
* Getters and Setters
*/
public void setMultisigDigests(ArrayList<MultisigAddress> multisigDigests) {
this.multisigDigests = multisigDigests;
}
public void setFlash(FlashObject flash) {
this.flash = flash;
}
public void setIndex(int index) {
this.index = index;
}

View File

@@ -1,13 +1,11 @@
import Model.*;
package com.flashwifi.flashwrapper;
import com.flashwifi.flashwrapper.Model.*;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Object;
import com.eclipsesource.v8.V8ResultUndefined;
import com.eclipsesource.v8.utils.V8ObjectUtils;
import com.sun.org.apache.xpath.internal.operations.Mult;
import sun.rmi.server.InactiveGroupException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -42,6 +40,25 @@ public class V8Converter {
return V8ObjectUtils.toV8Object(engine, sigMapg);
}
public static V8Object flashObjectToV8Object(V8 engine, FlashObject flash) {
return V8ObjectUtils.toV8Object(engine, flash.toMap());
}
public static FlashObject flashObjectFromV8Object(V8Object input) {
Map<String, Object> inputMap = V8ObjectUtils.toMap(input);
Integer singersCount = (Integer) inputMap.get("signersCount");
Integer balance = (Integer) inputMap.get("balance");
ArrayList<String> settlementAddresses = (ArrayList<String>) inputMap.get("settlementAddresses");
MultisigAddress root = multisigAddressFromPropertyMap((Map<String, Object>) inputMap.get("root"));
MultisigAddress remainderAddress = multisigAddressFromPropertyMap((Map<String, Object>) inputMap.get("remainderAddress"));
ArrayList<Integer> deposits = (ArrayList<Integer>) inputMap.get("deposits");
ArrayList<Bundle> transfers = bundleListFromArrayList((ArrayList<Object>) inputMap.get("transfers"));
ArrayList<Bundle> outputs = bundleListFromArrayList((ArrayList<Object>) inputMap.get("outputs"));
return new FlashObject(singersCount, balance, settlementAddresses, deposits, outputs, transfers, root, remainderAddress);
}
public static V8Array bundleListToV8Array(V8 engine, ArrayList<Bundle> bundles) {
List<Object> bundleTmp = new ArrayList<Object>();
@@ -55,6 +72,25 @@ public class V8Converter {
return V8ObjectUtils.toV8Array(engine, bundleTmp);
}
public static Bundle bundleFromArrayList(ArrayList<Object> bundleObject) {
ArrayList<Transaction> tr = new ArrayList<>();
for (Object transaction: bundleObject) {
tr.add(transactionFromObject(transaction));
}
return new Bundle(tr);
}
public static ArrayList<Bundle> bundleListFromArrayList(ArrayList<Object> input) {
ArrayList<Bundle> ret = new ArrayList<>();
for (Object o: input) {
ret.add(bundleFromArrayList((ArrayList<Object>) o));
}
return ret;
}
public static MultisigAddress multisigAddressFromV8Object(V8Object input) {
Map<String, ? super Object> multiSigMap = V8ObjectUtils.toMap(input);
return multisigAddressFromPropertyMap(multiSigMap);
@@ -129,31 +165,35 @@ public class V8Converter {
return transfers;
}
public static Transfer transferFromMap(Map<String, Object> values) {
String obsoleteTag = (String) values.get("obsoleteTag");
String address = (String) values.get("address");
Long value = parseLongFromObject(values.get("value"));
if (values.get("timestamp") instanceof String) {
String timestamp = (String) values.get("timestamp");
String hash = (String) values.get("hash");
Boolean persistance = (Boolean) values.get("persistance");
String message = (String) values.get("message");
String tag = (String) values.get("tag");
return new Transfer(
timestamp,
address,
hash,
persistance,
value,
message,
tag
);
} else {
System.out.println("[WARN] Could not find key for full transfer creating slim transfer object");
return new Transfer(address, value);
}
}
public static Transfer transferFromObject(Object input) {
if (input instanceof Map) {
Map<String, ? super Object> values = (Map<String, ? super Object>) input;
String obsoleteTag = (String) values.get("obsoleteTag");
String address = (String) values.get("address");
Long value = parseLongFromObject(values.get("value"));
if (values.get("timestamp") instanceof String) {
String timestamp = (String) values.get("timestamp");
String hash = (String) values.get("hash");
Boolean persistance = (Boolean) values.get("persistance");
String message = (String) values.get("message");
String tag = (String) values.get("tag");
return new Transfer(
timestamp,
address,
hash,
persistance,
value,
message,
tag
);
} else {
System.out.println("[WARN] Could not find key for full transfer creating slim transfer object");
return new Transfer(address, value);
}
return transferFromMap(values);
}
return null;
}