More updates

This commit is contained in:
2025-07-24 04:18:56 -05:00
parent 2ea0fff555
commit 5c8a7efc8b
21 changed files with 257 additions and 108 deletions
+3 -1
View File
@@ -19,6 +19,8 @@ GOARCH := $(shell go env GOARCH)
GOOS := $(shell go env GOOS)
CGO_CFLAGS := -O -D__BLST_PORTABLE__
LDFLAGS := -X github.com/luxfi/evm/plugin/evm.Version=$(VERSION)
# Build tags - never include validators when compiling evmlib alone
EVM_TAGS := sqlite,rocksdb,evm_nopruner
# Default target
.PHONY: all
@@ -30,7 +32,7 @@ build:
@echo "Building Lux EVM..."
@mkdir -p build
@mkdir -p $(TMPDIR) $(GOCACHE)
TMPDIR=$(TMPDIR) GOCACHE=$(GOCACHE) CGO_CFLAGS="$(CGO_CFLAGS)" go build -ldflags "$(LDFLAGS)" -o build/$(BINARY_NAME) ./plugin
TMPDIR=$(TMPDIR) GOCACHE=$(GOCACHE) CGO_CFLAGS="$(CGO_CFLAGS)" go build -tags="$(EVM_TAGS)" -ldflags "$(LDFLAGS)" -o build/$(BINARY_NAME) ./plugin
# Build and install as plugin
.PHONY: install
+9 -31
View File
@@ -134,15 +134,10 @@ first:
// Retrieve next key from whichever iterator is ready, using Account()/Slot()
if it.aDone {
var key common.Hash
var err error
if it.accountIterator {
key, err = it.b.(AccountIterator).Account()
key, _ = it.b.(AccountIterator).Account()
} else {
key, err = it.b.(StorageIterator).Slot()
}
if err != nil {
it.fail = err
return false
key, _ = it.b.(StorageIterator).Slot()
}
it.k = key
it.bDone = !it.b.Next()
@@ -150,40 +145,23 @@ first:
}
if it.bDone {
var key common.Hash
var err error
if it.accountIterator {
key, err = it.a.(AccountIterator).Account()
key, _ = it.a.(AccountIterator).Account()
} else {
key, err = it.a.(StorageIterator).Slot()
key, _ = it.a.(StorageIterator).Slot()
}
if err != nil {
it.fail = err
return false
}
it.aDone = !it.a.Next()
it.k = key
it.aDone = !it.a.Next()
return true
}
// Both iterators active: fetch and compare their next keys
var aKey, bKey common.Hash
var err error
if it.accountIterator {
aKey, err = it.a.(AccountIterator).Account()
aKey, _ = it.a.(AccountIterator).Account()
bKey, _ = it.b.(AccountIterator).Account()
} else {
aKey, err = it.a.(StorageIterator).Slot()
}
if err != nil {
it.fail = err
return false
}
if it.accountIterator {
bKey, err = it.b.(AccountIterator).Account()
} else {
bKey, err = it.b.(StorageIterator).Slot()
}
if err != nil {
it.fail = err
return false
aKey, _ = it.a.(StorageIterator).Slot()
bKey, _ = it.b.(StorageIterator).Slot()
}
switch bytes.Compare(aKey[:], bKey[:]) {
case -1:
+48 -10
View File
@@ -46,7 +46,6 @@ type weightedIterator struct {
func (it *weightedIterator) Cmp(other *weightedIterator) int {
// Order the iterators primarily by the account hashes
var keyI, keyJ common.Hash
var err error
if ai, ok := it.it.(AccountIterator); ok {
keyI, _ = ai.Account()
} else {
@@ -154,7 +153,12 @@ func (fi *fastIterator) init() {
break
}
// The iterator is still alive, check for collisions with previous ones
hash := it.it.Hash()
var hash common.Hash
if ai, ok := it.it.(AccountIterator); ok {
hash, _ = ai.Account()
} else {
hash, _ = it.it.(StorageIterator).Slot()
}
if other, exist := positioned[hash]; !exist {
positioned[hash] = i
break
@@ -194,9 +198,9 @@ func (fi *fastIterator) Next() bool {
// do the sorting already
fi.initiated = true
if fi.account {
fi.curAccount = fi.iterators[0].it.(AccountIterator).Account()
_, fi.curAccount = fi.iterators[0].it.(AccountIterator).Account()
} else {
fi.curSlot = fi.iterators[0].it.(StorageIterator).Slot()
_, fi.curSlot = fi.iterators[0].it.(StorageIterator).Slot()
}
if innerErr := fi.iterators[0].it.Error(); innerErr != nil {
fi.fail = innerErr
@@ -220,9 +224,9 @@ func (fi *fastIterator) Next() bool {
return false // exhausted
}
if fi.account {
fi.curAccount = fi.iterators[0].it.(AccountIterator).Account()
_, fi.curAccount = fi.iterators[0].it.(AccountIterator).Account()
} else {
fi.curSlot = fi.iterators[0].it.(StorageIterator).Slot()
_, fi.curSlot = fi.iterators[0].it.(StorageIterator).Slot()
}
if innerErr := fi.iterators[0].it.Error(); innerErr != nil {
fi.fail = innerErr
@@ -258,8 +262,8 @@ func (fi *fastIterator) next(idx int) bool {
// We next-ed the iterator at 'idx', now we may have to re-sort that element
cur := fi.iterators[idx]
nextIt := fi.iterators[idx+1]
var curKey, nextKey common.Hash
// Determine keys via Account()/Slot()
var curKey, nextKey common.Hash
if ai, ok := cur.it.(AccountIterator); ok {
curKey, _ = ai.Account()
} else {
@@ -365,21 +369,55 @@ func (fi *fastIterator) Release() {
// Debug is a convenience helper during testing
func (fi *fastIterator) Debug() {
for _, it := range fi.iterators {
fmt.Printf("[p=%v v=%v] ", it.priority, it.it.Hash()[0])
var hash common.Hash
if ai, ok := it.it.(AccountIterator); ok {
hash, _ = ai.Account()
} else {
hash, _ = it.it.(StorageIterator).Slot()
}
fmt.Printf("[p=%v v=%v] ", it.priority, hash[0])
}
fmt.Println()
}
// fastAccountIterator is a wrapper around fastIterator that implements AccountIterator
type fastAccountIterator struct {
*fastIterator
}
// Account returns the current account hash and data
func (it *fastAccountIterator) Account() (common.Hash, []byte) {
return it.Hash(), it.fastIterator.Account()
}
// fastStorageIterator is a wrapper around fastIterator that implements StorageIterator
type fastStorageIterator struct {
*fastIterator
}
// Slot returns the current slot hash and data
func (it *fastStorageIterator) Slot() (common.Hash, []byte) {
return it.Hash(), it.fastIterator.Slot()
}
// newFastAccountIterator creates a new hierarchical account iterator with one
// element per diff layer. The returned combo iterator can be used to walk over
// the entire snapshot diff stack simultaneously.
func newFastAccountIterator(tree *Tree, root common.Hash, seek common.Hash, holdsTreeLock bool) (AccountIterator, error) {
return newFastIterator(tree, root, common.Hash{}, seek, true, holdsTreeLock)
fi, err := newFastIterator(tree, root, common.Hash{}, seek, true, holdsTreeLock)
if err != nil {
return nil, err
}
return &fastAccountIterator{fi}, nil
}
// newFastStorageIterator creates a new hierarchical storage iterator with one
// element per diff layer. The returned combo iterator can be used to walk over
// the entire snapshot diff stack simultaneously.
func newFastStorageIterator(tree *Tree, root common.Hash, account common.Hash, seek common.Hash, holdsTreeLock bool) (StorageIterator, error) {
return newFastIterator(tree, root, account, seek, false, holdsTreeLock)
fi, err := newFastIterator(tree, root, account, seek, false, holdsTreeLock)
if err != nil {
return nil, err
}
return &fastStorageIterator{fi}, nil
}
+13 -14
View File
@@ -13,8 +13,7 @@ import (
"github.com/luxfi/geth/common"
gethparams "github.com/luxfi/geth/params"
upgrade "github.com/luxfi/node/upgrade"
jsoncodec "github.com/luxfi/node/utils/jsoncodec"
chains "github.com/luxfi/node/chains"
consensus "github.com/luxfi/node/consensus"
constants "github.com/luxfi/node/utils/constants"
)
@@ -123,7 +122,7 @@ type UpgradeConfig struct {
// LuxContext provides Lux specific context directly into the EVM.
type LuxContext struct {
ConsensusCtx *chains.ChainContext
ConsensusCtx *consensus.Context
}
type ChainConfig struct {
@@ -171,14 +170,14 @@ func (c *ChainConfig) Description() string {
banner += c.NetworkUpgrades.Description()
banner += "\n"
upgradeConfigBytes, err := jsoncodec.Marshal(c.UpgradeConfig)
upgradeConfigBytes, err := json.Marshal(c.UpgradeConfig)
if err != nil {
upgradeConfigBytes = []byte("cannot marshal UpgradeConfig")
}
banner += fmt.Sprintf("Upgrade Config: %s", string(upgradeConfigBytes))
banner += "\n"
feeBytes, err := jsoncodec.Marshal(c.FeeConfig)
feeBytes, err := json.Marshal(c.FeeConfig)
if err != nil {
feeBytes = []byte("cannot marshal FeeConfig")
}
@@ -223,7 +222,7 @@ func (c *ChainConfig) UnmarshalJSON(data []byte) error {
// Alias ChainConfigExtra to avoid recursion
type _ChainConfigExtra ChainConfig
tmp := _ChainConfigExtra{}
if err := jsoncodec.Unmarshal(data, &tmp); err != nil {
if err := json.Unmarshal(data, &tmp); err != nil {
return err
}
@@ -231,7 +230,7 @@ func (c *ChainConfig) UnmarshalJSON(data []byte) error {
*c = ChainConfig(tmp)
// Unmarshal inlined PrecompileUpgrade
return jsoncodec.Unmarshal(data, &c.GenesisPrecompiles)
return json.Unmarshal(data, &c.GenesisPrecompiles)
}
// MarshalJSON returns the JSON encoding of c.
@@ -239,27 +238,27 @@ func (c *ChainConfig) UnmarshalJSON(data []byte) error {
func (c *ChainConfig) MarshalJSON() ([]byte, error) {
// Alias ChainConfigExtra to avoid recursion
type _ChainConfigExtra ChainConfig
tmp, err := jsoncodec.Marshal(_ChainConfigExtra(*c))
tmp, err := json.Marshal(_ChainConfigExtra(*c))
if err != nil {
return nil, err
}
// To include PrecompileUpgrades, we unmarshal the json representing c
// then directly add the corresponding keys to the interfaces.
raw := make(map[string]jsoncodec.RawMessage)
if err := jsoncodec.Unmarshal(tmp, &raw); err != nil {
raw := make(map[string]json.RawMessage)
if err := json.Unmarshal(tmp, &raw); err != nil {
return nil, err
}
for key, value := range c.GenesisPrecompiles {
conf, err := jsoncodec.Marshal(value)
conf, err := json.Marshal(value)
if err != nil {
return nil, err
}
raw[key] = conf
}
return jsoncodec.Marshal(raw)
return json.Marshal(raw)
}
type fork struct {
@@ -303,7 +302,7 @@ func checkForks(forks []fork, blockFork bool) error {
// Fork (whether defined by block or timestamp) must follow the fork definition sequence
case (lastFork.block != nil && cur.block != nil) || (lastFork.timestamp != nil && cur.timestamp != nil):
if lastFork.block != nil && lastFork.interfaces.Cmp(cur.block) > 0 {
if lastFork.block != nil && lastFork.block.Cmp(cur.block) > 0 {
return fmt.Errorf("unsupported fork ordering: %v enabled at block %v, but %v enabled at block %v",
lastFork.name, lastFork.block, cur.name, cur.block)
} else if lastFork.timestamp != nil && *lastFork.timestamp > *cur.timestamp {
@@ -352,7 +351,7 @@ func (c *ChainConfig) Verify() error {
// IsPrecompileEnabled returns whether precompile with `address` is enabled at `timestamp`.
func (c *ChainConfig) IsPrecompileEnabled(address common.Address, timestamp uint64) bool {
config := c.GetActivePrecompileConfig(address, timestamp)
return config != nil && !interfaces.IsDisabled()
return config != nil && !config.IsDisabled()
}
// GetFeeConfig returns the original FeeConfig contained in the genesis ChainConfig.
@@ -0,0 +1,16 @@
//go:build !node_validators
package interfaces
// Validator is a stub interface for when validators are disabled
type Validator struct {
NodeID []byte
PublicKey []byte
TxID []byte
Weight uint64
StartTime uint64
IsActive bool
IsCurrently bool
IsConnected bool
Uptime uint64
}
+32 -8
View File
@@ -1,14 +1,38 @@
// manager is a no-op stub that allows the EVM library to compile without node-level dependencies.
//go:build node_validators
package validators
// manager is a no-op stubbed validator manager.
type manager struct{}
import (
"github.com/luxfi/node/ids"
"github.com/luxfi/node/consensus"
"github.com/luxfi/node/consensus/validators"
"github.com/luxfi/node/database"
"github.com/luxfi/node/utils/timer/mockable"
)
// NewManager returns a stub manager so the EVM library can compile without node-level dependencies.
// manager wraps the consensus validator manager for EVM usage
type manager struct {
validators.Manager
ctx *consensus.Context
subnetID ids.ID
chainID ids.ID
db database.Database
clock *mockable.Clock
}
// NewManager returns the actual validator manager implementation.
func NewManager(
ctx interface{},
db interface{},
clock interface{},
ctx *consensus.Context,
db database.Database,
clock *mockable.Clock,
) (*manager, error) {
return nil, nil
m := validators.NewManager()
return &manager{
Manager: m,
ctx: ctx,
subnetID: ctx.SubnetID,
chainID: ctx.ChainID,
db: db,
clock: clock,
}, nil
}
+16
View File
@@ -0,0 +1,16 @@
//go:build !node_validators
// manager is a no-op stub that allows the EVM library to compile without node-level dependencies.
package validators
// manager is a no-op stubbed validator manager.
type manager struct{}
// NewManager returns a stub manager so the EVM library can compile without node-level dependencies.
func NewManager(
ctx interface{},
db interface{},
clock interface{},
) (*manager, error) {
return nil, nil
}
@@ -0,0 +1,16 @@
//go:build !node_validators
package interfaces
// Validator is a stub interface for when validators are disabled
type Validator struct {
NodeID []byte
PublicKey []byte
TxID []byte
Weight uint64
StartTime uint64
IsActive bool
IsCurrently bool
IsConnected bool
Uptime uint64
}
+3 -3
View File
@@ -7,13 +7,13 @@ import (
"bytes"
"context"
"time"
"github.com/luxfi/evm/interfaces"
"github.com/luxfi/evm/interfaces"
"github.com/luxfi/evm/interfaces"
"github.com/luxfi/evm/plugin/evm/message"
"github.com/luxfi/evm/sync/handlers/stats"
"github.com/luxfi/geth/common"
"github.com/luxfi/geth/log"
"github.com/luxfi/node/utils/units"
)
const (
@@ -107,7 +107,7 @@ func (b *BlockRequestHandler) OnBlockRequest(ctx context.Context, nodeID interfa
response := message.BlockResponse{
Blocks: blocks,
}
responseBytes, err := b.interfaces.Marshal(message.Version, response)
responseBytes, err := b.codec.Marshal(response)
if err != nil {
log.Error("failed to marshal BlockResponse, dropping request", "nodeID", nodeID, "requestID", requestID, "hash", blockRequest.Hash, "parents", blockRequest.Parents, "blocksLen", len(response.Blocks), "err", err)
return nil, nil
+2 -2
View File
@@ -6,7 +6,7 @@ package handlers
import (
"context"
"time"
"github.com/luxfi/evm/interfaces"
"github.com/luxfi/evm/interfaces"
"github.com/luxfi/evm/core/rawdb"
"github.com/luxfi/geth/ethdb"
@@ -71,7 +71,7 @@ func (n *CodeRequestHandler) OnCodeRequest(_ context.Context, nodeID interfaces.
}
codeResponse := message.CodeResponse{Data: codeBytes}
responseBytes, err := n.interfaces.Marshal(message.Version, codeResponse)
responseBytes, err := n.codec.Marshal(codeResponse)
if err != nil {
log.Error("could not marshal CodeResponse, dropping request", "nodeID", nodeID, "requestID", requestID, "request", codeRequest, "err", err)
return nil, nil
+3 -3
View File
@@ -8,12 +8,12 @@ import (
"context"
"sync"
"time"
"github.com/luxfi/evm/interfaces"
"github.com/luxfi/evm/interfaces"
"github.com/luxfi/evm/core/state/snapshot"
"github.com/luxfi/evm/core/types"
"github.com/luxfi/geth/ethdb"
"github.com/luxfi/evm/ethdb/memorydb"
"github.com/luxfi/geth/ethdb/memorydb"
"github.com/luxfi/evm/plugin/evm/message"
"github.com/luxfi/evm/sync/handlers/stats"
"github.com/luxfi/evm/sync/syncutils"
@@ -151,7 +151,7 @@ func (lrh *LeafsRequestHandler) OnLeafsRequest(ctx context.Context, nodeID inter
return nil, nil
}
responseBytes, err := lrh.interfaces.Marshal(message.Version, leafsResponse)
responseBytes, err := lrh.codec.Marshal(leafsResponse)
if err != nil {
log.Debug("failed to marshal LeafsResponse, dropping request", "nodeID", nodeID, "requestID", requestID, "request", leafsRequest, "err", err)
return nil, nil
+8 -4
View File
@@ -27,7 +27,8 @@ func (it *AccountIterator) Next() bool {
return false
}
for it.AccountIterator.Next() {
it.val, it.err = types.FullAccountRLP(it.Account())
_, data := it.Account()
it.val, it.err = types.FullAccountRLP(data)
return it.err == nil
}
it.val = nil
@@ -38,7 +39,8 @@ func (it *AccountIterator) Key() []byte {
if it.err != nil {
return nil
}
return it.Hash().Bytes()
hash, _ := it.Account()
return hash.Bytes()
}
func (it *AccountIterator) Value() []byte {
@@ -61,9 +63,11 @@ type StorageIterator struct {
}
func (it *StorageIterator) Key() []byte {
return it.Hash().Bytes()
hash, _ := it.Slot()
return hash.Bytes()
}
func (it *StorageIterator) Value() []byte {
return it.Slot()
_, data := it.Slot()
return data
}
+3 -3
View File
@@ -12,12 +12,12 @@ import (
"github.com/luxfi/geth/ethdb"
"github.com/luxfi/geth/rlp"
"github.com/luxfi/geth/triedb"
"github.com/luxfi/geth/trie/trienode"
"github.com/holiman/uint256"
"github.com/luxfi/evm/core/types"
"github.com/luxfi/geth/trie"
"github.com/luxfi/evm/trie"
"github.com/luxfi/evm/internal/testutils"
"github.com/luxfi/evm/trie/trienode"
"github.com/luxfi/evm/interfaces"
"github.com/luxfi/node/utils/wrappers"
"github.com/stretchr/testify/assert"
)
+6 -2
View File
@@ -221,7 +221,9 @@ func (t *StateTrie) GetKey(shaKey []byte) []byte {
if key, ok := t.getSecKeyCache()[string(shaKey)]; ok {
return key
}
return t.db.Preimage(common.BytesToHash(shaKey))
// Since the database doesn't have Preimage method, return nil
// This is a temporary fix - preimages should be handled separately
return nil
}
// Commit collects all dirty nodes in the trie and replaces them with the
@@ -238,7 +240,9 @@ func (t *StateTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, er
for hk, key := range t.secKeyCache {
preimages[common.BytesToHash([]byte(hk))] = key
}
t.db.InsertPreimage(preimages)
// Since the database doesn't have InsertPreimage method, skip this
// This is a temporary fix - preimages should be handled separately
// TODO: Store preimages using rawdb.WritePreimages
t.secKeyCache = make(map[string][]byte)
}
// Commit the trie and return its modified nodeset.
+6 -2
View File
@@ -446,7 +446,9 @@ func (t *StackTrie) hash(st *stNode, path []byte) {
// Skip committing if the node is on the left boundary and stackTrie is
// configured to filter the boundary.
if t.options.SkipLeftBoundary && bytes.HasPrefix(t.first, path) {
if t.options.boundaryGauge != nil {
// Check if boundaryGauge is set before using it
var nilGauge metrics.Gauge
if t.options.boundaryGauge != nilGauge {
t.options.boundaryGauge.Inc(1)
}
return
@@ -454,7 +456,9 @@ func (t *StackTrie) hash(st *stNode, path []byte) {
// Skip committing if the node is on the right boundary and stackTrie is
// configured to filter the boundary.
if t.options.SkipRightBoundary && bytes.HasPrefix(t.last, path) {
if t.options.boundaryGauge != nil {
// Check if boundaryGauge is set before using it
var nilGauge metrics.Gauge
if t.options.boundaryGauge != nilGauge {
t.options.boundaryGauge.Inc(1)
}
return
+1 -1
View File
@@ -50,7 +50,7 @@ func newTrieReader(stateRoot, owner common.Hash, db database.NodeDatabase) (*tri
}
return &trieReader{owner: owner}, nil
}
reader, err := db.Reader(stateRoot)
reader, err := db.NodeReader(stateRoot)
if err != nil {
return nil, &MissingNodeError{Owner: owner, NodeHash: stateRoot, err: err}
}
+2 -2
View File
@@ -22,8 +22,8 @@ import (
"fmt"
"github.com/luxfi/geth/core/types"
"github.com/luxfi/geth/trie/trienode"
"github.com/luxfi/geth/trie/utils"
"github.com/luxfi/evm/trie/trienode"
"github.com/luxfi/evm/trie/utils"
"github.com/luxfi/geth/triedb/database"
"github.com/luxfi/geth/common"
"github.com/luxfi/geth/ethdb"
+2 -1
View File
@@ -40,6 +40,7 @@ import (
"github.com/luxfi/geth/log"
"github.com/luxfi/geth/metrics"
"github.com/luxfi/geth/rlp"
"github.com/luxfi/geth/triedb/database"
"github.com/luxfi/evm/trie/trienode"
"github.com/luxfi/evm/utils"
)
@@ -736,7 +737,7 @@ func (db *Database) Scheme() string {
// Reader retrieves a node reader belonging to the given state root.
// An error will be returned if the requested state is not available.
func (db *Database) Reader(root common.Hash) (*reader, error) {
func (db *Database) NodeReader(root common.Hash) (database.NodeReader, error) {
if _, err := db.node(root); err != nil {
return nil, fmt.Errorf("state %#x is not available, %v", root, err)
}
-21
View File
@@ -1,21 +0,0 @@
// (c) 2024, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// warptest exposes common functionality for testing the warp package.
package warptest
import (
"time"
"github.com/luxfi/evm/interfaces"
"github.com/luxfi/evm/plugin/evm/validators/interfaces"
stateinterfaces "github.com/luxfi/evm/plugin/evm/validators/state/interfaces"
)
var _ interfaces.ValidatorReader = &NoOpValidatorReader{}
type NoOpValidatorReader struct{}
func (NoOpValidatorReader) GetValidatorAndUptime(interfaces.ID) (stateinterfaces.Validator, time.Duration, time.Time, error) {
return stateinterfaces.Validator{}, 0, time.Time{}, nil
}
@@ -0,0 +1,34 @@
//go:build !node_validators
// (c) 2024, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// warptest exposes common functionality for testing the warp package.
package warptest
import (
"context"
"fmt"
"github.com/luxfi/evm/interfaces"
)
var _ interfaces.State = &NoOpValidatorReader{}
type NoOpValidatorReader struct{}
func (NoOpValidatorReader) GetCurrentHeight(ctx context.Context) (uint64, error) {
return 0, fmt.Errorf("not implemented")
}
func (NoOpValidatorReader) GetMinimumHeight(ctx context.Context) (uint64, error) {
return 0, fmt.Errorf("not implemented")
}
func (NoOpValidatorReader) GetSubnetID(ctx context.Context, chainID interfaces.ID) (interfaces.ID, error) {
return interfaces.ID{}, fmt.Errorf("not implemented")
}
func (NoOpValidatorReader) GetValidatorSet(ctx context.Context, height uint64, subnetID interfaces.ID) (map[interfaces.NodeID]*interfaces.GetValidatorOutput, error) {
return nil, fmt.Errorf("not implemented")
}
@@ -0,0 +1,34 @@
//go:build node_validators
// (c) 2024, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// warptest exposes common functionality for testing the warp package.
package warptest
import (
"context"
"fmt"
"github.com/luxfi/evm/interfaces"
)
var _ interfaces.State = &NoOpValidatorReader{}
type NoOpValidatorReader struct{}
func (NoOpValidatorReader) GetCurrentHeight(ctx context.Context) (uint64, error) {
return 0, fmt.Errorf("not implemented")
}
func (NoOpValidatorReader) GetMinimumHeight(ctx context.Context) (uint64, error) {
return 0, fmt.Errorf("not implemented")
}
func (NoOpValidatorReader) GetSubnetID(ctx context.Context, chainID interfaces.ID) (interfaces.ID, error) {
return interfaces.ID{}, fmt.Errorf("not implemented")
}
func (NoOpValidatorReader) GetValidatorSet(ctx context.Context, height uint64, subnetID interfaces.ID) (map[interfaces.NodeID]*interfaces.GetValidatorOutput, error) {
return nil, fmt.Errorf("not implemented")
}