feat: add appsender and engine/core packages

Add missing packages required by EVM:
- core/appsender: AppSender interface for application messaging
- engine/core: Common engine types including AppSender, AppHandler, AppError
This commit is contained in:
2026-02-05 21:17:16 -08:00
parent 78243273d6
commit c7991c3a84
2 changed files with 296 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// Package appsender defines the interface for sending application messages
// between nodes in the consensus network.
package appsender
import (
"context"
"github.com/luxfi/ids"
"github.com/luxfi/math/set"
)
// AppSender defines the interface for sending application-level messages
// in the consensus network.
type AppSender interface {
// SendAppRequest sends an application request to the specified nodes.
// The response will be received via the AppResponse callback.
SendAppRequest(
ctx context.Context,
nodeIDs set.Set[ids.NodeID],
requestID uint32,
appRequestBytes []byte,
) error
// SendAppResponse sends a response to a previously received request.
SendAppResponse(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
appResponseBytes []byte,
) error
// SendAppError sends an error response to a previously received request.
SendAppError(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
errorCode int32,
errorMessage string,
) error
// SendAppGossip sends a gossip message to nodes.
SendAppGossip(
ctx context.Context,
nodeIDs set.Set[ids.NodeID],
appGossipBytes []byte,
) error
// SendAppGossipSpecific sends a gossip message to specific nodes.
SendAppGossipSpecific(
ctx context.Context,
nodeIDs set.Set[ids.NodeID],
appGossipBytes []byte,
) error
}
// NoOpAppSender is an AppSender that does nothing.
type NoOpAppSender struct{}
func (NoOpAppSender) SendAppRequest(context.Context, set.Set[ids.NodeID], uint32, []byte) error {
return nil
}
func (NoOpAppSender) SendAppResponse(context.Context, ids.NodeID, uint32, []byte) error {
return nil
}
func (NoOpAppSender) SendAppError(context.Context, ids.NodeID, uint32, int32, string) error {
return nil
}
func (NoOpAppSender) SendAppGossip(context.Context, set.Set[ids.NodeID], []byte) error {
return nil
}
func (NoOpAppSender) SendAppGossipSpecific(context.Context, set.Set[ids.NodeID], []byte) error {
return nil
}
+216
View File
@@ -0,0 +1,216 @@
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// Package core provides common engine types and interfaces used across
// the consensus system.
package core
import (
"context"
"time"
"github.com/luxfi/ids"
"github.com/luxfi/math/set"
)
// AppError represents an application-level error that can be returned
// when handling requests.
type AppError struct {
Code int32
Message string
}
// Error implements the error interface.
func (e *AppError) Error() string {
if e == nil {
return ""
}
return e.Message
}
// Is implements errors.Is for AppError comparison.
func (e *AppError) Is(target error) bool {
if target == nil || e == nil {
return e == target
}
t, ok := target.(*AppError)
if !ok {
return false
}
return e.Code == t.Code
}
// AppSender is the interface for sending application messages.
type AppSender interface {
// SendAppRequest sends an application request to the specified nodes.
SendAppRequest(
ctx context.Context,
nodeIDs set.Set[ids.NodeID],
requestID uint32,
appRequestBytes []byte,
) error
// SendAppResponse sends a response to a previously received request.
SendAppResponse(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
appResponseBytes []byte,
) error
// SendAppError sends an error response to a previously received request.
SendAppError(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
errorCode int32,
errorMessage string,
) error
// SendAppGossip sends a gossip message to nodes.
SendAppGossip(
ctx context.Context,
nodeIDs set.Set[ids.NodeID],
appGossipBytes []byte,
) error
// SendAppGossipSpecific sends a gossip message to specific nodes.
SendAppGossipSpecific(
ctx context.Context,
nodeIDs set.Set[ids.NodeID],
appGossipBytes []byte,
) error
// SendRequest sends a request to a specific node (p2p.Sender compatible).
SendRequest(
ctx context.Context,
nodeID ids.NodeID,
handlerID uint64,
requestBytes []byte,
) error
// SendResponse sends a response (p2p.Sender compatible).
SendResponse(
ctx context.Context,
nodeID ids.NodeID,
handlerID uint64,
requestID uint32,
responseBytes []byte,
) error
// SendError sends an error (p2p.Sender compatible).
SendError(
ctx context.Context,
nodeID ids.NodeID,
handlerID uint64,
requestID uint32,
errorCode int32,
errorMessage string,
) error
}
// AppHandler is the interface for handling application messages.
type AppHandler interface {
// AppRequest handles an incoming request.
AppRequest(
ctx context.Context,
nodeID ids.NodeID,
deadline time.Time,
requestBytes []byte,
) ([]byte, *AppError)
// AppGossip handles an incoming gossip message.
AppGossip(
ctx context.Context,
nodeID ids.NodeID,
gossipBytes []byte,
) error
// AppRequestFailed handles a request failure notification.
AppRequestFailed(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
appErr *AppError,
) error
// CrossChainAppRequest handles a cross-chain request.
CrossChainAppRequest(
ctx context.Context,
chainID ids.ID,
deadline time.Time,
requestBytes []byte,
) ([]byte, error)
// CrossChainAppRequestFailed handles a cross-chain request failure.
CrossChainAppRequestFailed(
ctx context.Context,
chainID ids.ID,
requestID uint32,
appErr *AppError,
) error
}
// Fx represents a feature extension that can be registered with a VM.
type Fx struct {
ID ids.ID
Name string
}
// NoOpAppSender is an AppSender that does nothing.
type NoOpAppSender struct{}
func (NoOpAppSender) SendAppRequest(context.Context, set.Set[ids.NodeID], uint32, []byte) error {
return nil
}
func (NoOpAppSender) SendAppResponse(context.Context, ids.NodeID, uint32, []byte) error {
return nil
}
func (NoOpAppSender) SendAppError(context.Context, ids.NodeID, uint32, int32, string) error {
return nil
}
func (NoOpAppSender) SendAppGossip(context.Context, set.Set[ids.NodeID], []byte) error {
return nil
}
func (NoOpAppSender) SendAppGossipSpecific(context.Context, set.Set[ids.NodeID], []byte) error {
return nil
}
func (NoOpAppSender) SendRequest(context.Context, ids.NodeID, uint64, []byte) error {
return nil
}
func (NoOpAppSender) SendResponse(context.Context, ids.NodeID, uint64, uint32, []byte) error {
return nil
}
func (NoOpAppSender) SendError(context.Context, ids.NodeID, uint64, uint32, int32, string) error {
return nil
}
// NoOpAppHandler is an AppHandler that does nothing.
type NoOpAppHandler struct{}
func (NoOpAppHandler) AppRequest(context.Context, ids.NodeID, time.Time, []byte) ([]byte, *AppError) {
return nil, nil
}
func (NoOpAppHandler) AppGossip(context.Context, ids.NodeID, []byte) error {
return nil
}
func (NoOpAppHandler) AppRequestFailed(context.Context, ids.NodeID, uint32, *AppError) error {
return nil
}
func (NoOpAppHandler) CrossChainAppRequest(context.Context, ids.ID, time.Time, []byte) ([]byte, error) {
return nil, nil
}
func (NoOpAppHandler) CrossChainAppRequestFailed(context.Context, ids.ID, uint32, *AppError) error {
return nil
}