Skip to content
Open
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
23 changes: 23 additions & 0 deletions evmrpc/historical_debug_trace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"testing"

"github.com/ethereum/go-ethereum/common"
sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -91,3 +92,25 @@ func TestGuardHistoricalDebugTraceHeight(t *testing.T) {
require.Error(t, err)
require.Contains(t, err.Error(), "block number 9 is beyond max lookback of 0")
}

func TestGuardHistoricalDebugTraceByHashUsesTendermintHeight(t *testing.T) {
latestHeight := int64(10)
latestCtx := sdk.Context{}.WithBlockHeight(latestHeight)
tmClient := newHeightTestClient(8, 1, latestHeight)
api := &DebugAPI{
tmClient: tmClient,
ctxProvider: func(int64) sdk.Context { return latestCtx },
connectionType: ConnectionTypeHTTP,
maxBlockLookback: 1,
backend: &Backend{
watermarks: NewWatermarkManager(tmClient, func(int64) sdk.Context { return latestCtx }, nil, nil),
},
}

err := api.guardHistoricalDebugTraceByHash(context.Background(), "debug_traceBlockByHash", common.HexToHash(highBlockHashHex))
require.Error(t, err)
require.Contains(t, err.Error(), "block number 8 is beyond max lookback of 1")

err = api.guardHistoricalDebugTraceByHash(context.Background(), "debug_traceCall", common.HexToHash("0x1"))
require.NoError(t, err)
}
24 changes: 12 additions & 12 deletions evmrpc/tracers.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,14 @@ func (api *DebugAPI) guardHistoricalDebugTraceByNumber(ctx context.Context, endp
}

func (api *DebugAPI) guardHistoricalDebugTraceByHash(ctx context.Context, endpoint string, hash common.Hash) error {
if api.backend == nil {
if api.backend == nil || api.tmClient == nil {
return nil
}
block, _, err := api.backend.BlockByHash(ctx, hash)
if err != nil || block == nil {
block, err := blockByHashRespectingWatermarks(ctx, api.tmClient, api.backend.watermarks, hash.Bytes(), 1)
if err != nil || block == nil || block.Block == nil {
return nil
}
return api.guardHistoricalDebugTraceHeight(ctx, endpoint, int64(block.NumberU64())) //nolint:gosec
return api.guardHistoricalDebugTraceHeight(ctx, endpoint, block.Block.Height)
}

func (api *DebugAPI) guardHistoricalDebugTraceByNumberOrHash(ctx context.Context, endpoint string, blockNrOrHash rpc.BlockNumberOrHash) error {
Expand Down Expand Up @@ -646,16 +646,16 @@ func (api *DebugAPI) TraceBlockByHash(ctx context.Context, hash common.Hash, con
recordMetricsWithError(ctx, "debug_traceBlockByHash", api.connectionType, startTime, returnErr, recover())
}()

if returnErr = api.guardHistoricalDebugTraceByHash(ctx, "debug_traceBlockByHash", hash); returnErr != nil {
return nil, returnErr
}

ctx, done, err := api.prepareTraceContext(ctx)
if err != nil {
return nil, err
}
defer done()

if returnErr = api.guardHistoricalDebugTraceByHash(ctx, "debug_traceBlockByHash", hash); returnErr != nil {
return nil, returnErr
}

if cached, ok := api.tryBlockTraceCacheByHash(ctx, hash, config); ok {
return cached, nil
}
Expand All @@ -674,16 +674,16 @@ func (api *DebugAPI) TraceCall(ctx context.Context, args export.TransactionArgs,
recordMetricsWithError(ctx, "debug_traceCall", api.connectionType, startTime, returnErr, recover())
}()

if returnErr = api.guardHistoricalDebugTraceByNumberOrHash(ctx, "debug_traceCall", blockNrOrHash); returnErr != nil {
return nil, returnErr
}

ctx, done, err := api.prepareTraceContext(ctx)
if err != nil {
return nil, err
}
defer done()

if returnErr = api.guardHistoricalDebugTraceByNumberOrHash(ctx, "debug_traceCall", blockNrOrHash); returnErr != nil {
return nil, returnErr
}

result, returnErr = api.tracersAPI.TraceCall(ctx, args, blockNrOrHash, config)
return
}
Expand Down
45 changes: 45 additions & 0 deletions evmrpc/tracers_semaphore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import (
"testing"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/export"
"github.com/ethereum/go-ethereum/rpc"
sdk "github.com/sei-protocol/sei-chain/sei-cosmos/types"
tmbytes "github.com/sei-protocol/sei-chain/sei-tendermint/libs/bytes"
"github.com/sei-protocol/sei-chain/sei-tendermint/rpc/coretypes"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -82,3 +88,42 @@ func TestAcquireTraceSemaphoreCanceledContextDoesNotConsumeSlot(t *testing.T) {
}
}
}

type panicHashLookupClient struct {
*heightTestClient
}

func (c *panicHashLookupClient) BlockByHash(context.Context, tmbytes.HexBytes) (*coretypes.ResultBlock, error) {
panic("hash lookup should not happen before trace context setup")
}

func TestHashBasedTraceEndpointsAcquireSemaphoreBeforeHashLookup(t *testing.T) {
latestHeight := int64(10)
latestCtx := sdk.Context{}.WithBlockHeight(latestHeight)
tmClient := &panicHashLookupClient{
heightTestClient: newHeightTestClient(8, 1, latestHeight),
}
watermarks := NewWatermarkManager(tmClient, func(int64) sdk.Context { return latestCtx }, nil, nil)
api := &DebugAPI{
tmClient: tmClient,
ctxProvider: func(int64) sdk.Context { return latestCtx },
connectionType: ConnectionTypeHTTP,
traceCallSemaphore: make(chan struct{}, 1),
traceTimeout: time.Second,
backend: &Backend{
tmClient: tmClient,
watermarks: watermarks,
},
}

api.traceCallSemaphore <- struct{}{}
defer func() { <-api.traceCallSemaphore }()

hash := common.HexToHash(highBlockHashHex)
_, err := api.TraceBlockByHash(context.Background(), hash, nil)
require.ErrorIs(t, err, errTraceConcurrencyLimit)

blockNrOrHash := rpc.BlockNumberOrHashWithHash(hash, false)
_, err = api.TraceCall(context.Background(), export.TransactionArgs{}, blockNrOrHash, nil)
require.ErrorIs(t, err, errTraceConcurrencyLimit)
}
Loading