From 929b2c28027a91d03ab598565dac2172a8477873 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 11 Nov 2025 11:17:24 +0800 Subject: [PATCH] fix: align GetCoinbaseAddress to handle empty proposer address in contexts like CheckTx --- CHANGELOG.md | 1 + .../integration/x/vm/test_state_transition.go | 30 ++++++++++++++++--- x/vm/keeper/block_proposer.go | 7 ++++- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63f4cac18..c72bd9dfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ - [\#774](https://github.com/cosmos/evm/pull/774) Emit proper allowance amount in erc20 event. - [\#790](https://github.com/cosmos/evm/pull/790) fix panic in historical query due to missing EvmCoinInfo. - [\#800](https://github.com/cosmos/evm/pull/800) Fix denom exponent validation in virtual fee deduct in vm module. +- [\#817](https://github.com/cosmos/evm/pull/817) Align GetCoinbaseAddress to handle empty proposer address in contexts like CheckTx where proposer doesn't exist. ## v0.5.0 diff --git a/tests/integration/x/vm/test_state_transition.go b/tests/integration/x/vm/test_state_transition.go index f44f5d5e6..ece42bb74 100644 --- a/tests/integration/x/vm/test_state_transition.go +++ b/tests/integration/x/vm/test_state_transition.go @@ -156,15 +156,27 @@ func (s *KeeperTestSuite) TestGetCoinbaseAddress() { msg string malleate func() sdk.Context expPass bool + expEmpty bool }{ + { + "empty proposer address - should return empty address without error", + func() sdk.Context { + header := s.Network.GetContext().BlockHeader() + header.ProposerAddress = sdk.ConsAddress{} + return s.Network.GetContext().WithBlockHeader(header) + }, + true, + true, + }, { "validator not found", func() sdk.Context { header := s.Network.GetContext().BlockHeader() - header.ProposerAddress = []byte{} + header.ProposerAddress = []byte{1, 2, 3} return s.Network.GetContext().WithBlockHeader(header) }, false, + false, }, { "success", @@ -172,23 +184,33 @@ func (s *KeeperTestSuite) TestGetCoinbaseAddress() { return s.Network.GetContext() }, true, + false, }, } for _, tc := range testCases { s.Run(fmt.Sprintf("Case %s", tc.msg), func() { ctx := tc.malleate() - proposerAddress := ctx.BlockHeader().ProposerAddress + var proposerAddress sdk.ConsAddress + if tc.expEmpty { + proposerAddress = sdk.ConsAddress{} + } else { + proposerAddress = ctx.BlockHeader().ProposerAddress + } // Function being tested coinbase, err := s.Network.App.GetEVMKeeper().GetCoinbaseAddress( ctx, - sdk.ConsAddress(proposerAddress), + proposerAddress, ) if tc.expPass { s.Require().NoError(err) - s.Require().Equal(proposerAddressHex, coinbase) + if tc.expEmpty { + s.Require().Equal(common.Address{}, coinbase) + } else { + s.Require().Equal(proposerAddressHex, coinbase) + } } else { s.Require().Error(err) } diff --git a/x/vm/keeper/block_proposer.go b/x/vm/keeper/block_proposer.go index 59588ac6b..5f17f2414 100644 --- a/x/vm/keeper/block_proposer.go +++ b/x/vm/keeper/block_proposer.go @@ -11,7 +11,12 @@ import ( // GetCoinbaseAddress returns the block proposer's validator operator address. func (k Keeper) GetCoinbaseAddress(ctx sdk.Context, proposerAddress sdk.ConsAddress) (common.Address, error) { - validator, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, GetProposerAddress(ctx, proposerAddress)) + proposerAddress = GetProposerAddress(ctx, proposerAddress) + if len(proposerAddress) == 0 { + // it's ok that proposer address don't exsits in some contexts like CheckTx. + return common.Address{}, nil + } + validator, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, proposerAddress) if err != nil { return common.Address{}, errorsmod.Wrapf( stakingtypes.ErrNoValidatorFound,