fix(evm,rpc): coinbase should not be the current one in traceTransaction execution (#1392)

* add proposer address

* make proto-all

* update nix

* fix test

* keep default proposerAddress

* add change doc

* refine GetProposerAddress with test

* include ProposerAddress for trace api

* fix eth call req

* wrap proposerAddress for eth call

* allow proto translates to sdk.ConsAddress

* Update rpc/backend/call_tx.go

Co-authored-by: Freddy Caceres <facs95@gmail.com>
Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
mmsqe
2022-10-21 19:58:29 -04:00
committed by GitHub
co-authored by Freddy Caceres Federico Kunze Küllmer
parent f04b289e75
commit 295a8862db
11 changed files with 369 additions and 140 deletions
+4 -7
View File
@@ -224,7 +224,7 @@ func (k Keeper) EthCall(c context.Context, req *types.EthCallRequest) (*types.Ms
return nil, status.Error(codes.InvalidArgument, err.Error())
}
cfg, err := k.EVMConfig(ctx)
cfg, err := k.EVMConfig(ctx, GetProposerAddress(ctx, req.ProposerAddress))
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
@@ -294,8 +294,7 @@ func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*type
hi = req.GasCap
}
cap = hi
cfg, err := k.EVMConfig(ctx)
cfg, err := k.EVMConfig(ctx, GetProposerAddress(ctx, req.ProposerAddress))
if err != nil {
return nil, status.Error(codes.Internal, "failed to load evm config")
}
@@ -375,8 +374,7 @@ func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*typ
ctx = ctx.WithBlockHeight(contextHeight)
ctx = ctx.WithBlockTime(req.BlockTime)
ctx = ctx.WithHeaderHash(common.Hex2Bytes(req.BlockHash))
cfg, err := k.EVMConfig(ctx)
cfg, err := k.EVMConfig(ctx, GetProposerAddress(ctx, req.ProposerAddress))
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to load evm config: %s", err.Error())
}
@@ -443,8 +441,7 @@ func (k Keeper) TraceBlock(c context.Context, req *types.QueryTraceBlockRequest)
ctx = ctx.WithBlockHeight(contextHeight)
ctx = ctx.WithBlockTime(req.BlockTime)
ctx = ctx.WithHeaderHash(common.Hex2Bytes(req.BlockHash))
cfg, err := k.EVMConfig(ctx)
cfg, err := k.EVMConfig(ctx, GetProposerAddress(ctx, req.ProposerAddress))
if err != nil {
return nil, status.Error(codes.Internal, "failed to load evm config")
}
+10 -7
View File
@@ -735,8 +735,9 @@ func (suite *KeeperTestSuite) TestEstimateGas() {
args, err := json.Marshal(&args)
suite.Require().NoError(err)
req := types.EthCallRequest{
Args: args,
GasCap: gasCap,
Args: args,
GasCap: gasCap,
ProposerAddress: suite.ctx.BlockHeader().ProposerAddress,
}
rsp, err := suite.queryClient.EstimateGas(sdk.WrapSDKContext(suite.ctx), &req)
@@ -1145,16 +1146,18 @@ func (suite *KeeperTestSuite) TestNonceInQuery() {
Data: (*hexutil.Bytes)(&data),
})
suite.Require().NoError(err)
proposerAddress := suite.ctx.BlockHeader().ProposerAddress
_, err = suite.queryClient.EstimateGas(sdk.WrapSDKContext(suite.ctx), &types.EthCallRequest{
Args: args,
GasCap: uint64(config.DefaultGasCap),
Args: args,
GasCap: uint64(config.DefaultGasCap),
ProposerAddress: proposerAddress,
})
suite.Require().NoError(err)
_, err = suite.queryClient.EthCall(sdk.WrapSDKContext(suite.ctx), &types.EthCallRequest{
Args: args,
GasCap: uint64(config.DefaultGasCap),
Args: args,
GasCap: uint64(config.DefaultGasCap),
ProposerAddress: proposerAddress,
})
suite.Require().NoError(err)
}
+9 -7
View File
@@ -257,10 +257,10 @@ func (suite *KeeperTestSuite) DeployTestContract(t require.TestingT, owner commo
Data: (*hexutil.Bytes)(&data),
})
require.NoError(t, err)
res, err := suite.queryClient.EstimateGas(ctx, &types.EthCallRequest{
Args: args,
GasCap: uint64(config.DefaultGasCap),
Args: args,
GasCap: uint64(config.DefaultGasCap),
ProposerAddress: suite.ctx.BlockHeader().ProposerAddress,
})
require.NoError(t, err)
@@ -308,8 +308,9 @@ func (suite *KeeperTestSuite) TransferERC20Token(t require.TestingT, contractAdd
args, err := json.Marshal(&types.TransactionArgs{To: &contractAddr, From: &from, Data: (*hexutil.Bytes)(&transferData)})
require.NoError(t, err)
res, err := suite.queryClient.EstimateGas(ctx, &types.EthCallRequest{
Args: args,
GasCap: 25_000_000,
Args: args,
GasCap: 25_000_000,
ProposerAddress: suite.ctx.BlockHeader().ProposerAddress,
})
require.NoError(t, err)
@@ -365,8 +366,9 @@ func (suite *KeeperTestSuite) DeployTestMessageCall(t require.TestingT) common.A
require.NoError(t, err)
res, err := suite.queryClient.EstimateGas(ctx, &types.EthCallRequest{
Args: args,
GasCap: uint64(config.DefaultGasCap),
Args: args,
GasCap: uint64(config.DefaultGasCap),
ProposerAddress: suite.ctx.BlockHeader().ProposerAddress,
})
require.NoError(t, err)
+15 -8
View File
@@ -39,12 +39,12 @@ func GasToRefund(availableRefund, gasConsumed, refundQuotient uint64) uint64 {
}
// EVMConfig creates the EVMConfig based on current state
func (k *Keeper) EVMConfig(ctx sdk.Context) (*types.EVMConfig, error) {
func (k *Keeper) EVMConfig(ctx sdk.Context, proposerAddress sdk.ConsAddress) (*types.EVMConfig, error) {
params := k.GetParams(ctx)
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
// get the coinbase address from the block proposer
coinbase, err := k.GetCoinbaseAddress(ctx)
coinbase, err := k.GetCoinbaseAddress(ctx, proposerAddress)
if err != nil {
return nil, sdkerrors.Wrap(err, "failed to obtain coinbase address")
}
@@ -199,7 +199,7 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *ethtypes.Transaction) (*t
bloomReceipt ethtypes.Bloom
)
cfg, err := k.EVMConfig(ctx)
cfg, err := k.EVMConfig(ctx, sdk.ConsAddress(ctx.BlockHeader().ProposerAddress))
if err != nil {
return nil, sdkerrors.Wrap(err, "failed to load evm config")
}
@@ -464,7 +464,7 @@ func (k *Keeper) ApplyMessageWithConfig(ctx sdk.Context,
// ApplyMessage calls ApplyMessageWithConfig with default EVMConfig
func (k *Keeper) ApplyMessage(ctx sdk.Context, msg core.Message, tracer vm.EVMLogger, commit bool) (*types.MsgEthereumTxResponse, error) {
cfg, err := k.EVMConfig(ctx)
cfg, err := k.EVMConfig(ctx, sdk.ConsAddress(ctx.BlockHeader().ProposerAddress))
if err != nil {
return nil, sdkerrors.Wrap(err, "failed to load evm config")
}
@@ -519,15 +519,22 @@ func (k *Keeper) ResetGasMeterAndConsumeGas(ctx sdk.Context, gasUsed uint64) {
ctx.GasMeter().ConsumeGas(gasUsed, "apply evm transaction")
}
// GetProposerAddress returns current block proposer's address when provided proposer address is empty.
func GetProposerAddress(ctx sdk.Context, proposerAddress sdk.ConsAddress) sdk.ConsAddress {
if len(proposerAddress) == 0 {
proposerAddress = ctx.BlockHeader().ProposerAddress
}
return proposerAddress
}
// GetCoinbaseAddress returns the block proposer's validator operator address.
func (k Keeper) GetCoinbaseAddress(ctx sdk.Context) (common.Address, error) {
consAddr := sdk.ConsAddress(ctx.BlockHeader().ProposerAddress)
validator, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
func (k Keeper) GetCoinbaseAddress(ctx sdk.Context, proposerAddress sdk.ConsAddress) (common.Address, error) {
validator, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, GetProposerAddress(ctx, proposerAddress))
if !found {
return common.Address{}, sdkerrors.Wrapf(
stakingtypes.ErrNoValidatorFound,
"failed to retrieve validator from block proposer address %s",
consAddr.String(),
proposerAddress.String(),
)
}
+40 -5
View File
@@ -159,8 +159,8 @@ func (suite *KeeperTestSuite) TestGetCoinbaseAddress() {
suite.SetupTest() // reset
tc.malleate()
coinbase, err := suite.app.EvmKeeper.GetCoinbaseAddress(suite.ctx)
proposerAddress := suite.ctx.BlockHeader().ProposerAddress
coinbase, err := suite.app.EvmKeeper.GetCoinbaseAddress(suite.ctx, sdk.ConsAddress(proposerAddress))
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(valOpAddr, coinbase)
@@ -516,7 +516,8 @@ func (suite *KeeperTestSuite) TestResetGasMeterAndConsumeGas() {
}
func (suite *KeeperTestSuite) TestEVMConfig() {
cfg, err := suite.app.EvmKeeper.EVMConfig(suite.ctx)
proposerAddress := suite.ctx.BlockHeader().ProposerAddress
cfg, err := suite.app.EvmKeeper.EVMConfig(suite.ctx, proposerAddress)
suite.Require().NoError(err)
suite.Require().Equal(types.DefaultParams(), cfg.Params)
// london hardfork is enabled by default
@@ -535,7 +536,8 @@ func (suite *KeeperTestSuite) TestApplyMessage() {
expectedGasUsed := params.TxGas
var msg core.Message
config, err := suite.app.EvmKeeper.EVMConfig(suite.ctx)
proposerAddress := suite.ctx.BlockHeader().ProposerAddress
config, err := suite.app.EvmKeeper.EVMConfig(suite.ctx, proposerAddress)
suite.Require().NoError(err)
keeperParams := suite.app.EvmKeeper.GetParams(suite.ctx)
@@ -635,7 +637,8 @@ func (suite *KeeperTestSuite) TestApplyMessageWithConfig() {
suite.SetupTest()
expectedGasUsed = params.TxGas
config, err = suite.app.EvmKeeper.EVMConfig(suite.ctx)
proposerAddress := suite.ctx.BlockHeader().ProposerAddress
config, err = suite.app.EvmKeeper.EVMConfig(suite.ctx, proposerAddress)
suite.Require().NoError(err)
keeperParams = suite.app.EvmKeeper.GetParams(suite.ctx)
@@ -688,3 +691,35 @@ func (suite *KeeperTestSuite) createContractMsgTx(nonce uint64, signer ethtypes.
return ethMsg, ethMsg.Sign(signer, suite.signer)
}
func (suite *KeeperTestSuite) TestGetProposerAddress() {
var a sdk.ConsAddress
address := sdk.ConsAddress(suite.address.Bytes())
proposerAddress := sdk.ConsAddress(suite.ctx.BlockHeader().ProposerAddress)
testCases := []struct {
msg string
adr sdk.ConsAddress
expAdr sdk.ConsAddress
}{
{
"proposer address provided",
address,
address,
},
{
"nil proposer address provided",
nil,
proposerAddress,
},
{
"typed nil proposer address provided",
a,
proposerAddress,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.Require().Equal(tc.expAdr, keeper.GetProposerAddress(suite.ctx, tc.adr))
})
}
}