From 1c413a97efba80faf08190565d6dea10b559508a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20K=C3=B6nnecke?= <simonkoennecke@gmail.com>
Date: Sun, 3 Jul 2016 23:47:54 +0200
Subject: [PATCH] moved SuperVisorAction class, create statistic class and
 added to wallet, add snapshot (as json files), create new configuration
 called Statistics, automated communication between wallets over
 StatisticsWalletConfiguration

---
 .gitignore                                    |   1 +
 pom.xml                                       |   7 ++
 src/main/java/fucoin/AbstractNode.java        |  34 +++++-
 .../{transaction => }/SuperVisorAction.java   |   2 +-
 .../control/ActionAnnounceWalletCreation.java |   2 +-
 .../ActionCreateSuperVisorSnapshot.java       |  26 +++++
 .../control/ActionCreateWalletSnapshot.java   |  29 +++++
 .../fucoin/actions/join/ServerActionJoin.java |   2 +-
 .../statistics/ActionInterchangeState.java    |  26 +++++
 .../transaction/CoordinatorTransaction.java   |   1 +
 .../configurations/AbstractConfiguration.java |   6 +-
 .../MassWalletConfiguration.java              |   2 +-
 .../StatisticsWalletConfiguration.java        | 102 ++++++++++++++++++
 .../java/fucoin/gui/SuperVisorGuiControl.java |   6 +-
 .../fucoin/gui/SuperVisorGuiControlImpl.java  |   5 +
 .../fucoin/supervisor/ActionUpdateQueue.java  |   2 +-
 .../fucoin/supervisor/AmountTableModel.java   |   4 +-
 .../fucoin/supervisor/SuperVisorImpl.java     |  15 ++-
 .../java/fucoin/wallet/AbstractWallet.java    |  15 +++
 src/main/java/fucoin/wallet/WalletImpl.java   |  39 ++++++-
 .../java/fucoin/wallet/WalletStatistics.java  |  65 +++++++++++
 21 files changed, 372 insertions(+), 19 deletions(-)
 rename src/main/java/fucoin/actions/{transaction => }/SuperVisorAction.java (80%)
 create mode 100644 src/main/java/fucoin/actions/control/ActionCreateSuperVisorSnapshot.java
 create mode 100644 src/main/java/fucoin/actions/control/ActionCreateWalletSnapshot.java
 create mode 100644 src/main/java/fucoin/actions/statistics/ActionInterchangeState.java
 create mode 100644 src/main/java/fucoin/configurations/StatisticsWalletConfiguration.java
 create mode 100644 src/main/java/fucoin/wallet/WalletStatistics.java

diff --git a/.gitignore b/.gitignore
index 064cdbf..02efb3d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
 .idea/
 *.iml
 .DS_Store
+snapshots
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 1a37142..b32c125 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,5 +56,12 @@
             <artifactId>reflections</artifactId>
             <version>0.9.10</version>
         </dependency>
+        <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.7</version>
+        </dependency>
+
     </dependencies>
 </project>
\ No newline at end of file
diff --git a/src/main/java/fucoin/AbstractNode.java b/src/main/java/fucoin/AbstractNode.java
index 9777980..fb3d50e 100644
--- a/src/main/java/fucoin/AbstractNode.java
+++ b/src/main/java/fucoin/AbstractNode.java
@@ -3,10 +3,18 @@ package fucoin;
 import akka.actor.ActorRef;
 import akka.actor.Address;
 import akka.actor.UntypedActor;
+import com.google.gson.ExclusionStrategy;
+import com.google.gson.FieldAttributes;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
 import fucoin.actions.transaction.ActionGetAmount;
 import fucoin.wallet.AbstractWallet;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
 import java.io.Serializable;
