Skip to content

Commit

Permalink
Problem: incorrect balance when no tracer in predecessors (#558)
Browse files Browse the repository at this point in the history
* Problem: incorrect balance when no tracer in predecessors

* lint
  • Loading branch information
mmsqe authored Nov 11, 2024
1 parent 836617d commit c9e06fa
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 32 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (cli) [#543](https://github.com/crypto-org-chain/ethermint/pull/543) Fix graceful shutdown.
* (rpc) [#545](https://github.com/crypto-org-chain/ethermint/pull/545) Fix state overwrite in debug trace APIs.
* (rpc) [#554](https://github.com/crypto-org-chain/ethermint/pull/554) No trace detail on insufficient balance.
* (rpc) [#558](https://github.com/crypto-org-chain/ethermint/pull/558) New tracer in predecessors to trace balance correctly when `debug_traceTransaction`.

### Improvements

Expand Down
8 changes: 4 additions & 4 deletions rpc/types/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,9 @@ func BaseFeeFromEvents(events []abci.Event) *big.Int {

// CheckTxFee is an internal function used to check whether the fee of
// the given transaction is _reasonable_(under the cap).
func CheckTxFee(gasPrice *big.Int, gas uint64, cap float64) error {
func CheckTxFee(gasPrice *big.Int, gas uint64, feeCap float64) error {
// Short circuit if there is no cap for transaction fee at all.
if cap == 0 {
if feeCap == 0 {
return nil
}
totalfee := new(big.Float).SetInt(new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(gas)))
Expand All @@ -300,8 +300,8 @@ func CheckTxFee(gasPrice *big.Int, gas uint64, cap float64) error {
feeEth := new(big.Float).Quo(totalfee, oneToken)
// no need to check error from parsing
feeFloat, _ := feeEth.Float64()
if feeFloat > cap {
return fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, cap)
if feeFloat > feeCap {
return fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, feeCap)
}
return nil
}
Expand Down
4 changes: 2 additions & 2 deletions types/dynamic_fee.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
)

// HasDynamicFeeExtensionOption returns true if the tx implements the `ExtensionOptionDynamicFeeTx` extension option.
func HasDynamicFeeExtensionOption(any *codectypes.Any) bool {
_, ok := any.GetCachedValue().(*ExtensionOptionDynamicFeeTx)
func HasDynamicFeeExtensionOption(codecAny *codectypes.Any) bool {
_, ok := codecAny.GetCachedValue().(*ExtensionOptionDynamicFeeTx)
return ok
}
59 changes: 37 additions & 22 deletions x/evm/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (

rpctypes "github.com/evmos/ethermint/rpc/types"
ethermint "github.com/evmos/ethermint/types"
"github.com/evmos/ethermint/x/evm/statedb"
"github.com/evmos/ethermint/x/evm/types"
)

Expand Down Expand Up @@ -424,6 +425,7 @@ func execTrace[T traceRequest](
msgCb func(
ctx sdk.Context,
cfg *EVMConfig,
traceConfig *types.TraceConfig,
) (*core.Message, error),
) ([]byte, error) {
var zero T
Expand Down Expand Up @@ -457,7 +459,7 @@ func execTrace[T traceRequest](
return nil, status.Errorf(codes.Internal, "failed to load evm config: %s", err.Error())
}

msg, err := msgCb(ctx, cfg)
msg, err := msgCb(ctx, cfg, req.GetTraceConfig())
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
Expand All @@ -484,9 +486,14 @@ func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*typ
c,
req,
k,
func(ctx sdk.Context, cfg *EVMConfig) (*core.Message, error) {
func(ctx sdk.Context, cfg *EVMConfig, traceConfig *types.TraceConfig) (*core.Message, error) {
signer := ethtypes.MakeSigner(cfg.ChainConfig, big.NewInt(ctx.BlockHeight()))
cfg.Tracer = types.NewNoOpTracer()
tracer, err := newTacer(&logger.Config{}, cfg.TxConfig, traceConfig)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
cfg.Tracer = tracer
cfg.DebugTrace = true
for i, tx := range req.Predecessors {
ethTx := tx.AsTransaction()
msg, err := core.TransactionToMessage(ethTx, signer, cfg.BaseFee)
Expand Down Expand Up @@ -601,7 +608,7 @@ func (k Keeper) TraceCall(c context.Context, req *types.QueryTraceCallRequest) (
c,
req,
k,
func(ctx sdk.Context, cfg *EVMConfig) (*core.Message, error) {
func(ctx sdk.Context, cfg *EVMConfig, _ *types.TraceConfig) (*core.Message, error) {
var args types.TransactionArgs
err := json.Unmarshal(req.Args, &args)
if err != nil {
Expand All @@ -628,6 +635,31 @@ func (k Keeper) TraceCall(c context.Context, req *types.QueryTraceCallRequest) (
}, nil
}

func newTacer(logConfig *logger.Config, txConfig statedb.TxConfig, traceConfig *types.TraceConfig) (tracers.Tracer, error) {
tracer := logger.NewStructLogger(logConfig)
if traceConfig != nil && traceConfig.Tracer != "" {
txIndex, err := ethermint.SafeInt(txConfig.TxIndex)
if err != nil {
return nil, err
}
tCtx := &tracers.Context{
BlockHash: txConfig.BlockHash,
TxIndex: txIndex,
TxHash: txConfig.TxHash,
}
var cfg json.RawMessage
if traceConfig.TracerJsonConfig != "" {
cfg = json.RawMessage(traceConfig.TracerJsonConfig)
}
tracer, err := tracers.DefaultDirectory.New(traceConfig.Tracer, tCtx, cfg)
if err != nil {
return nil, err
}
return tracer, nil
}
return tracer, nil
}

// prepareTrace prepare trace on one Ethereum message, it returns a tuple: (traceResult, nextLogIndex, error).
func (k *Keeper) prepareTrace(
ctx sdk.Context,
Expand Down Expand Up @@ -663,28 +695,11 @@ func (k *Keeper) prepareTrace(
Overrides: overrides,
}

tracer = logger.NewStructLogger(&logConfig)

txIndex, err := ethermint.SafeInt(txConfig.TxIndex)
tracer, err = newTacer(&logConfig, txConfig, traceConfig)
if err != nil {
return nil, 0, status.Error(codes.Internal, err.Error())
}

tCtx := &tracers.Context{
BlockHash: txConfig.BlockHash,
TxIndex: txIndex,
TxHash: txConfig.TxHash,
}
if traceConfig.Tracer != "" {
var cfg json.RawMessage
if traceConfig.TracerJsonConfig != "" {
cfg = json.RawMessage(traceConfig.TracerJsonConfig)
}
if tracer, err = tracers.DefaultDirectory.New(traceConfig.Tracer, tCtx, cfg); err != nil {
return nil, 0, status.Error(codes.Internal, err.Error())
}
}

// Define a meaningful timeout of a single transaction trace
if traceConfig.Timeout != "" {
if timeout, err = time.ParseDuration(traceConfig.Timeout); err != nil {
Expand Down
8 changes: 4 additions & 4 deletions x/evm/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,14 @@ func PackTxData(txData TxData) (*codectypes.Any, error) {

// UnpackTxData unpacks an Any into a TxData. It returns an error if the
// client state can't be unpacked into a TxData.
func UnpackTxData(any *codectypes.Any) (TxData, error) {
if any == nil {
func UnpackTxData(codecAny *codectypes.Any) (TxData, error) {
if codecAny == nil {
return nil, errorsmod.Wrap(errortypes.ErrUnpackAny, "protobuf Any message cannot be nil")
}

txData, ok := any.GetCachedValue().(TxData)
txData, ok := codecAny.GetCachedValue().(TxData)
if !ok {
return nil, errorsmod.Wrapf(errortypes.ErrUnpackAny, "cannot unpack Any into TxData %T", any)
return nil, errorsmod.Wrapf(errortypes.ErrUnpackAny, "cannot unpack Any into TxData %T", codecAny)
}

return txData, nil
Expand Down

0 comments on commit c9e06fa

Please sign in to comment.