Skip to content
Snippets Groups Projects
Select Git revision
  • 453479bf3cc1bb9206dbc3848bdd8b5a413625b4
  • without_tipselection default
  • develop protected
  • fix/grafana-local-dashboard
  • wasp
  • fix/dashboard-explorer-freeze
  • master
  • feat/timerqueue
  • test/sync_debug_and_650
  • feat/sync_revamp_inv
  • wip/sync
  • tool/db-recovery
  • portcheck/fix
  • fix/synchronization
  • feat/new-dashboard-analysis
  • feat/refactored-analysis-dashboard
  • feat/new-analysis-dashboard
  • test/demo-prometheus-fpc
  • prometheus_metrics
  • wip/analysis-server
  • merge/fpc-test-value-transfer
  • v0.2.2
  • v0.2.1
  • v0.2.0
  • v0.1.3
  • v0.1.2
  • v0.1.1
  • v0.1.0
28 results

approvers.go

Blame
  • approvers.go 4.27 KiB
    package approvers
    
    import (
    	"encoding/binary"
    	"strconv"
    	"sync"
    
    	"github.com/iotaledger/goshimmer/packages/errors"
    	"github.com/iotaledger/goshimmer/packages/ternary"
    	"github.com/iotaledger/goshimmer/packages/typeutils"
    )
    
    type Approvers struct {
    	hash        ternary.Trytes
    	hashes      map[ternary.Trytes]bool
    	hashesMutex sync.RWMutex
    	modified    bool
    }
    
    func New(hash ternary.Trytes) *Approvers {
    	return &Approvers{
    		hash:     hash,
    		hashes:   make(map[ternary.Trytes]bool),
    		modified: false,
    	}
    }
    
    // region public methods with locking //////////////////////////////////////////////////////////////////////////////////
    
    func (approvers *Approvers) Add(transactionHash ternary.Trytes) {
    	approvers.hashesMutex.Lock()
    	approvers.add(transactionHash)
    	approvers.hashesMutex.Unlock()
    }
    
    func (approvers *Approvers) Remove(approverHash ternary.Trytes) {
    	approvers.hashesMutex.Lock()
    	approvers.remove(approverHash)
    	approvers.hashesMutex.Unlock()
    }
    
    func (approvers *Approvers) GetHashes() (result []ternary.Trytes) {
    	approvers.hashesMutex.RLock()
    	result = approvers.getHashes()
    	approvers.hashesMutex.RUnlock()
    
    	return
    }
    
    func (approvers *Approvers) GetHash() (result ternary.Trytes) {
    	approvers.hashesMutex.RLock()
    	result = approvers.hash
    	approvers.hashesMutex.RUnlock()
    
    	return
    }
    
    func (approvers *Approvers) GetModified() bool {
    	return true
    }
    
    func (approvers *Approvers) SetModified(modified bool) {
    }
    
    func (approvers *Approvers) Marshal() (result []byte) {
    	approvers.hashesMutex.RLock()
    
    	result = make([]byte, MARSHALED_APPROVERS_MIN_SIZE+len(approvers.hashes)*MARSHALED_APPROVERS_HASH_SIZE)
    
    	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.Trytes(typeutils.BytesToString(data[MARSHALED_APPROVERS_HASH_START:MARSHALED_APPROVERS_HASH_END]))
    	approvers.hashes = make(map[ternary.Trytes]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.Trytes(typeutils.BytesToString(data[HASH_START:HASH_END]))] = true
    	}
    
    	approvers.hashesMutex.Unlock()
    
    	return
    }
    
    // endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    // region private methods without locking //////////////////////////////////////////////////////////////////////////////
    
    func (approvers *Approvers) add(transactionHash ternary.Trytes) {
    	if _, exists := approvers.hashes[transactionHash]; !exists {
    		approvers.hashes[transactionHash] = true
    		approvers.modified = true
    	}
    }
    
    func (approvers *Approvers) remove(approverHash ternary.Trytes) {
    	if _, exists := approvers.hashes[approverHash]; exists {
    		delete(approvers.hashes, approverHash)
    		approvers.modified = true
    	}
    }
    
    func (approvers *Approvers) getHashes() (result []ternary.Trytes) {
    	result = make([]ternary.Trytes, len(approvers.hashes))
    
    	counter := 0
    	for hash := range approvers.hashes {
    		result[counter] = hash
    
    		counter++
    	}
    
    	return
    }
    
    // endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////