From ba474922123ac23a25011acaf59d6f396941e52e Mon Sep 17 00:00:00 2001
From: Hans Moog <hm@mkjc.net>
Date: Mon, 17 Jun 2019 16:43:34 +0200
Subject: [PATCH] Refactor: refactored approvers to use model package already

---
 packages/model/approvers/approvers.go |   2 +-
 packages/model/approvers/errors.go    |   8 ++
 plugins/tangle/approvers.go           | 172 ++------------------------
 plugins/tangle/solidifier.go          |   7 +-
 4 files changed, 21 insertions(+), 168 deletions(-)
 create mode 100644 packages/model/approvers/errors.go

diff --git a/packages/model/approvers/approvers.go b/packages/model/approvers/approvers.go
index f17c4ca3..0633e0f5 100644
--- a/packages/model/approvers/approvers.go
+++ b/packages/model/approvers/approvers.go
@@ -17,7 +17,7 @@ type Approvers struct {
 	modified    bool
 }
 
-func NewApprovers(hash ternary.Trinary) *Approvers {
+func New(hash ternary.Trinary) *Approvers {
 	return &Approvers{
 		hash:     hash,
 		hashes:   make(map[ternary.Trinary]bool),
diff --git a/packages/model/approvers/errors.go b/packages/model/approvers/errors.go
new file mode 100644
index 00000000..81e5d9e1
--- /dev/null
+++ b/packages/model/approvers/errors.go
@@ -0,0 +1,8 @@
+package approvers
+
+import "github.com/iotaledger/goshimmer/packages/errors"
+
+var (
+	ErrUnmarshalFailed = errors.Wrap(errors.New("unmarshall failed"), "input data is corrupted")
+	ErrMarshallFailed  = errors.Wrap(errors.New("marshal failed"), "the source object contains invalid values")
+)
diff --git a/plugins/tangle/approvers.go b/plugins/tangle/approvers.go
index 6b2f03d9..93d8877e 100644
--- a/plugins/tangle/approvers.go
+++ b/plugins/tangle/approvers.go
@@ -1,36 +1,32 @@
 package tangle
 
 import (
-	"encoding/binary"
-	"strconv"
-	"sync"
-
 	"github.com/dgraph-io/badger"
 	"github.com/iotaledger/goshimmer/packages/datastructure"
 	"github.com/iotaledger/goshimmer/packages/errors"
+	"github.com/iotaledger/goshimmer/packages/model/approvers"
 	"github.com/iotaledger/goshimmer/packages/ternary"
-	"github.com/iotaledger/goshimmer/packages/typeutils"
 )
 
 // region global public api ////////////////////////////////////////////////////////////////////////////////////////////
 
 var approversCache = datastructure.NewLRUCache(METADATA_CACHE_SIZE)
 
-func StoreApprovers(approvers *Approvers) {
+func StoreApprovers(approvers *approvers.Approvers) {
 	hash := approvers.GetHash()
 
 	approversCache.Set(hash, approvers)
 }
 
-func GetApprovers(transactionHash ternary.Trinary, computeIfAbsent ...func(ternary.Trinary) *Approvers) (result *Approvers, err errors.IdentifiableError) {
-	if approvers := approversCache.ComputeIfAbsent(transactionHash, func() interface{} {
+func GetApprovers(transactionHash ternary.Trinary, computeIfAbsent ...func(ternary.Trinary) *approvers.Approvers) (result *approvers.Approvers, err errors.IdentifiableError) {
+	if appr := approversCache.ComputeIfAbsent(transactionHash, func() interface{} {
 		if result, err = getApproversFromDatabase(transactionHash); err == nil && result == nil && len(computeIfAbsent) >= 1 {
 			result = computeIfAbsent[0](transactionHash)
 		}
 
 		return result
-	}); approvers != nil && approvers.(*Approvers) != nil {
-		result = approvers.(*Approvers)
+	}); appr != nil && appr.(*approvers.Approvers) != nil {
+		result = appr.(*approvers.Approvers)
 	}
 
 	return
@@ -46,159 +42,7 @@ func ContainsApprovers(transactionHash ternary.Trinary) (result bool, err errors
 	return
 }
 
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-type Approvers struct {
-	hash        ternary.Trinary
-	hashes      map[ternary.Trinary]bool
-	hashesMutex sync.RWMutex
-	modified    bool
-}
-
-func NewApprovers(hash ternary.Trinary) *Approvers {
-	return &Approvers{
-		hash:     hash,
-		hashes:   make(map[ternary.Trinary]bool),
-		modified: false,
-	}
-}
-
-// region public methods with locking //////////////////////////////////////////////////////////////////////////////////
-
-func (approvers *Approvers) Add(transactionHash ternary.Trinary) {
-	approvers.hashesMutex.Lock()
-	approvers.add(transactionHash)
-	approvers.hashesMutex.Unlock()
-}
-
-func (approvers *Approvers) Remove(approverHash ternary.Trinary) {
-	approvers.hashesMutex.Lock()
-	approvers.remove(approverHash)
-	approvers.hashesMutex.Unlock()
-}
-
-func (approvers *Approvers) GetHashes() (result []ternary.Trinary) {
-	approvers.hashesMutex.RLock()
-	result = approvers.getHashes()
-	approvers.hashesMutex.RUnlock()
-
-	return
-}
-
-func (approvers *Approvers) GetHash() (result ternary.Trinary) {
-	approvers.hashesMutex.RLock()
-	result = approvers.hash
-	approvers.hashesMutex.RUnlock()
-
-	return
-}
-
-func (approvers *Approvers) Marshal() (result []byte) {
-	result = make([]byte, MARSHALED_APPROVERS_MIN_SIZE+len(approvers.hashes)*MARSHALED_APPROVERS_HASH_SIZE)
-
-	approvers.hashesMutex.RLock()
-
-	binary.BigEndian.PutUint64(result[MARSHALED_APPROVERS_HASHES_COUNT_START:MARSHALED_APPROVERS_HASHES_COUNT_END], uint64(len(approvers.hashes)))
-
-	copy(result[MARSHALED_APPROVERS_HASH_START:MARSHALED_APPROVERS_HASH_END], approvers.hash.CastToBytes())
-
-	i := 0
-	for hash := range approvers.hashes {
-		var HASH_START = MARSHALED_APPROVERS_HASHES_START + i*(MARSHALED_APPROVERS_HASH_SIZE)
-		var HASH_END = HASH_START * MARSHALED_APPROVERS_HASH_SIZE
-
-		copy(result[HASH_START:HASH_END], hash.CastToBytes())
-
-		i++
-	}
-
-	approvers.hashesMutex.RUnlock()
-
-	return
-}
-
-func (approvers *Approvers) Unmarshal(data []byte) (err errors.IdentifiableError) {
-	dataLen := len(data)
-
-	if dataLen <= MARSHALED_APPROVERS_MIN_SIZE {
-		return ErrMarshallFailed.Derive(errors.New("unmarshall failed"), "marshaled approvers are too short")
-	}
-
-	hashesCount := binary.BigEndian.Uint64(data[MARSHALED_APPROVERS_HASHES_COUNT_START:MARSHALED_APPROVERS_HASHES_COUNT_END])
-
-	if dataLen <= MARSHALED_APPROVERS_MIN_SIZE+int(hashesCount)*MARSHALED_APPROVERS_HASH_SIZE {
-		return ErrMarshallFailed.Derive(errors.New("unmarshall failed"), "marshaled approvers are too short for "+strconv.FormatUint(hashesCount, 10)+" approvers")
-	}
-
-	approvers.hashesMutex.Lock()
-
-	approvers.hash = ternary.Trinary(typeutils.BytesToString(data[MARSHALED_APPROVERS_HASH_START:MARSHALED_APPROVERS_HASH_END]))
-	approvers.hashes = make(map[ternary.Trinary]bool, hashesCount)
-	for i := uint64(0); i < hashesCount; i++ {
-		var HASH_START = MARSHALED_APPROVERS_HASHES_START + i*(MARSHALED_APPROVERS_HASH_SIZE)
-		var HASH_END = HASH_START * MARSHALED_APPROVERS_HASH_SIZE
-
-		approvers.hashes[ternary.Trinary(typeutils.BytesToString(data[HASH_START:HASH_END]))] = true
-	}
-
-	approvers.hashesMutex.Unlock()
-
-	return
-}
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-const (
-	MARSHALED_APPROVERS_HASHES_COUNT_START = 0
-	MARSHALED_APPROVERS_HASH_START         = MARSHALED_APPROVERS_HASHES_COUNT_END
-	MARSHALED_APPROVERS_HASHES_START       = MARSHALED_APPROVERS_HASH_END
-
-	MARSHALED_APPROVERS_HASHES_COUNT_END = MARSHALED_APPROVERS_HASHES_COUNT_START + MARSHALED_APPROVERS_HASHES_COUNT_SIZE
-	MARSHALED_APPROVERS_HASH_END         = MARSHALED_APPROVERS_HASH_START + MARSHALED_APPROVERS_HASH_SIZE
-
-	MARSHALED_APPROVERS_HASHES_COUNT_SIZE = 8
-	MARSHALED_APPROVERS_HASH_SIZE         = 81
-	MARSHALED_APPROVERS_MIN_SIZE          = MARSHALED_APPROVERS_HASHES_COUNT_SIZE + MARSHALED_APPROVERS_HASH_SIZE
-)
-
-// region private methods without locking //////////////////////////////////////////////////////////////////////////////
-
-func (approvers *Approvers) add(transactionHash ternary.Trinary) {
-	if _, exists := approvers.hashes[transactionHash]; !exists {
-		approvers.hashes[transactionHash] = true
-		approvers.modified = true
-	}
-}
-
-func (approvers *Approvers) remove(approverHash ternary.Trinary) {
-	if _, exists := approvers.hashes[approverHash]; exists {
-		delete(approvers.hashes, approverHash)
-		approvers.modified = true
-	}
-}
-
-func (approvers *Approvers) getHashes() (result []ternary.Trinary) {
-	result = make([]ternary.Trinary, len(approvers.hashes))
-
-	counter := 0
-	for hash := range approvers.hashes {
-		result[counter] = hash
-
-		counter++
-	}
-
-	return
-}
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-func (approvers *Approvers) Store(approverHash ternary.Trinary) {
-	approvers.hashesMutex.Lock()
-	approvers.modified = false
-	approvers.hashesMutex.Unlock()
-}
-
-func getApproversFromDatabase(transactionHash ternary.Trinary) (result *Approvers, err errors.IdentifiableError) {
+func getApproversFromDatabase(transactionHash ternary.Trinary) (result *approvers.Approvers, err errors.IdentifiableError) {
 	approversData, dbErr := approversDatabase.Get(transactionHash.CastToBytes())
 	if dbErr != nil {
 		if dbErr != badger.ErrKeyNotFound {
@@ -208,7 +52,7 @@ func getApproversFromDatabase(transactionHash ternary.Trinary) (result *Approver
 		return
 	}
 
-	result = NewApprovers(transactionHash)
+	result = approvers.New(transactionHash)
 	if err = result.Unmarshal(approversData); err != nil {
 		result = nil
 	}
diff --git a/plugins/tangle/solidifier.go b/plugins/tangle/solidifier.go
index c5b0d38d..405f3dd0 100644
--- a/plugins/tangle/solidifier.go
+++ b/plugins/tangle/solidifier.go
@@ -3,6 +3,7 @@ package tangle
 import (
 	"github.com/iotaledger/goshimmer/packages/errors"
 	"github.com/iotaledger/goshimmer/packages/events"
+	"github.com/iotaledger/goshimmer/packages/model/approvers"
 	"github.com/iotaledger/goshimmer/packages/model/meta_transaction"
 	"github.com/iotaledger/goshimmer/packages/model/value_transaction"
 	"github.com/iotaledger/goshimmer/packages/node"
@@ -130,7 +131,7 @@ func IsSolid(transaction *value_transaction.ValueTransaction) (bool, errors.Iden
 }
 
 func propagateSolidity(transactionHash ternary.Trinary) errors.IdentifiableError {
-	if approvers, err := GetApprovers(transactionHash, NewApprovers); err != nil {
+	if approvers, err := GetApprovers(transactionHash, approvers.New); err != nil {
 		return err
 	} else {
 		for _, approverHash := range approvers.GetHashes() {
@@ -168,7 +169,7 @@ func processTransaction(plugin *node.Plugin, transaction *value_transaction.Valu
 	transactionHash := transaction.GetHash()
 
 	// register tx as approver for trunk
-	if trunkApprovers, err := GetApprovers(transaction.GetTrunkTransactionHash(), NewApprovers); err != nil {
+	if trunkApprovers, err := GetApprovers(transaction.GetTrunkTransactionHash(), approvers.New); err != nil {
 		plugin.LogFailure(err.Error())
 
 		return
@@ -177,7 +178,7 @@ func processTransaction(plugin *node.Plugin, transaction *value_transaction.Valu
 	}
 
 	// register tx as approver for branch
-	if branchApprovers, err := GetApprovers(transaction.GetBranchTransactionHash(), NewApprovers); err != nil {
+	if branchApprovers, err := GetApprovers(transaction.GetBranchTransactionHash(), approvers.New); err != nil {
 		plugin.LogFailure(err.Error())
 
 		return
-- 
GitLab