Skip to content

Commit

Permalink
Problem: trace block gas refund change not committed (#527)
Browse files Browse the repository at this point in the history
* Problem: trace block not accurate for dynamic fee transaction

fix

changelog

temp

* Update x/evm/keeper/state_transition.go

Signed-off-by: yihuang <huang@crypto.com>

* avoid mutate config tracer

* fix test

* adjust test

* more test

* resolve

---------

Signed-off-by: yihuang <huang@crypto.com>
Co-authored-by: mmsqe <mavis@crypto.com>
  • Loading branch information
yihuang and mmsqe committed Sep 24, 2024
1 parent 7e30762 commit bcac9e2
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (rpc) [#521](https://github.com/crypto-org-chain/ethermint/pull/521) Align hash and miner in subscribe newHeads with eth_getBlockByNumber.
* (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.

### Improvements

Expand Down
13 changes: 8 additions & 5 deletions x/evm/keeper/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ func (k *Keeper) RemoveParamsCache(ctx sdk.Context) {
ctx.ObjectStore(k.objectKey).Delete(types.KeyPrefixObjectParams)
}

func (cfg EVMConfig) GetTracer() vm.EVMLogger {
if _, ok := cfg.Tracer.(*types.NoOpTracer); ok {
return nil
}
return cfg.Tracer
}

// EVMConfig creates the EVMConfig based on current state
func (k *Keeper) EVMConfig(ctx sdk.Context, chainID *big.Int, txHash common.Hash) (*EVMConfig, error) {
blockCfg, err := k.EVMBlockConfig(ctx, chainID)
Expand Down Expand Up @@ -155,12 +162,8 @@ func (k Keeper) VMConfig(ctx sdk.Context, cfg *EVMConfig) vm.Config {
noBaseFee = cfg.FeeMarketParams.NoBaseFee
}

if _, ok := cfg.Tracer.(*types.NoOpTracer); ok {
cfg.Tracer = nil
}

return vm.Config{
Tracer: cfg.Tracer,
Tracer: cfg.GetTracer(),
NoBaseFee: noBaseFee,
ExtraEips: cfg.Params.EIPs(),
}
Expand Down
26 changes: 26 additions & 0 deletions x/evm/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,20 @@ func (suite *GRPCServerTestSuiteSuite) TestTraceTx() {
}
predecessors = []*types.MsgEthereumTx{}
},
expPass: false,
enableFeemarket: true,
},
{
msg: "default trace with enableFeemarket and sufficient balance",
malleate: func() {
suite.App.EvmKeeper.SetBalance(suite.Ctx, suite.Address, big.NewInt(1000000000000000000), types.DefaultEVMDenom)
traceConfig = &types.TraceConfig{
DisableStack: true,
DisableStorage: true,
EnableMemory: false,
}
predecessors = []*types.MsgEthereumTx{}
},
expPass: true,
traceResponse: "{\"gas\":34828,\"failed\":false,\"returnValue\":\"0000000000000000000000000000000000000000000000000000000000000001\",\"structLogs\":[{\"pc\":0,\"op\":\"PUSH1\",\"gas\":",
enableFeemarket: true,
Expand All @@ -911,6 +925,18 @@ func (suite *GRPCServerTestSuiteSuite) TestTraceTx() {
}
predecessors = []*types.MsgEthereumTx{}
},
expPass: false,
enableFeemarket: true,
},
{
msg: "javascript tracer with enableFeemarket and sufficient balance",
malleate: func() {
suite.App.EvmKeeper.SetBalance(suite.Ctx, suite.Address, big.NewInt(1000000000000000000), types.DefaultEVMDenom)
traceConfig = &types.TraceConfig{
Tracer: "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}",
}
predecessors = []*types.MsgEthereumTx{}
},
expPass: true,
traceResponse: "[]",
enableFeemarket: true,
Expand Down
42 changes: 25 additions & 17 deletions x/evm/keeper/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,33 +322,41 @@ func (k *Keeper) ApplyMessageWithConfig(
return nil, errorsmod.Wrap(types.ErrCallDisabled, "failed to call contract")
}

stateDB := statedb.NewWithParams(ctx, k, cfg.TxConfig, cfg.Params.EvmDenom)
var evm *vm.EVM
if cfg.Overrides != nil {
if err := cfg.Overrides.Apply(stateDB); err != nil {
return nil, errorsmod.Wrap(err, "failed to apply state override")
}
}
evm = k.NewEVM(ctx, msg, cfg, stateDB)
leftoverGas := msg.GasLimit
sender := vm.AccountRef(msg.From)
// Allow the tracer captures the tx level events, mainly the gas consumption.
vmCfg := evm.Config
if vmCfg.Tracer != nil {
leftoverGas := msg.GasLimit
senderAddr := sdk.AccAddress(msg.From.Bytes())
tracer := cfg.GetTracer()
if tracer != nil {
if cfg.DebugTrace {
// msg.GasPrice should have been set to effective gas price
stateDB.SubBalance(sender.Address(), new(big.Int).Mul(msg.GasPrice, new(big.Int).SetUint64(msg.GasLimit)))
stateDB.SetNonce(sender.Address(), stateDB.GetNonce(sender.Address())+1)
amount := new(big.Int).Mul(msg.GasPrice, new(big.Int).SetUint64(msg.GasLimit))
if err := k.SubBalance(ctx, senderAddr, sdk.NewCoins(sdk.NewCoin(cfg.Params.EvmDenom, sdkmath.NewIntFromBigInt(amount)))); err != nil {
return nil, errorsmod.Wrap(err, "failed to subtract balance")
}
if err := k.incrNonce(ctx, senderAddr); err != nil {
return nil, errorsmod.Wrap(err, "failed to increment nonce")
}
}
vmCfg.Tracer.CaptureTxStart(leftoverGas)
tracer.CaptureTxStart(leftoverGas)
defer func() {
if cfg.DebugTrace {
stateDB.AddBalance(sender.Address(), new(big.Int).Mul(msg.GasPrice, new(big.Int).SetUint64(leftoverGas)))
amount := new(big.Int).Mul(msg.GasPrice, new(big.Int).SetUint64(leftoverGas))
_ = k.AddBalance(ctx, senderAddr, sdk.NewCoins(sdk.NewCoin(cfg.Params.EvmDenom, sdkmath.NewIntFromBigInt(amount))))
}
vmCfg.Tracer.CaptureTxEnd(leftoverGas)
tracer.CaptureTxEnd(leftoverGas)
}()
}

stateDB := statedb.NewWithParams(ctx, k, cfg.TxConfig, cfg.Params.EvmDenom)
var evm *vm.EVM
if cfg.Overrides != nil {
if err := cfg.Overrides.Apply(stateDB); err != nil {
return nil, errorsmod.Wrap(err, "failed to apply state override")
}
}
evm = k.NewEVM(ctx, msg, cfg, stateDB)
sender := vm.AccountRef(msg.From)

rules := cfg.Rules
contractCreation := msg.To == nil
intrinsicGas, err := k.GetEthIntrinsicGas(msg, rules, contractCreation)
Expand Down
14 changes: 14 additions & 0 deletions x/evm/keeper/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,20 @@ func (k *Keeper) SetAccount(ctx sdk.Context, addr common.Address, account stated
return nil
}

func (k *Keeper) incrNonce(ctx sdk.Context, addr sdk.AccAddress) error {
acct := k.accountKeeper.GetAccount(ctx, addr)
if acct == nil {
acct = k.accountKeeper.NewAccountWithAddress(ctx, addr)
}

if err := acct.SetSequence(acct.GetSequence() + 1); err != nil {
return err
}

k.accountKeeper.SetAccount(ctx, acct)
return nil
}

// SetState update contract storage, delete if value is empty.
func (k *Keeper) SetState(ctx sdk.Context, addr common.Address, key common.Hash, value []byte) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AddressStoragePrefix(addr))
Expand Down

0 comments on commit bcac9e2

Please sign in to comment.