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, ðermint.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 }