Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem: get unnecessary block result in header related api call #535

Merged
merged 6 commits into from
Oct 4, 2024
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: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (ante) [#504](https://github.com/crypto-org-chain/ethermint/pull/504) Optimize AnteHandle method to skip checks if disabledMsgs is empty.
* [#517](https://github.com/crypto-org-chain/ethermint/pull/517) Add check for integer overflow to ensure safe conversion.
* [#522](https://github.com/crypto-org-chain/ethermint/pull/522) block-stm executor support optional pre-estimations.
* [#526](https://github.com/crypto-org-chain/ethermint/pull/526) Avoid unnecessary block result in header related api call.
* [#526](https://github.com/crypto-org-chain/ethermint/pull/526), [#535](https://github.com/crypto-org-chain/ethermint/pull/535) Avoid unnecessary block result in header related api call.
* [#533](https://github.com/crypto-org-chain/ethermint/pull/533) Bump cosmos-sdk to v0.50.10, cometbft to v0.38.13 and ibc-go to v8.5.1.

## v0.21.x-cronos
Expand Down
4 changes: 2 additions & 2 deletions rpc/backend/account_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (b *Backend) GetProof(address common.Address, storageKeys []string, blockNr
}

height := blockNum.Int64()
_, err = b.TendermintBlockByNumber(blockNum)
_, err = b.TendermintHeaderByNumber(blockNum)
if err != nil {
// the error message imitates geth behavior
return nil, errors.New("header not found")
Expand Down Expand Up @@ -163,7 +163,7 @@ func (b *Backend) GetBalance(address common.Address, blockNrOrHash rpctypes.Bloc
Address: address.String(),
}

_, err = b.TendermintBlockByNumber(blockNum)
_, err = b.TendermintHeaderByNumber(blockNum)
if err != nil {
return nil, err
}
Expand Down
29 changes: 18 additions & 11 deletions rpc/backend/account_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ func (suite *BackendTestSuite) TestGetProof() {
rpctypes.BlockNumberOrHash{BlockNumber: &blockNrInvalid},
func(bn rpctypes.BlockNumber, addr common.Address) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, bn.Int64(), nil)
height := bn.Int64()
RegisterHeader(client, &height, nil)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
RegisterAccount(queryClient, addr, blockNrInvalid.Int64())
},
Expand All @@ -111,7 +112,8 @@ func (suite *BackendTestSuite) TestGetProof() {
rpctypes.BlockNumberOrHash{BlockNumber: &blockNrInvalid},
func(bn rpctypes.BlockNumber, addr common.Address) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockError(client, bn.Int64())
height := bn.Int64()
RegisterHeaderError(client, &height)
},
false,
&rpctypes.AccountResult{},
Expand All @@ -122,12 +124,12 @@ func (suite *BackendTestSuite) TestGetProof() {
[]string{"0x0"},
rpctypes.BlockNumberOrHash{BlockNumber: &blockNr},
func(bn rpctypes.BlockNumber, addr common.Address) {
suite.backend.ctx = rpctypes.ContextWithHeight(bn.Int64())

height := bn.Int64()
suite.backend.ctx = rpctypes.ContextWithHeight(height)
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, bn.Int64(), nil)
RegisterHeader(client, &height, nil)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
RegisterAccount(queryClient, addr, bn.Int64())
RegisterAccount(queryClient, addr, height)

// Use the IAVL height if a valid tendermint height is passed in.
iavlHeight := bn.Int64()
Expand Down Expand Up @@ -270,7 +272,8 @@ func (suite *BackendTestSuite) TestGetBalance() {
rpctypes.BlockNumberOrHash{BlockNumber: &blockNr},
func(bn rpctypes.BlockNumber, addr common.Address) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockError(client, bn.Int64())
height := bn.Int64()
RegisterHeaderError(client, &height)
},
false,
nil,
Expand All @@ -281,7 +284,8 @@ func (suite *BackendTestSuite) TestGetBalance() {
rpctypes.BlockNumberOrHash{BlockNumber: &blockNr},
func(bn rpctypes.BlockNumber, addr common.Address) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, bn.Int64(), nil)
height := bn.Int64()
RegisterHeader(client, &height, nil)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
RegisterBalanceError(queryClient, addr, bn.Int64())
},
Expand All @@ -294,7 +298,8 @@ func (suite *BackendTestSuite) TestGetBalance() {
rpctypes.BlockNumberOrHash{BlockNumber: &blockNr},
func(bn rpctypes.BlockNumber, addr common.Address) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, bn.Int64(), nil)
height := bn.Int64()
RegisterHeader(client, &height, nil)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
RegisterBalanceInvalid(queryClient, addr, bn.Int64())
},
Expand All @@ -307,7 +312,8 @@ func (suite *BackendTestSuite) TestGetBalance() {
rpctypes.BlockNumberOrHash{BlockNumber: &blockNr},
func(bn rpctypes.BlockNumber, addr common.Address) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, bn.Int64(), nil)
height := bn.Int64()
RegisterHeader(client, &height, nil)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
RegisterBalanceNegative(queryClient, addr, bn.Int64())
},
Expand All @@ -320,7 +326,8 @@ func (suite *BackendTestSuite) TestGetBalance() {
rpctypes.BlockNumberOrHash{BlockNumber: &blockNr},
func(bn rpctypes.BlockNumber, addr common.Address) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, bn.Int64(), nil)
height := bn.Int64()
RegisterHeader(client, &height, nil)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
RegisterBalance(queryClient, addr, bn.Int64())
},
Expand Down
66 changes: 47 additions & 19 deletions rpc/backend/blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,30 +173,52 @@
// TendermintBlockByNumber returns a Tendermint-formatted block for a given
// block number
func (b *Backend) TendermintBlockByNumber(blockNum rpctypes.BlockNumber) (*tmrpctypes.ResultBlock, error) {
height, err := b.getHeightByBlockNum(blockNum)
if err != nil {
return nil, err
}
resBlock, err := b.clientCtx.Client.Block(b.ctx, &height)
if err != nil {
b.logger.Debug("tendermint client failed to get block", "height", height, "error", err.Error())
return nil, err
}

if resBlock.Block == nil {
b.logger.Debug("TendermintBlockByNumber block not found", "height", height)
return nil, nil
}

return resBlock, nil
}

func (b *Backend) getHeightByBlockNum(blockNum rpctypes.BlockNumber) (int64, error) {
height := blockNum.Int64()
if height <= 0 {
// fetch the latest block number from the app state, more accurate than the tendermint block store state.
n, err := b.BlockNumber()
if err != nil {
return nil, err
return 0, err
}
height, err = ethermint.SafeHexToInt64(n)
if err != nil {
return nil, err
return 0, err

Check warning on line 204 in rpc/backend/blocks.go

View check run for this annotation

Codecov / codecov/patch

rpc/backend/blocks.go#L204

Added line #L204 was not covered by tests
}
}
resBlock, err := b.clientCtx.Client.Block(b.ctx, &height)
return height, nil
}

// TendermintHeaderByNumber returns a Tendermint-formatted header for a given
// block number
func (b *Backend) TendermintHeaderByNumber(blockNum rpctypes.BlockNumber) (*tmrpctypes.ResultHeader, error) {
height, err := b.getHeightByBlockNum(blockNum)
if err != nil {
b.logger.Debug("tendermint client failed to get block", "height", height, "error", err.Error())
return nil, err
}

if resBlock.Block == nil {
b.logger.Debug("TendermintBlockByNumber block not found", "height", height)
return nil, nil
sc, ok := b.clientCtx.Client.(tmrpcclient.SignClient)
if !ok {
return nil, errors.New("invalid rpc client")

Check warning on line 219 in rpc/backend/blocks.go

View check run for this annotation

Codecov / codecov/patch

rpc/backend/blocks.go#L219

Added line #L219 was not covered by tests
}

return resBlock, nil
return sc.Header(b.ctx, &height)
}

// TendermintBlockResultByNumber returns a Tendermint-formatted block result
Expand Down Expand Up @@ -257,6 +279,9 @@
if err != nil {
return nil, err
}
if resHeader.Header == nil {
return nil, errors.Errorf("header not found for hash %s", blockHash.Hex())

Check warning on line 283 in rpc/backend/blocks.go

View check run for this annotation

Codecov / codecov/patch

rpc/backend/blocks.go#L283

Added line #L283 was not covered by tests
}
return big.NewInt(resHeader.Header.Height), nil
}

Expand Down Expand Up @@ -302,35 +327,35 @@

// HeaderByNumber returns the block header identified by height.
func (b *Backend) HeaderByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Header, error) {
resBlock, err := b.TendermintBlockByNumber(blockNum)
res, err := b.TendermintHeaderByNumber(blockNum)
if err != nil {
return nil, err
}

if resBlock == nil {
return nil, errors.Errorf("block not found for height %d", blockNum)
if res == nil || res.Header == nil {
return nil, errors.Errorf("header not found for height %d", blockNum)
}

blockRes, err := b.TendermintBlockResultByNumber(&resBlock.Block.Height)
blockRes, err := b.TendermintBlockResultByNumber(&res.Header.Height)
if err != nil {
return nil, fmt.Errorf("block result not found for height %d", resBlock.Block.Height)
return nil, fmt.Errorf("header result not found for height %d", res.Header.Height)
}

bloom, err := b.BlockBloom(blockRes)
if err != nil {
b.logger.Debug("HeaderByNumber BlockBloom failed", "height", resBlock.Block.Height)
b.logger.Debug("HeaderByNumber BlockBloom failed", "height", res.Header.Height)
}

baseFee, err := b.BaseFee(blockRes)
if err != nil {
// handle the error for pruned node.
b.logger.Error("failed to fetch Base Fee from prunned block. Check node prunning configuration", "height", resBlock.Block.Height, "error", err)
b.logger.Error("failed to fetch Base Fee from prunned block. Check node prunning configuration", "height", res.Header.Height, "error", err)
}
validator, err := b.getValidatorAccount(&resBlock.Block.Header)
validator, err := b.getValidatorAccount(res.Header)
if err != nil {
return nil, err
}
ethHeader := rpctypes.EthHeaderFromTendermint(resBlock.Block.Header, bloom, baseFee, validator)
ethHeader := rpctypes.EthHeaderFromTendermint(*res.Header, bloom, baseFee, validator)
return ethHeader, nil
}

Expand All @@ -344,6 +369,9 @@
if err != nil {
return nil, err
}
if resHeader.Header == nil {
return nil, errors.Errorf("header not found for hash %s", blockHash.Hex())
}
blockRes, err := b.TendermintBlockResultByNumber(&resHeader.Header.Height)
if err != nil {
return nil, errors.Errorf("block result not found for height %d", resHeader.Header.Height)
Expand Down
31 changes: 20 additions & 11 deletions rpc/backend/blocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1191,7 +1191,7 @@ func (suite *BackendTestSuite) TestEthMsgsFromTendermintBlock() {
}

func (suite *BackendTestSuite) TestHeaderByNumber() {
var expResultBlock *tmrpctypes.ResultBlock
var expResultHeader *tmrpctypes.ResultHeader

_, bz := suite.buildEthereumTx()
validator := sdk.AccAddress(tests.GenerateAddress().Bytes())
Expand All @@ -1210,29 +1210,29 @@ func (suite *BackendTestSuite) TestHeaderByNumber() {
func(blockNum ethrpc.BlockNumber, baseFee sdkmath.Int) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockError(client, height)
RegisterHeaderError(client, &height)
},
false,
},
{
"fail - block not found for height",
"fail - header not found for height",
ethrpc.BlockNumber(1),
sdkmath.NewInt(1).BigInt(),
func(blockNum ethrpc.BlockNumber, baseFee sdkmath.Int) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockNotFound(client, height)
RegisterHeaderNotFound(client, height)
},
false,
},
{
"fail - block not found for height",
"fail - header not found for height",
ethrpc.BlockNumber(1),
sdkmath.NewInt(1).BigInt(),
func(blockNum ethrpc.BlockNumber, baseFee sdkmath.Int) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, height, nil)
RegisterHeader(client, &height, nil)
RegisterBlockResultsError(client, height)
},
false,
Expand All @@ -1244,7 +1244,7 @@ func (suite *BackendTestSuite) TestHeaderByNumber() {
func(blockNum ethrpc.BlockNumber, baseFee sdkmath.Int) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
expResultBlock, _ = RegisterBlock(client, height, nil)
expResultHeader, _ = RegisterHeader(client, &height, nil)
RegisterBlockResults(client, height)

queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
Expand All @@ -1260,7 +1260,7 @@ func (suite *BackendTestSuite) TestHeaderByNumber() {
func(blockNum ethrpc.BlockNumber, baseFee sdkmath.Int) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
expResultBlock, _ = RegisterBlock(client, height, nil)
expResultHeader, _ = RegisterHeader(client, &height, nil)
RegisterBlockResults(client, height)

queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
Expand All @@ -1276,7 +1276,7 @@ func (suite *BackendTestSuite) TestHeaderByNumber() {
func(blockNum ethrpc.BlockNumber, baseFee sdkmath.Int) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
expResultBlock, _ = RegisterBlock(client, height, bz)
expResultHeader, _ = RegisterHeader(client, &height, bz)
RegisterBlockResults(client, height)

queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
Expand All @@ -1294,7 +1294,7 @@ func (suite *BackendTestSuite) TestHeaderByNumber() {
header, err := suite.backend.HeaderByNumber(tc.blockNumber)

if tc.expPass {
expHeader := ethrpc.EthHeaderFromTendermint(expResultBlock.Block.Header, ethtypes.Bloom{}, tc.baseFee, validator)
expHeader := ethrpc.EthHeaderFromTendermint(*expResultHeader.Header, ethtypes.Bloom{}, tc.baseFee, validator)
suite.Require().NoError(err)
suite.Require().Equal(expHeader, header)
} else {
Expand Down Expand Up @@ -1330,6 +1330,16 @@ func (suite *BackendTestSuite) TestHeaderByHash() {
},
false,
},
{
"fail - header not found for height",
common.BytesToHash(block.Hash()),
sdkmath.NewInt(1).BigInt(),
func(hash common.Hash, baseFee sdkmath.Int) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterHeaderByHashNotFound(client, hash, bz)
},
false,
},
{
"fail - block not found for height",
common.BytesToHash(block.Hash()),
Expand All @@ -1339,7 +1349,6 @@ func (suite *BackendTestSuite) TestHeaderByHash() {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterHeaderByHash(client, hash, bz)
RegisterBlockResultsError(client, height)
RegisterHeaderByHashError(client, hash, bz)
},
false,
},
Expand Down
9 changes: 4 additions & 5 deletions rpc/backend/call_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ func (b *Backend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *rp
return 0, err
}

header, err := b.TendermintBlockByNumber(blockNr)
header, err := b.TendermintHeaderByNumber(blockNr)
if err != nil {
// the error message imitates geth behavior
return 0, errors.New("header not found")
Expand All @@ -342,7 +342,7 @@ func (b *Backend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *rp
req := evmtypes.EthCallRequest{
Args: bz,
GasCap: b.RPCGasCap(),
ProposerAddress: sdk.ConsAddress(header.Block.ProposerAddress),
ProposerAddress: sdk.ConsAddress(header.Header.ProposerAddress),
ChainId: b.chainID.Int64(),
}

Expand All @@ -369,12 +369,11 @@ func (b *Backend) DoCall(
if err != nil {
return nil, err
}
header, err := b.TendermintBlockByNumber(blockNr)
header, err := b.TendermintHeaderByNumber(blockNr)
if err != nil {
// the error message imitates geth behavior
return nil, errors.New("header not found")
}

var bzOverrides []byte
if overrides != nil {
bzOverrides = *overrides
Expand All @@ -383,7 +382,7 @@ func (b *Backend) DoCall(
req := evmtypes.EthCallRequest{
Args: bz,
GasCap: b.RPCGasCap(),
ProposerAddress: sdk.ConsAddress(header.Block.ProposerAddress),
ProposerAddress: sdk.ConsAddress(header.Header.ProposerAddress),
ChainId: b.chainID.Int64(),
Overrides: bzOverrides,
}
Expand Down
Loading
Loading