Commit f99eca39 authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

txmgr: Include the revert reason in the error when estimateGas fails (#10829)

parent abbbd956
...@@ -3,12 +3,12 @@ package transactions ...@@ -3,12 +3,12 @@ package transactions
import ( import (
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"errors"
"fmt" "fmt"
"math/big" "math/big"
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-service/errutil"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
...@@ -20,10 +20,6 @@ import ( ...@@ -20,10 +20,6 @@ import (
type SendTxOpt func(cfg *sendTxCfg) type SendTxOpt func(cfg *sendTxCfg)
type ErrWithData interface {
ErrorData() interface{}
}
type sendTxCfg struct { type sendTxCfg struct {
receiptStatus uint64 receiptStatus uint64
} }
...@@ -83,11 +79,7 @@ func SendTx(ctx context.Context, client *ethclient.Client, candidate txmgr.TxCan ...@@ -83,11 +79,7 @@ func SendTx(ctx context.Context, client *ethclient.Client, candidate txmgr.TxCan
} }
gas, err := client.EstimateGas(ctx, msg) gas, err := client.EstimateGas(ctx, msg)
if err != nil { if err != nil {
var errWithData ErrWithData return nil, nil, fmt.Errorf("failed to estimate gas: %w", errutil.TryAddRevertReason(err))
if errors.As(err, &errWithData) {
return nil, nil, fmt.Errorf("failed to estimate gas. errdata: %v err: %w", errWithData.ErrorData(), err)
}
return nil, nil, fmt.Errorf("failed to estimate gas: %w", err)
} }
tx := types.MustSignNewTx(privKey, types.LatestSignerForChainID(chainID), &types.DynamicFeeTx{ tx := types.MustSignNewTx(privKey, types.LatestSignerForChainID(chainID), &types.DynamicFeeTx{
...@@ -102,7 +94,7 @@ func SendTx(ctx context.Context, client *ethclient.Client, candidate txmgr.TxCan ...@@ -102,7 +94,7 @@ func SendTx(ctx context.Context, client *ethclient.Client, candidate txmgr.TxCan
}) })
err = client.SendTransaction(ctx, tx) err = client.SendTransaction(ctx, tx)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("failed to send transaction: %w", err) return nil, nil, fmt.Errorf("failed to send transaction: %w", errutil.TryAddRevertReason(err))
} }
receipt, err := wait.ForReceipt(ctx, client, tx.Hash(), cfg.receiptStatus) receipt, err := wait.ForReceipt(ctx, client, tx.Hash(), cfg.receiptStatus)
if err != nil { if err != nil {
......
package errutil
import (
"errors"
"fmt"
)
type errWithData interface {
ErrorData() interface{}
}
// TryAddRevertReason attempts to extract the revert reason from geth RPC client errors and adds it to the error message.
// This is most useful when attempting to execute gas, as if the transaction reverts this will then show the reason.
func TryAddRevertReason(err error) error {
var errData errWithData
ok := errors.As(err, &errData)
if ok {
return fmt.Errorf("%w, reason: %v", err, errData.ErrorData())
} else {
return err
}
}
package errutil
import (
"errors"
"testing"
"github.com/stretchr/testify/require"
)
func TestTryAddRevertReason(t *testing.T) {
t.Run("AddsReason", func(t *testing.T) {
err := stubError{}
result := TryAddRevertReason(err)
require.Contains(t, result.Error(), "kaboom")
})
t.Run("ReturnOriginalWhenNoErrorDataMethod", func(t *testing.T) {
err := errors.New("boom")
result := TryAddRevertReason(err)
require.Same(t, err, result)
})
}
type stubError struct{}
func (s stubError) Error() string {
return "where's the"
}
func (s stubError) ErrorData() interface{} {
return "kaboom"
}
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/ethereum-optimism/optimism/op-service/errutil"
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/consensus/misc/eip4844"
...@@ -272,7 +273,7 @@ func (m *SimpleTxManager) craftTx(ctx context.Context, candidate TxCandidate) (* ...@@ -272,7 +273,7 @@ func (m *SimpleTxManager) craftTx(ctx context.Context, candidate TxCandidate) (*
Value: candidate.Value, Value: candidate.Value,
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to estimate gas: %w", err) return nil, fmt.Errorf("failed to estimate gas: %w", errutil.TryAddRevertReason(err))
} }
gasLimit = gas gasLimit = gas
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment