Files
vm/chain/blocktest/block.go
zeekay 1ffffe6ac5 chain/blocktest: add test utilities for block and VM mocking
Add blocktest package with test helpers consolidated from
node/vms/components/chain/blocktest. Provides:
- Block: test block implementation with status tracking
- VM/ChainVM: mock VM with function field overrides
- BatchedVM: mock for batch operations
- StateSyncableVM: mock for state sync
- StateSummary: test state summary implementation

This enables node, coreth, and EVM to share test utilities
from a single location without circular dependencies.
2026-01-01 14:06:10 -08:00

141 lines
2.6 KiB
Go

// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package blocktest
import (
"context"
"fmt"
"time"
"github.com/luxfi/ids"
)
var (
GenesisID = ids.GenerateTestID()
GenesisHeight = uint64(0)
GenesisTimestamp = time.Unix(1, 0)
GenesisBytes = []byte("genesis")
nextID = uint64(1)
)
// Status constants
const (
Unknown uint8 = 0
Processing uint8 = 1
Rejected uint8 = 2
Accepted uint8 = 3
)
// ReadOnlyChain provides read-only access to chain state.
// This is a minimal interface for testing purposes.
type ReadOnlyChain interface {
// GetTimestamp returns the chain timestamp
GetTimestamp() uint64
}
// Block is a test block that implements block.Block
type Block struct {
IDV ids.ID
HeightV uint64
TimestampV time.Time
ParentV ids.ID
BytesV []byte
StatusV uint8
ErrV error
state ReadOnlyChain
}
var Genesis = &Block{
IDV: GenesisID,
HeightV: GenesisHeight,
TimestampV: GenesisTimestamp,
ParentV: ids.Empty,
BytesV: GenesisBytes,
StatusV: Accepted,
}
func (b *Block) ID() ids.ID {
return b.IDV
}
func (b *Block) Height() uint64 {
return b.HeightV
}
func (b *Block) Timestamp() time.Time {
return b.TimestampV
}
func (b *Block) Parent() ids.ID {
return b.ParentV
}
func (b *Block) ParentID() ids.ID {
return b.ParentV
}
func (b *Block) Bytes() []byte {
return b.BytesV
}
func (b *Block) Verify(context.Context) error {
if b.ErrV != nil {
return b.ErrV
}
return nil
}
func (b *Block) Status() uint8 {
return b.StatusV
}
func (b *Block) Accept(context.Context) error {
if b.ErrV != nil {
return b.ErrV
}
b.StatusV = Accepted
return nil
}
func (b *Block) Reject(context.Context) error {
if b.ErrV != nil {
return b.ErrV
}
b.StatusV = Rejected
return nil
}
func (b *Block) State() ReadOnlyChain {
return b.state
}
// BuildChild creates a child block of the given parent
func BuildChild(parent *Block) *Block {
nextID++
blockID := ids.ID{}
copy(blockID[:], fmt.Sprintf("block_%d", nextID))
timestamp := parent.Timestamp().Add(time.Second)
return &Block{
IDV: blockID,
HeightV: parent.Height() + 1,
TimestampV: timestamp,
ParentV: parent.ID(),
BytesV: []byte(fmt.Sprintf("block_%d", nextID)),
StatusV: Processing,
}
}
// MakeLastAcceptedBlockF creates a LastAcceptedF function that returns the last block in the chain
func MakeLastAcceptedBlockF(blocks []*Block) func(context.Context) (ids.ID, error) {
return func(context.Context) (ids.ID, error) {
if len(blocks) == 0 {
return ids.Empty, nil
}
return blocks[len(blocks)-1].ID(), nil
}
}