Skip to content

Commit

Permalink
fix(rpc): Fix eth_getLogs with genesis/latest block filters
Browse files Browse the repository at this point in the history
  • Loading branch information
kostko committed Apr 13, 2023
1 parent f2b38f1 commit 9f4313e
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 10 deletions.
42 changes: 33 additions & 9 deletions rpc/eth/api.go
Expand Up @@ -596,6 +596,17 @@ func (api *publicAPI) GetTransactionReceipt(ctx context.Context, txHash common.H
return receipt, nil
}

// resolveLatest ensures that the special "latest round" marker is resolved into an actual value.
func (api *publicAPI) resolveLatest(ctx context.Context, round uint64) (uint64, error) {
switch round {
case client.RoundLatest:
// Resolve to actual latest round.
return api.backend.BlockNumber(ctx)
default:
return round, nil
}
}

// getStartEndRounds is a helper for fetching start and end rounds parameters.
func (api *publicAPI) getStartEndRounds(ctx context.Context, logger *logging.Logger, filter filters.FilterCriteria) (uint64, uint64, error) {
if filter.BlockHash != nil {
Expand All @@ -606,21 +617,34 @@ func (api *publicAPI) getStartEndRounds(ctx context.Context, logger *logging.Log
return round, round, nil
}

start := client.RoundLatest
end := client.RoundLatest
// Determine start round. If nothing passed, this is the genesis round.
blockNum := ethrpc.EarliestBlockNumber
if filter.FromBlock != nil {
round, err := api.roundParamFromBlockNum(ctx, logger, ethrpc.BlockNumber(filter.FromBlock.Int64()))
if err != nil {
return 0, 0, err
}
start = round
blockNum = ethrpc.BlockNumber(filter.FromBlock.Int64())
}
start, err := api.roundParamFromBlockNum(ctx, logger, blockNum)
if err != nil {
return 0, 0, err
}

Check warning on line 628 in rpc/eth/api.go

View check run for this annotation

Codecov / codecov/patch

rpc/eth/api.go#L627-L628

Added lines #L627 - L628 were not covered by tests

// Determine end round. If nothing passed, this is the latest round.
end := client.RoundLatest
if filter.ToBlock != nil {
round, err := api.roundParamFromBlockNum(ctx, logger, ethrpc.BlockNumber(filter.ToBlock.Int64()))
end, err = api.roundParamFromBlockNum(ctx, logger, ethrpc.BlockNumber(filter.ToBlock.Int64()))
if err != nil {
return 0, 0, err
}
end = round
}

// Ensure we have concrete round numbers here before proceeding as these rounds are used to
// determine whether the range of blocks is too large.
start, err = api.resolveLatest(ctx, start)
if err != nil {
return 0, 0, err
}

Check warning on line 644 in rpc/eth/api.go

View check run for this annotation

Codecov / codecov/patch

rpc/eth/api.go#L643-L644

Added lines #L643 - L644 were not covered by tests
end, err = api.resolveLatest(ctx, end)
if err != nil {
return 0, 0, err

Check warning on line 647 in rpc/eth/api.go

View check run for this annotation

Codecov / codecov/patch

rpc/eth/api.go#L647

Added line #L647 was not covered by tests
}

return start, end, nil
Expand Down
24 changes: 24 additions & 0 deletions tests/rpc/rpc_test.go
Expand Up @@ -407,6 +407,30 @@ func TestEth_GetLogsWithoutBlockhash(t *testing.T) {
require.NoError(t, err, "getLogs without explicit block hash")
}

func TestEth_GetLogsWithLatestHeight(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), OasisBlockTimeout)
defer cancel()

ec := localClient(t, false)

// Submit test transaction.
receipt := submitTestTransaction(ctx, t)
require.Equal(t, uint64(1), receipt.Status)
require.NotNil(t, receipt)

_, err := ec.FilterLogs(ctx, ethereum.FilterQuery{FromBlock: receipt.BlockNumber, ToBlock: nil})
require.NoError(t, err, "getLogs from specific block to latest block")
}

func TestEth_GetLogsWithGenesisHeight(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), OasisBlockTimeout)
defer cancel()

ec := localClient(t, false)
_, err := ec.FilterLogs(ctx, ethereum.FilterQuery{FromBlock: nil, ToBlock: big.NewInt(10)})
require.NoError(t, err, "getLogs from genesis block to specific block")
}

func TestEth_GetLogsWithFilters(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), OasisBlockTimeout)
defer cancel()
Expand Down
4 changes: 3 additions & 1 deletion tests/rpc/tx_test.go
Expand Up @@ -391,7 +391,9 @@ func TestERC20(t *testing.T) {
require.NoError(t, err)
require.Equal(t, uint64(1), receipt.Status)
require.NotEmpty(t, receipt.Logs, "ERC20-transfer receipt should contain the emitted log")
require.EqualValues(t, uint64(49700), receipt.GasUsed, "ERC20-transfer expected gas use")
// NOTE: Gas used may vary depending on the nonce value was so this may need updates if other
// tests submit more or less transactions.
require.EqualValues(t, uint64(49699), receipt.GasUsed, "ERC20-transfer expected gas use")

// Get balance of token receiver
balanceOfCall, err := testabi.Pack("balanceOf", common.Address{1})
Expand Down

0 comments on commit 9f4313e

Please sign in to comment.