mirror of
https://github.com/luxfi/consensus.git
synced 2026-09-24 00:26:58 +00:00
Reorganize consensus packages following Go conventions and best practices: Protocol Consolidation: - Move prism/, photon/, wave/ → protocol/ directory - Consolidate all protocol implementations under single namespace - Follows standard library pattern (encoding/json, encoding/xml) Package Naming: - Rename validators/ → validator/ (singular, lowercase per Go convention) - Aligns with stdlib patterns (net/http, database/sql) Import Path Updates: - Update all 241 Go files with new import paths - github.com/luxfi/consensus/prism → protocol/prism - github.com/luxfi/consensus/photon → protocol/photon - github.com/luxfi/consensus/wave → protocol/wave - github.com/luxfi/consensus/validators → validator Benefits: - Clear separation: core (contracts) vs protocol (algorithms) vs engine (runtime) - Improved discoverability (all protocols under protocol/) - Consistent with Go naming conventions - Zero breaking changes to core APIs - Easier to add new protocol implementations Test Results: - All 67+ tests passing across 21 packages - 100% test coverage maintained - No performance regression Structure: consensus/ ├── core/ # Pure contracts (interfaces, zero deps) ├── protocol/ # Consensus algorithms & mechanics │ ├── prism/ # Polling/quorum primitives │ ├── photon/ # Unary consensus │ ├── wave/ # N-ary consensus (FPC) │ └── ... # Other protocol phases ├── engine/ # Runtime glue (runs protocols) └── validator/ # Validator management (singular)
212 lines
5.3 KiB
Go
212 lines
5.3 KiB
Go
package block
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/luxfi/ids"
|
|
)
|
|
|
|
// Block is a block in the chain
|
|
type Block interface {
|
|
ID() ids.ID
|
|
Parent() ids.ID // Alias for ParentID for compatibility
|
|
ParentID() ids.ID
|
|
Height() uint64
|
|
Timestamp() time.Time
|
|
Status() uint8
|
|
Verify(context.Context) error
|
|
Accept(context.Context) error
|
|
Reject(context.Context) error
|
|
Bytes() []byte
|
|
}
|
|
|
|
// Epoch represents a P-Chain epoch for validator set coordination
|
|
type Epoch struct {
|
|
PChainHeight uint64 `serialize:"true" json:"pChainHeight"`
|
|
Number uint64 `serialize:"true" json:"number"`
|
|
StartTime int64 `serialize:"true" json:"startTime"`
|
|
}
|
|
|
|
// SignedBlock extends Block with proposer and epoch information
|
|
type SignedBlock interface {
|
|
Block
|
|
|
|
// PChainHeight returns the P-Chain height when this block was proposed
|
|
PChainHeight() uint64
|
|
|
|
// PChainEpoch returns the P-Chain epoch information
|
|
PChainEpoch() Epoch
|
|
|
|
// Timestamp returns the block timestamp
|
|
Timestamp() time.Time
|
|
|
|
// Proposer returns the ID of the node that proposed this block.
|
|
// If no node signed this block, ids.EmptyNodeID will be returned.
|
|
Proposer() ids.NodeID
|
|
}
|
|
|
|
// ChainVM defines the interface for a blockchain VM
|
|
type ChainVM interface {
|
|
// Initialize initializes the VM
|
|
Initialize(
|
|
ctx context.Context,
|
|
chainCtx interface{},
|
|
db interface{},
|
|
genesisBytes []byte,
|
|
upgradeBytes []byte,
|
|
configBytes []byte,
|
|
msgChan interface{},
|
|
fxs []interface{},
|
|
appSender interface{},
|
|
) error
|
|
|
|
// BuildBlock builds a new block
|
|
BuildBlock(context.Context) (Block, error)
|
|
|
|
// ParseBlock parses a block from bytes
|
|
ParseBlock(context.Context, []byte) (Block, error)
|
|
|
|
// GetBlock gets a block by ID
|
|
GetBlock(context.Context, ids.ID) (Block, error)
|
|
|
|
// Shutdown shuts down the VM
|
|
Shutdown(context.Context) error
|
|
|
|
// NewHTTPHandler returns a new HTTP handler for the VM
|
|
NewHTTPHandler(context.Context) (interface{}, error)
|
|
|
|
// SetState sets the VM state
|
|
SetState(context.Context, uint32) error
|
|
|
|
// Version returns the VM version
|
|
Version(context.Context) (string, error)
|
|
|
|
// Network callbacks - optional
|
|
Connected(context.Context, ids.NodeID, interface{}) error
|
|
Disconnected(context.Context, ids.NodeID) error
|
|
HealthCheck(context.Context) (interface{}, error)
|
|
|
|
// GetBlockIDAtHeight gets block ID at a specific height
|
|
GetBlockIDAtHeight(context.Context, uint64) (ids.ID, error)
|
|
|
|
// SetPreference sets the preferred block
|
|
SetPreference(context.Context, ids.ID) error
|
|
|
|
// LastAccepted returns the last accepted block
|
|
LastAccepted(context.Context) (ids.ID, error)
|
|
|
|
// WaitForEvent blocks until an event occurs that should trigger block building
|
|
WaitForEvent(context.Context) (interface{}, error)
|
|
}
|
|
|
|
// StateSyncMode defines state sync modes
|
|
type StateSyncMode uint8
|
|
|
|
const (
|
|
StateSyncSkipped StateSyncMode = iota
|
|
StateSyncStatic
|
|
StateSyncDynamic
|
|
)
|
|
|
|
// StateSyncableVM defines a VM that supports state sync
|
|
type StateSyncableVM interface {
|
|
ChainVM
|
|
|
|
// StateSyncEnabled returns whether state sync is enabled
|
|
StateSyncEnabled(context.Context) (bool, error)
|
|
|
|
// GetOngoingSyncStateSummary returns the ongoing sync state summary
|
|
GetOngoingSyncStateSummary(context.Context) (StateSummary, error)
|
|
|
|
// GetLastStateSummary returns the last state summary
|
|
GetLastStateSummary(context.Context) (StateSummary, error)
|
|
|
|
// ParseStateSummary parses a state summary
|
|
ParseStateSummary(context.Context, []byte) (StateSummary, error)
|
|
|
|
// GetStateSummary gets a state summary by height
|
|
GetStateSummary(context.Context, uint64) (StateSummary, error)
|
|
}
|
|
|
|
// StateSummary represents a state summary
|
|
type StateSummary interface {
|
|
ID() ids.ID
|
|
Height() uint64
|
|
Bytes() []byte
|
|
Accept(context.Context) (StateSyncMode, error)
|
|
}
|
|
|
|
// BuildBlockWithContextVM extends ChainVM with context support
|
|
type BuildBlockWithContextVM interface {
|
|
ChainVM
|
|
BuildBlockWithContext(context.Context, *Context) (Block, error)
|
|
}
|
|
|
|
// Context provides context for building blocks
|
|
type Context struct {
|
|
PChainHeight uint64
|
|
}
|
|
|
|
// WithVerifyContext provides verify context support
|
|
type WithVerifyContext interface {
|
|
// VerifyWithContext verifies with context
|
|
VerifyWithContext(context.Context, *Context) error
|
|
|
|
// ShouldVerifyWithContext returns whether to verify with context
|
|
ShouldVerifyWithContext(context.Context) (bool, error)
|
|
}
|
|
|
|
// GetAncestors retrieves ancestors of a block up to a maximum count
|
|
func GetAncestors(
|
|
ctx context.Context,
|
|
vm ChainVM,
|
|
blkID ids.ID,
|
|
maxBlocks int,
|
|
maxBlocksSize int,
|
|
maxBlocksRetrievalTime time.Duration,
|
|
) ([][]byte, error) {
|
|
if maxBlocks <= 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
startTime := time.Now()
|
|
ancestors := make([][]byte, 0, maxBlocks)
|
|
totalSize := 0
|
|
|
|
for len(ancestors) < maxBlocks && totalSize < maxBlocksSize {
|
|
if time.Since(startTime) > maxBlocksRetrievalTime {
|
|
break
|
|
}
|
|
|
|
blk, err := vm.GetBlock(ctx, blkID)
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
blkBytes := blk.Bytes()
|
|
totalSize += len(blkBytes)
|
|
if totalSize > maxBlocksSize {
|
|
break
|
|
}
|
|
|
|
ancestors = append(ancestors, blkBytes)
|
|
blkID = blk.ParentID()
|
|
}
|
|
|
|
return ancestors, nil
|
|
}
|
|
|
|
// Network callbacks
|
|
type ChainVMWithNetwork interface {
|
|
ChainVM
|
|
Connected(ctx context.Context, nodeID ids.NodeID, version interface{}) error
|
|
Disconnected(ctx context.Context, nodeID ids.NodeID) error
|
|
}
|
|
|
|
// HealthCheck interface
|
|
type ChainVMWithHealth interface {
|
|
ChainVM
|
|
HealthCheck(ctx context.Context) (interface{}, error)
|
|
}
|