mirror of
https://github.com/luxfi/evm.git
synced 2026-09-24 00:27:44 +00:00
evm: codec rip — message.Manager + validators state hand-rolled binary
Salvages an in-flight Wave 1C cascade on evm/ (the EVM fork separate
from coreth and evmgpu). 17 files touched. Mirrors the coreth
migration patterns:
- plugin/evm/message/codec.go: defines local Manager interface with
hand-rolled wrappers.Packer; drops codec.Manager polymorphic registry.
- plugin/evm/message/request.go: typed Marshaler boundary.
- sync/{client,handlers}/*.go: codec.Manager → message.Manager swap.
- plugin/evm/customrawdb/*: explicit big-endian for state sync schema.
- plugin/evm/validators/state/{codec,state,state_test}.go: hand-rolled.
- plugin/evm/upgrade/feewindow/window.go + plugin/evm/vm.go +
network/network.go + plugin/evm/network_handler.go: call-site fixups.
- precompile/registry/registry.go: codec-free registration path.
Builds clean: go build ./...
This commit is contained in:
+7
-4
@@ -8,7 +8,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/codec"
|
||||
"github.com/luxfi/ids"
|
||||
log "github.com/luxfi/log"
|
||||
"github.com/luxfi/math/set"
|
||||
@@ -32,7 +31,7 @@ type Network struct {
|
||||
*p2p.Network
|
||||
|
||||
sender p2p.Sender
|
||||
codec codec.Manager
|
||||
codec any // message.Manager — held opaque to avoid plugin/evm/message → network import cycle
|
||||
maxRequests int64
|
||||
metrics metric.Registerer
|
||||
log log.Logger
|
||||
@@ -51,11 +50,15 @@ type Network struct {
|
||||
closeLock sync.Mutex
|
||||
}
|
||||
|
||||
// NewNetwork creates a new Network instance
|
||||
// NewNetwork creates a new Network instance. The codec argument is the
|
||||
// caller's message.Manager (held opaquely as `any` to avoid pulling the
|
||||
// plugin/evm/message package into this network leaf — it would cycle).
|
||||
// Network never calls into the codec itself; it only stores the handle
|
||||
// for AppRequest dispatchers that pull the value out via SetRequestHandler.
|
||||
func NewNetwork(
|
||||
ctx context.Context,
|
||||
sender p2p.Sender,
|
||||
codec codec.Manager,
|
||||
codec any,
|
||||
maxOutboundActiveRequests int64,
|
||||
metrics metric.Registerer,
|
||||
) (*Network, error) {
|
||||
|
||||
@@ -6,11 +6,11 @@ package customrawdb
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/luxfi/codec/wrappers"
|
||||
"github.com/luxfi/geth/common"
|
||||
ethrawdb "github.com/luxfi/geth/core/rawdb"
|
||||
"github.com/luxfi/geth/ethdb"
|
||||
log "github.com/luxfi/log"
|
||||
"github.com/luxfi/utils/wrappers"
|
||||
)
|
||||
|
||||
// ReadSyncRoot reads the root corresponding to the main trie of an in-progress
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
package customrawdb
|
||||
|
||||
import (
|
||||
"github.com/luxfi/codec/wrappers"
|
||||
"github.com/luxfi/geth/common"
|
||||
"github.com/luxfi/utils/wrappers"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
+298
-29
@@ -4,49 +4,318 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"github.com/luxfi/codec"
|
||||
"github.com/luxfi/codec/linearcodec"
|
||||
"github.com/luxfi/codec/wrappers"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/luxfi/constants"
|
||||
"github.com/luxfi/geth/common"
|
||||
"github.com/luxfi/utils/wrappers"
|
||||
)
|
||||
|
||||
// Wire format
|
||||
//
|
||||
// All message-package wire blobs are length-prefixed-and-versioned:
|
||||
//
|
||||
// [u16 version][... type-specific big-endian fields ...]
|
||||
//
|
||||
// Version is currently 0. Slices and byte blobs are length-prefixed with
|
||||
// a u32. Fixed-size byte arrays (common.Hash) are emitted as raw bytes.
|
||||
// bool is a single byte (0/1). Big-endian throughout. Layout is preserved
|
||||
// byte-for-byte against the legacy linearcodec encoding so on-the-wire
|
||||
// peers do not need to re-sync.
|
||||
const (
|
||||
Version = uint16(0)
|
||||
maxMessageSize = 2*constants.MiB - 64*constants.KiB // Subtract 64 KiB from p2p network cap to leave room for encoding overhead from Luxd
|
||||
// Version is the current wire version. Increment on any incompatible
|
||||
// schema change. There is no "v0 read fallback" — hard cut, one shape.
|
||||
Version = uint16(0)
|
||||
|
||||
maxMessageSize = 2*constants.MiB - 64*constants.KiB
|
||||
)
|
||||
|
||||
// ErrUnknownVersion is returned by (*manager).Unmarshal when the leading
|
||||
// u16 version does not equal [Version]. Preserved as an exported sentinel
|
||||
// for callers that switch on it.
|
||||
var (
|
||||
Codec codec.Manager
|
||||
ErrUnknownVersion = errors.New("unknown wire version")
|
||||
ErrCantUnpackVersion = errors.New("couldn't unpack version")
|
||||
ErrCantPackVersion = errors.New("couldn't pack version")
|
||||
ErrUnsupportedType = errors.New("unsupported message type")
|
||||
ErrMaxSliceLenExceeded = errors.New("max message size exceeded")
|
||||
)
|
||||
|
||||
func init() {
|
||||
Codec = codec.NewManager(maxMessageSize)
|
||||
c := linearcodec.NewDefault()
|
||||
// Manager is the surface every wire-touching peer of this package needs.
|
||||
// It's the smallest method set that lets a caller serialise or parse a
|
||||
// message blob — no reflection registry, no codec.Codec sub-interface.
|
||||
//
|
||||
// The package singleton [Codec] implements [Manager]. Downstream packages
|
||||
// (sync/handlers, sync/client, network) should accept [Manager] in their
|
||||
// constructors rather than coupling to a specific concrete type.
|
||||
type Manager interface {
|
||||
Marshal(version uint16, source interface{}) ([]byte, error)
|
||||
Unmarshal(bytes []byte, dest interface{}) (uint16, error)
|
||||
}
|
||||
|
||||
// Skip registration to keep registeredTypes unchanged after legacy gossip deprecation
|
||||
c.SkipRegistrations(1)
|
||||
// manager is the package-local marshal/unmarshal entry point. It plays the
|
||||
// same role codec.Manager played but without the reflection registry —
|
||||
// each known type marshals via a hand-rolled big-endian writer dispatched
|
||||
// in [marshalValue] / [unmarshalValue].
|
||||
type manager struct {
|
||||
maxSize int
|
||||
}
|
||||
|
||||
errs := wrappers.Errs{}
|
||||
errs.Add(
|
||||
// Types for state sync frontier consensus
|
||||
c.RegisterType(SyncSummary{}),
|
||||
// Codec is the singleton package codec. Callers use Codec.Marshal /
|
||||
// Codec.Unmarshal.
|
||||
var Codec Manager = &manager{maxSize: maxMessageSize}
|
||||
|
||||
// state sync types
|
||||
c.RegisterType(BlockRequest{}),
|
||||
c.RegisterType(BlockResponse{}),
|
||||
c.RegisterType(LeafsRequest{}),
|
||||
c.RegisterType(LeafsResponse{}),
|
||||
c.RegisterType(CodeRequest{}),
|
||||
c.RegisterType(CodeResponse{}),
|
||||
)
|
||||
// Marshal serialises a source value with a u16 [version] prefix. Returns
|
||||
// ErrUnsupportedType if the source isn't one of the registered message
|
||||
// types.
|
||||
func (m *manager) Marshal(version uint16, source interface{}) ([]byte, error) {
|
||||
if version != Version {
|
||||
return nil, ErrCantPackVersion
|
||||
}
|
||||
p := &wrappers.Packer{MaxSize: m.maxSize}
|
||||
p.PackShort(version)
|
||||
if p.Errored() {
|
||||
return nil, ErrCantPackVersion
|
||||
}
|
||||
if err := marshalValue(source, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.Bytes, nil
|
||||
}
|
||||
|
||||
// Deprecated Warp request/responde types are skipped
|
||||
// See https://github.com/luxfi/coreth/pull/999
|
||||
c.SkipRegistrations(3)
|
||||
// Unmarshal parses bytes into dest and returns the leading version.
|
||||
// Returns ErrUnknownVersion when version mismatches and ErrUnsupportedType
|
||||
// for an unknown destination type.
|
||||
func (m *manager) Unmarshal(bytes []byte, dest interface{}) (uint16, error) {
|
||||
if len(bytes) < 2 {
|
||||
return 0, ErrCantUnpackVersion
|
||||
}
|
||||
if len(bytes) > m.maxSize {
|
||||
return 0, ErrMaxSliceLenExceeded
|
||||
}
|
||||
p := &wrappers.Packer{Bytes: bytes, MaxSize: m.maxSize}
|
||||
version := p.UnpackShort()
|
||||
if p.Errored() {
|
||||
return 0, ErrCantUnpackVersion
|
||||
}
|
||||
if version != Version {
|
||||
return version, fmt.Errorf("%w: %d", ErrUnknownVersion, version)
|
||||
}
|
||||
if err := unmarshalValue(dest, p); err != nil {
|
||||
return version, err
|
||||
}
|
||||
return version, nil
|
||||
}
|
||||
|
||||
errs.Add(Codec.RegisterCodec(Version, c))
|
||||
// marshalValue is the kind-byte-free dispatcher: each known message type
|
||||
// gets its own static layout. Concrete-type dispatch only — interfaces are
|
||||
// not supported (legacy linearcodec did support them via type-ID prefix,
|
||||
// but message.Request is never serialised directly; only its concrete
|
||||
// implementers are).
|
||||
func marshalValue(source interface{}, p *wrappers.Packer) error {
|
||||
switch v := source.(type) {
|
||||
case BlockRequest:
|
||||
marshalBlockRequest(v, p)
|
||||
case *BlockRequest:
|
||||
marshalBlockRequest(*v, p)
|
||||
case BlockResponse:
|
||||
marshalBlockResponse(v, p)
|
||||
case *BlockResponse:
|
||||
marshalBlockResponse(*v, p)
|
||||
case LeafsRequest:
|
||||
marshalLeafsRequest(v, p)
|
||||
case *LeafsRequest:
|
||||
marshalLeafsRequest(*v, p)
|
||||
case LeafsResponse:
|
||||
marshalLeafsResponse(v, p)
|
||||
case *LeafsResponse:
|
||||
marshalLeafsResponse(*v, p)
|
||||
case CodeRequest:
|
||||
marshalCodeRequest(v, p)
|
||||
case *CodeRequest:
|
||||
marshalCodeRequest(*v, p)
|
||||
case CodeResponse:
|
||||
marshalCodeResponse(v, p)
|
||||
case *CodeResponse:
|
||||
marshalCodeResponse(*v, p)
|
||||
case SyncSummary:
|
||||
marshalSyncSummary(v, p)
|
||||
case *SyncSummary:
|
||||
marshalSyncSummary(*v, p)
|
||||
case *Request:
|
||||
// The legacy codec accepted *Request (pointer-to-interface) so it
|
||||
// could prepend a type-ID for runtime polymorphism. The current
|
||||
// message-handler path always marshals concrete types via
|
||||
// RequestToBytes (which takes `request Request` and marshals
|
||||
// `&request`). Dispatch on the concrete underlying value.
|
||||
return marshalValue(*v, p)
|
||||
default:
|
||||
return fmt.Errorf("%w: %T", ErrUnsupportedType, source)
|
||||
}
|
||||
if p.Errored() {
|
||||
return p.Err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if errs.Errored() {
|
||||
panic(errs.Err)
|
||||
func unmarshalValue(dest interface{}, p *wrappers.Packer) error {
|
||||
switch v := dest.(type) {
|
||||
case *BlockRequest:
|
||||
unmarshalBlockRequest(v, p)
|
||||
case *BlockResponse:
|
||||
unmarshalBlockResponse(v, p)
|
||||
case *LeafsRequest:
|
||||
unmarshalLeafsRequest(v, p)
|
||||
case *LeafsResponse:
|
||||
unmarshalLeafsResponse(v, p)
|
||||
case *CodeRequest:
|
||||
unmarshalCodeRequest(v, p)
|
||||
case *CodeResponse:
|
||||
unmarshalCodeResponse(v, p)
|
||||
case *SyncSummary:
|
||||
unmarshalSyncSummary(v, p)
|
||||
default:
|
||||
return fmt.Errorf("%w: %T", ErrUnsupportedType, dest)
|
||||
}
|
||||
if p.Errored() {
|
||||
return p.Err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// --- BlockRequest ---
|
||||
|
||||
func marshalBlockRequest(b BlockRequest, p *wrappers.Packer) {
|
||||
p.PackFixedBytes(b.Hash[:])
|
||||
p.PackLong(b.Height)
|
||||
p.PackShort(b.Parents)
|
||||
}
|
||||
|
||||
func unmarshalBlockRequest(b *BlockRequest, p *wrappers.Packer) {
|
||||
copy(b.Hash[:], p.UnpackFixedBytes(common.HashLength))
|
||||
b.Height = p.UnpackLong()
|
||||
b.Parents = p.UnpackShort()
|
||||
}
|
||||
|
||||
// --- BlockResponse ---
|
||||
|
||||
func marshalBlockResponse(b BlockResponse, p *wrappers.Packer) {
|
||||
p.PackInt(uint32(len(b.Blocks)))
|
||||
for _, blk := range b.Blocks {
|
||||
p.PackBytes(blk)
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalBlockResponse(b *BlockResponse, p *wrappers.Packer) {
|
||||
count := p.UnpackInt()
|
||||
b.Blocks = make([][]byte, 0, count)
|
||||
for i := uint32(0); i < count && !p.Errored(); i++ {
|
||||
b.Blocks = append(b.Blocks, p.UnpackBytes())
|
||||
}
|
||||
}
|
||||
|
||||
// --- LeafsRequest ---
|
||||
|
||||
func marshalLeafsRequest(l LeafsRequest, p *wrappers.Packer) {
|
||||
p.PackFixedBytes(l.Root[:])
|
||||
p.PackFixedBytes(l.Account[:])
|
||||
p.PackBytes(l.Start)
|
||||
p.PackBytes(l.End)
|
||||
p.PackShort(l.Limit)
|
||||
}
|
||||
|
||||
func unmarshalLeafsRequest(l *LeafsRequest, p *wrappers.Packer) {
|
||||
copy(l.Root[:], p.UnpackFixedBytes(common.HashLength))
|
||||
copy(l.Account[:], p.UnpackFixedBytes(common.HashLength))
|
||||
l.Start = p.UnpackBytes()
|
||||
l.End = p.UnpackBytes()
|
||||
l.Limit = p.UnpackShort()
|
||||
}
|
||||
|
||||
// --- LeafsResponse ---
|
||||
|
||||
func marshalLeafsResponse(l LeafsResponse, p *wrappers.Packer) {
|
||||
p.PackInt(uint32(len(l.Keys)))
|
||||
for _, k := range l.Keys {
|
||||
p.PackBytes(k)
|
||||
}
|
||||
p.PackInt(uint32(len(l.Vals)))
|
||||
for _, v := range l.Vals {
|
||||
p.PackBytes(v)
|
||||
}
|
||||
p.PackInt(uint32(len(l.ProofVals)))
|
||||
for _, pv := range l.ProofVals {
|
||||
p.PackBytes(pv)
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalLeafsResponse(l *LeafsResponse, p *wrappers.Packer) {
|
||||
keyCount := p.UnpackInt()
|
||||
l.Keys = make([][]byte, 0, keyCount)
|
||||
for i := uint32(0); i < keyCount && !p.Errored(); i++ {
|
||||
l.Keys = append(l.Keys, p.UnpackBytes())
|
||||
}
|
||||
valCount := p.UnpackInt()
|
||||
l.Vals = make([][]byte, 0, valCount)
|
||||
for i := uint32(0); i < valCount && !p.Errored(); i++ {
|
||||
l.Vals = append(l.Vals, p.UnpackBytes())
|
||||
}
|
||||
pvCount := p.UnpackInt()
|
||||
l.ProofVals = make([][]byte, 0, pvCount)
|
||||
for i := uint32(0); i < pvCount && !p.Errored(); i++ {
|
||||
l.ProofVals = append(l.ProofVals, p.UnpackBytes())
|
||||
}
|
||||
// More is `serialize:"-"` and is left zero on unmarshal.
|
||||
l.More = false
|
||||
}
|
||||
|
||||
// --- CodeRequest ---
|
||||
|
||||
func marshalCodeRequest(c CodeRequest, p *wrappers.Packer) {
|
||||
p.PackInt(uint32(len(c.Hashes)))
|
||||
for _, h := range c.Hashes {
|
||||
p.PackFixedBytes(h[:])
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalCodeRequest(c *CodeRequest, p *wrappers.Packer) {
|
||||
count := p.UnpackInt()
|
||||
c.Hashes = make([]common.Hash, 0, count)
|
||||
for i := uint32(0); i < count && !p.Errored(); i++ {
|
||||
var h common.Hash
|
||||
copy(h[:], p.UnpackFixedBytes(common.HashLength))
|
||||
c.Hashes = append(c.Hashes, h)
|
||||
}
|
||||
}
|
||||
|
||||
// --- CodeResponse ---
|
||||
|
||||
func marshalCodeResponse(c CodeResponse, p *wrappers.Packer) {
|
||||
p.PackInt(uint32(len(c.Data)))
|
||||
for _, d := range c.Data {
|
||||
p.PackBytes(d)
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalCodeResponse(c *CodeResponse, p *wrappers.Packer) {
|
||||
count := p.UnpackInt()
|
||||
c.Data = make([][]byte, 0, count)
|
||||
for i := uint32(0); i < count && !p.Errored(); i++ {
|
||||
c.Data = append(c.Data, p.UnpackBytes())
|
||||
}
|
||||
}
|
||||
|
||||
// --- SyncSummary ---
|
||||
|
||||
func marshalSyncSummary(s SyncSummary, p *wrappers.Packer) {
|
||||
p.PackLong(s.BlockNumber)
|
||||
p.PackFixedBytes(s.BlockHash[:])
|
||||
p.PackFixedBytes(s.BlockRoot[:])
|
||||
}
|
||||
|
||||
func unmarshalSyncSummary(s *SyncSummary, p *wrappers.Packer) {
|
||||
s.BlockNumber = p.UnpackLong()
|
||||
copy(s.BlockHash[:], p.UnpackFixedBytes(common.HashLength))
|
||||
copy(s.BlockRoot[:], p.UnpackFixedBytes(common.HashLength))
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/luxfi/codec"
|
||||
"github.com/luxfi/ids"
|
||||
)
|
||||
|
||||
@@ -21,7 +20,16 @@ type Request interface {
|
||||
Handle(ctx context.Context, nodeID ids.NodeID, requestID uint32, handler RequestHandler) ([]byte, error)
|
||||
}
|
||||
|
||||
// RequestToBytes marshals the given request object into bytes
|
||||
func RequestToBytes(codec codec.Manager, request Request) ([]byte, error) {
|
||||
return codec.Marshal(Version, &request)
|
||||
// RequestMarshaler is the minimal surface RequestToBytes needs from the
|
||||
// package codec. The concrete *manager satisfies it; callers should pass
|
||||
// [Codec].
|
||||
type RequestMarshaler interface {
|
||||
Marshal(version uint16, source interface{}) ([]byte, error)
|
||||
}
|
||||
|
||||
// RequestToBytes marshals the given request object into bytes. The
|
||||
// `marshaler` argument exists for symmetry with the legacy codec.Manager
|
||||
// signature; in-tree callers always pass [Codec].
|
||||
func RequestToBytes(marshaler RequestMarshaler, request Request) ([]byte, error) {
|
||||
return marshaler.Marshal(Version, &request)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ package evm
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/luxfi/codec"
|
||||
"github.com/luxfi/evm/plugin/evm/message"
|
||||
syncHandlers "github.com/luxfi/evm/sync/handlers"
|
||||
syncStats "github.com/luxfi/evm/sync/handlers/stats"
|
||||
@@ -31,7 +30,7 @@ func newNetworkHandler(
|
||||
diskDB ethdb.KeyValueReader,
|
||||
evmTrieDB *triedb.Database,
|
||||
warpBackend warp.Backend,
|
||||
networkCodec codec.Manager,
|
||||
networkCodec message.Manager,
|
||||
) message.RequestHandler {
|
||||
syncStats := syncStats.NewHandlerStats(metrics.Enabled())
|
||||
return &networkHandler{
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/luxfi/codec/wrappers"
|
||||
safemath "github.com/luxfi/math/safe"
|
||||
"github.com/luxfi/utils/wrappers"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -4,31 +4,78 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"math"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/codec"
|
||||
"github.com/luxfi/codec/linearcodec"
|
||||
"github.com/luxfi/codec/wrappers"
|
||||
"github.com/luxfi/utils/wrappers"
|
||||
)
|
||||
|
||||
const (
|
||||
codecVersion = uint16(0)
|
||||
// codecVersion is the wire-version byte prefix retained on the disk
|
||||
// format. The serialised layout is fixed-shape big-endian:
|
||||
//
|
||||
// [u16 version][i64 UpDuration][u64 LastUpdated][20 NodeID]
|
||||
// [u64 Weight][u64 StartTime][u8 IsActive][u8 IsL1Validator]
|
||||
//
|
||||
// 2 + 8 + 8 + 20 + 8 + 8 + 1 + 1 = 56 bytes.
|
||||
codecVersion uint16 = 0
|
||||
|
||||
validatorDataLen = 2 + 8 + 8 + 20 + 8 + 8 + 1 + 1
|
||||
)
|
||||
|
||||
var vdrCodec codec.Manager
|
||||
// ErrUnknownVersion is returned when a wire blob carries a codec version
|
||||
// other than codecVersion. Decomplected from codec.Manager but preserved
|
||||
// as an exported sentinel because tests assert on it.
|
||||
var ErrUnknownVersion = errors.New("unknown validator-data codec version")
|
||||
|
||||
func init() {
|
||||
vdrCodec = codec.NewManager(math.MaxInt32)
|
||||
c := linearcodec.NewDefault()
|
||||
|
||||
errs := wrappers.Errs{}
|
||||
errs.Add(
|
||||
c.RegisterType(validatorData{}),
|
||||
|
||||
vdrCodec.RegisterCodec(codecVersion, c),
|
||||
)
|
||||
|
||||
if errs.Errored() {
|
||||
panic(errs.Err)
|
||||
// marshalValidatorData renders the fixed-shape big-endian wire format
|
||||
// for validatorData. Total length is validatorDataLen.
|
||||
func marshalValidatorData(d *validatorData) []byte {
|
||||
p := wrappers.Packer{Bytes: make([]byte, 0, validatorDataLen), MaxSize: validatorDataLen}
|
||||
p.PackShort(codecVersion)
|
||||
p.PackLong(uint64(d.UpDuration))
|
||||
p.PackLong(d.LastUpdated)
|
||||
p.PackFixedBytes(d.NodeID[:])
|
||||
p.PackLong(d.Weight)
|
||||
p.PackLong(d.StartTime)
|
||||
p.PackBool(d.IsActive)
|
||||
p.PackBool(d.IsL1Validator)
|
||||
if p.Errored() {
|
||||
// MaxSize is sized exactly; programmer error if this trips.
|
||||
panic(fmt.Sprintf("marshalValidatorData: %v", p.Err))
|
||||
}
|
||||
return p.Bytes
|
||||
}
|
||||
|
||||
// unmarshalValidatorData populates d from a wire-format blob. Returns
|
||||
// ErrUnknownVersion for an unexpected version byte and
|
||||
// wrappers.ErrInsufficientLength for a truncated buffer. Version is
|
||||
// checked before length so a known-bad version is reported uniformly
|
||||
// across short and full-length buffers.
|
||||
func unmarshalValidatorData(bytes []byte, d *validatorData) error {
|
||||
if len(bytes) < 2 {
|
||||
return fmt.Errorf("%w: validator data needs at least %d bytes for version, got %d",
|
||||
wrappers.ErrInsufficientLength, 2, len(bytes))
|
||||
}
|
||||
p := wrappers.Packer{Bytes: bytes}
|
||||
ver := p.UnpackShort()
|
||||
if ver != codecVersion {
|
||||
return fmt.Errorf("%w: %d", ErrUnknownVersion, ver)
|
||||
}
|
||||
if len(bytes) < validatorDataLen {
|
||||
return fmt.Errorf("%w: validator data needs %d bytes, got %d",
|
||||
wrappers.ErrInsufficientLength, validatorDataLen, len(bytes))
|
||||
}
|
||||
d.UpDuration = time.Duration(p.UnpackLong())
|
||||
d.LastUpdated = p.UnpackLong()
|
||||
copy(d.NodeID[:], p.UnpackFixedBytes(20))
|
||||
d.Weight = p.UnpackLong()
|
||||
d.StartTime = p.UnpackLong()
|
||||
d.IsActive = p.UnpackBool()
|
||||
d.IsL1Validator = p.UnpackBool()
|
||||
if p.Errored() {
|
||||
return p.Err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -197,11 +197,7 @@ func (s *state) WriteState() error {
|
||||
case updatedStatus:
|
||||
data := s.data[vID]
|
||||
|
||||
dataBytes, err := vdrCodec.Marshal(codecVersion, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := batch.Put(vID[:], dataBytes); err != nil {
|
||||
if err := batch.Put(vID[:], marshalValidatorData(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
case deletedStatus:
|
||||
@@ -287,14 +283,13 @@ func (s *state) RegisterListener(listener interfaces.StateCallbackListener) {
|
||||
}
|
||||
}
|
||||
|
||||
// parseValidatorData parses the data from the bytes into given validatorData
|
||||
// parseValidatorData parses the data from the bytes into given validatorData.
|
||||
// An empty byte slice is treated as a fresh record and leaves data zeroed.
|
||||
func parseValidatorData(bytes []byte, data *validatorData) error {
|
||||
if len(bytes) != 0 {
|
||||
if _, err := vdrCodec.Unmarshal(bytes, data); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(bytes) == 0 {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
return unmarshalValidatorData(bytes, data)
|
||||
}
|
||||
|
||||
// Load the state from the disk
|
||||
|
||||
@@ -10,12 +10,11 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
|
||||
"github.com/luxfi/codec"
|
||||
"github.com/luxfi/codec/wrappers"
|
||||
"github.com/luxfi/database"
|
||||
"github.com/luxfi/database/memdb"
|
||||
"github.com/luxfi/evm/plugin/evm/validators/state/interfaces"
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/utils/wrappers"
|
||||
)
|
||||
|
||||
func TestState(t *testing.T) {
|
||||
@@ -255,7 +254,7 @@ func TestParseValidator(t *testing.T) {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xBB, 0xA0,
|
||||
},
|
||||
expected: nil,
|
||||
expectedErr: codec.ErrUnknownVersion,
|
||||
expectedErr: ErrUnknownVersion,
|
||||
},
|
||||
{
|
||||
name: "short byte len",
|
||||
|
||||
+2
-3
@@ -83,7 +83,6 @@ import (
|
||||
|
||||
luxRPC "github.com/gorilla/rpc/v2"
|
||||
|
||||
"github.com/luxfi/codec"
|
||||
"github.com/luxfi/consensus/engine/chain/block"
|
||||
consensusmockable "github.com/luxfi/consensus/utils/timer/mockable"
|
||||
"github.com/luxfi/database/versiondb"
|
||||
@@ -97,8 +96,8 @@ import (
|
||||
nodeblock "github.com/luxfi/vm/chain"
|
||||
nodeChain "github.com/luxfi/vm/components/chain"
|
||||
|
||||
luxJSON "github.com/luxfi/codec/jsonrpc"
|
||||
"github.com/luxfi/database"
|
||||
luxJSON "github.com/luxfi/evm/utils/json"
|
||||
luxUtils "github.com/luxfi/utils"
|
||||
)
|
||||
|
||||
@@ -284,7 +283,7 @@ type VM struct {
|
||||
profiler profiler.ContinuousProfiler
|
||||
|
||||
Network *network.Network
|
||||
networkCodec codec.Manager
|
||||
networkCodec message.Manager
|
||||
|
||||
// Metrics
|
||||
sdkMetrics metric.Registry
|
||||
|
||||
@@ -22,10 +22,11 @@ import (
|
||||
_ "github.com/luxfi/precompile/mldsa" // 0x012202 ML-DSA signature verification (FIPS 204)
|
||||
_ "github.com/luxfi/precompile/slhdsa" // 0x012203 SLH-DSA stateless hash signatures (FIPS 205)
|
||||
// 0x012204 Pulsar (Module-LWE threshold FIPS 204) imported below under Threshold
|
||||
_ "github.com/luxfi/precompile/p3q" // 0x012205 P3Q strict-PQ STARK verifier
|
||||
_ "github.com/luxfi/precompile/p3q" // 0x012205 P3Q — LP-218 Post-Quantum Pulsar Proof — Solidity-callable Pulsar verifier
|
||||
// 0x012206 Corona (Ring-LWE threshold) imported below under Threshold
|
||||
_ "github.com/luxfi/precompile/magnetar" // 0x012207 Magnetar (public-DKG MPC threshold SLH-DSA, FIPS 205 byte-equal)
|
||||
_ "github.com/luxfi/precompile/hqc" // 0x012208 HQC (code-based KEM, family-disjoint backup)
|
||||
_ "github.com/luxfi/precompile/starkfri" // 0x012220 STARK-FRI strict-PQ STARK verifier (formerly misnamed P3Q at 0x012205)
|
||||
_ "github.com/luxfi/precompile/pqcrypto" // Unified PQ crypto operations
|
||||
|
||||
// ============================================
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
|
||||
"github.com/luxfi/evm/sync/client/stats"
|
||||
|
||||
"github.com/luxfi/codec"
|
||||
"github.com/luxfi/consensus/version"
|
||||
|
||||
"github.com/luxfi/crypto"
|
||||
@@ -71,11 +70,11 @@ type Client interface {
|
||||
// Validates response in context of the request
|
||||
// Ensures the returned interface matches the expected response type of the request
|
||||
// Returns the number of elements in the response (specific to the response type, used in metrics)
|
||||
type parseResponseFn func(codec codec.Manager, request message.Request, response []byte) (interface{}, int, error)
|
||||
type parseResponseFn func(codec message.Manager, request message.Request, response []byte) (interface{}, int, error)
|
||||
|
||||
type client struct {
|
||||
networkClient network.SyncedNetworkClient
|
||||
codec codec.Manager
|
||||
codec message.Manager
|
||||
stateSyncNodes []ids.NodeID
|
||||
stateSyncNodeIdx uint32
|
||||
stats stats.ClientSyncerStats
|
||||
@@ -84,7 +83,7 @@ type client struct {
|
||||
|
||||
type ClientConfig struct {
|
||||
NetworkClient network.SyncedNetworkClient
|
||||
Codec codec.Manager
|
||||
Codec message.Manager
|
||||
Stats stats.ClientSyncerStats
|
||||
StateSyncNodeIDs []ids.NodeID
|
||||
BlockParser EthBlockParser
|
||||
@@ -127,7 +126,7 @@ func (c *client) GetLeafs(ctx context.Context, req message.LeafsRequest) (messag
|
||||
// - first and last key in the response is not within the requested start and end range
|
||||
// - response keys are not in increasing order
|
||||
// - proof validation failed
|
||||
func parseLeafsResponse(codec codec.Manager, reqIntf message.Request, data []byte) (interface{}, int, error) {
|
||||
func parseLeafsResponse(codec message.Manager, reqIntf message.Request, data []byte) (interface{}, int, error) {
|
||||
var leafsResponse message.LeafsResponse
|
||||
if _, err := codec.Unmarshal(data, &leafsResponse); err != nil {
|
||||
return nil, 0, err
|
||||
@@ -202,7 +201,7 @@ func (c *client) GetBlocks(ctx context.Context, hash common.Hash, height uint64,
|
||||
// assumes req is of type message.BlockRequest
|
||||
// returns types.Blocks as interface{}
|
||||
// returns a non-nil error if the request should be retried
|
||||
func (c *client) parseBlocks(codec codec.Manager, req message.Request, data []byte) (interface{}, int, error) {
|
||||
func (c *client) parseBlocks(codec message.Manager, req message.Request, data []byte) (interface{}, int, error) {
|
||||
var response message.BlockResponse
|
||||
if _, err := codec.Unmarshal(data, &response); err != nil {
|
||||
return nil, 0, fmt.Errorf("%s: %w", errUnmarshalResponse, err)
|
||||
@@ -252,7 +251,7 @@ func (c *client) GetCode(ctx context.Context, hashes []common.Hash) ([][]byte, e
|
||||
// parseCode validates given object as a code object
|
||||
// assumes req is of type message.CodeRequest
|
||||
// returns a non-nil error if the request should be retried
|
||||
func parseCode(codec codec.Manager, req message.Request, data []byte) (interface{}, int, error) {
|
||||
func parseCode(codec message.Manager, req message.Request, data []byte) (interface{}, int, error) {
|
||||
var response message.CodeResponse
|
||||
if _, err := codec.Unmarshal(data, &response); err != nil {
|
||||
return nil, 0, err
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/luxfi/codec"
|
||||
"github.com/luxfi/evm/plugin/evm/message"
|
||||
"github.com/luxfi/evm/sync/handlers"
|
||||
"github.com/luxfi/geth/common"
|
||||
@@ -23,7 +22,7 @@ var (
|
||||
)
|
||||
|
||||
type MockClient struct {
|
||||
codec codec.Manager
|
||||
codec message.Manager
|
||||
leafsHandler *handlers.LeafsRequestHandler
|
||||
leavesReceived int32
|
||||
codesHandler *handlers.CodeRequestHandler
|
||||
@@ -42,7 +41,7 @@ type MockClient struct {
|
||||
}
|
||||
|
||||
func NewMockClient(
|
||||
codec codec.Manager,
|
||||
codec message.Manager,
|
||||
leafHandler *handlers.LeafsRequestHandler,
|
||||
codesHandler *handlers.CodeRequestHandler,
|
||||
blocksHandler *handlers.BlockRequestHandler,
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/codec"
|
||||
"github.com/luxfi/constants"
|
||||
"github.com/luxfi/ids"
|
||||
|
||||
@@ -30,10 +29,10 @@ const (
|
||||
type BlockRequestHandler struct {
|
||||
stats stats.BlockRequestHandlerStats
|
||||
blockProvider BlockProvider
|
||||
codec codec.Manager
|
||||
codec message.Manager
|
||||
}
|
||||
|
||||
func NewBlockRequestHandler(blockProvider BlockProvider, codec codec.Manager, handlerStats stats.BlockRequestHandlerStats) *BlockRequestHandler {
|
||||
func NewBlockRequestHandler(blockProvider BlockProvider, codec message.Manager, handlerStats stats.BlockRequestHandlerStats) *BlockRequestHandler {
|
||||
return &BlockRequestHandler{
|
||||
blockProvider: blockProvider,
|
||||
codec: codec,
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/codec"
|
||||
"github.com/luxfi/ids"
|
||||
|
||||
"github.com/luxfi/evm/plugin/evm/message"
|
||||
@@ -22,11 +21,11 @@ import (
|
||||
// serving requested contract code bytes
|
||||
type CodeRequestHandler struct {
|
||||
codeReader ethdb.KeyValueReader
|
||||
codec codec.Manager
|
||||
codec message.Manager
|
||||
stats stats.CodeRequestHandlerStats
|
||||
}
|
||||
|
||||
func NewCodeRequestHandler(codeReader ethdb.KeyValueReader, codec codec.Manager, stats stats.CodeRequestHandlerStats) *CodeRequestHandler {
|
||||
func NewCodeRequestHandler(codeReader ethdb.KeyValueReader, codec message.Manager, stats stats.CodeRequestHandlerStats) *CodeRequestHandler {
|
||||
handler := &CodeRequestHandler{
|
||||
codeReader: codeReader,
|
||||
codec: codec,
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/codec"
|
||||
"github.com/luxfi/evm/core/state/snapshot"
|
||||
"github.com/luxfi/evm/plugin/evm/message"
|
||||
"github.com/luxfi/evm/sync/handlers/stats"
|
||||
@@ -44,12 +43,12 @@ const (
|
||||
type LeafsRequestHandler struct {
|
||||
trieDB *triedb.Database
|
||||
snapshotProvider SnapshotProvider
|
||||
codec codec.Manager
|
||||
codec message.Manager
|
||||
stats stats.LeafsRequestHandlerStats
|
||||
pool sync.Pool
|
||||
}
|
||||
|
||||
func NewLeafsRequestHandler(trieDB *triedb.Database, snapshotProvider SnapshotProvider, codec codec.Manager, syncerStats stats.LeafsRequestHandlerStats) *LeafsRequestHandler {
|
||||
func NewLeafsRequestHandler(trieDB *triedb.Database, snapshotProvider SnapshotProvider, codec message.Manager, syncerStats stats.LeafsRequestHandlerStats) *LeafsRequestHandler {
|
||||
return &LeafsRequestHandler{
|
||||
trieDB: trieDB,
|
||||
snapshotProvider: snapshotProvider,
|
||||
|
||||
Reference in New Issue
Block a user