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  }