From 054e8958976450d6ced55cb9cdec171afa68040b Mon Sep 17 00:00:00 2001 From: Ganesh Vanahalli Date: Mon, 25 Mar 2024 14:48:31 -0500 Subject: [PATCH] refactor --- arbnode/batch_poster.go | 13 ++++++++++- arbutil/wait_for_l1.go | 48 ++++++++++++++++++++++++++++++----------- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/arbnode/batch_poster.go b/arbnode/batch_poster.go index b5f8558f59..b6c62d60a2 100644 --- a/arbnode/batch_poster.go +++ b/arbnode/batch_poster.go @@ -18,6 +18,7 @@ import ( "github.com/andybalholm/brotli" "github.com/spf13/pflag" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -485,7 +486,17 @@ func (b *BatchPoster) checkReverts(ctx context.Context, to int64) (bool, error) if shouldHalt { logLevel = log.Error } - txErr := arbutil.DetailTxErrorForTxInfo(ctx, b.l1Reader.Client(), tx.Hash, r, tx.From, tx.To, tx.GasPrice.ToInt(), tx.GasFeeCap.ToInt(), tx.GasTipCap.ToInt(), tx.Value.ToInt(), tx.Input, *tx.Accesses, uint64(tx.Gas)) + txErr := arbutil.DetailTxErrorUsingCallMsg(ctx, b.l1Reader.Client(), tx.Hash, r, ethereum.CallMsg{ + From: tx.From, + To: tx.To, + Gas: uint64(tx.Gas), + GasPrice: tx.GasPrice.ToInt(), + GasFeeCap: tx.GasFeeCap.ToInt(), + GasTipCap: tx.GasTipCap.ToInt(), + Value: tx.Value.ToInt(), + Data: tx.Input, + AccessList: *tx.Accesses, + }) logLevel("Transaction from batch poster reverted", "nonce", tx.Nonce, "txHash", tx.Hash, "blockNumber", r.BlockNumber, "blockHash", r.BlockHash, "txErr", txErr) return shouldHalt, nil } diff --git a/arbutil/wait_for_l1.go b/arbutil/wait_for_l1.go index 8fbaaed4d4..cfe24cf636 100644 --- a/arbutil/wait_for_l1.go +++ b/arbutil/wait_for_l1.go @@ -13,6 +13,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/rpc" ) @@ -29,20 +30,23 @@ type L1Interface interface { Client() rpc.ClientInterface } -func SendTxAsCall(ctx context.Context, client L1Interface, from common.Address, to *common.Address, gasPrice, gasFeeCap, gasTipCap, value, blockNum *big.Int, data []byte, accessList types.AccessList, gas uint64, unlimitedGas bool) ([]byte, error) { +func SendTxAsCall(ctx context.Context, client L1Interface, tx *types.Transaction, from common.Address, blockNum *big.Int, unlimitedGas bool) ([]byte, error) { + var gas uint64 if unlimitedGas { gas = 0 + } else { + gas = tx.Gas() } callMsg := ethereum.CallMsg{ From: from, - To: to, + To: tx.To(), Gas: gas, - GasPrice: gasPrice, - GasFeeCap: gasFeeCap, - GasTipCap: gasTipCap, - Value: value, - Data: data, - AccessList: accessList, + GasPrice: tx.GasPrice(), + GasFeeCap: tx.GasFeeCap(), + GasTipCap: tx.GasTipCap(), + Value: tx.Value(), + Data: tx.Data(), + AccessList: tx.AccessList(), } return client.CallContract(ctx, callMsg, blockNum) } @@ -69,14 +73,31 @@ func GetPendingCallBlockNumber(ctx context.Context, client L1Interface) (*big.In func DetailTxError(ctx context.Context, client L1Interface, tx *types.Transaction, txRes *types.Receipt) error { // Re-execute the transaction as a call to get a better error + if ctx.Err() != nil { + return ctx.Err() + } + if txRes == nil { + return errors.New("expected receipt") + } + if txRes.Status == types.ReceiptStatusSuccessful { + return nil + } from, err := client.TransactionSender(ctx, tx, txRes.BlockHash, txRes.TransactionIndex) if err != nil { return fmt.Errorf("TransactionSender got: %w for tx %v", err, tx.Hash()) } - return DetailTxErrorForTxInfo(ctx, client, tx.Hash(), txRes, from, tx.To(), tx.GasPrice(), tx.GasFeeCap(), tx.GasTipCap(), tx.Value(), tx.Data(), tx.AccessList(), tx.Gas()) + _, err = SendTxAsCall(ctx, client, tx, from, txRes.BlockNumber, false) + if err == nil { + return fmt.Errorf("tx failed but call succeeded for tx hash %v", tx.Hash()) + } + _, err = SendTxAsCall(ctx, client, tx, from, txRes.BlockNumber, true) + if err == nil { + return fmt.Errorf("%w for tx hash %v", vm.ErrOutOfGas, tx.Hash()) + } + return fmt.Errorf("SendTxAsCall got: %w for tx hash %v", err, tx.Hash()) } -func DetailTxErrorForTxInfo(ctx context.Context, client L1Interface, txHash common.Hash, txRes *types.Receipt, from common.Address, to *common.Address, gasPrice, gasFeeCap, gasTipCap, value *big.Int, data []byte, accessList types.AccessList, gas uint64) error { +func DetailTxErrorUsingCallMsg(ctx context.Context, client L1Interface, txHash common.Hash, txRes *types.Receipt, callMsg ethereum.CallMsg) error { // Re-execute the transaction as a call to get a better error if ctx.Err() != nil { return ctx.Err() @@ -88,11 +109,12 @@ func DetailTxErrorForTxInfo(ctx context.Context, client L1Interface, txHash comm return nil } var err error - if _, err = SendTxAsCall(ctx, client, from, to, gasPrice, gasFeeCap, gasTipCap, value, txRes.BlockNumber, data, accessList, gas, false); err == nil { + if _, err = client.CallContract(ctx, callMsg, txRes.BlockNumber); err == nil { return fmt.Errorf("tx failed but call succeeded for tx hash %v", txHash) } - if _, err = SendTxAsCall(ctx, client, from, to, gasPrice, gasFeeCap, gasTipCap, value, txRes.BlockNumber, data, accessList, gas, true); err == nil { - return fmt.Errorf("tx failed but call succeeded for tx hash %v", txHash) + callMsg.Gas = 0 + if _, err = client.CallContract(ctx, callMsg, txRes.BlockNumber); err == nil { + return fmt.Errorf("%w for tx hash %v", vm.ErrOutOfGas, txHash) } return fmt.Errorf("SendTxAsCall got: %w for tx hash %v", err, txHash) }