Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions eth/tracers/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ type Backend interface {
// so this method should be called with the parent.
StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, checkLive, preferDisk bool) (*state.StateDB, error)
StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, error)

HistoricalRPCService() *rpc.Client
}

// API is the collection of tracing APIs exposed over the private debugging endpoint.
Expand Down
67 changes: 63 additions & 4 deletions eth/tracers/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,16 @@ import (
"errors"
"fmt"
"math/big"
"net"
"net/http"
"reflect"
"sort"
"testing"
"time"

"github.com/ethereum/go-ethereum/node"

"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus"
Expand All @@ -52,18 +57,68 @@ var (
errTransactionNotFound = errors.New("transaction not found")
)

type mockHistoricalBackend struct{}
Comment thread
maurelian marked this conversation as resolved.

func (m *mockHistoricalBackend) Dummy() {

}

func newMockHistoricalBackend(t *testing.T) string {
s := rpc.NewServer()
err := node.RegisterApis([]rpc.API{
{
Namespace: "eth",
Service: new(mockHistoricalBackend),
Public: true,
Authenticated: false,
},
}, nil, s)
if err != nil {
t.Fatalf("error creating mock historical backend: %v", err)
}

hdlr := node.NewHTTPHandlerStack(s, []string{"*"}, []string{"*"}, nil)
mux := http.NewServeMux()
mux.Handle("/", hdlr)

listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatalf("error creating mock historical backend listener: %v", err)
}

go func() {
httpS := &http.Server{Handler: mux}
httpS.Serve(listener)

t.Cleanup(func() {
httpS.Shutdown(context.Background())
})
}()

return fmt.Sprintf("http://%s", listener.Addr().String())
}

type testBackend struct {
chainConfig *params.ChainConfig
engine consensus.Engine
chaindb ethdb.Database
chain *core.BlockChain
historical *rpc.Client
}

func newTestBackend(t *testing.T, n int, gspec *core.Genesis, generator func(i int, b *core.BlockGen)) *testBackend {
historicalAddr := newMockHistoricalBackend(t)

historicalClient, err := rpc.Dial(historicalAddr)
if err != nil {
t.Fatalf("error making historical client: %v", err)
}

backend := &testBackend{
chainConfig: params.TestChainConfig,
engine: ethash.NewFaker(),
chaindb: rawdb.NewMemoryDatabase(),
historical: historicalClient,
}
// Generate blocks for testing
gspec.Config = backend.chainConfig
Expand Down Expand Up @@ -178,6 +233,10 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block
return nil, vm.BlockContext{}, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
}

func (b *testBackend) HistoricalRPCService() *rpc.Client {
return b.historical
}

func TestTraceCall(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -240,7 +299,7 @@ func TestTraceCall(t *testing.T) {
Value: (*hexutil.Big)(big.NewInt(1000)),
},
config: nil,
expectErr: fmt.Errorf("block #%d not found", genBlocks+1),
expectErr: fmt.Errorf("block #%d %w", genBlocks+1, ethereum.NotFound),
//expect: nil,
},
// Standard JSON trace upon the latest block
Expand Down Expand Up @@ -288,7 +347,7 @@ func TestTraceCall(t *testing.T) {
t.Errorf("test %d: expect error %v, got nothing", i, testspec.expectErr)
continue
}
if !reflect.DeepEqual(err, testspec.expectErr) {
if err.Error() != testspec.expectErr.Error() {
t.Errorf("test %d: error mismatch, want %v, git %v", i, testspec.expectErr, err)
}
} else {
Expand Down Expand Up @@ -393,7 +452,7 @@ func TestTraceBlock(t *testing.T) {
// Trace non-existent block
{
blockNumber: rpc.BlockNumber(genBlocks + 1),
expectErr: fmt.Errorf("block #%d not found", genBlocks+1),
expectErr: fmt.Errorf("block #%d %w", genBlocks+1, ethereum.NotFound),
},
// Trace latest block
{
Expand All @@ -413,7 +472,7 @@ func TestTraceBlock(t *testing.T) {
t.Errorf("test %d, want error %v", i, tc.expectErr)
continue
}
if !reflect.DeepEqual(err, tc.expectErr) {
if err.Error() != tc.expectErr.Error() {
t.Errorf("test %d: error mismatch, want %v, get %v", i, tc.expectErr, err)
}
continue
Expand Down
2 changes: 2 additions & 0 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ import (
"github.com/tyler-smith/go-bip39"
)

var ErrHeaderNotFound = fmt.Errorf("header %w", ethereum.NotFound)

// EthereumAPI provides an API to access Ethereum related information.
type EthereumAPI struct {
b Backend
Expand Down