+import java.time.LocalTime;
 import java.util.HashMap;
 
 public abstract class AbstractNode extends UntypedActor implements Serializable {
@@ -68,4 +76,28 @@ public abstract class AbstractNode extends UntypedActor implements Serializable
     public HashMap<String, ActorRef> getKnownNeighbors() {
         return knownNeighbors;
     }
-}
\ No newline at end of file
+
+    public void createDump(String name, String content, LocalTime time) {
+        String filename = "snapshots/Dump_" + time.getNano() + "_" + name + ".json";
+
+        try {
+            File theDir = new File("snapshots");
+
+            // if the directory does not exist, create it
+            if (!theDir.exists()) {
+                theDir.mkdir();
+            }
+
+            File myFile = new File(filename);
+            myFile.createNewFile();
+            FileOutputStream fOut = new FileOutputStream(myFile);
+            OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
+            myOutWriter.append(content);
+            myOutWriter.close();
+            fOut.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
+
diff --git a/src/main/java/fucoin/actions/transaction/SuperVisorAction.java b/src/main/java/fucoin/actions/SuperVisorAction.java
similarity index 80%
rename from src/main/java/fucoin/actions/transaction/SuperVisorAction.java
rename to src/main/java/fucoin/actions/SuperVisorAction.java
index 19e93a8..1cae3ea 100644
--- a/src/main/java/fucoin/actions/transaction/SuperVisorAction.java
+++ b/src/main/java/fucoin/actions/SuperVisorAction.java
@@ -1,4 +1,4 @@
-package fucoin.actions.transaction;
+package fucoin.actions;
 
 import fucoin.actions.Action;
 import fucoin.supervisor.SuperVisorImpl;
diff --git a/src/main/java/fucoin/actions/control/ActionAnnounceWalletCreation.java b/src/main/java/fucoin/actions/control/ActionAnnounceWalletCreation.java
index ee897f7..205424d 100644
--- a/src/main/java/fucoin/actions/control/ActionAnnounceWalletCreation.java
+++ b/src/main/java/fucoin/actions/control/ActionAnnounceWalletCreation.java
@@ -2,7 +2,7 @@ package fucoin.actions.control;
 
 import akka.actor.ActorRef;
 import akka.actor.UntypedActorContext;
-import fucoin.actions.transaction.SuperVisorAction;
+import fucoin.actions.SuperVisorAction;
 import fucoin.supervisor.SuperVisorImpl;
 
 /**
diff --git a/src/main/java/fucoin/actions/control/ActionCreateSuperVisorSnapshot.java b/src/main/java/fucoin/actions/control/ActionCreateSuperVisorSnapshot.java
new file mode 100644
index 0000000..7bfa9d1
--- /dev/null
+++ b/src/main/java/fucoin/actions/control/ActionCreateSuperVisorSnapshot.java
@@ -0,0 +1,26 @@
+package fucoin.actions.control;
+
+import akka.actor.ActorRef;
+import akka.actor.UntypedActorContext;
+import fucoin.actions.SuperVisorAction;
+import fucoin.supervisor.SuperVisorImpl;
+
+import java.time.LocalTime;
+
+public class ActionCreateSuperVisorSnapshot extends SuperVisorAction {
+    /**
+     * Timestamp for the file name
+     */
+    private final LocalTime time;
+
+
+    public ActionCreateSuperVisorSnapshot(LocalTime time) {
+        this.time = time;
+    }
+
+
+    @Override
+    protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, SuperVisorImpl abstractNode) {
+        abstractNode.createDump(time);
+    }
+}
diff --git a/src/main/java/fucoin/actions/control/ActionCreateWalletSnapshot.java b/src/main/java/fucoin/actions/control/ActionCreateWalletSnapshot.java
new file mode 100644
index 0000000..f730419
--- /dev/null
+++ b/src/main/java/fucoin/actions/control/ActionCreateWalletSnapshot.java
@@ -0,0 +1,29 @@
+package fucoin.actions.control;
+
+import akka.actor.ActorRef;
+import akka.actor.UntypedActorContext;
+import com.google.gson.Gson;
+import fucoin.actions.ClientAction;
+import fucoin.wallet.AbstractWallet;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.time.LocalTime;
+
+public class ActionCreateWalletSnapshot extends ClientAction {
+    /**
+     * Timestamp for the file name
+     */
+    private final LocalTime time;
+
+
+    public ActionCreateWalletSnapshot(LocalTime time) {
+        this.time = time;
+    }
+
+    @Override
+    protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, AbstractWallet abstractNode) {
+        abstractNode.createDump(time);
+    }
+}
diff --git a/src/main/java/fucoin/actions/join/ServerActionJoin.java b/src/main/java/fucoin/actions/join/ServerActionJoin.java
index 18a1cf6..f203170 100644
--- a/src/main/java/fucoin/actions/join/ServerActionJoin.java
+++ b/src/main/java/fucoin/actions/join/ServerActionJoin.java
@@ -3,7 +3,7 @@ package fucoin.actions.join;
 import akka.actor.ActorRef;
 import akka.actor.UntypedActorContext;
 import fucoin.actions.transaction.ActionInvokeDistributedCommittedTransfer;
