Fantom-foundation/go-lachesis

View on GitHub
app/store_sfc_stakers.go

Summary

Maintainability
B
5 hrs
Test Coverage
package app

import (
    "github.com/ethereum/go-ethereum/ethdb"
    "github.com/ethereum/go-ethereum/rlp"

    "github.com/Fantom-foundation/go-lachesis/inter/idx"
    "github.com/Fantom-foundation/go-lachesis/inter/sfctype"
)

// SetEpochValidator stores EpochValidator
func (s *Store) SetEpochValidators(epoch idx.Epoch, vv []sfctype.SfcStakerAndID) {
    s.mutex.Validators.Lock()
    defer s.mutex.Validators.Unlock()

    for _, v := range vv {
        key := append(epoch.Bytes(), v.StakerID.Bytes()...)
        s.set(s.table.Validators, key, v.Staker)
    }

    // Add to LRU cache.
    s.cache.Validators.Add(epoch, vv)
}

// HasEpochValidator returns true if validator exists
func (s *Store) HasEpochValidator(epoch idx.Epoch, stakerID idx.StakerID) bool {
    key := append(epoch.Bytes(), stakerID.Bytes()...)
    return s.has(s.table.Validators, key)
}

// SetSfcStaker stores SfcStaker
func (s *Store) SetSfcStaker(stakerID idx.StakerID, v *sfctype.SfcStaker) {
    s.mutex.Stakers.Lock()
    defer s.mutex.Stakers.Unlock()

    s.set(s.table.Stakers, stakerID.Bytes(), v)

    // Add to LRU cache.
    if s.cache.Stakers != nil {
        s.cache.Stakers.Add(stakerID, v)
    }
}

// DelSfcStaker deletes SfcStaker
func (s *Store) DelSfcStaker(stakerID idx.StakerID) {
    s.mutex.Stakers.Lock()
    defer s.mutex.Stakers.Unlock()

    err := s.table.Stakers.Delete(stakerID.Bytes())
    if err != nil {
        s.Log.Crit("Failed to erase staker")
    }

    // Add to LRU cache.
    if s.cache.Stakers != nil {
        s.cache.Stakers.Remove(stakerID)
    }
}

// ForEachSfcStaker iterates all stored SfcStakers
func (s *Store) ForEachSfcStaker(do func(sfctype.SfcStakerAndID)) {
    it := s.table.Stakers.NewIterator(nil, nil)
    defer it.Release()
    s.forEachSfcStaker(it, do)
}

// GetSfcStakers returns all stored SfcStakers
func (s *Store) GetSfcStakers() []sfctype.SfcStakerAndID {
    stakers := make([]sfctype.SfcStakerAndID, 0, 200)
    s.ForEachSfcStaker(func(it sfctype.SfcStakerAndID) {
        stakers = append(stakers, it)
    })
    return stakers
}

// GetEpochValidators returns all stored EpochValidators on the epoch
func (s *Store) GetEpochValidators(epoch idx.Epoch) []sfctype.SfcStakerAndID {
    s.mutex.Validators.Lock()
    defer s.mutex.Validators.Unlock()

    // Get from cache
    if bVal, okGet := s.cache.Validators.Get(epoch); okGet {
        return bVal.([]sfctype.SfcStakerAndID)
    }

    it := s.table.Validators.NewIterator(epoch.Bytes(), nil)
    defer it.Release()
    validators := make([]sfctype.SfcStakerAndID, 0, 200)
    s.forEachSfcStaker(it, func(staker sfctype.SfcStakerAndID) {
        validators = append(validators, staker)
    })

    // Add to LRU cache.
    s.cache.Validators.Add(epoch, validators)

    return validators
}

func (s *Store) forEachSfcStaker(it ethdb.Iterator, do func(sfctype.SfcStakerAndID)) {
    for it.Next() {
        staker := &sfctype.SfcStaker{}
        err := rlp.DecodeBytes(it.Value(), staker)
        if err != nil {
            s.Log.Crit("Failed to decode rlp while iteration", "err", err)
        }

        stakerIDBytes := it.Key()[len(it.Key())-4:]
        do(sfctype.SfcStakerAndID{
            StakerID: idx.BytesToStakerID(stakerIDBytes),
            Staker:   staker,
        })
    }
}

// GetSfcStaker returns stored SfcStaker
func (s *Store) GetSfcStaker(stakerID idx.StakerID) *sfctype.SfcStaker {
    s.mutex.Stakers.Lock()
    defer s.mutex.Stakers.Unlock()

    // Get data from LRU cache first.
    if s.cache.Stakers != nil {
        if c, ok := s.cache.Stakers.Get(stakerID); ok {
            if b, ok := c.(*sfctype.SfcStaker); ok {
                return b
            }
        }
    }

    w, _ := s.get(s.table.Stakers, stakerID.Bytes(), &sfctype.SfcStaker{}).(*sfctype.SfcStaker)

    // Add to LRU cache.
    if w != nil && s.cache.Stakers != nil {
        s.cache.Stakers.Add(stakerID, w)
    }

    return w
}

// HasSfcStaker returns true if staker exists
func (s *Store) HasSfcStaker(stakerID idx.StakerID) bool {
    ok, err := s.table.Stakers.Has(stakerID.Bytes())
    if err != nil {
        s.Log.Crit("Failed to get staker", "err", err)
    }
    return ok
}