github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/ante/EthSetupContextDecorator.go (about)

     1  package ante
     2  
     3  import (
     4  	"fmt"
     5  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     6  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
     7  )
     8  
     9  // EthSetupContextDecorator sets the infinite GasMeter in the Context and wraps
    10  // the next AnteHandler with a defer clause to recover from any downstream
    11  // OutOfGas panics in the AnteHandler chain to return an error with information
    12  // on gas provided and gas used.
    13  // CONTRACT: Must be first decorator in the chain
    14  // CONTRACT: Tx must implement GasTx interface
    15  type EthSetupContextDecorator struct{}
    16  
    17  // NewEthSetupContextDecorator creates a new EthSetupContextDecorator
    18  func NewEthSetupContextDecorator() EthSetupContextDecorator {
    19  	return EthSetupContextDecorator{}
    20  }
    21  
    22  // AnteHandle sets the infinite gas meter to done to ignore costs in AnteHandler checks.
    23  // This is undone at the EthGasConsumeDecorator, where the context is set with the
    24  // ethereum tx GasLimit.
    25  func (escd EthSetupContextDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
    26  	pinAnte(ctx.AnteTracer(), "EthSetupContextDecorator")
    27  
    28  	// Decorator will catch an OutOfGasPanic caused in the next antehandler
    29  	// AnteHandlers must have their own defer/recover in order for the BaseApp
    30  	// to know how much gas was used! This is because the GasMeter is created in
    31  	// the AnteHandler, but if it panics the context won't be set properly in
    32  	// runTx's recover call.
    33  	defer func() {
    34  		if r := recover(); r != nil {
    35  			switch rType := r.(type) {
    36  			case sdk.ErrorOutOfGas:
    37  				log := fmt.Sprintf(
    38  					"out of gas in location: %v; gasLimit: %d, gasUsed: %d",
    39  					rType.Descriptor, tx.GetGas(), ctx.GasMeter().GasConsumed(),
    40  				)
    41  				err = sdkerrors.Wrap(sdkerrors.ErrOutOfGas, log)
    42  			default:
    43  				panic(r)
    44  			}
    45  		}
    46  	}()
    47  	return next(ctx, tx, simulate)
    48  }