github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/core/state/trailing_slot_state_cache.go (about)

     1  package state
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"sync"
     7  
     8  	"github.com/prometheus/client_golang/prometheus"
     9  	"github.com/prometheus/client_golang/prometheus/promauto"
    10  	iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
    11  )
    12  
    13  type nextSlotCache struct {
    14  	sync.RWMutex
    15  	root  []byte
    16  	state iface.BeaconState
    17  }
    18  
    19  var (
    20  	nsc nextSlotCache
    21  	// Metrics for the validator cache.
    22  	nextSlotCacheHit = promauto.NewCounter(prometheus.CounterOpts{
    23  		Name: "next_slot_cache_hit",
    24  		Help: "The total number of cache hits on the next slot state cache.",
    25  	})
    26  	nextSlotCacheMiss = promauto.NewCounter(prometheus.CounterOpts{
    27  		Name: "next_slot_cache_miss",
    28  		Help: "The total number of cache misses on the next slot state cache.",
    29  	})
    30  )
    31  
    32  // NextSlotState returns the saved state if the input root matches the root in `nextSlotCache`. Returns nil otherwise.
    33  // This is useful to check before processing slots. With a cache hit, it will return last processed state with slot plus
    34  // one advancement.
    35  func NextSlotState(ctx context.Context, root []byte) (iface.BeaconState, error) {
    36  	nsc.RLock()
    37  	defer nsc.RUnlock()
    38  	if !bytes.Equal(root, nsc.root) {
    39  		nextSlotCacheMiss.Inc()
    40  		return nil, nil
    41  	}
    42  	nextSlotCacheHit.Inc()
    43  	// Returning copied state.
    44  	return nsc.state.Copy(), nil
    45  }
    46  
    47  // UpdateNextSlotCache updates the `nextSlotCache`. It saves the input state after advancing the state slot by 1
    48  // by calling `ProcessSlots`, it also saves the input root for later look up.
    49  // This is useful to call after successfully processing a block.
    50  func UpdateNextSlotCache(ctx context.Context, root []byte, state iface.BeaconState) error {
    51  	// Advancing one slot by using a copied state.
    52  	copied := state.Copy()
    53  	copied, err := ProcessSlots(ctx, copied, copied.Slot()+1)
    54  	if err != nil {
    55  		return err
    56  	}
    57  
    58  	nsc.Lock()
    59  	defer nsc.Unlock()
    60  
    61  	nsc.root = root
    62  	nsc.state = copied
    63  	return nil
    64  }