github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/app_parallel.go (about) 1 package app 2 3 import ( 4 "encoding/hex" 5 "sort" 6 "strings" 7 8 ethermint "github.com/fibonacci-chain/fbc/app/types" 9 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 10 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth" 11 authante "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/ante" 12 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank" 13 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/supply" 14 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 15 "github.com/fibonacci-chain/fbc/libs/tendermint/types" 16 "github.com/fibonacci-chain/fbc/x/evm" 17 evmtypes "github.com/fibonacci-chain/fbc/x/evm/types" 18 ) 19 20 // feeCollectorHandler set or get the value of feeCollectorAcc 21 func updateFeeCollectorHandler(bk bank.Keeper, sk supply.Keeper) sdk.UpdateFeeCollectorAccHandler { 22 return func(ctx sdk.Context, balance sdk.Coins, txFeesplit []*sdk.FeeSplitInfo) error { 23 err := bk.SetCoins(ctx, sk.GetModuleAccount(ctx, auth.FeeCollectorName).GetAddress(), balance) 24 if err != nil { 25 return err 26 } 27 28 // split fee 29 // come from feesplit module 30 if txFeesplit != nil { 31 feesplits, sortAddrs := groupByAddrAndSortFeeSplits(txFeesplit) 32 for _, addr := range sortAddrs { 33 acc := sdk.MustAccAddressFromBech32(addr) 34 err = sk.SendCoinsFromModuleToAccount(ctx, auth.FeeCollectorName, acc, feesplits[addr]) 35 if err != nil { 36 return err 37 } 38 } 39 } 40 return nil 41 } 42 } 43 44 // fixLogForParallelTxHandler fix log for parallel tx 45 func fixLogForParallelTxHandler(ek *evm.Keeper) sdk.LogFix { 46 return func(tx []sdk.Tx, logIndex []int, hasEnterEvmTx []bool, anteErrs []error, resp []abci.ResponseDeliverTx) (logs [][]byte) { 47 return ek.FixLog(tx, logIndex, hasEnterEvmTx, anteErrs, resp) 48 } 49 } 50 51 func preDeliverTxHandler(ak auth.AccountKeeper) sdk.PreDeliverTxHandler { 52 return func(ctx sdk.Context, tx sdk.Tx, onlyVerifySig bool) { 53 if evmTx, ok := tx.(*evmtypes.MsgEthereumTx); ok { 54 if evmTx.BaseTx.From == "" { 55 _ = evmTxVerifySigHandler(ctx.ChainID(), ctx.BlockHeight(), evmTx) 56 } 57 58 if types.HigherThanMars(ctx.BlockHeight()) { 59 return 60 } 61 62 if onlyVerifySig { 63 return 64 } 65 66 if from := evmTx.AccountAddress(); from != nil { 67 ak.LoadAccount(ctx, from) 68 } 69 if to := evmTx.Data.Recipient; to != nil { 70 ak.LoadAccount(ctx, to.Bytes()) 71 } 72 } 73 } 74 } 75 76 func evmTxVerifySigHandler(chainID string, blockHeight int64, evmTx *evmtypes.MsgEthereumTx) error { 77 chainIDEpoch, err := ethermint.ParseChainID(chainID) 78 if err != nil { 79 return err 80 } 81 err = evmTx.VerifySig(chainIDEpoch, blockHeight) 82 if err != nil { 83 return err 84 } 85 return nil 86 } 87 88 func getTxFeeHandler() sdk.GetTxFeeHandler { 89 return func(tx sdk.Tx) (fee sdk.Coins) { 90 if feeTx, ok := tx.(authante.FeeTx); ok { 91 fee = feeTx.GetFee() 92 } 93 94 return 95 } 96 } 97 98 // getTxFeeAndFromHandler get tx fee and from 99 func getTxFeeAndFromHandler(ak auth.AccountKeeper) sdk.GetTxFeeAndFromHandler { 100 return func(ctx sdk.Context, tx sdk.Tx) (fee sdk.Coins, isEvm bool, from string, to string, err error) { 101 if evmTx, ok := tx.(*evmtypes.MsgEthereumTx); ok { 102 isEvm = true 103 err = evmTxVerifySigHandler(ctx.ChainID(), ctx.BlockHeight(), evmTx) 104 if err != nil { 105 return 106 } 107 fee = evmTx.GetFee() 108 from = evmTx.BaseTx.From 109 if len(from) > 2 { 110 from = strings.ToLower(from[2:]) 111 } 112 if evmTx.To() != nil { 113 to = strings.ToLower(evmTx.To().String()[2:]) 114 } 115 } else if feeTx, ok := tx.(authante.FeeTx); ok { 116 fee = feeTx.GetFee() 117 feePayer := feeTx.FeePayer(ctx) 118 feePayerAcc := ak.GetAccount(ctx, feePayer) 119 from = hex.EncodeToString(feePayerAcc.GetAddress()) 120 } 121 122 return 123 } 124 } 125 126 // groupByAddrAndSortFeeSplits 127 // feesplits must be ordered, not map(random), 128 // to ensure that the account number of the withdrawer(new account) is consistent 129 func groupByAddrAndSortFeeSplits(txFeesplit []*sdk.FeeSplitInfo) (feesplits map[string]sdk.Coins, sortAddrs []string) { 130 feesplits = make(map[string]sdk.Coins) 131 for _, f := range txFeesplit { 132 feesplits[f.Addr.String()] = feesplits[f.Addr.String()].Add(f.Fee...) 133 } 134 if len(feesplits) == 0 { 135 return 136 } 137 138 sortAddrs = make([]string, len(feesplits)) 139 index := 0 140 for key := range feesplits { 141 sortAddrs[index] = key 142 index++ 143 } 144 sort.Strings(sortAddrs) 145 146 return 147 }