-import fucoin.actions.transaction.SuperVisorAction;
+import fucoin.actions.SuperVisorAction;
 import fucoin.supervisor.SuperVisorImpl;
 
 /**
diff --git a/src/main/java/fucoin/actions/statistics/ActionInterchangeState.java b/src/main/java/fucoin/actions/statistics/ActionInterchangeState.java
new file mode 100644
index 0000000..8d06ab5
--- /dev/null
+++ b/src/main/java/fucoin/actions/statistics/ActionInterchangeState.java
@@ -0,0 +1,26 @@
+package fucoin.actions.statistics;
+
+import akka.actor.ActorRef;
+import akka.actor.UntypedActorContext;
+import fucoin.actions.ClientAction;
+import fucoin.wallet.AbstractWallet;
+import fucoin.wallet.WalletStatistics;
+
+/**
+ * Wallet A sends a Wallet B current Amount and statistic's.
+ * Wallet B updates his statistic's.
+ * @see WalletStatistics
+ */
+public class ActionInterchangeState extends ClientAction {
+
+    private final int currentAmount;
+
+    public ActionInterchangeState(int currentAmount) {
+        this.currentAmount = currentAmount;
+    }
+
+    @Override
+    protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, AbstractWallet abstractNode) {
+        abstractNode.getStatistics().update(currentAmount);
+    }
+}
diff --git a/src/main/java/fucoin/actions/transaction/CoordinatorTransaction.java b/src/main/java/fucoin/actions/transaction/CoordinatorTransaction.java
index b28dc56..d9844e0 100644
--- a/src/main/java/fucoin/actions/transaction/CoordinatorTransaction.java
+++ b/src/main/java/fucoin/actions/transaction/CoordinatorTransaction.java
@@ -2,6 +2,7 @@ package fucoin.actions.transaction;
 
 import akka.actor.ActorRef;
 import akka.actor.UntypedActorContext;
