diff --git a/itests/fevm_test.go b/itests/fevm_test.go index d9c0019de65..940d56ef140 100644 --- a/itests/fevm_test.go +++ b/itests/fevm_test.go @@ -901,14 +901,23 @@ func TestFEVMErrorParsing(t *testing.T) { "failCustom()": customError, } { sig := sig - expected := expected + expected := fmt.Sprintf("exit 33, revert reason: %s, vm error", expected) t.Run(sig, func(t *testing.T) { entryPoint := kit.CalcFuncSignature(sig) - _, err := e.EthCall(ctx, ethtypes.EthCall{ - To: &contractAddrEth, - Data: entryPoint, - }, "latest") - require.ErrorContains(t, err, fmt.Sprintf("exit 33, revert reason: %s, vm error", expected)) + t.Run("EthCall", func(t *testing.T) { + _, err := e.EthCall(ctx, ethtypes.EthCall{ + To: &contractAddrEth, + Data: entryPoint, + }, "latest") + require.ErrorContains(t, err, expected) + }) + t.Run("EthEstimateGas", func(t *testing.T) { + _, err := e.EthEstimateGas(ctx, ethtypes.EthCall{ + To: &contractAddrEth, + Data: entryPoint, + }) + require.ErrorContains(t, err, expected) + }) }) } } diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go index 454b3eca538..2f50d873e19 100644 --- a/node/impl/full/eth.go +++ b/node/impl/full/eth.go @@ -888,12 +888,22 @@ func (a *EthModule) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (et msg.GasLimit = 0 ts := a.Chain.GetHeaviestTipSet() - msg, err = a.GasAPI.GasEstimateMessageGas(ctx, msg, nil, ts.Key()) - if err != nil { + gassedMsg, err := a.GasAPI.GasEstimateMessageGas(ctx, msg, nil, ts.Key()) + if err != nil { + // On failure, GasEstimateMessageGas doesn't actually return the invocation result, + // it just returns an error. That means we can't get the revert reason. + // + // So we re-execute the message with EthCall (well, applyMessage which contains the + // guts of EthCall). This will give us an ethereum specific error with revert + // information. + msg.GasLimit = build.BlockGasLimit + if _, err2 := a.applyMessage(ctx, msg, ts.Key()); err2 != nil { + err = err2 + } return ethtypes.EthUint64(0), xerrors.Errorf("failed to estimate gas: %w", err) } - expectedGas, err := ethGasSearch(ctx, a.Chain, a.Stmgr, a.Mpool, msg, ts) + expectedGas, err := ethGasSearch(ctx, a.Chain, a.Stmgr, a.Mpool, gassedMsg, ts) if err != nil { log.Errorw("expected gas", "err", err) }