mirror of
https://github.com/luxfi/node.git
synced 2026-10-30 15:24:05 +00:00
The module already called itself github.com/luxfi/node while containing no node in Go: cmd/luxd was twenty-one lines that printed the size of a few types, and the Go column of the matrix measured a VM plugin. A repo that fetches the thing it claims to be has not replaced it, so the Go sources move in — 1515 files, the daemon and everything under it — and the build reaches outside this module for nothing. Rust and C++ sit beside it unchanged and are still measured against it by the differential. That is the point of one repo: the reference implementation and the two ports are the same checkout, so parity is a thing you can run rather than a thing you assert. Verified: builds, and the closure carries no lux-private — checked at build time rather than believed. The daemon starts twelve chains on a local network (P X C Q Z A B G K M F, plus D through its plugin) and reports healthy.
142 lines
3.6 KiB
Go
142 lines
3.6 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package state
|
|
|
|
import (
|
|
"github.com/luxfi/database"
|
|
"github.com/luxfi/database/prefixdb"
|
|
"github.com/luxfi/database/versiondb"
|
|
"github.com/luxfi/ids"
|
|
"github.com/luxfi/node/cache"
|
|
"github.com/luxfi/node/cache/lru"
|
|
)
|
|
|
|
const cacheSize = 8192 // max cache entries
|
|
|
|
var (
|
|
_ HeightIndex = (*heightIndex)(nil)
|
|
|
|
heightPrefix = []byte("height")
|
|
metadataPrefix = []byte("metadata")
|
|
|
|
forkKey = []byte("fork")
|
|
checkpointKey = []byte("checkpoint")
|
|
)
|
|
|
|
type HeightIndexGetter interface {
|
|
// GetMinimumHeight return the smallest height of an indexed blockID. If
|
|
// there are no indexed blockIDs, ErrNotFound will be returned.
|
|
GetMinimumHeight() (uint64, error)
|
|
GetBlockIDAtHeight(height uint64) (ids.ID, error)
|
|
|
|
// Fork height is stored when the first post-fork block/option is accepted.
|
|
// Before that, fork height won't be found.
|
|
GetForkHeight() (uint64, error)
|
|
GetCheckpoint() (ids.ID, error)
|
|
}
|
|
|
|
type HeightIndexWriter interface {
|
|
SetForkHeight(height uint64) error
|
|
SetBlockIDAtHeight(height uint64, blkID ids.ID) error
|
|
DeleteBlockIDAtHeight(height uint64) error
|
|
SetCheckpoint(blkID ids.ID) error
|
|
DeleteCheckpoint() error
|
|
}
|
|
|
|
// HeightIndex contains mapping of blockHeights to accepted proposer block IDs
|
|
// along with some metadata (fork height and checkpoint).
|
|
type HeightIndex interface {
|
|
HeightIndexWriter
|
|
HeightIndexGetter
|
|
versiondb.Commitable
|
|
}
|
|
|
|
type heightIndex struct {
|
|
versiondb.Commitable
|
|
|
|
// Caches block height -> proposerVMBlockID.
|
|
heightsCache cache.Cacher[uint64, ids.ID]
|
|
|
|
heightDB database.Database
|
|
metadataDB database.Database
|
|
}
|
|
|
|
func NewHeightIndex(db database.Database, commitable versiondb.Commitable) HeightIndex {
|
|
return &heightIndex{
|
|
Commitable: commitable,
|
|
|
|
heightsCache: lru.NewCache[uint64, ids.ID](cacheSize),
|
|
heightDB: prefixdb.New(heightPrefix, db),
|
|
metadataDB: prefixdb.New(metadataPrefix, db),
|
|
}
|
|
}
|
|
|
|
func (hi *heightIndex) GetMinimumHeight() (uint64, error) {
|
|
it := hi.heightDB.NewIterator()
|
|
defer it.Release()
|
|
|
|
if !it.Next() {
|
|
return 0, database.ErrNotFound
|
|
}
|
|
|
|
height, err := database.ParseUInt64(it.Key())
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return height, it.Error()
|
|
}
|
|
|
|
func (hi *heightIndex) GetBlockIDAtHeight(height uint64) (ids.ID, error) {
|
|
if blkID, found := hi.heightsCache.Get(height); found {
|
|
return blkID, nil
|
|
}
|
|
|
|
key := database.PackUInt64(height)
|
|
luxID, err := database.GetID(hi.heightDB, key)
|
|
if err != nil {
|
|
return ids.Empty, err
|
|
}
|
|
blkID := ids.ID(luxID)
|
|
hi.heightsCache.Put(height, blkID)
|
|
return blkID, nil
|
|
}
|
|
|
|
func (hi *heightIndex) SetBlockIDAtHeight(height uint64, blkID ids.ID) error {
|
|
hi.heightsCache.Put(height, blkID)
|
|
key := database.PackUInt64(height)
|
|
luxID := ([32]byte)(blkID)
|
|
return database.PutID(hi.heightDB, key, luxID)
|
|
}
|
|
|
|
func (hi *heightIndex) DeleteBlockIDAtHeight(height uint64) error {
|
|
hi.heightsCache.Evict(height)
|
|
key := database.PackUInt64(height)
|
|
return hi.heightDB.Delete(key)
|
|
}
|
|
|
|
func (hi *heightIndex) GetForkHeight() (uint64, error) {
|
|
return database.GetUInt64(hi.metadataDB, forkKey)
|
|
}
|
|
|
|
func (hi *heightIndex) SetForkHeight(height uint64) error {
|
|
return database.PutUInt64(hi.metadataDB, forkKey, height)
|
|
}
|
|
|
|
func (hi *heightIndex) GetCheckpoint() (ids.ID, error) {
|
|
luxID, err := database.GetID(hi.metadataDB, checkpointKey)
|
|
if err != nil {
|
|
return ids.Empty, err
|
|
}
|
|
return ids.ID(luxID), nil
|
|
}
|
|
|
|
func (hi *heightIndex) SetCheckpoint(blkID ids.ID) error {
|
|
luxID := ([32]byte)(blkID)
|
|
return database.PutID(hi.metadataDB, checkpointKey, luxID)
|
|
}
|
|
|
|
func (hi *heightIndex) DeleteCheckpoint() error {
|
|
return hi.metadataDB.Delete(checkpointKey)
|
|
}
|