From c7efb94942f0674284107501c42d98d6aa44970a Mon Sep 17 00:00:00 2001
From: Luca Keidel <info@lucakeidel.de>
Date: Thu, 23 Jun 2016 02:03:46 +0200
Subject: [PATCH] Implemented multiple automated random commits

---
 ...ionCommitDistributedCommittedTransfer.java |  9 ++-
 ...onPrepareDistributedCommittedTransfer.java |  1 -
 .../configurations/AbstractConfiguration.java | 66 +++++++++++++++++++
 .../configurations/DefaultConfiguration.java  | 44 ++-----------
 .../MassWalletConfiguration.java              |  4 +-
 5 files changed, 80 insertions(+), 44 deletions(-)

diff --git a/src/main/java/fucoin/actions/transaction/ActionCommitDistributedCommittedTransfer.java b/src/main/java/fucoin/actions/transaction/ActionCommitDistributedCommittedTransfer.java
index 54ab5b0..641fc12 100644
--- a/src/main/java/fucoin/actions/transaction/ActionCommitDistributedCommittedTransfer.java
+++ b/src/main/java/fucoin/actions/transaction/ActionCommitDistributedCommittedTransfer.java
@@ -53,10 +53,9 @@ public class ActionCommitDistributedCommittedTransfer extends ClientAction {
                 wallet.setAmount(wallet.getAmount() + amount);
                 wallet.addTransactionLogMessageSuccess("Received " + amount + " FUC from " + source.path().name());
                 // recipient should notify a possible observer
-                if (observer != null){
-                   observer.tell(new ActionNotifyObserver(source,target,amount,granted,timestamp, id), self);
+                if (observer != null) {
+                    observer.tell(new ActionNotifyObserver(source, target, amount, granted, timestamp, id), self);
                 }
-
             }
 
         } else {
@@ -70,8 +69,8 @@ public class ActionCommitDistributedCommittedTransfer extends ClientAction {
 
             if (source.compareTo(self) == 0) {
                 wallet.addTransactionLogMessageFail("Failed to send " + amount + " FUC to " + target.path().name() + " (Commit has not been granted)");
-                if (observer != null){
-                    observer.tell(new ActionNotifyObserver(source,target,amount,granted,timestamp, id), self);
+                if (observer != null) {
+                    observer.tell(new ActionNotifyObserver(source, target, amount, granted, timestamp, id), self);
                 }
             }
 
diff --git a/src/main/java/fucoin/actions/transaction/ActionPrepareDistributedCommittedTransfer.java b/src/main/java/fucoin/actions/transaction/ActionPrepareDistributedCommittedTransfer.java
index bb961e8..9971786 100644
--- a/src/main/java/fucoin/actions/transaction/ActionPrepareDistributedCommittedTransfer.java
+++ b/src/main/java/fucoin/actions/transaction/ActionPrepareDistributedCommittedTransfer.java
@@ -38,7 +38,6 @@ public class ActionPrepareDistributedCommittedTransfer extends Transaction {
         wallet.amounts.put(source, sourceAmount - amount);
         wallet.amounts.put(target, targetAmount + amount);
 
-
         sender.tell(new ActionPrepareDistributedCommittedTransferAnswer(source, target, amount, timestamp, granted, id), self);
     }
 
diff --git a/src/main/java/fucoin/configurations/AbstractConfiguration.java b/src/main/java/fucoin/configurations/AbstractConfiguration.java
index 3693fdd..8493704 100644
--- a/src/main/java/fucoin/configurations/AbstractConfiguration.java
+++ b/src/main/java/fucoin/configurations/AbstractConfiguration.java
@@ -6,7 +6,11 @@ import akka.pattern.Patterns;
 import akka.util.Timeout;
 import fucoin.AbstractNode;
 import fucoin.actions.control.ActionAnnounceWalletCreation;
+import fucoin.actions.control.ActionWalletSendMoney;
 import fucoin.actions.join.ActionTellSupervisor;
+import fucoin.actions.transaction.ActionGetAmount;
+import fucoin.actions.transaction.ActionGetAmountAnswer;
+import fucoin.actions.transaction.ActionNotifyObserver;
 import fucoin.configurations.internal.ConfigurationCreator;
 import fucoin.supervisor.SuperVisorImpl;
 import fucoin.wallet.WalletImpl;
@@ -15,6 +19,7 @@ import scala.concurrent.Future;
 import scala.concurrent.duration.Duration;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.ThreadLocalRandom;
 
@@ -29,6 +34,8 @@ public abstract class AbstractConfiguration extends AbstractNode {
 
     private Timeout timeout = new Timeout(Duration.create(10, "seconds"));
 
+    private int remainingTransactions;
+
     public static Props props(Class configurationClass) {
 
         return Props.create(new ConfigurationCreator(configurationClass));
@@ -36,6 +43,7 @@ public abstract class AbstractConfiguration extends AbstractNode {
 
     /**
      * Spawns a new wallet and blocks until it has received its initial money
+     *
      * @throws Exception on timeout
      */
     ActorRef spawnWallet(String name, boolean createGUI) throws Exception {
@@ -70,6 +78,7 @@ public abstract class AbstractConfiguration extends AbstractNode {
 
     /**
      * Spawn multiple wallets and wait until they all have their initial FUC
+     *
      * @throws Exception on timeout
      */
     public void spawnWallets(int n, boolean createGUI) throws Exception {
@@ -92,6 +101,43 @@ public abstract class AbstractConfiguration extends AbstractNode {
         return this.activeActors;
     }
 
+    protected void randomTransactions(int number, int maxTransactionsAtTheSameTime) {
+
+        remainingTransactions = number;
+
+        for (int i = 0; i < Math.min(number, maxTransactionsAtTheSameTime); i++) {
+            nextRandomTransaction();
+        }
+
+    }
+
+    private void nextRandomTransaction() {
+        remainingTransactions--;
+        try {
+            randomTransaction();
+        } catch (Exception e) {
+            System.err.println("Error while trying to perform a random transaction: "+e.getMessage());
+            remainingTransactions = 0;
+        }
+    }
+
+    private void randomTransaction() throws Exception {
+        List<ActorRef> wallets = wallets();
+        Collections.shuffle(wallets);
+
+        ActorRef sender = wallets.get(0);
+        ActorRef recipient = wallets.get(1);
+
+
+        Future<Object> future = Patterns.ask(sender, new ActionGetAmount(), timeout);
+        ActionGetAmountAnswer answer = (ActionGetAmountAnswer) Await.result(future, timeout.duration());
+
+        int transferAmount = 1 + ThreadLocalRandom.current().nextInt(answer.amount);
+
+        sender.tell(new ActionWalletSendMoney(recipient.path().name(), transferAmount, self()), self());
+    }
+
+
     /**
      * Create the supervisor node
      */
@@ -107,6 +153,26 @@ public abstract class AbstractConfiguration extends AbstractNode {
         return superVisor;
     }
 
+    @Override
+    public void onReceive(Object message) {
+        if (message instanceof ActionNotifyObserver) {
+
+            ActionNotifyObserver notification = (ActionNotifyObserver) message;
+
+            String status = "successful";
+            if (!notification.granted) {
+                status = "failed";
+            }
+
+            System.out.println("Observed a " + status + " transaction of " + notification.amount + " FUCs from " +
+                    notification.source.path().name() + " to " + notification.target.path().name());
+
+            if (remainingTransactions > 0) {
+                nextRandomTransaction();
+            }
+        }
+    }
+
     @Override
     public void preStart() throws Exception {
         super.preStart();
diff --git a/src/main/java/fucoin/configurations/DefaultConfiguration.java b/src/main/java/fucoin/configurations/DefaultConfiguration.java
index a837c17..403d071 100644
--- a/src/main/java/fucoin/configurations/DefaultConfiguration.java
+++ b/src/main/java/fucoin/configurations/DefaultConfiguration.java
@@ -14,7 +14,7 @@ import scala.concurrent.duration.Duration;
 
 import java.util.Collections;
 import java.util.List;
-import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
 
 /**
  * This configuration is the previous default of 2 wallets with GUI and a supervisor.
@@ -22,10 +22,11 @@ import java.util.Random;
 @ConfigurationName("Default Configuration")
 public class DefaultConfiguration extends AbstractConfiguration {
 
-    private Random rand;
+    private ThreadLocalRandom rand;
+    private Timeout timeout = new Timeout(Duration.create(10, "seconds"));
 
     public DefaultConfiguration(){
-        rand = new Random();
+        rand = ThreadLocalRandom.current();
     }
 
     @Override
@@ -44,47 +45,16 @@ public class DefaultConfiguration extends AbstractConfiguration {
         } catch (Exception e) {
             System.out.println("Wallet1 spawning timed out");
         }
-/*
+
         if (wallet1 != null && wallet2 != null) {
             wallet1.tell(new ActionWalletSendMoney(wallet2.path().name(), 50, getSelf()), wallet1);
         }
-        */
-        try {
-            randomTransaction();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    private void randomTransaction() throws Exception{
-        List<ActorRef> wallets = wallets();
-        Collections.shuffle(wallets);
-
-        ActorRef sender = wallets.get(0);
-        ActorRef recipient = wallets.get(1);
 
-        Timeout timeout = new Timeout(Duration.create(10, "seconds"));
-        Future<Object> future = Patterns.ask(sender, new ActionGetAmount(), timeout);
-        ActionGetAmountAnswer answer = (ActionGetAmountAnswer) Await.result(future, timeout.duration());
-
-        int transferAmount = rand.nextInt(answer.amount);
-
-        sender.tell(new ActionWalletSendMoney(recipient.path().name(), transferAmount, self()), self());
     }
 
+
     @Override
     public void onReceive(Object message) {
-        if (message instanceof ActionNotifyObserver){
-            ActionNotifyObserver notification = (ActionNotifyObserver) message;
-
-            String status = "successful";
-            if(! notification.granted){
-                status = "failed";
-            }
-
-            System.out.println("Observed a " + status + " transaction of " + notification.amount+" FUCs from " +
-                    notification.source.path().name() + " to " + notification.target.path().name());
-        }
-
+        super.onReceive(message);
     }
 }
diff --git a/src/main/java/fucoin/configurations/MassWalletConfiguration.java b/src/main/java/fucoin/configurations/MassWalletConfiguration.java
index e2d3c0a..fcaaadf 100644
--- a/src/main/java/fucoin/configurations/MassWalletConfiguration.java
+++ b/src/main/java/fucoin/configurations/MassWalletConfiguration.java
@@ -16,10 +16,12 @@ public class MassWalletConfiguration extends AbstractConfiguration {
         } catch (Exception e) {
             System.out.println("Wallet spawning timed out!");
         }
+
+        randomTransactions(100, 10);
     }
 
     @Override
     public void onReceive(Object message) {
-
+        super.onReceive(message);
     }
 }
-- 
GitLab