github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/baseapp/baseapp_mode_base.go (about)

     1  package baseapp
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     7  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
     8  	//"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/types"
     9  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    10  	tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types"
    11  )
    12  
    13  type modeHandler interface {
    14  	getMode() runTxMode
    15  
    16  	handleStartHeight(info *runTxInfo, height int64) error
    17  	handleGasConsumed(info *runTxInfo) error
    18  	handleRunMsg(info *runTxInfo) error
    19  	handleDeferRefund(info *runTxInfo)
    20  	handleDeferGasConsumed(info *runTxInfo)
    21  }
    22  
    23  func (app *BaseApp) getModeHandler(mode runTxMode) modeHandler {
    24  	var h modeHandler
    25  	switch mode {
    26  	case runTxModeCheck, runTxModeWrappedCheck:
    27  		h = &modeHandlerCheck{&modeHandlerBase{mode: mode, app: app}}
    28  	case runTxModeReCheck:
    29  		h = &modeHandlerRecheck{&modeHandlerBase{mode: mode, app: app}}
    30  	case runTxModeTrace:
    31  		h = &modeHandlerTrace{&modeHandlerDeliver{&modeHandlerBase{mode: mode, app: app}}}
    32  	case runTxModeDeliver:
    33  		h = &modeHandlerDeliver{&modeHandlerBase{mode: mode, app: app}}
    34  	case runTxModeSimulate:
    35  		h = &modeHandlerSimulate{&modeHandlerBase{mode: mode, app: app}}
    36  	case runTxModeDeliverInAsync:
    37  		h = &modeHandlerDeliverInAsync{&modeHandlerBase{mode: mode, app: app}}
    38  	default:
    39  		h = &modeHandlerBase{mode: mode, app: app}
    40  	}
    41  
    42  	return h
    43  }
    44  
    45  type modeHandlerBase struct {
    46  	mode runTxMode
    47  	app  *BaseApp
    48  }
    49  
    50  type modeHandlerDeliverInAsync struct {
    51  	*modeHandlerBase
    52  }
    53  
    54  type modeHandlerDeliver struct {
    55  	*modeHandlerBase
    56  }
    57  type modeHandlerCheck struct {
    58  	*modeHandlerBase
    59  }
    60  
    61  func (m *modeHandlerCheck) handleRunMsg(info *runTxInfo) (err error) {
    62  	if m.mode != runTxModeCheck {
    63  		return m.modeHandlerBase.handleRunMsg(info)
    64  	}
    65  
    66  	info.result = &sdk.Result{
    67  		Data:   make([]byte, 0),
    68  		Log:    "[]",
    69  		Events: sdk.EmptyEvents(),
    70  	}
    71  	info.runMsgFinished = true
    72  
    73  	m.handleRunMsg4CheckMode(info)
    74  	err = m.checkHigherThanMercury(err, info)
    75  	return
    76  }
    77  
    78  type modeHandlerRecheck struct {
    79  	*modeHandlerBase
    80  }
    81  
    82  func (m *modeHandlerRecheck) handleRunMsg(info *runTxInfo) (err error) {
    83  	if m.mode != runTxModeReCheck {
    84  		return m.modeHandlerBase.handleRunMsg(info)
    85  	}
    86  
    87  	info.result = &sdk.Result{
    88  		Data:   make([]byte, 0),
    89  		Log:    "[]",
    90  		Events: sdk.EmptyEvents(),
    91  	}
    92  	info.runMsgFinished = true
    93  
    94  	m.handleRunMsg4CheckMode(info)
    95  	err = m.checkHigherThanMercury(err, info)
    96  	return
    97  }
    98  
    99  type modeHandlerSimulate struct {
   100  	*modeHandlerBase
   101  }
   102  
   103  // modeHandlerTrace derived from modeHandlerDeliver
   104  type modeHandlerTrace struct {
   105  	*modeHandlerDeliver
   106  }
   107  
   108  func (m *modeHandlerBase) getMode() runTxMode {
   109  	return m.mode
   110  }
   111  
   112  // ====================================================
   113  // 1. handleStartHeight
   114  func (m *modeHandlerBase) handleStartHeight(info *runTxInfo, height int64) error {
   115  	app := m.app
   116  	startHeight := tmtypes.GetStartBlockHeight()
   117  
   118  	if height < startHeight && height != 0 {
   119  		return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest,
   120  			fmt.Sprintf("height(%d) should be greater than start block height(%d)", height, startHeight))
   121  	} else {
   122  		info.ctx = app.getContextForTx(m.mode, info.txBytes)
   123  	}
   124  
   125  	return nil
   126  }
   127  
   128  // ====================================================
   129  // 2. handleGasConsumed
   130  func (m *modeHandlerBase) handleGasConsumed(info *runTxInfo) (err error) {
   131  
   132  	if info.ctx.BlockGasMeter().IsOutOfGas() {
   133  		info.gInfo = sdk.GasInfo{GasUsed: info.ctx.BlockGasMeter().GasConsumed()}
   134  		err = sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "no block gas left to run tx")
   135  	} else {
   136  		info.startingGas = info.ctx.BlockGasMeter().GasConsumed()
   137  	}
   138  
   139  	return err
   140  }
   141  
   142  // noop
   143  func (m *modeHandlerRecheck) handleGasConsumed(*runTxInfo) (err error)  { return }
   144  func (m *modeHandlerCheck) handleGasConsumed(*runTxInfo) (err error)    { return }
   145  func (m *modeHandlerSimulate) handleGasConsumed(*runTxInfo) (err error) { return }
   146  
   147  //==========================================================================
   148  // 3. handleRunMsg
   149  
   150  // modeHandlerBase.handleRunMsg derived by:
   151  // (m *modeHandlerRecheck)
   152  // (m *modeHandlerCheck)
   153  // (m *modeHandlerSimulate)
   154  func (m *modeHandlerBase) handleRunMsg(info *runTxInfo) (err error) {
   155  	app := m.app
   156  	mode := m.mode
   157  
   158  	info.runMsgCtx, info.msCache = app.cacheTxContext(info.ctx, info.txBytes)
   159  	info.result, err = app.runMsgs(info.runMsgCtx, info.tx.GetMsgs(), mode)
   160  	info.runMsgFinished = true
   161  
   162  	m.handleRunMsg4CheckMode(info)
   163  	err = m.checkHigherThanMercury(err, info)
   164  	return
   165  }
   166  
   167  // =============================
   168  // 4. handleDeferGasConsumed
   169  func (m *modeHandlerBase) handleDeferGasConsumed(*runTxInfo) {}
   170  
   171  // ====================================================================
   172  // 5. handleDeferRefund
   173  func (m *modeHandlerBase) handleDeferRefund(*runTxInfo) {}
   174  
   175  // ===========================================================================================
   176  // other members
   177  func (m *modeHandlerBase) setGasConsumed(info *runTxInfo) {
   178  	info.ctx.BlockGasMeter().ConsumeGas(info.ctx.GasMeter().GasConsumedToLimit(), "block gas meter")
   179  	if info.ctx.BlockGasMeter().GasConsumed() < info.startingGas {
   180  		panic(sdk.ErrorGasOverflow{Descriptor: "tx gas summation"})
   181  	}
   182  }
   183  
   184  func (m *modeHandlerBase) checkHigherThanMercury(err error, info *runTxInfo) error {
   185  
   186  	if err != nil {
   187  		if tmtypes.HigherThanMercury(info.ctx.BlockHeight()) {
   188  			codeSpace, code, info := sdkerrors.ABCIInfo(err, m.app.trace)
   189  			err = sdkerrors.New(codeSpace, abci.CodeTypeNonceInc+code, info)
   190  		}
   191  		info.msCache = nil
   192  	}
   193  	return err
   194  }
   195  
   196  func (m *modeHandlerBase) handleRunMsg4CheckMode(info *runTxInfo) {
   197  	if m.mode != runTxModeCheck && m.mode != runTxModeWrappedCheck {
   198  		return
   199  	}
   200  
   201  	exTxInfo := m.app.GetTxInfo(info.ctx, info.tx)
   202  	exTxInfo.SenderNonce = info.accountNonce
   203  
   204  	data, err := json.Marshal(exTxInfo)
   205  	if err == nil {
   206  		info.result.Data = data
   207  	}
   208  }