github.com/ava-labs/avalanchego@v1.11.11/vms/proposervm/state/block_height_index.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package state
     5  
     6  import (
     7  	"github.com/ava-labs/avalanchego/cache"
     8  	"github.com/ava-labs/avalanchego/database"
     9  	"github.com/ava-labs/avalanchego/database/prefixdb"
    10  	"github.com/ava-labs/avalanchego/database/versiondb"
    11  	"github.com/ava-labs/avalanchego/ids"
    12  )
    13  
    14  const cacheSize = 8192 // max cache entries
    15  
    16  var (
    17  	_ HeightIndex = (*heightIndex)(nil)
    18  
    19  	heightPrefix   = []byte("height")
    20  	metadataPrefix = []byte("metadata")
    21  
    22  	forkKey = []byte("fork")
    23  )
    24  
    25  type HeightIndexGetter interface {
    26  	// GetMinimumHeight return the smallest height of an indexed blockID. If
    27  	// there are no indexed blockIDs, ErrNotFound will be returned.
    28  	GetMinimumHeight() (uint64, error)
    29  	GetBlockIDAtHeight(height uint64) (ids.ID, error)
    30  
    31  	// Fork height is stored when the first post-fork block/option is accepted.
    32  	// Before that, fork height won't be found.
    33  	GetForkHeight() (uint64, error)
    34  }
    35  
    36  type HeightIndexWriter interface {
    37  	SetForkHeight(height uint64) error
    38  	SetBlockIDAtHeight(height uint64, blkID ids.ID) error
    39  	DeleteBlockIDAtHeight(height uint64) error
    40  }
    41  
    42  // HeightIndex contains mapping of blockHeights to accepted proposer block IDs
    43  // along with some metadata (fork height and checkpoint).
    44  type HeightIndex interface {
    45  	HeightIndexWriter
    46  	HeightIndexGetter
    47  }
    48  
    49  type heightIndex struct {
    50  	versiondb.Commitable
    51  
    52  	// Caches block height -> proposerVMBlockID.
    53  	heightsCache cache.Cacher[uint64, ids.ID]
    54  
    55  	heightDB   database.Database
    56  	metadataDB database.Database
    57  }
    58  
    59  func NewHeightIndex(db database.Database, commitable versiondb.Commitable) HeightIndex {
    60  	return &heightIndex{
    61  		Commitable: commitable,
    62  
    63  		heightsCache: &cache.LRU[uint64, ids.ID]{Size: cacheSize},
    64  		heightDB:     prefixdb.New(heightPrefix, db),
    65  		metadataDB:   prefixdb.New(metadataPrefix, db),
    66  	}
    67  }
    68  
    69  func (hi *heightIndex) GetMinimumHeight() (uint64, error) {
    70  	it := hi.heightDB.NewIterator()
    71  	defer it.Release()
    72  
    73  	if !it.Next() {
    74  		return 0, database.ErrNotFound
    75  	}
    76  
    77  	height, err := database.ParseUInt64(it.Key())
    78  	if err != nil {
    79  		return 0, err
    80  	}
    81  	return height, it.Error()
    82  }
    83  
    84  func (hi *heightIndex) GetBlockIDAtHeight(height uint64) (ids.ID, error) {
    85  	if blkID, found := hi.heightsCache.Get(height); found {
    86  		return blkID, nil
    87  	}
    88  
    89  	key := database.PackUInt64(height)
    90  	blkID, err := database.GetID(hi.heightDB, key)
    91  	if err != nil {
    92  		return ids.Empty, err
    93  	}
    94  	hi.heightsCache.Put(height, blkID)
    95  	return blkID, err
    96  }
    97  
    98  func (hi *heightIndex) SetBlockIDAtHeight(height uint64, blkID ids.ID) error {
    99  	hi.heightsCache.Put(height, blkID)
   100  	key := database.PackUInt64(height)
   101  	return database.PutID(hi.heightDB, key, blkID)
   102  }
   103  
   104  func (hi *heightIndex) DeleteBlockIDAtHeight(height uint64) error {
   105  	hi.heightsCache.Evict(height)
   106  	key := database.PackUInt64(height)
   107  	return hi.heightDB.Delete(key)
   108  }
   109  
   110  func (hi *heightIndex) GetForkHeight() (uint64, error) {
   111  	return database.GetUInt64(hi.metadataDB, forkKey)
   112  }
   113  
   114  func (hi *heightIndex) SetForkHeight(height uint64) error {
   115  	return database.PutUInt64(hi.metadataDB, forkKey, height)
   116  }