Files
coreth/sync/client/test_client.go
zeekay 445db75699 coreth: complete codec rip Wave 1C — message.Manager replaces codec.Manager
Salvages Wave 1C agent's incomplete work (11 files, 328+ lines) plus
the call-site fixups needed to make sync packages compile.

The new plugin/evm/message/codec.go defines a Manager interface (same
shape as legacy codec.Manager: Marshal/Unmarshal/Size) backed by a
hand-rolled wrappers.Packer with explicit big-endian field encoding.
No reflection registry. Byte-equal to legacy linearcodec output.

Call-site swaps (sync/client/client.go + sync/client/test_client.go):
codec.Manager → message.Manager. Drop the github.com/luxfi/codec
import where it's no longer referenced.

Packages green:
  ok  github.com/luxfi/coreth/plugin/evm/message
  ok  github.com/luxfi/coreth/predicate
  ok  github.com/luxfi/coreth/sync/vm

coreth plugin/evm codec importer count: 21 → 15. Remaining 15 are in
atomic/, predicate/, warp aggregator, tx pool — not in this Wave's
scope.
2026-06-05 13:37:50 -07:00

153 lines
4.6 KiB
Go

// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package statesyncclient
import (
"context"
"fmt"
"sync/atomic"
"github.com/luxfi/coreth/plugin/evm/message"
"github.com/luxfi/coreth/sync/handlers"
"github.com/luxfi/geth/common"
"github.com/luxfi/geth/core/types"
"github.com/luxfi/geth/rlp"
"github.com/luxfi/ids"
)
var (
_ Client = (*TestClient)(nil)
_ EthBlockParser = (*testBlockParser)(nil)
)
type TestClient struct {
codec message.Manager
leafsHandler handlers.LeafRequestHandler
leavesReceived int32
codesHandler *handlers.CodeRequestHandler
codeReceived int32
blocksHandler *handlers.BlockRequestHandler
blocksReceived int32
// GetLeafsIntercept is called on every GetLeafs request if set to a non-nil callback.
// The returned response will be returned by TestClient to the caller.
GetLeafsIntercept func(req message.LeafsRequest, res message.LeafsResponse) (message.LeafsResponse, error)
// GetCodesIntercept is called on every GetCode request if set to a non-nil callback.
// The returned response will be returned by TestClient to the caller.
GetCodeIntercept func(hashes []common.Hash, codeBytes [][]byte) ([][]byte, error)
// GetBlocksIntercept is called on every GetBlocks request if set to a non-nil callback.
// The returned response will be returned by TestClient to the caller.
GetBlocksIntercept func(blockReq message.BlockRequest, blocks types.Blocks) (types.Blocks, error)
}
func NewTestClient(
codec message.Manager,
leafHandler handlers.LeafRequestHandler,
codesHandler *handlers.CodeRequestHandler,
blocksHandler *handlers.BlockRequestHandler,
) *TestClient {
return &TestClient{
codec: codec,
leafsHandler: leafHandler,
codesHandler: codesHandler,
blocksHandler: blocksHandler,
}
}
func (ml *TestClient) GetLeafs(ctx context.Context, request message.LeafsRequest) (message.LeafsResponse, error) {
response, err := ml.leafsHandler.OnLeafsRequest(ctx, ids.GenerateTestNodeID(), 1, request)
if err != nil {
return message.LeafsResponse{}, err
}
leafResponseIntf, numLeaves, err := parseLeafsResponse(ml.codec, request, response)
if err != nil {
return message.LeafsResponse{}, err
}
leafsResponse := leafResponseIntf.(message.LeafsResponse)
if ml.GetLeafsIntercept != nil {
leafsResponse, err = ml.GetLeafsIntercept(request, leafsResponse)
}
// Increment the number of leaves received by the test client
atomic.AddInt32(&ml.leavesReceived, int32(numLeaves))
return leafsResponse, err
}
func (ml *TestClient) LeavesReceived() int32 {
return atomic.LoadInt32(&ml.leavesReceived)
}
func (ml *TestClient) GetCode(ctx context.Context, hashes []common.Hash) ([][]byte, error) {
if ml.codesHandler == nil {
panic("no code handler for test client")
}
request := message.CodeRequest{Hashes: hashes}
response, err := ml.codesHandler.OnCodeRequest(ctx, ids.GenerateTestNodeID(), 1, request)
if err != nil {
return nil, err
}
codeBytesIntf, lenCode, err := parseCode(ml.codec, request, response)
if err != nil {
return nil, err
}
code := codeBytesIntf.([][]byte)
if ml.GetCodeIntercept != nil {
code, err = ml.GetCodeIntercept(hashes, code)
}
if err == nil {
atomic.AddInt32(&ml.codeReceived, int32(lenCode))
}
return code, err
}
func (ml *TestClient) CodeReceived() int32 {
return atomic.LoadInt32(&ml.codeReceived)
}
func (ml *TestClient) GetBlocks(ctx context.Context, blockHash common.Hash, height uint64, numParents uint16) ([]*types.Block, error) {
if ml.blocksHandler == nil {
panic("no blocks handler for test client")
}
request := message.BlockRequest{
Hash: blockHash,
Height: height,
Parents: numParents,
}
response, err := ml.blocksHandler.OnBlockRequest(ctx, ids.GenerateTestNodeID(), 1, request)
if err != nil {
return nil, err
}
client := &client{blockParser: newTestBlockParser()} // Hack to avoid duplicate code
blocksRes, numBlocks, err := client.parseBlocks(ml.codec, request, response)
if err != nil {
return nil, err
}
blocks := blocksRes.(types.Blocks)
if ml.GetBlocksIntercept != nil {
blocks, err = ml.GetBlocksIntercept(request, blocks)
}
atomic.AddInt32(&ml.blocksReceived, int32(numBlocks))
return blocks, err
}
func (ml *TestClient) BlocksReceived() int32 {
return atomic.LoadInt32(&ml.blocksReceived)
}
type testBlockParser struct{}
func newTestBlockParser() *testBlockParser {
return &testBlockParser{}
}
func (t *testBlockParser) ParseEthBlock(b []byte) (*types.Block, error) {
block := new(types.Block)
if err := rlp.DecodeBytes(b, block); err != nil {
return nil, fmt.Errorf("%s: %w", errUnmarshalResponse, err)
}
return block, nil
}