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 }