diff --git a/app/ante/account.go b/app/ante/account.go index 8fe95a2cb..a99eb877f 100644 --- a/app/ante/account.go +++ b/app/ante/account.go @@ -12,7 +12,6 @@ import ( "github.com/okx/okbchain/libs/cosmos-sdk/baseapp" sdk "github.com/okx/okbchain/libs/cosmos-sdk/types" sdkerrors "github.com/okx/okbchain/libs/cosmos-sdk/types/errors" - "github.com/okx/okbchain/libs/cosmos-sdk/types/innertx" "github.com/okx/okbchain/libs/cosmos-sdk/x/auth" "github.com/okx/okbchain/libs/cosmos-sdk/x/auth/exported" "github.com/okx/okbchain/libs/cosmos-sdk/x/auth/types" @@ -152,7 +151,7 @@ func nonceVerification(ctx sdk.Context, acc exported.Account, msgEthTx *evmtypes return ctx, nil } -func ethGasConsume(ek EVMKeeper, ak accountKeeperInterface, sk types.SupplyKeeper, ctx *sdk.Context, acc exported.Account, accGetGas sdk.Gas, msgEthTx *evmtypes.MsgEthereumTx, simulate bool) error { +func ethGasConsume(ek EVMKeeper, sk types.SupplyKeeper, ctx *sdk.Context, acc exported.Account, accGetGas sdk.Gas, msgEthTx *evmtypes.MsgEthereumTx, simulate bool) error { gasLimit := msgEthTx.GetGas() if shouldIntrinsicGas(ek, ctx, msgEthTx) { @@ -181,7 +180,7 @@ func ethGasConsume(ek EVMKeeper, ak accountKeeperInterface, sk types.SupplyKeepe ctx.UpdateFromAccountCache(acc, accGetGas) - err := deductFees(ek, ak, sk, *ctx, acc, feeAmt) + err := auth.DeductFees(sk, *ctx, acc, feeAmt) if err != nil { return err } @@ -208,43 +207,6 @@ func IsE2CTx(ek EVMKeeper, ctx *sdk.Context, msgEthTx *evmtypes.MsgEthereumTx) b return false } -func deductFees(ik innertx.InnerTxKeeper, ak accountKeeperInterface, sk types.SupplyKeeper, ctx sdk.Context, acc exported.Account, fees sdk.Coins) error { - blockTime := ctx.BlockTime() - coins := acc.GetCoins() - - if !fees.IsValid() { - return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "invalid fee amount: %s", fees) - } - - // verify the account has enough funds to pay for fees - balance, hasNeg := coins.SafeSub(fees) - if hasNeg { - return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, - "insufficient funds to pay for fees; %s < %s", coins, fees) - } - - // Validate the account has enough "spendable" coins as this will cover cases - // such as vesting accounts. - spendableCoins := acc.SpendableCoins(blockTime) - if _, hasNeg := spendableCoins.SafeSub(fees); hasNeg { - return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, - "insufficient funds to pay for fees; %s < %s", spendableCoins, fees) - } - - // set coins and record innertx - err := acc.SetCoins(balance) - if !ctx.IsCheckTx() { - toAcc := sk.GetModuleAddress(types.FeeCollectorName) - ik.UpdateInnerTx(ctx.TxBytes(), ctx.BlockHeight(), innertx.CosmosDepth, acc.GetAddress(), toAcc, innertx.CosmosCallType, innertx.SendCallName, fees, err) - } - if err != nil { - return err - } - ak.SetAccount(ctx, acc) - - return nil -} - func incrementSeq(ctx sdk.Context, msgEthTx *evmtypes.MsgEthereumTx, accAddress sdk.AccAddress, ak auth.AccountKeeper, acc exported.Account) { if ctx.IsCheckTx() && !ctx.IsReCheckTx() && !baseapp.IsMempoolEnableRecheck() && !ctx.IsTraceTx() { return @@ -335,7 +297,7 @@ func (avd AccountAnteDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate ctx.EnableAccountCache() // account would be updated - err = ethGasConsume(avd.evmKeeper, avd.ak, avd.sk, &ctx, acc, getAccGasUsed, msgEthTx, simulate) + err = ethGasConsume(avd.evmKeeper, avd.sk, &ctx, acc, getAccGasUsed, msgEthTx, simulate) acc = nil acc, _ = ctx.GetFromAccountCacheData().(exported.Account) ctx.DisableAccountCache() diff --git a/app/app.go b/app/app.go index 785349250..79641f701 100644 --- a/app/app.go +++ b/app/app.go @@ -700,6 +700,7 @@ func NewOKBChainApp( app.SetUpdateWasmTxCount(fixCosmosTxCountInWasmForParallelTx(app.WasmHandler.TXCounterStoreKey)) app.SetUpdateFeeCollectorAccHandler(updateFeeCollectorHandler(app.BankKeeper, app.SupplyKeeper)) + app.SetGetFeeCollectorInfo(getFeeCollectorInfo(app.BankKeeper, app.SupplyKeeper)) app.SetParallelTxLogHandlers(fixLogForParallelTxHandler(app.EvmKeeper)) app.SetPreDeliverTxHandler(preDeliverTxHandler(app.AccountKeeper)) app.SetPartialConcurrentHandlers(getTxFeeAndFromHandler(app.EvmKeeper)) diff --git a/app/app_parallel.go b/app/app_parallel.go index 88a7cf328..979c128cd 100644 --- a/app/app_parallel.go +++ b/app/app_parallel.go @@ -19,12 +19,23 @@ import ( wasmkeeper "github.com/okx/okbchain/x/wasm/keeper" ) +func getFeeCollectorInfo(bk bank.Keeper, sk supply.Keeper) sdk.GetFeeCollectorInfo { + return func(ctx sdk.Context, onlyGetFeeCollectorStoreKey bool) (sdk.Coins, []byte) { + if onlyGetFeeCollectorStoreKey { + return sdk.Coins{}, auth.AddressStoreKey(sk.GetModuleAddress(auth.FeeCollectorName)) + } + return bk.GetCoins(ctx, sk.GetModuleAddress(auth.FeeCollectorName)), nil + } +} + // feeCollectorHandler set or get the value of feeCollectorAcc func updateFeeCollectorHandler(bk bank.Keeper, sk supply.Keeper) sdk.UpdateFeeCollectorAccHandler { return func(ctx sdk.Context, balance sdk.Coins, txFeesplit []*sdk.FeeSplitInfo) error { - err := bk.SetCoins(ctx, sk.GetModuleAccount(ctx, auth.FeeCollectorName).GetAddress(), balance) - if err != nil { - return err + if !balance.Empty() { + err := bk.SetCoins(ctx, sk.GetModuleAccount(ctx, auth.FeeCollectorName).GetAddress(), balance) + if err != nil { + return err + } } // split fee @@ -33,7 +44,7 @@ func updateFeeCollectorHandler(bk bank.Keeper, sk supply.Keeper) sdk.UpdateFeeCo feesplits, sortAddrs := groupByAddrAndSortFeeSplits(txFeesplit) for _, addr := range sortAddrs { acc := sdk.MustAccAddressFromBech32(addr) - err = sk.SendCoinsFromModuleToAccount(ctx, auth.FeeCollectorName, acc, feesplits[addr]) + err := sk.SendCoinsFromModuleToAccount(ctx, auth.FeeCollectorName, acc, feesplits[addr]) if err != nil { return err } diff --git a/app/refund/refund.go b/app/refund/refund.go index 9ba8a1914..c2f53d238 100644 --- a/app/refund/refund.go +++ b/app/refund/refund.go @@ -4,14 +4,14 @@ import ( "math/big" "sync" - "github.com/okx/okbchain/libs/cosmos-sdk/x/auth/ante" - "github.com/okx/okbchain/libs/cosmos-sdk/x/auth/keeper" - sdk "github.com/okx/okbchain/libs/cosmos-sdk/types" sdkerrors "github.com/okx/okbchain/libs/cosmos-sdk/types/errors" "github.com/okx/okbchain/libs/cosmos-sdk/types/innertx" "github.com/okx/okbchain/libs/cosmos-sdk/x/auth" + "github.com/okx/okbchain/libs/cosmos-sdk/x/auth/ante" "github.com/okx/okbchain/libs/cosmos-sdk/x/auth/exported" + "github.com/okx/okbchain/libs/cosmos-sdk/x/auth/keeper" + "github.com/okx/okbchain/libs/cosmos-sdk/x/auth/refund" "github.com/okx/okbchain/libs/cosmos-sdk/x/auth/types" tmtypes "github.com/okx/okbchain/libs/tendermint/types" ) @@ -89,18 +89,12 @@ func gasRefund(ik innertx.InnerTxKeeper, ak accountKeeperInterface, sk types.Sup gas := feeTx.GetGas() fees := feeTx.GetFee() gasFees := calculateRefundFees(gasUsed, gas, fees) - newCoins := feePayerAcc.GetCoins().Add(gasFees...) // set coins and record innertx - err = feePayerAcc.SetCoins(newCoins) - if !ctx.IsCheckTx() { - fromAddr := sk.GetModuleAddress(types.FeeCollectorName) - ik.UpdateInnerTx(ctx.TxBytes(), ctx.BlockHeight(), innertx.CosmosDepth, fromAddr, feePayerAcc.GetAddress(), innertx.CosmosCallType, innertx.SendCallName, gasFees, err) - } + err = refund.RefundFees(sk, ctx, feePayerAcc.GetAddress(), gasFees) if err != nil { return nil, err } - ak.SetAccount(ctx, feePayerAcc) return gasFees, nil } diff --git a/libs/cosmos-sdk/baseapp/abci.go b/libs/cosmos-sdk/baseapp/abci.go index da8d34941..c09a4b24e 100644 --- a/libs/cosmos-sdk/baseapp/abci.go +++ b/libs/cosmos-sdk/baseapp/abci.go @@ -173,8 +173,7 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg app.anteTracer = trace.NewTracer(trace.AnteChainDetail) - app.feeCollector = sdk.Coins{} - app.feeChanged = false + app.feeCollector = nil // clean FeeSplitCollector app.FeeSplitCollector = make([]*sdk.FeeSplitInfo, 0) @@ -188,20 +187,8 @@ func (app *BaseApp) UpdateGlobalGasConfig(ctx sdk.Context) { stypes.UpdateGlobalGasConfig(app.getGasConfigHandler(ctx)) } -func (app *BaseApp) UpdateFeeCollector(fee sdk.Coins, add bool) { - if fee.IsZero() { - return - } - app.feeChanged = true - if add { - app.feeCollector = app.feeCollector.Add(fee...) - } else { - app.feeCollector = app.feeCollector.Sub(fee) - } -} - func (app *BaseApp) updateFeeCollectorAccount(isEndBlock bool) { - if app.updateFeeCollectorAccHandler == nil || !app.feeChanged { + if app.updateFeeCollectorAccHandler == nil { return } diff --git a/libs/cosmos-sdk/baseapp/baseapp.go b/libs/cosmos-sdk/baseapp/baseapp.go index 5763d961a..8b12e2099 100644 --- a/libs/cosmos-sdk/baseapp/baseapp.go +++ b/libs/cosmos-sdk/baseapp/baseapp.go @@ -150,6 +150,7 @@ type BaseApp struct { // nolint: maligned fauxMerkleMode bool // if true, IAVL MountStores uses MountStoresDB for simulation speed. updateFeeCollectorAccHandler sdk.UpdateFeeCollectorAccHandler + getFeeCollectorInfoHandler sdk.GetFeeCollectorInfo logFix sdk.LogFix updateCosmosTxCount sdk.UpdateCosmosTxCount @@ -203,7 +204,6 @@ type BaseApp struct { // nolint: maligned parallelTxManage *parallelTxManager feeCollector sdk.Coins - feeChanged bool // used to judge whether should update the fee-collector account FeeSplitCollector []*sdk.FeeSplitInfo checkTxNum int64 diff --git a/libs/cosmos-sdk/baseapp/baseapp_mode_deliver.go b/libs/cosmos-sdk/baseapp/baseapp_mode_deliver.go index 301962548..fb437e9aa 100644 --- a/libs/cosmos-sdk/baseapp/baseapp_mode_deliver.go +++ b/libs/cosmos-sdk/baseapp/baseapp_mode_deliver.go @@ -53,8 +53,8 @@ func (m *modeHandlerDeliver) handleDeferRefund(info *runTxInfo) { if m.app.GasRefundHandler == nil { return } - refund := handleGasRefund(info, m.app.cacheTxContext, m.app.GasRefundHandler) - m.app.UpdateFeeCollector(refund, false) + handleGasRefund(info, m.app.cacheTxContext, m.app.GasRefundHandler) + if info.ctx.GetFeeSplitInfo().HasFee { m.app.FeeSplitCollector = append(m.app.FeeSplitCollector, info.ctx.GetFeeSplitInfo()) } diff --git a/libs/cosmos-sdk/baseapp/baseapp_parallel.go b/libs/cosmos-sdk/baseapp/baseapp_parallel.go index bb5b923fd..9f14c056c 100644 --- a/libs/cosmos-sdk/baseapp/baseapp_parallel.go +++ b/libs/cosmos-sdk/baseapp/baseapp_parallel.go @@ -19,6 +19,8 @@ var ( maxTxResultInChan = 200000 maxGoroutineNumberInParaTx = runtime.NumCPU() multiCacheListClearInterval = int64(100) + + feeAccountKeyInStore = make([]byte, 0) ) type extraDataForTx struct { @@ -184,6 +186,10 @@ func (app *BaseApp) ParallelTxs(txs [][]byte, onlyCalSender bool) []*abci.Respon return make([]*abci.ResponseDeliverTx, 0) } + if len(feeAccountKeyInStore) == 0 { + _, feeAccountKeyInStore = app.getFeeCollectorInfoHandler(app.deliverState.ctx, true) + } + pm := app.parallelTxManage pm.init(txs, app.deliverState.ctx.BlockHeight(), app.deliverState.ms) @@ -260,6 +266,11 @@ func (app *BaseApp) runTxs() []*abci.ResponseDeliverTx { pm.blockGasMeterMu.Unlock() pm.SetCurrentIndexTxRes(pm.upComingTxIndex, res) + + if !res.msIsNil { + pm.currTxFee = pm.currTxFee.Add(pm.extraTxsInfo[pm.upComingTxIndex].fee.Sub(pm.finalResult[pm.upComingTxIndex].paraMsg.RefundFee)...) + } + currentGas += uint64(res.resp.GasUsed) if isReRun { @@ -297,9 +308,10 @@ func (app *BaseApp) runTxs() []*abci.ResponseDeliverTx { pm.alreadyEnd = true pm.stop <- struct{}{} - // fix logs - app.feeChanged = true + // update fee collector balance app.feeCollector = app.parallelTxManage.currTxFee + + // fix logs receiptsLogs := app.endParallelTxs(pm.txSize) ctx, _ := app.cacheTxContext(app.getContextForTx(runTxModeDeliver, []byte{}), []byte{}) ctx.SetMultiStore(app.parallelTxManage.cms) @@ -698,7 +710,6 @@ func (pm *parallelTxManager) addBlockCacheToChainCache() { } var ( - feeAccountKey, _ = hex.DecodeString("01f1829676db577682e944fc3493d451b67ff3e29f") wasmTxCountKey, _ = hex.DecodeString("08") ) @@ -711,7 +722,7 @@ func (pm *parallelTxManager) isConflict(e *executeResult) bool { return true } for storeKey, rw := range e.rwSet { - delete(rw.Read, string(feeAccountKey)) + delete(rw.Read, string(feeAccountKeyInStore)) delete(rw.Read, string(wasmTxCountKey)) for key, value := range rw.Read { @@ -827,7 +838,6 @@ func (pm *parallelTxManager) SetCurrentIndexTxRes(txIndex int, res *executeResul pm.conflictCheck[storeKey].Write[key] = value } } - pm.currTxFee = pm.currTxFee.Add(pm.extraTxsInfo[txIndex].fee.Sub(pm.finalResult[txIndex].paraMsg.RefundFee)...) } func (pm *parallelTxManager) NeedUpdateTXCounter() bool { diff --git a/libs/cosmos-sdk/baseapp/baseapp_runtx.go b/libs/cosmos-sdk/baseapp/baseapp_runtx.go index cbbea2a0c..b28d7f113 100644 --- a/libs/cosmos-sdk/baseapp/baseapp_runtx.go +++ b/libs/cosmos-sdk/baseapp/baseapp_runtx.go @@ -86,12 +86,6 @@ func (app *BaseApp) runtxWithInfo(info *runTxInfo, mode runTxMode, txBytes []byt handler := info.handler app.pin(trace.ValTxMsgs, true, mode) - if tx.GetType() != sdk.EvmTxType && mode == runTxModeDeliver { - // should update the balance of FeeCollector's account when run non-evm tx - // which uses non-infiniteGasMeter during AnteHandleChain - app.updateFeeCollectorAccount(false) - } - //init info context err = handler.handleStartHeight(info, height) if err != nil { @@ -177,12 +171,7 @@ func (app *BaseApp) runtxWithInfo(info *runTxInfo, mode runTxMode, txBytes []byt } } app.pin(trace.RunAnte, false, mode) - - if app.getTxFeeHandler != nil && mode == runTxModeDeliver { - fee := app.getTxFeeHandler(tx) - app.UpdateFeeCollector(fee, true) - } - + isAnteSucceed = true app.pin(trace.RunMsg, true, mode) err = handler.handleRunMsg(info) diff --git a/libs/cosmos-sdk/baseapp/options.go b/libs/cosmos-sdk/baseapp/options.go index 624304be6..f2aa0095a 100644 --- a/libs/cosmos-sdk/baseapp/options.go +++ b/libs/cosmos-sdk/baseapp/options.go @@ -170,6 +170,13 @@ func (app *BaseApp) SetUpdateFeeCollectorAccHandler(handler sdk.UpdateFeeCollect app.updateFeeCollectorAccHandler = handler } +func (app *BaseApp) SetGetFeeCollectorInfo(handle sdk.GetFeeCollectorInfo) { + if app.sealed { + panic("SetGetFeeCollectorBalance() on sealed BaseApp") + } + app.getFeeCollectorInfoHandler = handle +} + func (app *BaseApp) SetParallelTxLogHandlers(fixLog sdk.LogFix) { if app.sealed { panic("SetPallTxLogHandler() on sealed BaseApp") diff --git a/libs/cosmos-sdk/types/handler.go b/libs/cosmos-sdk/types/handler.go index ee5db44e7..605e2e482 100644 --- a/libs/cosmos-sdk/types/handler.go +++ b/libs/cosmos-sdk/types/handler.go @@ -30,6 +30,8 @@ type GetGasConfigHandler func(ctx Context) *stypes.GasConfig type UpdateCosmosTxCount func(ctx Context, txCount int) +type GetFeeCollectorInfo func(ctx Context, onlyGetFeeCollectorStoreKey bool) (Coins, []byte) + type LogFix func(tx []Tx, logIndex []int, hasEnterEvmTx []bool, errs []error, resp []abci.ResponseDeliverTx) (logs [][]byte) type UpdateFeeSplitHandler func(txHash common.Hash, addr AccAddress, fee Coins, isDelete bool) type GetTxFeeAndFromHandler func(ctx Context, tx Tx) (Coins, bool, bool, string, string, error, bool) diff --git a/libs/ibc-go/testing/simapp/app.go b/libs/ibc-go/testing/simapp/app.go index 9f39ba77e..97e60218f 100644 --- a/libs/ibc-go/testing/simapp/app.go +++ b/libs/ibc-go/testing/simapp/app.go @@ -695,6 +695,7 @@ func NewSimApp( app.SetAccNonceHandler(NewAccHandler(app.AccountKeeper)) app.SetUpdateWasmTxCount(fixCosmosTxCountInWasmForParallelTx(app.WasmHandler.TXCounterStoreKey)) app.SetUpdateFeeCollectorAccHandler(updateFeeCollectorHandler(app.BankKeeper, app.SupplyKeeper.Keeper)) + app.SetGetFeeCollectorInfo(getFeeCollectorInfo(app.BankKeeper, app.SupplyKeeper.Keeper)) app.SetParallelTxLogHandlers(fixLogForParallelTxHandler(app.EvmKeeper)) app.SetPartialConcurrentHandlers(getTxFeeAndFromHandler(app.EvmKeeper)) app.SetGetTxFeeHandler(getTxFeeHandler()) @@ -722,7 +723,19 @@ func NewSimApp( func updateFeeCollectorHandler(bk bank.Keeper, sk supply.Keeper) sdk.UpdateFeeCollectorAccHandler { return func(ctx sdk.Context, balance sdk.Coins, txFeesplit []*sdk.FeeSplitInfo) error { - return bk.SetCoins(ctx, sk.GetModuleAccount(ctx, auth.FeeCollectorName).GetAddress(), balance) + if !balance.Empty() { + return bk.SetCoins(ctx, sk.GetModuleAccount(ctx, auth.FeeCollectorName).GetAddress(), balance) + } + return nil + } +} + +func getFeeCollectorInfo(bk bank.Keeper, sk supply.Keeper) sdk.GetFeeCollectorInfo { + return func(ctx sdk.Context, onlyGetFeeCollectorStoreKey bool) (sdk.Coins, []byte) { + if onlyGetFeeCollectorStoreKey { + return sdk.Coins{}, auth.AddressStoreKey(sk.GetModuleAddress(auth.FeeCollectorName)) + } + return bk.GetCoins(ctx, sk.GetModuleAddress(auth.FeeCollectorName)), nil } }