Fixed conversion errors, added dynamich branch generation, refactor and code cleanup.

This commit is contained in:
gosticks
2018-01-20 16:13:49 +01:00
parent 3a6510d575
commit 02a2893eca
9 changed files with 459 additions and 282 deletions

View File

@@ -1,5 +1,6 @@
package iotaFlashWrapper;
import com.sun.org.apache.xpath.internal.operations.Mult;
import iotaFlashWrapper.Model.*;
@@ -8,89 +9,218 @@ import java.util.List;
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.");
}
/**
* Get a transaction object. The object contains the address to use and if required the number of new addresses to generate
* @param root multisig address at the top of the tree
* @return Transaction object with address and number of addresses to create.
*/
public static CreateTransactionHelperObject getTransactionHelper(MultisigAddress root) {
return IotaFlashBridge.updateLeafToRoot(root);
}
/**
*
* @param transfers
* @param toUse Transaction helper object
* @param user
* @param shouldClose
* @return
*/
public static ArrayList<Bundle> createTransaction(ArrayList<Transfer> transfers, CreateTransactionHelperObject toUse, UserObject user, boolean shouldClose) {
// 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<Transfer> newTransfers;
FlashObject flash = user.getFlash();
if (shouldClose) {
newTransfers = IotaFlashBridge.close(user.getFlash().getSettlementAddresses(), user.getFlash().getDeposits());
newTransfers = IotaFlashBridge.close(flash.getSettlementAddresses(), flash.getDeposits());
} else {
// Prepare a new transaction.
newTransfers = IotaFlashBridge.prepare(
user.getFlash().getSettlementAddresses(),
user.getFlash().getDeposits(),
flash.getSettlementAddresses(),
flash.getDeposits(),
user.getUserIndex(),
transfers
);
}
// Compose the transaction. This may also add some management transactions (moving remainder tokens.)
ArrayList<Bundle> bundles = IotaFlashBridge.compose(
user.getFlash().getBalance(),
user.getFlash().getDeposits(),
user.getFlash().getOutputs(),
flash.getBalance(),
flash.getDeposits(),
flash.getOutputs(),
toUse.getAddress(),
user.getFlash().getRemainderAddress(),
user.getFlash().getTransfers(),
flash.getRemainderAddress(),
flash.getTransfers(),
newTransfers,
shouldClose
);
return bundles;
System.out.println("[SUCCESS] Created signatures for user" + user.getUserIndex());
// Apply the signature of the transaction creater to the current transactions bundle.
ArrayList<Signature> signatures = IotaFlashBridge.sign(toUse.getAddress(), 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);
}
public static ArrayList<Signature> signTransaction(UserObject user, ArrayList<Bundle> bundles) {
return IotaFlashBridge.sign(user.getFlash().getRoot(), user.getSeed(), bundles);
}
//
// public static ArrayList<Bundle> appliedSignatures(ArrayList<Bundle> bundles, ArrayList<Signature> signatures) {
// ArrayList<Bundle> clonedBundles = clone(bundles);
// bundles.clone();
//
// for (int i = 0; i < bundles.size(); i++) {
// Signature sig = signatures.get(i);
// Bundle b = bundles.get(i);
// if (sig == null) {
// continue;
// }
//
// ArrayList<Transaction> transactions = b.getBundles();
// String addy = transactions.stream().filter(tx -> tx.getValue() < 0).findFirst().get().getAddress();
// List<Transaction> tmp = transactions.stream()
// .filter(tx -> tx.getAddress().equals(addy))
// .collect(Collectors.toList());
//
// tmp = tmp.subList(sig.getIndex(), sig.getIndex() + sig.getSignatureFragments().size());
//
// for (int j = 0; j < tmp.size(); j++) {
// tmp.get(j).setSignatureFragments(sig.getSignatureFragments().get(j));
// }
// }
//
// return clonedBundles;
// }
/**
*
* Tree management.
*
*/
public static void applyTransfers(UserObject user, ArrayList<Bundle> bundles) {
FlashObject flash = IotaFlashBridge.applyTransfersToUser(user, bundles);
user.setFlash(flash);
// 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) {
ArrayList<Bundle> clonedBundles = new ArrayList<>();
for (Bundle b : bundles) {
clonedBundles.add(b.clone());
/**
*
* @param user
* @param toGenerate
* @return
*/
public static ArrayList<Digest> getNewBranchDigests(UserObject user, int toGenerate) {
ArrayList<Digest> digests = new ArrayList<>();
for (int i = 0; i < toGenerate; i++) {
Digest digest = IotaFlashBridge.getDigest(user.getSeed(), user.getIndex(), user.getSecurity());
System.out.println("USING index for digest: " + user.getIndex() );
user.incrementIndex();
digests.add(digest);
}
return clonedBundles;
return digests;
}
/**
*
* @param oneDigests
* @param twoDigests
* @param user
* @param address
* @return
*/
public static MultisigAddress getNewBranch(ArrayList<Digest> oneDigests, ArrayList<Digest> twoDigests, UserObject user, MultisigAddress address) {
ArrayList<ArrayList<Digest>> userDigestList = new ArrayList<>();
userDigestList.add(oneDigests);
userDigestList.add(twoDigests);
ArrayList<MultisigAddress> multisigs = getMultisigsForUser(userDigestList, user);
System.out.println("[INFO]: Adding to address " + address.getAddress());
// Build flash trees
for (int i = 1; i < multisigs.size(); i++) {
multisigs.get(i - 1).push(multisigs.get(i));
}
// Clone the address to avoid overwriting params.
MultisigAddress output = address.clone();
// Add new multisigs to address.
output.push(multisigs.get(0));
return output;
}
/**
*
* Digests and MultisigAddress creation
*
*/
/**
* Creates initial digests for a user. This will only create digests for a given TREE_DEPTH -> Digests.size == TREE_DEPTH + 1
* Other transactions will be generated when required.
* @param user user for which the digests should be generated
* @param TREE_DEPTH number of initial digests to generate
* @return digests for provided user.
*/
public static ArrayList<Digest> getDigestsForUser(UserObject user, int TREE_DEPTH) {
ArrayList<Digest> digests = new ArrayList<>();
// Create digests for the start of the channel
for (int i = 0; i < TREE_DEPTH + 1; i++) {
// Create new digest
Digest digest = IotaFlashBridge.getDigest(
user.getSeed(),
user.getIndex(),
user.getSecurity()
);
user.incrementIndex();
System.out.println("Adding digest (" + digest.toString() + ") to user " + user.getUserIndex());
// Increment key index
digests.add(digest);
}
return digests;
}
/**
*
* @param allDigests
* @param currentUser
* @return
*/
public static ArrayList<MultisigAddress> getMultisigsForUser(ArrayList<ArrayList<Digest>> allDigests, UserObject currentUser) {
// Generate the first addresses
ArrayList<MultisigAddress> multisigs = new ArrayList<MultisigAddress>();
// Loop for all digests.
for (int index = 0; index < allDigests.get(0).size(); index++) {
ArrayList<Digest> alignedDigests = new ArrayList<>();
int securitySum = 0;
// Loop for all users.
for (int userIndex = 0; userIndex < allDigests.size(); userIndex++) {
Digest digest = allDigests.get(userIndex).get(index);
// Get array of digests for all users.
alignedDigests.add(digest);
securitySum += digest.getSecurity();
}
// Create multisgAddr from digests.
MultisigAddress multisigAddress = IotaFlashBridge.composeAddress(alignedDigests);
// Get digests data for current user.
Digest digest = allDigests.get(currentUser.getUserIndex()).get(index);
multisigAddress.setIndex(digest.getIndex());
multisigAddress.setSigningIndex(currentUser.getUserIndex() * digest.getSecurity());
multisigAddress.setSecuritySum(securitySum);
multisigAddress.setSecurity(digest.getSecurity());
System.out.println("Creating address " + multisigAddress.getAddress() + " index" + multisigAddress.getIndex() + " signingIndex: " + multisigAddress.getSigningIndex());
multisigs.add(multisigAddress);
}
return multisigs;
}
/**
*
* @param user
* @param multisigAddress
* @return
*/
public static MultisigAddress updateMultisigChildrenForUser(UserObject user, MultisigAddress multisigAddress) {
FlashObject flash = user.getFlash();
MultisigAddress originAddress = flash.getRoot().find(multisigAddress.getAddress());
if (originAddress != null) {
System.out.println("[INFO]: found address in user" + user.getUserIndex() + " data");
originAddress.setChildren(multisigAddress.getChildren());
originAddress.setBundles(multisigAddress.getBundles());
originAddress.setSecurity(multisigAddress.getSecurity());
return originAddress;
}
return null;
}
}

View File

@@ -124,7 +124,7 @@ public class IotaFlashBridge {
* @param transfers array of all transfers (value, address) pairs
* @return
*/
public static ArrayList<Transfer> prepare(ArrayList<String> settlementAddresses, ArrayList<Integer> deposits, int index, ArrayList<Transfer> transfers) {
public static ArrayList<Transfer> prepare(ArrayList<String> settlementAddresses, ArrayList<Double> deposits, int index, ArrayList<Transfer> transfers) {
// Now put all params into JS ready array.
List<Object> params = new ArrayList<>();
@@ -145,7 +145,7 @@ public class IotaFlashBridge {
* @param deposits
* @return
*/
public static ArrayList<Transfer> close(ArrayList<String> settlementAddresses, ArrayList<Integer> deposits) {
public static ArrayList<Transfer> close(ArrayList<String> settlementAddresses, ArrayList<Double> deposits) {
V8Array saJS = V8ObjectUtils.toV8Array(engine, settlementAddresses);
// Deposits
V8Array depositsJS = V8ObjectUtils.toV8Array(engine, deposits);
@@ -172,16 +172,13 @@ public class IotaFlashBridge {
* @return
*/
public static ArrayList<Bundle> compose(int balance,
List<Integer> deposits,
List<Double> deposits,
ArrayList<Bundle> outputs,
MultisigAddress root,
MultisigAddress remainderAddress,
ArrayList<Bundle> history,
ArrayList<Transfer> transfers,
boolean close) {
// Create params.
// Now put all params into JS ready array.
List<Object> params = new ArrayList<Object>();

View File

@@ -1,5 +1,6 @@
package iotaFlashWrapper;
import com.sun.org.apache.xpath.internal.operations.Mult;
import iotaFlashWrapper.Model.*;
import java.io.IOException;
@@ -25,7 +26,7 @@ public class Main {
// INITIAL CHANNEL CONDITIONS
// Security level
int SECURITY = 2;
int SECURITY = 1;
// Number of parties taking signing part in the channel
int SIGNERS_COUNT = 2;
// Flash tree depth
@@ -33,252 +34,189 @@ public class Main {
// Total channel Balance
int CHANNEL_BALANCE = 2000;
// Users deposits
ArrayList<Integer> DEPOSITS = new ArrayList<>();
DEPOSITS.add(1000);
DEPOSITS.add(1000);
ArrayList<Double> DEPOSITS = new ArrayList<>();
DEPOSITS.add(1000.0);
DEPOSITS.add(1000.0);
// Setup users.
FlashObject oneFlashObj = new FlashObject(SIGNERS_COUNT, CHANNEL_BALANCE, DEPOSITS);
UserObject oneFlash = new UserObject(0, oneSeed, TREE_DEPTH, oneFlashObj);
UserObject oneFlash = new UserObject(0, oneSeed, TREE_DEPTH, SECURITY, oneFlashObj);
FlashObject twoFlashObj = new FlashObject(SIGNERS_COUNT, CHANNEL_BALANCE, DEPOSITS);
UserObject twoFlash = new UserObject(1, twoSeed, TREE_DEPTH, twoFlashObj);
UserObject twoFlash = new UserObject(1, twoSeed, TREE_DEPTH, SECURITY, twoFlashObj);
// USER ONE
setupUser(oneFlash, TREE_DEPTH);
ArrayList<Digest> oneDigests = Helpers.getDigestsForUser(oneFlash, TREE_DEPTH);
// USER TWO
setupUser(twoFlash, TREE_DEPTH);
ArrayList<Digest> twoDigests = Helpers.getDigestsForUser(twoFlash, TREE_DEPTH);
//////////////////////////////////
// INITAL MULTISIG
// Make an array of digests
ArrayList<UserObject> allUsers = new ArrayList<UserObject>();
allUsers.add(oneFlash);
allUsers.add(twoFlash);
ArrayList<ArrayList<Digest>> allUserDigests = new ArrayList<>();
allUserDigests.add(oneDigests);
allUserDigests.add(twoDigests);
// Create partial digests for users.
createInitialPartialDigests(allUsers, oneFlash);
createInitialPartialDigests(allUsers, twoFlash);
ArrayList<MultisigAddress> oneMultisigs = oneFlash.getMultisigDigests();
ArrayList<MultisigAddress> twoMultisigs = twoFlash.getMultisigDigests();
/***************************************
User one setup.
***************************************/
// Create multisigs.
ArrayList<MultisigAddress> oneMultisigs = Helpers.getMultisigsForUser(allUserDigests, oneFlash);
// Set renainder address.
MultisigAddress oneRemainderAddr = oneMultisigs.remove(0); //shiftCopyArray();
oneFlash.getFlash().setRemainderAddress(oneRemainderAddr);
MultisigAddress twoRemainderAddr = twoMultisigs.remove(0);
twoFlash.getFlash().setRemainderAddress(twoRemainderAddr);
// Build flash trees
for (int i = 1; i < oneMultisigs.size(); i++) {
System.out.println(oneMultisigs.get(i - 1).toString() + " -> " + oneMultisigs.get(i).toString());
oneMultisigs.get(i - 1).push(oneMultisigs.get(i));
}
oneFlash.getFlash().setRoot(oneMultisigs.remove(0));
/***************************************
User one setup.
***************************************/
ArrayList<MultisigAddress> twoMultisigs = Helpers.getMultisigsForUser(allUserDigests, twoFlash);
// Set user two remainder addr.
MultisigAddress twoRemainderAddr = twoMultisigs.remove(0);
twoFlash.getFlash().setRemainderAddress(twoRemainderAddr);
// Build flash trees
for (int i = 1; i < twoMultisigs.size(); i++) {
twoMultisigs.get(i - 1).push(twoMultisigs.get(i));
}
oneFlash.getFlash().setRoot(oneMultisigs.remove(0));
twoFlash.getFlash().setRoot(twoMultisigs.remove(0));
/***************************************
Setup tettlements.
***************************************/
ArrayList<String> settlementAddresses = new ArrayList<>();
settlementAddresses.add(oneSettlement);
settlementAddresses.add(twoSettlement);
/***************************************
Setup tettlements.
***************************************/
oneFlash.getFlash().setSettlementAddresses(settlementAddresses);
twoFlash.getFlash().setSettlementAddresses(settlementAddresses);
// Set digest/key index
oneFlash.setIndex(oneFlash.getPartialDigests().size());
twoFlash.setIndex(twoFlash.getPartialDigests().size());
oneFlash.setIndex(oneDigests.size());
twoFlash.setIndex(twoDigests.size());
System.out.println("Channel Setup!");
System.out.println("Channel Setup completed!");
ArrayList<Transfer> transfers = new ArrayList<>();
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);
ArrayList<Bundle> partialSignedBundles = signTransfer(bundles, oneFlash);
ArrayList<Bundle> signedBundles = signTransfer(partialSignedBundles, twoFlash);
/////////////////////////////////
/// APPLY SIGNED BUNDLES
// Apply transfers to User ONE
Helpers.applyTransfers(oneFlash, signedBundles);
// Save latest channel bundles
oneFlash.setBundles(signedBundles);
// Apply transfers to User TWO
Helpers.applyTransfers(twoFlash, signedBundles);
// Save latest channel bundles
twoFlash.setBundles(signedBundles);
System.out.println("[SUCCESS] Apply Transfer to flash channel.");
/***************************************
Create transactions.
***************************************/
System.out.println("Transaction Applied!");
// System.out.println(
// "Transactable tokens: " +
// oneFlash.getFlash().getDeposits().stream().mapToInt(v -> v.intValue()).sum()
// );
// Create transfer from user one
ArrayList<Bundle> suggestedTransfer;
// Accept transfers from other user
ArrayList<Bundle> confirmedTransfers;
// Try to make 10 transfers.
for (int i = 0; i < 10; i++) {
// Create transaction helper and check if we need to add nodes
CreateTransactionHelperObject helper = Helpers.getTransactionHelper(oneFlash.getFlash().getRoot());
// Check if we need to create new addresses. This must be done before a transaction is prepared.
// The createTransaction will then create funding fundles for the new address.
if (helper.getGenerate() != 0) {
System.out.println("[WARN]: generating " + helper.getGenerate() + "new branches!");
// Add user one digests.
ArrayList<Digest> newOneDigests = Helpers.getNewBranchDigests(oneFlash, helper.getGenerate());
// Add user two digests
ArrayList<Digest> newTwoDigests = Helpers.getNewBranchDigests(twoFlash, helper.getGenerate());
// Now we can create new multisig addresses
MultisigAddress multisigAddressOne = Helpers.getNewBranch(newOneDigests, newTwoDigests, oneFlash, helper.getAddress());
MultisigAddress multisigAddressTwo = Helpers.getNewBranch(newOneDigests, newTwoDigests, twoFlash, helper.getAddress());
// Find the multisig with the address and append new address to children
Helpers.updateMultisigChildrenForUser(oneFlash, multisigAddressOne);
Helpers.updateMultisigChildrenForUser(twoFlash, multisigAddressTwo);
// Set the updated multisig as origin of the transaction.
helper.setAddress(multisigAddressOne);
}
// Create transfers.
ArrayList<Transfer> transfers = new ArrayList<>();
transfers.add(new Transfer(twoSettlement, 20));
// Create a transaction from a transfer.
suggestedTransfer = Helpers.createTransaction(transfers, helper, oneFlash, false);
System.out.println("[INFO] Created transfer suggestion.");
// TODO: check here if transaction is valid.
// If transactions should be signed create signatures.
ArrayList<Signature> userTwoSignatures = IotaFlashBridge.sign(twoFlash.getFlash().getRoot(), twoFlash.getSeed(), suggestedTransfer);
System.out.println("[INFO] Created user two signatures.");
// TODO: the signatures should be sind to the first user.
// Apply transfers by all users.
System.out.println("[INFO] Signing transfers.");
ArrayList<Bundle> signedBundlesOne = IotaFlashBridge.appliedSignatures(suggestedTransfer, userTwoSignatures);
ArrayList<Bundle> signedBundlesTwo = IotaFlashBridge.appliedSignatures(suggestedTransfer, userTwoSignatures);
applyTransfers(signedBundlesOne, oneFlash);
applyTransfers(signedBundlesTwo, twoFlash);
System.out.println("Transaction Applied! Transactable tokens: " + getFlashDeposits(oneFlash));
}
System.out.println("Closing channel... not yet working...");
/*
// Supplying the CORRECT varibles to create a closing bundle
bundles = Helpers.createTransaction(
oneFlash,
oneFlash.getFlash().getSettlementAddresses(),
true
);
/////////////////////////////////
/// SIGN BUNDLES
// Get signatures for the bundles
oneSignatures = Helpers.signTransaction(oneFlash, bundles)
// Generate USER TWO'S Singatures
twoSignatures = Helpers.signTransaction(twoFlash, bundles)
// Sign bundle with your USER ONE'S signatures
signedBundles = transfer.appliedSignatures(bundles, oneSignatures)
// ADD USER TWOS'S signatures to the partially signed bundles
signedBundles = transfer.appliedSignatures(signedBundles, twoSignatures)
/////////////////////////////////
/// APPLY SIGNED BUNDLES
}
public static void applyTransfers(ArrayList<Bundle> signedBundles, UserObject user) {
// Apply transfers to User ONE
oneFlash = Helpers.applyTransfers(oneFlash, signedBundles)
FlashObject newFlash = IotaFlashBridge.applyTransfersToUser(user, signedBundles);
// Set new flash object to user
user.setFlash(newFlash);
// Save latest channel bundles
oneFlash.bundles = signedBundles
// Apply transfers to User TWO
twoFlash = Helpers.applyTransfers(twoFlash, signedBundles)
// Save latest channel bundles
twoFlash.bundles = signedBundles
console.log("Channel Closed")
console.log("Final Bundle to be attached: ")*/
user.setBundles(signedBundles);
}
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++) {
// Create new digest
Digest digest = IotaFlashBridge.getDigest(
user.getSeed(),
user.getIndex(),
user.getSecurity()
);
System.out.println("Adding digest (" + digest.toString() + ") to user " + user.getUserIndex());
// Increment key index
user.incrementIndex();
user.add(digest);
public static double getFlashDeposits(UserObject user) {
double sum = 0;
for (double deposit : user.getFlash().getDeposits()) {
sum += deposit;
}
return sum;
}
private static void createInitialPartialDigests(ArrayList<UserObject> allUsers, UserObject currentUser) {
// Generate the first addresses
ArrayList<MultisigAddress> oneMultisigs = new ArrayList<MultisigAddress>();
System.out.println("_________________________________________________________________");
System.out.println("Creating multisigs on user: " + currentUser.getUserIndex());
int index = 0;
// Create address
for (Digest digest: allUsers.get(index).getPartialDigests()) {
int i = index;
MultisigAddress addy = IotaFlashBridge.composeAddress(
allUsers.stream().map(u -> u.getPartialDigests().get(i)).collect(Collectors.toCollection(ArrayList::new))
);
System.out.println("Multisig: " + addy.toString());
// Add key index in
addy.setIndex(digest.getIndex());
// Add the signing index to the object IMPORTANT
addy.setSigningIndex(currentUser.getUserIndex() * digest.getSecurity());
// Get the sum of all digest security to get address security sum
addy.setSecuritySum(allUsers.stream()
.map(u -> u.getPartialDigests().get(i))
.mapToInt(Digest::getSecurity)
.sum()
);
addy.setSecurity(digest.getSecurity());
oneMultisigs.add(addy);
index++;
}
currentUser.setMultisigDigests(oneMultisigs);
}
private static ArrayList<MultisigAddress> shiftCopyArray(ArrayList<MultisigAddress> input) {
ArrayList<MultisigAddress> output = new ArrayList<>();
for (int i = 1; i < input.size(); i++) {
output.add(input.get(i));
}
return output;
}
private static void test() throws IOException {
System.out.println("IOTA Flash channel tester");
String pathToLib = "res/iota.flash.js";
System.out.println("Loading lib into V8 engine");
System.out.println("Lib imported");
System.out.println("Testing getDigest(seed, index, security):");
Digest digest1 = IotaFlashBridge.getDigest("USERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSER", 0, 2);
Digest digest2 = IotaFlashBridge.getDigest("USERTWOUSERTWOUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSERONEUSER", 0, 2);
System.out.println("Digest1: " + digest1.toString());
System.out.println("Testing composeAddress(digests):");
ArrayList<Digest> digests = new ArrayList<Digest>();
digests.add(digest1);
digests.add(digest2);
MultisigAddress composedAddr = IotaFlashBridge.composeAddress(digests);
System.out.println("Got multisig addr for digests: " + composedAddr.getAddress() + ", securitySum: " + composedAddr.getSecuritySum());
testPrepare();
}
private static void testPrepare() {
System.out.println("Testing prepare()");
ArrayList<String> settlementAddr = new ArrayList<String>();
settlementAddr.add("RCZHCRDWMGJPHKROKEGVADVJXPGKEKNJRNLZZFPITUVEWNPGIWNUMKTYKMNB9DCNLWGMJZDNKYQDQKDLC");
ArrayList<Integer> depositsPrep = new ArrayList<Integer>();
ArrayList<Transfer> transfers = new ArrayList<Transfer>();
IotaFlashBridge.prepare(settlementAddr, depositsPrep, 0, transfers);
/**
* acceptTransfer applies signatures of a
* @param bundles half signed transfers
* @param signatures signatures of the second user
*/
public static void acceptTransfer(ArrayList<Bundle> bundles, ArrayList<Signature> signatures, UserObject user) {
ArrayList<Bundle> signedBundles = IotaFlashBridge.appliedSignatures(bundles, signatures);
applyTransfers(signedBundles, user);
}
}

View File

@@ -28,12 +28,17 @@ public class Bundle {
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("bundles", toArrayList());
return map;
}
public List<Object> toArrayList() {
List<Object> bundleList = new ArrayList<Object>();
for (Transaction b: bundles) {
bundleList.add(b.toMap());
}
map.put("bundles", bundleList);
return map;
return bundleList;
}
public ArrayList<Transaction> getBundles() {

View File

@@ -16,4 +16,8 @@ public class CreateTransactionHelperObject {
public MultisigAddress getAddress() {
return address;
}
public void setAddress(MultisigAddress address) {
this.address = address;
}
}

View File

@@ -8,20 +8,20 @@ public class FlashObject {
int signersCount = 2;
int balance;
ArrayList<String> settlementAddresses;
ArrayList<Integer> deposits; // Clone correctly
ArrayList<Double> deposits;
ArrayList<Bundle> outputs = new ArrayList<Bundle>();
ArrayList<Bundle> transfers = new ArrayList<Bundle>();
MultisigAddress root;
MultisigAddress remainderAddress;
public FlashObject(int signersCount, int balance, ArrayList<Integer> deposits) {
public FlashObject(int signersCount, int balance, ArrayList<Double> deposits) {
this.signersCount = signersCount;
this.balance = balance;
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) {
public FlashObject(int signersCount, int balance, ArrayList<String> settlementAddresses, ArrayList<Double> deposits, ArrayList<Bundle> outputs, ArrayList<Bundle> transfers, MultisigAddress root, MultisigAddress remainderAddress) {
this.signersCount = signersCount;
this.balance = balance;
this.settlementAddresses = settlementAddresses;
@@ -42,7 +42,7 @@ public class FlashObject {
out += "\t" + b + "\n";
}
out += "deposits: " + "\n";
for (Integer b: deposits) {
for (double b: deposits) {
out += "\t" + b + "\n";
}
@@ -98,7 +98,7 @@ public class FlashObject {
return root;
}
public ArrayList<Integer> getDeposits() {
public ArrayList<Double> getDeposits() {
return deposits;
}

View File

@@ -3,6 +3,7 @@ package iotaFlashWrapper.Model;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Object;
import com.eclipsesource.v8.utils.V8ObjectUtils;
import com.sun.org.apache.xpath.internal.operations.Mult;
import java.util.ArrayList;
import java.util.HashMap;
@@ -24,7 +25,6 @@ public class MultisigAddress {
this.securitySum = securitySum;
this.children = new ArrayList<MultisigAddress>();
this.bundles = new ArrayList<Bundle>();
}
public MultisigAddress(String address, int securitySum, ArrayList<MultisigAddress> children) {
@@ -34,6 +34,42 @@ public class MultisigAddress {
this.bundles = new ArrayList<Bundle>();
}
public MultisigAddress find(String address) {
if (getAddress().equals(address)) {
return this;
} else {
for (MultisigAddress mult: getChildren()) {
MultisigAddress result = mult.find(address);
if (result != null) {
return result;
}
}
}
return null;
}
public MultisigAddress clone() {
MultisigAddress output = new MultisigAddress(this.getAddress(), this.getSecuritySum());
output.setSecurity(this.getSecurity());
output.setIndex(this.getIndex());
output.setSigningIndex(this.getSigningIndex());
// Copy all bundles
ArrayList<Bundle> bundleCopy = new ArrayList<>();
for (Bundle b : this.getBundles()) {
bundleCopy.add(b.clone());
}
output.setBundles(bundleCopy);
// Copy all children
ArrayList<MultisigAddress> childrenCopy = new ArrayList<>();
for (MultisigAddress child : this.getChildren()) {
childrenCopy.add(child.clone());
}
output.setChildren(childrenCopy);
return output;
}
public void push(MultisigAddress addr) {
children.add(addr);
}
@@ -53,6 +89,22 @@ public class MultisigAddress {
return index;
}
public void setAddress(String address) {
this.address = address;
}
public void setChildren(ArrayList<MultisigAddress> children) {
this.children = children;
}
public ArrayList<Bundle> getBundles() {
return bundles;
}
public void setBundles(ArrayList<Bundle> bundles) {
this.bundles = bundles;
}
public int getSigningIndex() {
return signingIndex;
}
@@ -92,7 +144,7 @@ public class MultisigAddress {
List<Object> bundleList = new ArrayList<Object>();
for (Bundle b: bundles) {
bundleList.add(b.getBundles());
bundleList.add(b.toArrayList());
}
map.put("bundles", bundleList);

View File

@@ -5,25 +5,27 @@ import java.util.HashMap;
import java.util.Map;
public class UserObject {
private int userIndex = 1;
private int userIndex;
private String seed;
private int index = 0;
private int security = 2;
private int depth = 4;
private int security;
private int depth;
private ArrayList<Bundle> bundles = new ArrayList<Bundle>();
private ArrayList<Digest> partialDigests = new ArrayList<Digest>();
private ArrayList<MultisigAddress> multisigDigests = new ArrayList<MultisigAddress>();
private FlashObject flash;
public UserObject(int userID, String seed, int depth, FlashObject flash) {
public UserObject(int userID, String seed, int depth, int security, FlashObject flash) {
this.userIndex = userID;
this.seed = seed;
this.depth = depth;
this.security = security;
this.flash = flash;
}
public void incrementIndex() {
index++;
public int incrementIndex() {
this.index = this.index + 1;
return index;
}
public void add(Digest digest) {

View File

@@ -3,6 +3,7 @@ package iotaFlashWrapper;
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 iotaFlashWrapper.Model.*;
@@ -52,7 +53,17 @@ public class V8Converter {
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<Double> deposits = new ArrayList<>();
if (inputMap.get("deposits") instanceof ArrayList) {
Object depositEntry = inputMap.get("deposits");
if (((ArrayList<Object>) depositEntry).size() > 0 && ((ArrayList<Object>) depositEntry).get(0) instanceof Integer) {
for (int val: (ArrayList<Integer>) depositEntry) {
deposits.add(new Double(val));
}
} else {
deposits = (ArrayList<Double>) depositEntry;
}
}
ArrayList<Bundle> transfers = bundleListFromArrayList((ArrayList<Object>) inputMap.get("transfers"));
ArrayList<Bundle> outputs = bundleListFromArrayList((ArrayList<Object>) inputMap.get("outputs"));
@@ -84,7 +95,17 @@ public class V8Converter {
ArrayList<Bundle> ret = new ArrayList<>();
for (Object o: input) {
ret.add(bundleFromArrayList((ArrayList<Object>) o));
if (o instanceof Map) {
if (((Map) o).get("bundles") instanceof String) {
ArrayList<Object> bundles = (ArrayList<Object>) ((Map<String, Object>) o).get("bundles");
ret.add(bundleFromArrayList(bundles));
} else {
continue;
}
}
if (o instanceof ArrayList) {
ret.add(bundleFromArrayList((ArrayList<Object>) o));
}
}
@@ -92,6 +113,10 @@ public class V8Converter {
}
public static MultisigAddress multisigAddressFromV8Object(V8Object input) {
if (input.isUndefined()) {
System.out.println("[ERROR]: could not parse object");
return null;
}
Map<String, ? super Object> multiSigMap = V8ObjectUtils.toMap(input);
return multisigAddressFromPropertyMap(multiSigMap);
}
@@ -101,7 +126,6 @@ public class V8Converter {
String addr = (String) propMap.get("address");
int secSum = (Integer) propMap.get("securitySum");
ArrayList<MultisigAddress> children = new ArrayList<>();
for (Object child: (ArrayList<Object>) propMap.get("children")) {
@@ -111,6 +135,23 @@ public class V8Converter {
MultisigAddress multisig = new MultisigAddress(addr, secSum, children);
if (propMap.get("bundles") instanceof ArrayList) {
ArrayList<Bundle> bundles = new ArrayList<>();
for (Object bundle: (ArrayList<Object>) propMap.get("bundles")) {
Bundle b = new Bundle();
if (!(bundle instanceof ArrayList)) {
continue;
} else {
for (Object transactionMap: (ArrayList<Object>) bundle) {
b.getBundles().add(transactionFromObject(transactionMap));
}
}
bundles.add(b);
}
multisig.setBundles(bundles);
}
if (propMap.get("index") != null) {
multisig.setIndex((Integer) propMap.get("index"));
}
@@ -118,6 +159,10 @@ public class V8Converter {
multisig.setSigningIndex((Integer) propMap.get("signingIndex"));
}
if (propMap.get("security") instanceof Integer) {
multisig.setSecurity((Integer) propMap.get("security"));
}
return multisig;
}
@@ -126,6 +171,10 @@ public class V8Converter {
// Parse return as array of bundles
ArrayList<Bundle> returnBundles = new ArrayList<>();
for (Object bundleItem: inputList) {
if (!(bundleItem instanceof ArrayList)) {
System.out.println("[ERROR]: got undefined for bunle");
continue;
}
ArrayList<Object> bundleContent = (ArrayList<Object>) bundleItem;
ArrayList<Transaction> returnedTransactions = new ArrayList<>();