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