Skip to content

Commit

Permalink
Problem: opBlockhash broke after sdk50
Browse files Browse the repository at this point in the history
  • Loading branch information
mmsqe committed Oct 2, 2024
1 parent 5acb559 commit ceeb4b0
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 35 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (rpc) [#516](https://github.com/crypto-org-chain/ethermint/pull/516) Avoid method eth_chainId crashed due to nil pointer on IsEIP155 check.
* (cli) [#524](https://github.com/crypto-org-chain/ethermint/pull/524) Allow tx evm raw run for generate only when offline with evm-denom flag.
* (rpc) [#527](https://github.com/crypto-org-chain/ethermint/pull/527) Fix balance consistency between trace-block and state machine.
* (rpc) [#534](https://github.com/crypto-org-chain/ethermint/pull/534) Fix opBlockhash when no block header in abci request.

### Improvements

Expand Down
1 change: 1 addition & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,7 @@ func (app *EthermintApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.

// RegisterTxService implements the Application.RegisterTxService method.
func (app *EthermintApp) RegisterTxService(clientCtx client.Context) {
app.EvmKeeper.WithCometClient(clientCtx.Client)

Check warning on line 1051 in app/app.go

View check run for this annotation

Codecov / codecov/patch

app/app.go#L1051

Added line #L1051 was not covered by tests
authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract TestBlockTxProperties {
function getBlockHash(uint256 blockNumber) public view returns (bytes32) {
return blockhash(blockNumber);
}
}
11 changes: 11 additions & 0 deletions tests/integration_tests/test_block.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from .utils import CONTRACTS, deploy_contract, w3_wait_for_new_blocks


def test_call(ethermint):
w3 = ethermint.w3
contract, res = deploy_contract(w3, CONTRACTS["TestBlockTxProperties"])
height = w3.eth.get_block_number()
w3_wait_for_new_blocks(w3, 1)
res = contract.caller.getBlockHash(height).hex()
blk = w3.eth.get_block(height)
assert f"0x{res}" == blk.hash.hex(), res
1 change: 1 addition & 0 deletions tests/integration_tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"Calculator": "Calculator.sol",
"Caller": "Caller.sol",
"Random": "Random.sol",
"TestBlockTxProperties": "TestBlockTxProperties.sol",
}


Expand Down
12 changes: 12 additions & 0 deletions x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
errorsmod "cosmossdk.io/errors"
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
tmrpcclient "github.com/cometbft/cometbft/rpc/client"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
Expand Down Expand Up @@ -73,6 +75,8 @@ type Keeper struct {
// Legacy subspace
ss paramstypes.Subspace
customContractFns []CustomContractFn

signClient tmrpcclient.SignClient
}

// NewKeeper generates new evm module keeper
Expand Down Expand Up @@ -144,6 +148,14 @@ func (k Keeper) ChainID() *big.Int {
return k.eip155ChainID
}

func (k *Keeper) WithCometClient(c client.CometRPC) {
sc, ok := c.(tmrpcclient.SignClient)
if !ok {
panic("invalid rpc client")

Check warning on line 154 in x/evm/keeper/keeper.go

View check run for this annotation

Codecov / codecov/patch

x/evm/keeper/keeper.go#L154

Added line #L154 was not covered by tests
}
k.signClient = sc
}

// ----------------------------------------------------------------------------
// Block Bloom
// Required by Web3 API.
Expand Down
12 changes: 2 additions & 10 deletions x/evm/keeper/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,19 +128,11 @@ func (k Keeper) GetHashFn(ctx sdk.Context) vm.GetHashFunc {
case ctx.BlockHeight() > h:
// Case 2: if the chain is not the current height we need to retrieve the hash from the store for the
// current chain epoch. This only applies if the current height is greater than the requested height.
histInfo, err := k.stakingKeeper.GetHistoricalInfo(ctx, h)
res, err := k.signClient.Header(ctx, &h)
if err != nil {
k.Logger(ctx).Debug("historical info not found", "height", h, "err", err.Error())
return common.Hash{}
}

header, err := cmttypes.HeaderFromProto(&histInfo.Header)
if err != nil {
k.Logger(ctx).Error("failed to cast tendermint header from proto", "error", err)
return common.Hash{}
}

return common.BytesToHash(header.Hash())
return common.BytesToHash(res.Header.Hash())
default:
// Case 3: heights greater than the current one returns an empty hash.
return common.Hash{}
Expand Down
46 changes: 21 additions & 25 deletions x/evm/keeper/state_transition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
storetypes "cosmossdk.io/store/types"
"github.com/cometbft/cometbft/crypto/tmhash"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
tmrpctypes "github.com/cometbft/cometbft/rpc/core/types"
tmtypes "github.com/cometbft/cometbft/types"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -22,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/evmos/ethermint/app"
"github.com/evmos/ethermint/rpc/backend/mocks"
"github.com/evmos/ethermint/tests"
"github.com/evmos/ethermint/testutil"
utiltx "github.com/evmos/ethermint/testutil/tx"
Expand Down Expand Up @@ -92,68 +94,62 @@ func (suite *StateTransitionTestSuite) TestGetHashFn() {
testCases := []struct {
msg string
height uint64
malleate func()
malleate func(height uint64)
expHash common.Hash
}{
{
"case 1.1: context hash cached",
uint64(suite.Ctx.BlockHeight()),
func() {
func(_ uint64) {
suite.Ctx = suite.Ctx.WithHeaderHash(tmhash.Sum([]byte("header"))).WithConsensusParams(*testutil.DefaultConsensusParams)
},
common.BytesToHash(tmhash.Sum([]byte("header"))),
},
{
"case 1.2: failed to cast Tendermint header",
uint64(suite.Ctx.BlockHeight()),
func() {
header := tmproto.Header{}
func(_ uint64) {
header.Height = suite.Ctx.BlockHeight()
suite.Ctx = suite.Ctx.WithBlockHeader(header).WithConsensusParams(*testutil.DefaultConsensusParams)
suite.Ctx = suite.Ctx.WithBlockHeader(tmproto.Header{}).WithConsensusParams(*testutil.DefaultConsensusParams)
},
common.Hash{},
},
{
"case 1.3: hash calculated from Tendermint header",
uint64(suite.Ctx.BlockHeight()),
func() {
func(_ uint64) {
suite.Ctx = suite.Ctx.WithBlockHeader(header).WithConsensusParams(*testutil.DefaultConsensusParams)
},
common.BytesToHash(hash),
},
{
"case 2.1: height lower than current one, hist info not found",
1,
func() {
suite.Ctx = suite.Ctx.WithBlockHeight(10).WithConsensusParams(*testutil.DefaultConsensusParams)
},
common.Hash{},
},
{
"case 2.2: height lower than current one, invalid hist info header",
"case 2.1: height lower than current one, header not found",
1,
func() {
suite.App.StakingKeeper.SetHistoricalInfo(suite.Ctx, 1, &stakingtypes.HistoricalInfo{})
func(height uint64) {
c := mocks.NewClient(suite.T())
suite.App.EvmKeeper.WithCometClient(c)
suite.Ctx = suite.Ctx.WithBlockHeight(10).WithConsensusParams(*testutil.DefaultConsensusParams)
height0 := int64(height)
c.On("Header", suite.Ctx, &height0).Return(&tmrpctypes.ResultHeader{Header: &h}, nil)
},
common.Hash{},
},
{
"case 2.3: height lower than current one, calculated from hist info header",
"case 2.2: height lower than current one, header found",
1,
func() {
histInfo := &stakingtypes.HistoricalInfo{
Header: header,
}
suite.App.StakingKeeper.SetHistoricalInfo(suite.Ctx, 1, histInfo)
func(height uint64) {
c := mocks.NewClient(suite.T())
suite.App.EvmKeeper.WithCometClient(c)
suite.Ctx = suite.Ctx.WithBlockHeight(10).WithConsensusParams(*testutil.DefaultConsensusParams)
height0 := int64(height)
c.On("Header", suite.Ctx, &height0).Return(&tmrpctypes.ResultHeader{Header: &h}, nil)
},
common.BytesToHash(hash),
},
{
"case 3: height greater than current one",
200,
func() {},
func(_ uint64) {},
common.Hash{},
},
}
Expand All @@ -162,7 +158,7 @@ func (suite *StateTransitionTestSuite) TestGetHashFn() {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset

tc.malleate()
tc.malleate(tc.height)

hash := suite.App.EvmKeeper.GetHashFn(suite.Ctx)(tc.height)
suite.Require().Equal(tc.expHash, hash)
Expand Down

0 comments on commit ceeb4b0

Please sign in to comment.