From f45af81d512699b78a59ab869bb43c6b50b9fe44 Mon Sep 17 00:00:00 2001
From: Luca Keidel <info@lucakeidel.de>
Date: Wed, 22 Jun 2016 16:48:40 +0200
Subject: [PATCH] Provisional fix of double spending/agreeing

Before it was possible that a wallet was able to spend more money than it has. The cause were two pending distributed commits in the system at the same time. Since the wallets only update their ledger when the supervisor sends the commit message, they also agreed to the second request because their ledger was not updated. However, the second request could exceed the rest amount of FUCs in the ledger
---
 src/main/java/fucoin/Main.java                        |  2 +-
 .../ActionCommitDistributedCommittedTransfer.java     | 11 ++++++-----
 .../ActionPrepareDistributedCommittedTransfer.java    |  7 +++++++
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/src/main/java/fucoin/Main.java b/src/main/java/fucoin/Main.java
index f992c44..73f9b8d 100644
--- a/src/main/java/fucoin/Main.java
+++ b/src/main/java/fucoin/Main.java
@@ -18,7 +18,7 @@ import java.util.List;
 public class Main {
 
     private static int numberOfWallets = 2;
-    private static boolean createGUI = false;
+    private static boolean createGUI = true;
 
     private static ActorSystem cSystem;
 
diff --git a/src/main/java/fucoin/actions/transaction/ActionCommitDistributedCommittedTransfer.java b/src/main/java/fucoin/actions/transaction/ActionCommitDistributedCommittedTransfer.java
index 6c4b480..1d1a7b2 100644
--- a/src/main/java/fucoin/actions/transaction/ActionCommitDistributedCommittedTransfer.java
+++ b/src/main/java/fucoin/actions/transaction/ActionCommitDistributedCommittedTransfer.java
@@ -42,11 +42,6 @@ public class ActionCommitDistributedCommittedTransfer extends ClientAction {
         wallet.addLogMsg("ActionCommitDistributedCommittedTransfer is granted? " + granted);
         if (granted) {
 
-            Integer sourceAmount = wallet.amounts.getOrDefault(source, 0);
-            Integer targetAmount = wallet.amounts.getOrDefault(target, 0);
-            wallet.amounts.put(source, sourceAmount - amount);
-            wallet.amounts.put(target, targetAmount + amount);
-
             if (source.compareTo(self) == 0) {
                 wallet.setAmount(wallet.getAmount() - amount);
                 wallet.addTransactionLogMessageSuccess("Sent " + amount + " FUC to " + target.path().name());
@@ -58,6 +53,12 @@ public class ActionCommitDistributedCommittedTransfer extends ClientAction {
         } else {
             wallet.addLogMsg("abort transaction with id" + id);
 
+            // rollback
+            Integer sourceAmount = wallet.amounts.getOrDefault(source, 0);
+            Integer targetAmount = wallet.amounts.getOrDefault(target, 0);
+            wallet.amounts.put(source, sourceAmount + amount);
+            wallet.amounts.put(target, targetAmount - amount);
+
             if (source.compareTo(self) == 0) {
                 wallet.addTransactionLogMessageFail("Failed to send " + amount + " FUC to " + target.path().name() + " (Commit has not been granted)");
             }
diff --git a/src/main/java/fucoin/actions/transaction/ActionPrepareDistributedCommittedTransfer.java b/src/main/java/fucoin/actions/transaction/ActionPrepareDistributedCommittedTransfer.java
index 7e7de88..bb961e8 100644
--- a/src/main/java/fucoin/actions/transaction/ActionPrepareDistributedCommittedTransfer.java
+++ b/src/main/java/fucoin/actions/transaction/ActionPrepareDistributedCommittedTransfer.java
@@ -32,6 +32,13 @@ public class ActionPrepareDistributedCommittedTransfer extends Transaction {
                         //sender have enough money
                         && wallet.amounts.getOrDefault(source, 0) >= amount));
 
+        // precautionly update own ledger to prevent double spending (respectively agreeing)
+        Integer sourceAmount = wallet.amounts.getOrDefault(source, 0);
+        Integer targetAmount = wallet.amounts.getOrDefault(target, 0);
+        wallet.amounts.put(source, sourceAmount - amount);
+        wallet.amounts.put(target, targetAmount + amount);
+
+
         sender.tell(new ActionPrepareDistributedCommittedTransferAnswer(source, target, amount, timestamp, granted, id), self);
     }
 
-- 
GitLab