Skip to content
Snippets Groups Projects
Commit ba474922 authored by Hans Moog's avatar Hans Moog
Browse files

Refactor: refactored approvers to use model package already

parent 1fc60694
No related branches found
No related tags found
No related merge requests found
...@@ -17,7 +17,7 @@ type Approvers struct { ...@@ -17,7 +17,7 @@ type Approvers struct {
modified bool modified bool
} }
func NewApprovers(hash ternary.Trinary) *Approvers { func New(hash ternary.Trinary) *Approvers {
return &Approvers{ return &Approvers{
hash: hash, hash: hash,
hashes: make(map[ternary.Trinary]bool), hashes: make(map[ternary.Trinary]bool),
......
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")
)
package tangle package tangle
import ( import (
"encoding/binary"
"strconv"
"sync"
"github.com/dgraph-io/badger" "github.com/dgraph-io/badger"
"github.com/iotaledger/goshimmer/packages/datastructure" "github.com/iotaledger/goshimmer/packages/datastructure"
"github.com/iotaledger/goshimmer/packages/errors" "github.com/iotaledger/goshimmer/packages/errors"
"github.com/iotaledger/goshimmer/packages/model/approvers"
"github.com/iotaledger/goshimmer/packages/ternary" "github.com/iotaledger/goshimmer/packages/ternary"
"github.com/iotaledger/goshimmer/packages/typeutils"
) )
// region global public api //////////////////////////////////////////////////////////////////////////////////////////// // region global public api ////////////////////////////////////////////////////////////////////////////////////////////
var approversCache = datastructure.NewLRUCache(METADATA_CACHE_SIZE) var approversCache = datastructure.NewLRUCache(METADATA_CACHE_SIZE)
func StoreApprovers(approvers *Approvers) { func StoreApprovers(approvers *approvers.Approvers) {
hash := approvers.GetHash() hash := approvers.GetHash()
approversCache.Set(hash, approvers) approversCache.Set(hash, approvers)
} }
func GetApprovers(transactionHash ternary.Trinary, computeIfAbsent ...func(ternary.Trinary) *Approvers) (result *Approvers, err errors.IdentifiableError) { func GetApprovers(transactionHash ternary.Trinary, computeIfAbsent ...func(ternary.Trinary) *approvers.Approvers) (result *approvers.Approvers, err errors.IdentifiableError) {
if approvers := approversCache.ComputeIfAbsent(transactionHash, func() interface{} { if appr := approversCache.ComputeIfAbsent(transactionHash, func() interface{} {
if result, err = getApproversFromDatabase(transactionHash); err == nil && result == nil && len(computeIfAbsent) >= 1 { if result, err = getApproversFromDatabase(transactionHash); err == nil && result == nil && len(computeIfAbsent) >= 1 {
result = computeIfAbsent[0](transactionHash) result = computeIfAbsent[0](transactionHash)
} }
return result return result
}); approvers != nil && approvers.(*Approvers) != nil { }); appr != nil && appr.(*approvers.Approvers) != nil {
result = approvers.(*Approvers) result = appr.(*approvers.Approvers)
} }
return return
...@@ -46,159 +42,7 @@ func ContainsApprovers(transactionHash ternary.Trinary) (result bool, err errors ...@@ -46,159 +42,7 @@ func ContainsApprovers(transactionHash ternary.Trinary) (result bool, err errors
return return
} }
// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// func getApproversFromDatabase(transactionHash ternary.Trinary) (result *approvers.Approvers, err errors.IdentifiableError) {
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) {
approversData, dbErr := approversDatabase.Get(transactionHash.CastToBytes()) approversData, dbErr := approversDatabase.Get(transactionHash.CastToBytes())
if dbErr != nil { if dbErr != nil {
if dbErr != badger.ErrKeyNotFound { if dbErr != badger.ErrKeyNotFound {
...@@ -208,7 +52,7 @@ func getApproversFromDatabase(transactionHash ternary.Trinary) (result *Approver ...@@ -208,7 +52,7 @@ func getApproversFromDatabase(transactionHash ternary.Trinary) (result *Approver
return return
} }
result = NewApprovers(transactionHash) result = approvers.New(transactionHash)
if err = result.Unmarshal(approversData); err != nil { if err = result.Unmarshal(approversData); err != nil {
result = nil result = nil
} }
......
...@@ -3,6 +3,7 @@ package tangle ...@@ -3,6 +3,7 @@ package tangle
import ( import (
"github.com/iotaledger/goshimmer/packages/errors" "github.com/iotaledger/goshimmer/packages/errors"
"github.com/iotaledger/goshimmer/packages/events" "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/meta_transaction"
"github.com/iotaledger/goshimmer/packages/model/value_transaction" "github.com/iotaledger/goshimmer/packages/model/value_transaction"
"github.com/iotaledger/goshimmer/packages/node" "github.com/iotaledger/goshimmer/packages/node"
...@@ -130,7 +131,7 @@ func IsSolid(transaction *value_transaction.ValueTransaction) (bool, errors.Iden ...@@ -130,7 +131,7 @@ func IsSolid(transaction *value_transaction.ValueTransaction) (bool, errors.Iden
} }
func propagateSolidity(transactionHash ternary.Trinary) errors.IdentifiableError { 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 return err
} else { } else {
for _, approverHash := range approvers.GetHashes() { for _, approverHash := range approvers.GetHashes() {
...@@ -168,7 +169,7 @@ func processTransaction(plugin *node.Plugin, transaction *value_transaction.Valu ...@@ -168,7 +169,7 @@ func processTransaction(plugin *node.Plugin, transaction *value_transaction.Valu
transactionHash := transaction.GetHash() transactionHash := transaction.GetHash()
// register tx as approver for trunk // 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()) plugin.LogFailure(err.Error())
return return
...@@ -177,7 +178,7 @@ func processTransaction(plugin *node.Plugin, transaction *value_transaction.Valu ...@@ -177,7 +178,7 @@ func processTransaction(plugin *node.Plugin, transaction *value_transaction.Valu
} }
// register tx as approver for branch // 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()) plugin.LogFailure(err.Error())
return return
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment