github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/auth/ante/setup.go (about) 1 package ante 2 3 import ( 4 "fmt" 5 6 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 7 sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors" 8 ) 9 10 // SetUpContextDecorator sets the GasMeter in the Context and wraps the next AnteHandler with a defer clause 11 // to recover from any downstream 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 SetUpContextDecorator struct{} 16 17 func NewSetUpContextDecorator() SetUpContextDecorator { 18 return SetUpContextDecorator{} 19 } 20 21 func (sud SetUpContextDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { 22 // all transactions must implement GasTx 23 gasTx := tx 24 25 SetGasMeter(simulate, &ctx, gasTx.GetGas()) 26 newCtx = ctx 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; gasWanted: %d, gasUsed: %d", 39 rType.Descriptor, gasTx.GetGas(), newCtx.GasMeter().GasConsumed()) 40 41 err = sdkerrors.Wrap(sdkerrors.ErrOutOfGas, log) 42 default: 43 panic(r) 44 } 45 } 46 }() 47 48 return next(newCtx, tx, simulate) 49 } 50 51 // SetGasMeter update context with a gas meter with gasLimit 52 func SetGasMeter(simulate bool, ctx *sdk.Context, gasLimit uint64) { 53 // In various cases such as simulation and during the genesis block, we do not 54 // meter any gas utilization. 55 if simulate || ctx.BlockHeight() == 0 { 56 ctx.SetGasMeter(sdk.NewInfiniteGasMeter()) 57 return 58 } 59 60 ctx.SetGasMeter(sdk.NewGasMeter(gasLimit)) 61 return 62 }