From 42c71da7dd9a9c024b474427cd51189fdba90293 Mon Sep 17 00:00:00 2001
From: ledgerwatch <akhounov@gmail.com>
Date: Tue, 20 Jul 2021 10:36:32 +0100
Subject: [PATCH] Fix for trace_replayTransaction due to gasPrice bug (#2403)

* Print CALL instr

* Print more info

* try to remove gas bailout

* gas bailout control and txHash

* Swap tracer

* Flush stream

* Add more json structure

* Print gasPrice

* Print gas price

* Fix

* Fix

* Clean up

Co-authored-by: Alex Sharp <alexsharp@Alexs-MacBook-Pro.local>
---
 cmd/rpcdaemon/commands/trace_adhoc.go     | 16 +++++++++----
 cmd/rpcdaemon/commands/trace_filtering.go | 28 ++++++++++++++++-------
 2 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/cmd/rpcdaemon/commands/trace_adhoc.go b/cmd/rpcdaemon/commands/trace_adhoc.go
index 2ddb6cd2bd..4793d8551a 100644
--- a/cmd/rpcdaemon/commands/trace_adhoc.go
+++ b/cmd/rpcdaemon/commands/trace_adhoc.go
@@ -54,6 +54,7 @@ type TraceCallParam struct {
 	Value                *hexutil.Big      `json:"value"`
 	Data                 hexutil.Bytes     `json:"data"`
 	AccessList           *types.AccessList `json:"accessList"`
+	txHash               *common.Hash
 	traceTypes           []string
 }
 
@@ -135,8 +136,9 @@ func (args *TraceCallParam) ToMessage(globalGasCap uint64, baseFee *uint256.Int)
 	} else {
 		// A basefee is provided, necessitating 1559-type execution
 		if args.GasPrice != nil {
+			var overflow bool
 			// User specified the legacy gas field, convert to 1559 gas typing
-			gasPrice, overflow := uint256.FromBig(args.GasPrice.ToInt())
+			gasPrice, overflow = uint256.FromBig(args.GasPrice.ToInt())
 			if overflow {
 				return types.Message{}, fmt.Errorf("args.GasPrice higher than 2^256-1")
 			}
@@ -179,7 +181,6 @@ func (args *TraceCallParam) ToMessage(globalGasCap uint64, baseFee *uint256.Int)
 	if args.AccessList != nil {
 		accessList = *args.AccessList
 	}
-
 	msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, false /* checkNonce */)
 	return msg, nil
 }
@@ -862,10 +863,11 @@ func (api *TraceAPIImpl) CallMany(ctx context.Context, calls json.RawMessage, bl
 	if tok != json.Delim(']') {
 		return nil, fmt.Errorf("expected end of array of [callparam, tracetypes]")
 	}
-	return api.doCallMany(ctx, dbtx, callParams, blockNrOrHash, nil)
+	return api.doCallMany(ctx, dbtx, callParams, blockNrOrHash, nil, true /* gasBailout */)
 }
 
-func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx ethdb.Tx, callParams []TraceCallParam, parentNrOrHash *rpc.BlockNumberOrHash, header *types.Header) ([]*TraceCallResult, error) {
+func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx ethdb.Tx, callParams []TraceCallParam, parentNrOrHash *rpc.BlockNumberOrHash, header *types.Header,
+	gasBailout bool) ([]*TraceCallResult, error) {
 	chainConfig, err := api.chainConfig(dbtx)
 	if err != nil {
 		return nil, err
@@ -971,7 +973,11 @@ func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx ethdb.Tx, callPara
 			cloneCache := stateCache.Clone()
 			cloneReader = state.NewCachedReader(stateReader, cloneCache)
 		}
-		ibs.Prepare(common.Hash{}, header.Hash(), txIndex)
+		if args.txHash != nil {
+			ibs.Prepare(*args.txHash, header.Hash(), txIndex)
+		} else {
+			ibs.Prepare(common.Hash{}, header.Hash(), txIndex)
+		}
 		execResult, err = core.ApplyMessage(evm, msg, gp, true /* refunds */, true /* gasBailout */)
 		if err != nil {
 			return nil, fmt.Errorf("first run for txIndex %d error: %w", txIndex, err)
diff --git a/cmd/rpcdaemon/commands/trace_filtering.go b/cmd/rpcdaemon/commands/trace_filtering.go
index 6707852d34..7dbaeb6f0e 100644
--- a/cmd/rpcdaemon/commands/trace_filtering.go
+++ b/cmd/rpcdaemon/commands/trace_filtering.go
@@ -419,15 +419,27 @@ func (api *TraceAPIImpl) callManyTransactions(ctx context.Context, dbtx ethdb.Tx
 		sender, _ := tx.GetSender()
 		gas := hexutil.Uint64(tx.GetGas())
 		gasPrice := hexutil.Big(*tx.GetPrice().ToBig())
+		var feeCap *hexutil.Big
+		if tx.GetFeeCap() != nil {
+			feeCap = (*hexutil.Big)(tx.GetFeeCap().ToBig())
+		}
+		var tip *hexutil.Big
+		if tx.GetTip() != nil {
+			tip = (*hexutil.Big)(tx.GetTip().ToBig())
+		}
 		value := hexutil.Big(*tx.GetValue().ToBig())
+		hash := tx.Hash()
 		toExecute = append(toExecute, TraceCallParam{
-			From:       &sender,
-			To:         tx.GetTo(),
-			Gas:        &gas,
-			GasPrice:   &gasPrice,
-			Value:      &value,
-			Data:       tx.GetData(),
-			traceTypes: []string{TraceTypeTrace, TraceTypeStateDiff},
+			From:                 &sender,
+			To:                   tx.GetTo(),
+			Gas:                  &gas,
+			GasPrice:             &gasPrice,
+			MaxFeePerGas:         feeCap,
+			MaxPriorityFeePerGas: tip,
+			Value:                &value,
+			Data:                 tx.GetData(),
+			txHash:               &hash,
+			traceTypes:           []string{TraceTypeTrace, TraceTypeStateDiff},
 		})
 	}
 
@@ -435,7 +447,7 @@ func (api *TraceAPIImpl) callManyTransactions(ctx context.Context, dbtx ethdb.Tx
 		BlockNumber:      &parentNo,
 		BlockHash:        &parentHash,
 		RequireCanonical: true,
-	}, header)
+	}, header, false /* gasBailout */)
 
 	if cmErr != nil {
 		return nil, cmErr
-- 
GitLab