From 19f276af78392fd6acce545972b32f79b64632b4 Mon Sep 17 00:00:00 2001
From: capossele <angelocapossele@gmail.com>
Date: Thu, 19 Dec 2019 10:35:00 +0000
Subject: [PATCH] :bug: fix data races on spammer

---
 .../transactionspammer/transactionspammer.go  | 117 +++++++++---------
 1 file changed, 56 insertions(+), 61 deletions(-)

diff --git a/packages/transactionspammer/transactionspammer.go b/packages/transactionspammer/transactionspammer.go
index b8283e55..d189acde 100644
--- a/packages/transactionspammer/transactionspammer.go
+++ b/packages/transactionspammer/transactionspammer.go
@@ -14,79 +14,74 @@ import (
 )
 
 var spamming = false
+var spammingMutex sync.Mutex
 
-var startMutex sync.Mutex
-
-var shutdownSignal chan int
+var shutdownSignal chan struct{}
+var done chan struct{}
 
 var sentCounter = uint(0)
 
-func Start(tps uint) {
-	startMutex.Lock()
-
-	if !spamming {
-		shutdownSignal = make(chan int, 1)
-
-		func(shutdownSignal chan int) {
-			daemon.BackgroundWorker("Transaction Spammer", func() {
-				for {
-					start := time.Now()
-					totalSentCounter := int64(0)
-
-					for {
-						select {
-						case <-daemon.ShutdownSignal:
-							return
-
-						case <-shutdownSignal:
-							return
-
-						default:
-							sentCounter++
-							totalSentCounter++
-
-							tx := value_transaction.New()
-							tx.SetHead(true)
-							tx.SetTail(true)
-							tx.SetValue(totalSentCounter)
-							tx.SetBranchTransactionHash(tipselection.GetRandomTip())
-							tx.SetTrunkTransactionHash(tipselection.GetRandomTip())
-
-							mtx := &pb.Transaction{Body: tx.MetaTransaction.GetBytes()}
-							b, _ := proto.Marshal(mtx)
-							gossip.Events.TransactionReceived.Trigger(&gossip.TransactionReceivedEvent{Body: b, Peer: &local.INSTANCE.Peer})
-
-							if sentCounter >= tps {
-								duration := time.Since(start)
-
-								if duration < time.Second {
-									time.Sleep(time.Second - duration)
-								}
-
-								start = time.Now()
+func init() {
+	shutdownSignal = make(chan struct{})
+	done = make(chan struct{})
+}
 
-								sentCounter = 0
-							}
-						}
+func Start(tps uint) {
+	spammingMutex.Lock()
+	spamming = true
+	spammingMutex.Unlock()
+
+	daemon.BackgroundWorker("Transaction Spammer", func() {
+		start := time.Now()
+		totalSentCounter := int64(0)
+
+		for {
+			select {
+			case <-daemon.ShutdownSignal:
+				return
+
+			case <-shutdownSignal:
+				done <- struct{}{}
+				return
+
+			default:
+				sentCounter++
+				totalSentCounter++
+
+				tx := value_transaction.New()
+				tx.SetHead(true)
+				tx.SetTail(true)
+				tx.SetValue(totalSentCounter)
+				tx.SetBranchTransactionHash(tipselection.GetRandomTip())
+				tx.SetTrunkTransactionHash(tipselection.GetRandomTip())
+
+				mtx := &pb.Transaction{Body: tx.MetaTransaction.GetBytes()}
+				b, _ := proto.Marshal(mtx)
+				gossip.Events.TransactionReceived.Trigger(&gossip.TransactionReceivedEvent{Body: b, Peer: &local.INSTANCE.Peer})
+
+				if sentCounter >= tps {
+					duration := time.Since(start)
+
+					if duration < time.Second {
+						time.Sleep(time.Second - duration)
 					}
-				}
-			})
-		}(shutdownSignal)
 
-		spamming = true
-	}
+					start = time.Now()
 
-	startMutex.Unlock()
+					sentCounter = 0
+				}
+			}
+		}
+	})
 }
 
 func Stop() {
-	startMutex.Lock()
-
+	spammingMutex.Lock()
 	if spamming {
-		close(shutdownSignal)
-
+		shutdownSignal <- struct{}{}
+		// wait for spammer to be done
+		<-done
 		spamming = false
 	}
-
-	startMutex.Unlock()
+	spammingMutex.Unlock()
 }
-- 
GitLab