From 2077d6a3dd57a34a2e6e33bf88066052f190cee6 Mon Sep 17 00:00:00 2001
From: Hans Moog <hm@mkjc.net>
Date: Wed, 18 Sep 2019 15:03:20 +0200
Subject: [PATCH] Refactor: refactored heartbeat manager

---
 packages/ca/heartbeat/errors.go            |  9 ++
 packages/ca/heartbeat/heartbeat.go         | 16 ++++
 packages/ca/heartbeat/opinion_statement.go | 16 ++++
 packages/ca/heartbeat_manager.go           | 97 +++++++++-------------
 4 files changed, 79 insertions(+), 59 deletions(-)
 create mode 100644 packages/ca/heartbeat/errors.go

diff --git a/packages/ca/heartbeat/errors.go b/packages/ca/heartbeat/errors.go
new file mode 100644
index 00000000..a472a252
--- /dev/null
+++ b/packages/ca/heartbeat/errors.go
@@ -0,0 +1,9 @@
+package heartbeat
+
+import (
+	"github.com/iotaledger/goshimmer/packages/errors"
+)
+
+var (
+	ErrSigningFailed = errors.Wrap(errors.New("failed to sign"), "failed to sign")
+)
diff --git a/packages/ca/heartbeat/heartbeat.go b/packages/ca/heartbeat/heartbeat.go
index dd2d3da8..0b959100 100644
--- a/packages/ca/heartbeat/heartbeat.go
+++ b/packages/ca/heartbeat/heartbeat.go
@@ -3,6 +3,8 @@ package heartbeat
 import (
 	"sync"
 
+	"github.com/iotaledger/goshimmer/packages/identity"
+
 	"github.com/iotaledger/goshimmer/packages/stringify"
 
 	"github.com/iotaledger/goshimmer/packages/errors"
@@ -77,6 +79,20 @@ func (heartbeat *Heartbeat) GetSignature() []byte {
 	return heartbeat.signature
 }
 
+func (heartbeat *Heartbeat) Sign(identity *identity.Identity) (err errors.IdentifiableError) {
+	if marshaledHeartbeat, marshalErr := heartbeat.MarshalBinary(); marshalErr == nil {
+		if signature, signingErr := identity.Sign(marshaledHeartbeat); signingErr == nil {
+			heartbeat.SetSignature(signature)
+		} else {
+			err = ErrSigningFailed.Derive(signingErr, "failed to sign heartbeat")
+		}
+	} else {
+		err = marshalErr
+	}
+
+	return
+}
+
 func (heartbeat *Heartbeat) SetSignature(signature []byte) {
 	heartbeat.signatureMutex.Lock()
 	defer heartbeat.signatureMutex.Unlock()
diff --git a/packages/ca/heartbeat/opinion_statement.go b/packages/ca/heartbeat/opinion_statement.go
index 5442749c..6aca30cf 100644
--- a/packages/ca/heartbeat/opinion_statement.go
+++ b/packages/ca/heartbeat/opinion_statement.go
@@ -3,6 +3,8 @@ package heartbeat
 import (
 	"sync"
 
+	"github.com/iotaledger/goshimmer/packages/identity"
+
 	"golang.org/x/crypto/blake2b"
 
 	"github.com/iotaledger/goshimmer/packages/stringify"
@@ -104,6 +106,20 @@ func (opinionStatement *OpinionStatement) SetSignature(signature []byte) {
 	opinionStatement.signature = signature
 }
 
+func (opinionStatement *OpinionStatement) Sign(identity *identity.Identity) (err errors.IdentifiableError) {
+	if marshaledStatement, marshalErr := opinionStatement.MarshalBinary(); marshalErr == nil {
+		if signature, signingErr := identity.Sign(marshaledStatement); signingErr == nil {
+			opinionStatement.SetSignature(signature)
+		} else {
+			err = ErrSigningFailed.Derive(signingErr, "failed to sign opinion statement")
+		}
+	} else {
+		err = marshalErr
+	}
+
+	return
+}
+
 func (opinionStatement *OpinionStatement) GetHash() []byte {
 	opinionStatement.hashMutex.RLock()
 	defer opinionStatement.hashMutex.RUnlock()
diff --git a/packages/ca/heartbeat_manager.go b/packages/ca/heartbeat_manager.go
index 3f0ef5b7..bda2408c 100644
--- a/packages/ca/heartbeat_manager.go
+++ b/packages/ca/heartbeat_manager.go
@@ -40,86 +40,65 @@ func (heartbeatManager *HeartbeatManager) InitialLike(transactionId []byte) {
 	heartbeatManager.initialOpinions[string(transactionId)] = true
 }
 
-func (heartbeatManager *HeartbeatManager) GenerateMainStatement() (result *heartbeat.OpinionStatement, err errors.IdentifiableError) {
-	toggledTransactions := make([]*heartbeat.ToggledTransaction, 0)
-	for transactionId, liked := range heartbeatManager.initialOpinions {
-		if !liked {
-			newToggledTransaction := heartbeat.NewToggledTransaction()
-			newToggledTransaction.SetInitialStatement(true)
-			newToggledTransaction.SetFinalStatement(false)
-			newToggledTransaction.SetTransactionId([]byte(transactionId))
-
-			toggledTransactions = append(toggledTransactions, newToggledTransaction)
+func (heartbeatManager *HeartbeatManager) GenerateHeartbeat() (result *heartbeat.Heartbeat, err errors.IdentifiableError) {
+	if mainStatement, mainStatementErr := heartbeatManager.GenerateMainStatement(); mainStatementErr == nil {
+		generatedHeartbeat := heartbeat.NewHeartbeat()
+		generatedHeartbeat.SetNodeId(heartbeatManager.identity.StringIdentifier)
+		generatedHeartbeat.SetMainStatement(mainStatement)
+		generatedHeartbeat.SetNeighborStatements(nil)
+
+		if signingErr := generatedHeartbeat.Sign(heartbeatManager.identity); signingErr == nil {
+			result = generatedHeartbeat
+		} else {
+			err = signingErr
 		}
+	} else {
+		err = mainStatementErr
 	}
 
+	return
+}
+
+func (heartbeatManager *HeartbeatManager) GenerateMainStatement() (result *heartbeat.OpinionStatement, err errors.IdentifiableError) {
 	mainStatement := heartbeat.NewOpinionStatement()
 	mainStatement.SetNodeId(heartbeatManager.identity.StringIdentifier)
 	mainStatement.SetTime(uint64(time.Now().Unix()))
-	mainStatement.SetToggledTransactions(toggledTransactions)
+	mainStatement.SetToggledTransactions(heartbeatManager.GenerateToggledTransactions())
 
 	if lastAppliedStatement := heartbeatManager.statementChain.lastAppliedStatement; lastAppliedStatement != nil {
 		mainStatement.SetPreviousStatementHash(lastAppliedStatement.GetHash())
 	}
 
-	marshaledStatement, marshalErr := mainStatement.MarshalBinary()
-	if marshalErr != nil {
-		err = marshalErr
-
-		return
-	}
-
-	signature, signingErr := heartbeatManager.identity.Sign(marshaledStatement)
-	if signingErr != nil {
-		err = ErrMalformedHeartbeat.Derive(signingErr.Error())
+	if signingErr := mainStatement.Sign(heartbeatManager.identity); signingErr == nil {
+		result = mainStatement
 
-		return
+		heartbeatManager.ResetInitialOpinions()
+		heartbeatManager.statementChain.lastAppliedStatement = mainStatement
+	} else {
+		err = signingErr
 	}
 
-	mainStatement.SetSignature(signature)
-
-	result = mainStatement
-
-	heartbeatManager.ResetInitialStatements()
-	heartbeatManager.statementChain.lastAppliedStatement = mainStatement
-
 	return
 }
 
-func (heartbeatManager *HeartbeatManager) ResetInitialStatements() {
-	heartbeatManager.initialOpinions = make(map[string]bool)
-}
-
-func (heartbeatManager *HeartbeatManager) GenerateHeartbeat() (result *heartbeat.Heartbeat, err errors.IdentifiableError) {
-	mainStatement, mainStatementErr := heartbeatManager.GenerateMainStatement()
-	if mainStatementErr != nil {
-		err = mainStatementErr
-
-		return
-	}
-
-	generatedHeartbeat := heartbeat.NewHeartbeat()
-	generatedHeartbeat.SetNodeId(heartbeatManager.identity.StringIdentifier)
-	generatedHeartbeat.SetMainStatement(mainStatement)
-	generatedHeartbeat.SetNeighborStatements(nil)
-
-	marshaledHeartbeat, marshalErr := generatedHeartbeat.MarshalBinary()
-	if marshalErr != nil {
-		err = marshalErr
-
-		return
-	}
-	signature, signingErr := heartbeatManager.identity.Sign(marshaledHeartbeat)
-	if signingErr != nil {
-		err = ErrMalformedHeartbeat.Derive(signingErr.Error())
+func (heartbeatManager *HeartbeatManager) GenerateToggledTransactions() []*heartbeat.ToggledTransaction {
+	toggledTransactions := make([]*heartbeat.ToggledTransaction, 0)
+	for transactionId, liked := range heartbeatManager.initialOpinions {
+		if !liked {
+			newToggledTransaction := heartbeat.NewToggledTransaction()
+			newToggledTransaction.SetInitialStatement(true)
+			newToggledTransaction.SetFinalStatement(false)
+			newToggledTransaction.SetTransactionId([]byte(transactionId))
 
-		return
+			toggledTransactions = append(toggledTransactions, newToggledTransaction)
+		}
 	}
-	generatedHeartbeat.SetSignature(signature)
 
-	result = generatedHeartbeat
+	return toggledTransactions
+}
 
-	return
+func (heartbeatManager *HeartbeatManager) ResetInitialOpinions() {
+	heartbeatManager.initialOpinions = make(map[string]bool)
 }
 
 func (heartbeatManager *HeartbeatManager) ApplyHeartbeat(heartbeat *heartbeat.Heartbeat) (err errors.IdentifiableError) {
-- 
GitLab