Files
evm/sync/handlers/block_request.go
zeekay edce485ac1 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 ./...
2026-06-05 15:31:59 -07:00

121 lines
4.0 KiB
Go

// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package handlers
import (
"bytes"
"context"
"time"
"github.com/luxfi/constants"
"github.com/luxfi/ids"
"github.com/luxfi/evm/plugin/evm/message"
"github.com/luxfi/evm/sync/handlers/stats"
"github.com/luxfi/geth/common"
log "github.com/luxfi/log"
)
const (
// parentLimit specifies how many parents to retrieve and send given a starting hash
// This value overrides any specified limit in blockRequest.Parents if it is greater than this value
parentLimit = uint16(64)
targetMessageByteSize = constants.MiB - constants.KiB // Target total block bytes slightly under original network codec max size of 1MB
)
// BlockRequestHandler is a peer.RequestHandler for message.BlockRequest
// serving requested blocks starting at specified hash
type BlockRequestHandler struct {
stats stats.BlockRequestHandlerStats
blockProvider BlockProvider
codec message.Manager
}
func NewBlockRequestHandler(blockProvider BlockProvider, codec message.Manager, handlerStats stats.BlockRequestHandlerStats) *BlockRequestHandler {
return &BlockRequestHandler{
blockProvider: blockProvider,
codec: codec,
stats: handlerStats,
}
}
// OnBlockRequest handles incoming message.BlockRequest, returning blocks as requested
// Never returns error
// Expects returned errors to be treated as FATAL
// Returns empty response or subset of requested blocks if ctx expires during fetch
// Assumes ctx is active
func (b *BlockRequestHandler) OnBlockRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, blockRequest message.BlockRequest) ([]byte, error) {
startTime := time.Now()
b.stats.IncBlockRequest()
// override given Parents limit if it is greater than parentLimit
parents := blockRequest.Parents
if parents > parentLimit {
parents = parentLimit
}
blocks := make([][]byte, 0, parents)
totalBytes := 0
// ensure metrics are captured properly on all return paths
defer func() {
b.stats.UpdateBlockRequestProcessingTime(time.Since(startTime))
b.stats.UpdateBlocksReturned(uint16(len(blocks)))
}()
hash := blockRequest.Hash
height := blockRequest.Height
log.Info("BlockRequestHandler: processing request", "hash", hash, "height", height, "parents", parents)
for i := 0; i < int(parents); i++ {
// we return whatever we have until ctx errors, limit is exceeded, or we reach the genesis block
// this will happen either when the ctx is cancelled or we hit the ctx deadline
if ctx.Err() != nil {
break
}
if (hash == common.Hash{}) {
break
}
block := b.blockProvider.GetBlock(hash, height)
if block == nil {
log.Info("BlockRequestHandler: block not found", "hash", hash, "height", height)
b.stats.IncMissingBlockHash()
break
}
buf := new(bytes.Buffer)
if err := block.EncodeRLP(buf); err != nil {
log.Error("failed to RLP encode block", "hash", block.Hash(), "height", block.NumberU64(), "err", err)
return nil, nil
}
if uint64(buf.Len()+totalBytes) > targetMessageByteSize && len(blocks) > 0 {
log.Debug("Skipping block due to max total bytes size", "totalBlockDataSize", totalBytes, "blockSize", buf.Len(), "maxTotalBytesSize", targetMessageByteSize)
break
}
blocks = append(blocks, buf.Bytes())
totalBytes += buf.Len()
hash = block.ParentHash()
height--
}
if len(blocks) == 0 {
// drop this request
log.Debug("no requested blocks found, dropping request", "nodeID", nodeID, "requestID", requestID, "hash", blockRequest.Hash, "parents", blockRequest.Parents)
return nil, nil
}
response := message.BlockResponse{
Blocks: blocks,
}
responseBytes, err := b.codec.Marshal(message.Version, 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
}
return responseBytes, nil
}