forked from cerc-io/laconicd-deprecated
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:
co-authored by
Freddy Caceres
Federico Kunze Küllmer
parent
f04b289e75
commit
295a8862db
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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(),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user