github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/evm/genesis.go (about)

     1  package evm
     2  
     3  import (
     4  	"fmt"
     5  
     6  	ethcmn "github.com/ethereum/go-ethereum/common"
     7  	ethermint "github.com/fibonacci-chain/fbc/app/types"
     8  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/server"
     9  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    10  	authexported "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/exported"
    11  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    12  	"github.com/fibonacci-chain/fbc/x/evm/types"
    13  	"github.com/spf13/viper"
    14  )
    15  
    16  // InitGenesis initializes genesis state based on exported genesis
    17  func InitGenesis(ctx sdk.Context, k Keeper, accountKeeper types.AccountKeeper, data GenesisState) []abci.ValidatorUpdate { // nolint: interfacer
    18  	logger := ctx.Logger().With("module", types.ModuleName)
    19  
    20  	k.SetParams(ctx, data.Params)
    21  
    22  	csdb := types.CreateEmptyCommitStateDB(k.GenerateCSDBParams(), ctx)
    23  	mode := viper.GetString(server.FlagEvmImportMode)
    24  	if mode == "" {
    25  		// for some UT
    26  		mode = defaultMode
    27  	}
    28  	initImportEnv(viper.GetString(server.FlagEvmImportPath), mode, viper.GetUint64(server.FlagGoroutineNum))
    29  
    30  	for _, account := range data.Accounts {
    31  		address := ethcmn.HexToAddress(account.Address)
    32  		accAddress := sdk.AccAddress(address.Bytes())
    33  
    34  		// check that the EVM balance the matches the account balance
    35  		acc := accountKeeper.GetAccount(ctx, accAddress)
    36  		if acc == nil {
    37  			panic(fmt.Errorf("account not found for address %s", account.Address))
    38  		}
    39  
    40  		ethAcc, ok := acc.(*ethermint.EthAccount)
    41  		if !ok {
    42  			panic(
    43  				fmt.Errorf("account %s must be an %T type, got %T",
    44  					account.Address, &ethermint.EthAccount{}, acc,
    45  				),
    46  			)
    47  		}
    48  
    49  		evmBalance := acc.GetCoins().AmountOf(sdk.DefaultBondDenom)
    50  		csdb.SetNonce(address, acc.GetSequence())
    51  		csdb.SetBalance(address, evmBalance.BigInt())
    52  
    53  		switch mode {
    54  		case defaultMode:
    55  			if account.Code != nil {
    56  				csdb.SetCode(address, account.Code)
    57  				codeCount++
    58  			}
    59  			for _, storage := range account.Storage {
    60  				k.SetStateDirectly(ctx, address, storage.Key, storage.Value)
    61  				storageCount++
    62  			}
    63  		case filesMode:
    64  			importFromFile(ctx, logger, k, address, ethAcc.CodeHash)
    65  		case dbMode:
    66  			importFromDB(ctx, k, address, ethAcc.CodeHash)
    67  		default:
    68  			panic("unsupported import mode")
    69  		}
    70  	}
    71  
    72  	// wait for all data to be imported from files
    73  	if mode == filesMode {
    74  		wg.Wait()
    75  	}
    76  
    77  	// set contract deployment whitelist into store
    78  	csdb.SetContractDeploymentWhitelist(data.ContractDeploymentWhitelist)
    79  
    80  	// set contract blocked list into store
    81  	csdb.InsertContractMethodBlockedList(data.ContractMethodBlockedList)
    82  
    83  	// set contract blocked list into store
    84  	csdb.SetContractBlockedList(data.ContractBlockedList)
    85  
    86  	logger.Debug("Import finished", "code", codeCount, "storage", storageCount)
    87  
    88  	// set state objects and code to store
    89  	_, err := csdb.Commit(false)
    90  	if err != nil {
    91  		panic(err)
    92  	}
    93  
    94  	k.SetChainConfig(ctx, data.ChainConfig)
    95  
    96  	return []abci.ValidatorUpdate{}
    97  }
    98  
    99  // ExportGenesis exports genesis state of the EVM module
   100  func ExportGenesis(ctx sdk.Context, k Keeper, ak types.AccountKeeper) GenesisState {
   101  	logger := ctx.Logger().With("module", types.ModuleName)
   102  
   103  	mode := viper.GetString(server.FlagEvmExportMode)
   104  	if mode == "" {
   105  		// for some UT
   106  		mode = defaultMode
   107  	}
   108  	initExportEnv(viper.GetString(server.FlagEvmExportPath), mode, viper.GetUint64(server.FlagGoroutineNum))
   109  
   110  	// nolint: prealloc
   111  	var ethGenAccounts []types.GenesisAccount
   112  	csdb := types.CreateEmptyCommitStateDB(k.GenerateCSDBParams(), ctx)
   113  
   114  	ak.IterateAccounts(ctx, func(account authexported.Account) bool {
   115  		ethAccount, ok := account.(*ethermint.EthAccount)
   116  		if !ok {
   117  			// ignore non EthAccounts
   118  			return false
   119  		}
   120  
   121  		addr := ethAccount.EthAddress()
   122  		code, storage := []byte(nil), types.Storage(nil)
   123  		var err error
   124  
   125  		switch mode {
   126  		case defaultMode:
   127  			code = csdb.GetCode(addr)
   128  			if code != nil {
   129  				codeCount++
   130  			}
   131  			if storage, err = k.GetAccountStorage(ctx, addr); err != nil {
   132  				panic(err)
   133  			}
   134  			storageCount += uint64(len(storage))
   135  		case filesMode:
   136  			exportToFile(ctx, k, addr)
   137  		case dbMode:
   138  			exportToDB(ctx, k, addr, ethAccount.CodeHash)
   139  
   140  		default:
   141  			panic("unsupported export mode")
   142  		}
   143  
   144  		genAccount := types.GenesisAccount{
   145  			Address: addr.String(),
   146  			Code:    code,
   147  			Storage: storage,
   148  		}
   149  
   150  		ethGenAccounts = append(ethGenAccounts, genAccount)
   151  		return false
   152  	})
   153  	// wait for all data to be written into files or db
   154  	if mode == filesMode || mode == dbMode {
   155  		wg.Wait()
   156  	}
   157  	logger.Debug("Export finished", "code", codeCount, "storage", storageCount)
   158  
   159  	config, _ := k.GetChainConfig(ctx)
   160  	bcml := csdb.GetContractMethodBlockedList()
   161  	for i := 0; i < len(bcml); i++ {
   162  		if bcml[i].IsAllMethodBlocked() {
   163  			bcml = append(bcml[:i], bcml[i+1:]...)
   164  		}
   165  	}
   166  	return GenesisState{
   167  		Accounts:                    ethGenAccounts,
   168  		ChainConfig:                 config,
   169  		Params:                      k.GetParams(ctx),
   170  		ContractDeploymentWhitelist: csdb.GetContractDeploymentWhitelist(),
   171  		ContractBlockedList:         csdb.GetContractBlockedList(),
   172  		ContractMethodBlockedList:   bcml,
   173  	}
   174  }