+import fucoin.actions.SuperVisorAction;
 import fucoin.supervisor.SuperVisorImpl;
 
 public abstract class CoordinatorTransaction extends SuperVisorAction {
diff --git a/src/main/java/fucoin/configurations/AbstractConfiguration.java b/src/main/java/fucoin/configurations/AbstractConfiguration.java
index 8493704..8fb57e7 100644
--- a/src/main/java/fucoin/configurations/AbstractConfiguration.java
+++ b/src/main/java/fucoin/configurations/AbstractConfiguration.java
@@ -28,11 +28,11 @@ import java.util.concurrent.ThreadLocalRandom;
  */
 public abstract class AbstractConfiguration extends AbstractNode {
 
-    private ActorRef superVisor;
+    protected ActorRef superVisor;
 
-    private final List<ActorRef> activeActors = new ArrayList<>();
+    protected final List<ActorRef> activeActors = new ArrayList<>();
 
-    private Timeout timeout = new Timeout(Duration.create(10, "seconds"));
+    protected Timeout timeout = new Timeout(Duration.create(10, "seconds"));
 
     private int remainingTransactions;
 
diff --git a/src/main/java/fucoin/configurations/MassWalletConfiguration.java b/src/main/java/fucoin/configurations/MassWalletConfiguration.java
index fcaaadf..b0f222f 100644
--- a/src/main/java/fucoin/configurations/MassWalletConfiguration.java
+++ b/src/main/java/fucoin/configurations/MassWalletConfiguration.java
@@ -11,7 +11,7 @@ public class MassWalletConfiguration extends AbstractConfiguration {
     public void run() {
         initSupervisor();
         try {
-            spawnWallets(200, false);
+            spawnWallets(20, false);
             System.out.println("Wallet spawning done!");
         } catch (Exception e) {
             System.out.println("Wallet spawning timed out!");
diff --git a/src/main/java/fucoin/configurations/StatisticsWalletConfiguration.java b/src/main/java/fucoin/configurations/StatisticsWalletConfiguration.java
new file mode 100644
index 0000000..5a5fc7c
--- /dev/null
+++ b/src/main/java/fucoin/configurations/StatisticsWalletConfiguration.java
@@ -0,0 +1,102 @@
+package fucoin.configurations;
+
+import akka.actor.ActorRef;
+import akka.pattern.Patterns;
+import fucoin.actions.control.ActionCreateSuperVisorSnapshot;
+import fucoin.actions.control.ActionCreateWalletSnapshot;
+import fucoin.actions.statistics.ActionInterchangeState;
+import fucoin.actions.transaction.ActionGetAmount;
+import fucoin.actions.transaction.ActionGetAmountAnswer;
+import fucoin.configurations.internal.ConfigurationName;
+import scala.concurrent.Await;
+import scala.concurrent.Future;
+
+import java.time.LocalTime;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This configuration spawns 200 wallets to demonstrate the spawning of many headless wallets
+ */
+@ConfigurationName("Statistics")
+public class StatisticsWalletConfiguration extends AbstractConfiguration {
+    /**
+     * Spawn the number of wallets.
+     */
+    private final static int sNumberOfWallets = 10;
+
+    private int numberOfInterchangeStatistic = 20;
+
+    @Override
+    public void run() {
+        initSupervisor();
+        try {
+            spawnWallets(sNumberOfWallets, false);
+            System.out.println("Wallet spawning done!");
+        } catch (Exception e) {
+            System.out.println("Wallet spawning timed out!");
+        }
+
+        randomTransactions(10, 10);
+
+        try {
+            //Busy wait
+            while (activeActors.size() < sNumberOfWallets) {
+
+            }
+            try {
+                Thread.sleep(4000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            System.out.println("=========== Stats runs");
+            interchangeStatistic();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void interchangeStatistic() throws Exception {
+        if (!(numberOfInterchangeStatistic > 0)) {
+            //stop interchange statistics
+            return;
+        }
+
+        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());
+
+        recipient.tell(new ActionInterchangeState(answer.amount), sender);
+
+        numberOfInterchangeStatistic--;
+        if (numberOfInterchangeStatistic == 0) {
+            createDump();
+        } else {
+            interchangeStatistic();
+        }
+    }
+
+    /**
+     * Create a Dump of the SuperVisor and all active Wallets.
+     */
+    private void createDump() {
+        System.out.println("Create Dumps");
+        LocalTime time = LocalTime.now();
+        superVisor.tell(new ActionCreateSuperVisorSnapshot(time), superVisor);
+        for (ActorRef wallet: activeActors) {
+            wallet.tell(new ActionCreateWalletSnapshot(time), wallet);
+        }
+    }
+
+    @Override
+    public void onReceive(Object message) {
+        super.onReceive(message);
+    }
+
+
+}
diff --git a/src/main/java/fucoin/gui/SuperVisorGuiControl.java b/src/main/java/fucoin/gui/SuperVisorGuiControl.java
index b8b29e5..9c2fbef 100644
--- a/src/main/java/fucoin/gui/SuperVisorGuiControl.java
+++ b/src/main/java/fucoin/gui/SuperVisorGuiControl.java
@@ -1,5 +1,7 @@
 package fucoin.gui;
 
+import fucoin.supervisor.AmountTableModel;
+
 public interface SuperVisorGuiControl extends TransactionLogger {
 
     /**
@@ -7,6 +9,8 @@ public interface SuperVisorGuiControl extends TransactionLogger {
      */
     void onLeave();
 
-    public void updateTable(String address, String name, int amount);
+    void updateTable(String address, String name, int amount);
+
+    AmountTableModel getTable();
 
 }
diff --git a/src/main/java/fucoin/gui/SuperVisorGuiControlImpl.java b/src/main/java/fucoin/gui/SuperVisorGuiControlImpl.java
index b0c9a12..f5d75e4 100644
--- a/src/main/java/fucoin/gui/SuperVisorGuiControlImpl.java
+++ b/src/main/java/fucoin/gui/SuperVisorGuiControlImpl.java
@@ -48,6 +48,11 @@ public class SuperVisorGuiControlImpl implements SuperVisorGuiControl {
         this.amountTableModel.updateTable(address, name, amount);
     }
 
+    @Override
+    public AmountTableModel getTable() {
+        return this.amountTableModel;
+    }
+
     private void log(LogMessage logMessage) {
         if (logActive) {
             threadGUI.log(logMessage);
diff --git a/src/main/java/fucoin/supervisor/ActionUpdateQueue.java b/src/main/java/fucoin/supervisor/ActionUpdateQueue.java
index e15ce4b..81ac1a5 100644
--- a/src/main/java/fucoin/supervisor/ActionUpdateQueue.java
+++ b/src/main/java/fucoin/supervisor/ActionUpdateQueue.java
@@ -3,7 +3,7 @@ package fucoin.supervisor;
 import akka.actor.ActorRef;
 import akka.actor.UntypedActorContext;
 import fucoin.actions.transaction.ActionCommitDistributedCommittedTransfer;
-import fucoin.actions.transaction.SuperVisorAction;
+import fucoin.actions.SuperVisorAction;
 
 import java.util.List;
 
diff --git a/src/main/java/fucoin/supervisor/AmountTableModel.java b/src/main/java/fucoin/supervisor/AmountTableModel.java
index 80378e9..8ed4172 100644
--- a/src/main/java/fucoin/supervisor/AmountTableModel.java
+++ b/src/main/java/fucoin/supervisor/AmountTableModel.java
@@ -1,10 +1,10 @@
 package fucoin.supervisor;
 
-import javax.swing.*;
 import javax.swing.table.DefaultTableModel;
+import java.io.Serializable;
 import java.util.Vector;
 
-public class AmountTableModel extends DefaultTableModel {
+public class AmountTableModel extends DefaultTableModel implements Serializable {
 
     public AmountTableModel() {
         super(new Object[]{"Address", "Name", "Amount"}, 0);
diff --git a/src/main/java/fucoin/supervisor/SuperVisorImpl.java b/src/main/java/fucoin/supervisor/SuperVisorImpl.java
index 8b4ec17..9b9778b 100644
--- a/src/main/java/fucoin/supervisor/SuperVisorImpl.java
+++ b/src/main/java/fucoin/supervisor/SuperVisorImpl.java
@@ -2,17 +2,19 @@ package fucoin.supervisor;
 
 import akka.actor.ActorRef;
 import akka.actor.Props;
+import com.google.gson.Gson;
 import fucoin.actions.Action;
 import fucoin.actions.control.ActionWalletCreationDone;
 import fucoin.actions.persist.ActionInvokeUpdate;
 import fucoin.actions.transaction.ActionGetAmountAnswer;
 import fucoin.actions.transaction.ActionNotifyObserver;
-import fucoin.actions.transaction.SuperVisorAction;
+import fucoin.actions.SuperVisorAction;
 import fucoin.gui.SuperVisorGuiControl;
 import fucoin.AbstractNode;
 import fucoin.gui.TransactionLogger;
 
 import javax.swing.*;
+import java.time.LocalTime;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -23,12 +25,12 @@ public class SuperVisorImpl extends AbstractNode implements TransactionLogger {
 
     //private AmountTableModel amountTableModel;
 
-    private Map<Long, DistributedCommittedTransferRequest> requestQueue;
+    private transient Map<Long, DistributedCommittedTransferRequest> requestQueue;
 
-    private SuperVisorGuiControl gui;
+    private transient SuperVisorGuiControl gui;
 
     private int pendingBankCommits = 0;
-    private ActorRef bankCommitObserver = null;
+    private transient ActorRef bankCommitObserver = null;
 
     public SuperVisorImpl() {
 
@@ -167,4 +169,9 @@ public class SuperVisorImpl extends AbstractNode implements TransactionLogger {
     public void setBankCommitObserver(ActorRef bankCommitObserver) {
         this.bankCommitObserver = bankCommitObserver;
     }
+
+    public void createDump(LocalTime time) {
+        String str = new Gson().toJson(this.gui.getTable());
+        super.createDump("SuperVisor", str, time);
+    }
 }
diff --git a/src/main/java/fucoin/wallet/AbstractWallet.java b/src/main/java/fucoin/wallet/AbstractWallet.java
index 882c2a5..ec1e0ae 100644
--- a/src/main/java/fucoin/wallet/AbstractWallet.java
+++ b/src/main/java/fucoin/wallet/AbstractWallet.java
@@ -6,12 +6,17 @@ import fucoin.gui.TransactionLogger;
 import scala.concurrent.Future;
 
 import java.io.Serializable;
+import java.time.LocalTime;
 
 /**
  *
  */
 public abstract class AbstractWallet extends AbstractNode implements Serializable, TransactionLogger {
 
+    /**
+     *
+     */
+    protected WalletStatistics statistics = new WalletStatistics();
     /**
      * Currently amount of this wallet
      */
@@ -77,6 +82,14 @@ public abstract class AbstractWallet extends AbstractNode implements Serializabl
      */
     public abstract void setActive(boolean isActive);
 
+    public WalletStatistics getStatistics() {
+        return statistics;
+    }
+
+    public void setStatistics(WalletStatistics statistics) {
+        this.statistics = statistics;
+    }
+
     /**
      * Returns the
      *
@@ -114,4 +127,6 @@ public abstract class AbstractWallet extends AbstractNode implements Serializabl
      * @param observer
      */
     public abstract void send(String address, int amount, ActorRef observer);
+
+    public abstract void createDump(LocalTime time);
 }
diff --git a/src/main/java/fucoin/wallet/WalletImpl.java b/src/main/java/fucoin/wallet/WalletImpl.java
index 951a151..f25e0a0 100644
--- a/src/main/java/fucoin/wallet/WalletImpl.java
+++ b/src/main/java/fucoin/wallet/WalletImpl.java
@@ -2,6 +2,10 @@ package fucoin.wallet;
 
 import akka.actor.ActorRef;
 import akka.actor.Props;
+import com.google.gson.ExclusionStrategy;
+import com.google.gson.FieldAttributes;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
 import fucoin.actions.ClientAction;
 import fucoin.actions.join.ActionJoin;
 import fucoin.actions.join.ActionJoinAnswer;
@@ -16,16 +20,17 @@ import scala.concurrent.Future;
 
 import static akka.dispatch.Futures.future;
 
+import java.time.LocalTime;
 import java.util.concurrent.ConcurrentLinkedQueue;
 
 public class WalletImpl extends AbstractWallet {
 
-    private ActorRef preKnownNeighbour;
-    private ActorRef remoteSuperVisorActor;
+    private transient ActorRef preKnownNeighbour;
+    private transient ActorRef remoteSuperVisorActor;
     private transient WalletGuiControl gui;
     private String preKnownNeighbourName;
     private boolean isActive;
-    private ConcurrentLinkedQueue<ActorRef> deferedSupervisorReceivers = new ConcurrentLinkedQueue<>();
+    private transient ConcurrentLinkedQueue<ActorRef> deferedSupervisorReceivers = new ConcurrentLinkedQueue<>();
 
     public WalletImpl(String name) {
         super(name);
@@ -245,4 +250,32 @@ public class WalletImpl extends AbstractWallet {
             System.out.println(message);
         }
     }
+
+    public void createDump(LocalTime time){
+        Gson gson = new GsonBuilder()
+                .setExclusionStrategies(new ExcludeAttributes())
+                //.serializeNulls() <-- uncomment to serialize NULL fields as well
+                .create();
+        String s = gson.toJson(this);
+        super.createDump(getName(), s, time);
+    }
+
+    class ExcludeAttributes implements ExclusionStrategy {
+
+        public boolean shouldSkipClass(Class<?> arg0) {
+            return false;
+        }
+
+        public boolean shouldSkipField(FieldAttributes f) {
+
+            return !(f.getName().equals("statistics") ||
+                     f.getName().equals("min") ||
+                     f.getName().equals("max") ||
+                     f.getName().equals("sum") ||
+                     f.getName().equals("count") ||
+                     f.getName().equals("amount") ||
+                     f.getName().equals("name"));
+        }
+
+    }
 }
diff --git a/src/main/java/fucoin/wallet/WalletStatistics.java b/src/main/java/fucoin/wallet/WalletStatistics.java
new file mode 100644
index 0000000..833fa21
--- /dev/null
+++ b/src/main/java/fucoin/wallet/WalletStatistics.java
@@ -0,0 +1,65 @@
+package fucoin.wallet;
+
+import java.io.Serializable;
+
+/**
+ *
+ */
+public class WalletStatistics implements Serializable {
+    private int min;
+    private int max;
+    private int sum;
+    private int count;
+
+    public WalletStatistics() {
+        this.min = Integer.MAX_VALUE;
+        this.max = Integer.MIN_VALUE;
+        this.sum = 0;
+        this.count = 0;
+    }
+
+    public WalletStatistics(int min, int max, int sum, int count) {
+        this.min = min;
+        this.max = max;
+        this.sum = sum;
+        this.count = count;
+    }
+
+    public void update(int currentWalletAmount) {
+        setMin(currentWalletAmount);
+        setMax(currentWalletAmount);
+        setSum(currentWalletAmount);
+    }
+
+    public int getMin() {
+        return min;
+    }
+
+    public void setMin(int min) {
+        this.min = Math.min(this.min, min);
+    }
+
+    public int getMax() {
+        return max;
+    }
+
+    public void setMax(int max) {
+        this.max = Math.max(this.max, max);
+    }
+
+    public int getSum() {
+        return sum;
+    }
+
+    public void setSum(int sum) {
+        this.sum = (this.sum + sum) / 2;
+    }
+
+    public int getCount() {
+        return count;
+    }
+
+    public void setCount(int count) {
+        this.count = (this.count + count) / 2;
+    }
+}
-- 
GitLab