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

     1  package evm_test
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"strings"
     7  
     8  	"github.com/ethereum/go-ethereum/common"
     9  	ethcmn "github.com/ethereum/go-ethereum/common"
    10  	"github.com/ethereum/go-ethereum/common/hexutil"
    11  	ethtypes "github.com/ethereum/go-ethereum/core/types"
    12  	ethcrypto "github.com/ethereum/go-ethereum/crypto"
    13  	"github.com/fibonacci-chain/fbc/app"
    14  	"github.com/fibonacci-chain/fbc/app/crypto/ethsecp256k1"
    15  	ethermint "github.com/fibonacci-chain/fbc/app/types"
    16  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    17  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/simapp"
    18  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    19  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
    20  	authtypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/types"
    21  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    22  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
    23  	dbm "github.com/fibonacci-chain/fbc/libs/tm-db"
    24  	"github.com/fibonacci-chain/fbc/x/evm"
    25  	"github.com/fibonacci-chain/fbc/x/evm/types"
    26  	"github.com/spf13/viper"
    27  )
    28  
    29  func (suite *EvmTestSuite) TestExportImport() {
    30  	var genState types.GenesisState
    31  	suite.Require().NotPanics(func() {
    32  		genState = evm.ExportGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper)
    33  	})
    34  
    35  	_ = evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper, genState)
    36  }
    37  
    38  func (suite *EvmTestSuite) TestInitGenesis() {
    39  	privkey, err := ethsecp256k1.GenerateKey()
    40  	suite.Require().NoError(err)
    41  
    42  	address := privkey.PubKey().Address()
    43  
    44  	privkey1, err := ethsecp256k1.GenerateKey()
    45  	suite.Require().NoError(err)
    46  
    47  	address1 := privkey1.PubKey().Address()
    48  
    49  	testCases := []struct {
    50  		name        string
    51  		malleate    func()
    52  		genState    types.GenesisState
    53  		statusCheck func()
    54  		expPanic    bool
    55  	}{
    56  		{
    57  			"default",
    58  			func() {},
    59  			types.DefaultGenesisState(),
    60  			func() {},
    61  			false,
    62  		},
    63  		{
    64  			"valid account",
    65  			func() {
    66  				acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
    67  				suite.Require().NotNil(acc)
    68  				err := acc.SetCoins(sdk.NewCoins(ethermint.NewPhotonCoinInt64(1)))
    69  				suite.Require().NoError(err)
    70  				suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
    71  			},
    72  			types.GenesisState{
    73  				Params: types.DefaultParams(),
    74  				Accounts: []types.GenesisAccount{
    75  					{
    76  						Address: address.String(),
    77  						Storage: types.Storage{
    78  							{Key: common.BytesToHash([]byte("key")), Value: common.BytesToHash([]byte("value"))},
    79  						},
    80  					},
    81  				},
    82  			},
    83  			func() {},
    84  			false,
    85  		},
    86  		{
    87  			"account not found",
    88  			func() {},
    89  			types.GenesisState{
    90  				Params: types.DefaultParams(),
    91  				Accounts: []types.GenesisAccount{
    92  					{
    93  						Address: address.String(),
    94  					},
    95  				},
    96  			},
    97  			func() {},
    98  			true,
    99  		},
   100  		{
   101  			"invalid account type",
   102  			func() {
   103  				acc := authtypes.NewBaseAccountWithAddress(address.Bytes())
   104  				suite.app.AccountKeeper.SetAccount(suite.ctx, &acc)
   105  			},
   106  			types.GenesisState{
   107  				Params: types.DefaultParams(),
   108  				Accounts: []types.GenesisAccount{
   109  					{
   110  						Address: address.String(),
   111  					},
   112  				},
   113  			},
   114  			func() {},
   115  			true,
   116  		},
   117  		{
   118  			"valid contract deployment whitelist",
   119  			func() {
   120  				acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
   121  				suite.Require().NotNil(acc)
   122  				err := acc.SetCoins(sdk.NewCoins(ethermint.NewPhotonCoinInt64(1)))
   123  				suite.Require().NoError(err)
   124  				suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
   125  			},
   126  			types.GenesisState{
   127  				Params: types.DefaultParams(),
   128  				Accounts: []types.GenesisAccount{
   129  					{
   130  						Address: address.String(),
   131  					},
   132  				},
   133  				ContractDeploymentWhitelist: types.AddressList{address.Bytes()},
   134  			},
   135  			func() {
   136  				whitelist := suite.stateDB.GetContractDeploymentWhitelist()
   137  				suite.Require().Equal(1, len(whitelist))
   138  				suite.Require().Equal(sdk.AccAddress(address.Bytes()), whitelist[0])
   139  			},
   140  			false,
   141  		},
   142  		{
   143  			"valid contract blocked list",
   144  			func() {
   145  				acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
   146  				suite.Require().NotNil(acc)
   147  				err := acc.SetCoins(sdk.NewCoins(ethermint.NewPhotonCoinInt64(1)))
   148  				suite.Require().NoError(err)
   149  				suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
   150  			},
   151  			types.GenesisState{
   152  				Params: types.DefaultParams(),
   153  				Accounts: []types.GenesisAccount{
   154  					{
   155  						Address: address.String(),
   156  					},
   157  				},
   158  				ContractBlockedList: types.AddressList{address.Bytes()},
   159  			},
   160  			func() {
   161  				blockedList := suite.stateDB.GetContractBlockedList()
   162  				suite.Require().Equal(1, len(blockedList))
   163  				suite.Require().Equal(sdk.AccAddress(address.Bytes()), blockedList[0])
   164  			},
   165  			false,
   166  		},
   167  		{
   168  			"valid contract method blocked list",
   169  			func() {
   170  				acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
   171  				suite.Require().NotNil(acc)
   172  				err := acc.SetCoins(sdk.NewCoins(ethermint.NewPhotonCoinInt64(1)))
   173  				suite.Require().NoError(err)
   174  				suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
   175  			},
   176  			types.GenesisState{
   177  				Params: types.DefaultParams(),
   178  				Accounts: []types.GenesisAccount{
   179  					{
   180  						Address: address.String(),
   181  					},
   182  				},
   183  				ContractBlockedList: types.AddressList{address.Bytes()},
   184  				ContractMethodBlockedList: types.BlockedContractList{
   185  					types.BlockedContract{
   186  						Address: address1.Bytes(),
   187  						BlockMethods: types.ContractMethods{
   188  							types.ContractMethod{
   189  								Sign:  "0x11111111",
   190  								Extra: "TEST1",
   191  							},
   192  						},
   193  					},
   194  				},
   195  			},
   196  			func() {
   197  				blockedList := suite.stateDB.GetContractBlockedList()
   198  				suite.Require().Equal(1, len(blockedList))
   199  				suite.Require().Equal(sdk.AccAddress(address.Bytes()), blockedList[0])
   200  
   201  				bcl := suite.stateDB.GetContractMethodBlockedList()
   202  				expected := types.BlockedContractList{
   203  					types.BlockedContract{
   204  						Address: address1.Bytes(),
   205  						BlockMethods: types.ContractMethods{
   206  							types.ContractMethod{
   207  								Sign:  "0x11111111",
   208  								Extra: "TEST1",
   209  							},
   210  						},
   211  					},
   212  					types.BlockedContract{
   213  						Address: address.Bytes(),
   214  					},
   215  				}
   216  				suite.Require().Equal(2, len(bcl))
   217  				ok := types.BlockedContractListIsEqual(suite.T(), bcl, expected)
   218  				suite.Require().True(ok)
   219  			},
   220  			false,
   221  		},
   222  	}
   223  
   224  	for _, tc := range testCases {
   225  		suite.Run(tc.name, func() {
   226  			suite.SetupTest() // reset values
   227  
   228  			tc.malleate()
   229  
   230  			if tc.expPanic {
   231  				suite.Require().Panics(
   232  					func() {
   233  						_ = evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper, tc.genState)
   234  					},
   235  				)
   236  			} else {
   237  				suite.Require().NotPanics(
   238  					func() {
   239  						_ = evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper, tc.genState)
   240  					},
   241  				)
   242  				// status check after genesis initialization
   243  				tc.statusCheck()
   244  			}
   245  		})
   246  	}
   247  }
   248  
   249  func (suite *EvmTestSuite) TestInit() {
   250  	privkey, err := ethsecp256k1.GenerateKey()
   251  	suite.Require().NoError(err)
   252  
   253  	address := privkey.PubKey().Address()
   254  
   255  	testCases := []struct {
   256  		name     string
   257  		malleate func(genesisState *simapp.GenesisState)
   258  		genState types.GenesisState
   259  		expPanic bool
   260  	}{
   261  		{
   262  			"valid account",
   263  			func(genesisState *simapp.GenesisState) {
   264  				acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
   265  				suite.Require().NotNil(acc)
   266  				err := acc.SetCoins(sdk.NewCoins(ethermint.NewPhotonCoinInt64(1)))
   267  				suite.Require().NoError(err)
   268  				suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
   269  				authGenesisState := auth.ExportGenesis(suite.ctx, suite.app.AccountKeeper)
   270  				(*genesisState)["auth"] = authtypes.ModuleCdc.MustMarshalJSON(authGenesisState)
   271  
   272  			},
   273  			types.GenesisState{
   274  				Params: types.DefaultParams(),
   275  				Accounts: []types.GenesisAccount{
   276  					{
   277  						Address: address.String(),
   278  					},
   279  				},
   280  				TxsLogs:     []types.TransactionLogs{},
   281  				ChainConfig: types.DefaultChainConfig(),
   282  			},
   283  			false,
   284  		},
   285  	}
   286  
   287  	for _, tc := range testCases {
   288  		suite.Run(tc.name, func() {
   289  			suite.SetupTest() // reset values
   290  
   291  			db := dbm.NewMemDB()
   292  			chain := app.NewFBChainApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 0)
   293  			genesisState := app.NewDefaultGenesisState()
   294  
   295  			tc.malleate(&genesisState)
   296  
   297  			genesisState["evm"] = types.ModuleCdc.MustMarshalJSON(tc.genState)
   298  			stateBytes, err := codec.MarshalJSONIndent(chain.Codec(), genesisState)
   299  			if err != nil {
   300  				panic(err)
   301  			}
   302  
   303  			if tc.expPanic {
   304  				suite.Require().Panics(
   305  					func() {
   306  						chain.InitChain(
   307  							abci.RequestInitChain{
   308  								Validators:    []abci.ValidatorUpdate{},
   309  								AppStateBytes: stateBytes,
   310  							},
   311  						)
   312  					},
   313  				)
   314  			} else {
   315  				suite.Require().NotPanics(
   316  					func() {
   317  						chain.InitChain(
   318  							abci.RequestInitChain{
   319  								Validators:    []abci.ValidatorUpdate{},
   320  								AppStateBytes: stateBytes,
   321  							},
   322  						)
   323  					},
   324  				)
   325  			}
   326  		})
   327  	}
   328  }
   329  
   330  func (suite *EvmTestSuite) TestExport() {
   331  	privkey, err := ethsecp256k1.GenerateKey()
   332  	suite.Require().NoError(err)
   333  
   334  	address := ethcmn.HexToAddress(privkey.PubKey().Address().String())
   335  
   336  	acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
   337  	suite.Require().NotNil(acc)
   338  	err = acc.SetCoins(sdk.NewCoins(ethermint.NewPhotonCoinInt64(1)))
   339  	suite.Require().NoError(err)
   340  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
   341  
   342  	initGenesis := types.GenesisState{
   343  		Params: types.DefaultParams(),
   344  		Accounts: []types.GenesisAccount{
   345  			{
   346  				Address: address.String(),
   347  				Storage: types.Storage{
   348  					{Key: common.BytesToHash([]byte("key")), Value: common.BytesToHash([]byte("value"))},
   349  				},
   350  			},
   351  		},
   352  		TxsLogs: []types.TransactionLogs{
   353  			{
   354  				Hash: common.BytesToHash([]byte("tx_hash")),
   355  				Logs: []*ethtypes.Log{
   356  					{
   357  						Address:     address,
   358  						Topics:      []ethcmn.Hash{ethcmn.BytesToHash([]byte("topic"))},
   359  						Data:        []byte("data"),
   360  						BlockNumber: 1,
   361  						TxHash:      ethcmn.BytesToHash([]byte("tx_hash")),
   362  						TxIndex:     1,
   363  						BlockHash:   ethcmn.BytesToHash([]byte("block_hash")),
   364  						Index:       1,
   365  						Removed:     false,
   366  					},
   367  				},
   368  			},
   369  		},
   370  		ContractDeploymentWhitelist: types.AddressList{address.Bytes()},
   371  		ContractBlockedList:         types.AddressList{address.Bytes()},
   372  	}
   373  	evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper, initGenesis)
   374  
   375  	suite.Require().NotPanics(func() {
   376  		evm.ExportGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper)
   377  	})
   378  }
   379  
   380  func (suite *EvmTestSuite) TestExport1() {
   381  	privkey, err := ethsecp256k1.GenerateKey()
   382  	suite.Require().NoError(err)
   383  
   384  	address := ethcmn.HexToAddress(privkey.PubKey().Address().String())
   385  
   386  	privkey1, err := ethsecp256k1.GenerateKey()
   387  	suite.Require().NoError(err)
   388  
   389  	address1 := privkey1.PubKey().Address()
   390  
   391  	acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
   392  	suite.Require().NotNil(acc)
   393  	err = acc.SetCoins(sdk.NewCoins(ethermint.NewPhotonCoinInt64(1)))
   394  	suite.Require().NoError(err)
   395  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
   396  
   397  	initGenesis := types.GenesisState{
   398  		Params: types.DefaultParams(),
   399  		Accounts: []types.GenesisAccount{
   400  			{
   401  				Address: address.String(),
   402  				Storage: types.Storage{
   403  					{Key: common.BytesToHash([]byte("key")), Value: common.BytesToHash([]byte("value"))},
   404  				},
   405  			},
   406  		},
   407  		TxsLogs: []types.TransactionLogs{
   408  			{
   409  				Hash: common.BytesToHash([]byte("tx_hash")),
   410  				Logs: []*ethtypes.Log{
   411  					{
   412  						Address:     address,
   413  						Topics:      []ethcmn.Hash{ethcmn.BytesToHash([]byte("topic"))},
   414  						Data:        []byte("data"),
   415  						BlockNumber: 1,
   416  						TxHash:      ethcmn.BytesToHash([]byte("tx_hash")),
   417  						TxIndex:     1,
   418  						BlockHash:   ethcmn.BytesToHash([]byte("block_hash")),
   419  						Index:       1,
   420  						Removed:     false,
   421  					},
   422  				},
   423  			},
   424  		},
   425  		ContractDeploymentWhitelist: types.AddressList{address.Bytes()},
   426  		ContractBlockedList:         types.AddressList{address.Bytes()},
   427  		ContractMethodBlockedList: types.BlockedContractList{
   428  			types.BlockedContract{
   429  				Address: address1.Bytes(),
   430  				BlockMethods: types.ContractMethods{
   431  					types.ContractMethod{
   432  						Sign:  "0x11111111",
   433  						Extra: "TEST1",
   434  					},
   435  				},
   436  			},
   437  		},
   438  	}
   439  	evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper, initGenesis)
   440  
   441  	suite.Require().NotPanics(func() {
   442  		evm.ExportGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper)
   443  	})
   444  }
   445  
   446  func (suite *EvmTestSuite) TestExport_db() {
   447  	viper.SetEnvPrefix("FIBOCHAIN")
   448  	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
   449  	viper.AutomaticEnv()
   450  	viper.Set(sdk.FlagDBBackend, string(dbm.GoLevelDBBackend))
   451  
   452  	privkey, err := ethsecp256k1.GenerateKey()
   453  	suite.Require().NoError(err)
   454  
   455  	address := ethcmn.HexToAddress(privkey.PubKey().Address().String())
   456  	acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
   457  	suite.Require().NotNil(acc)
   458  	err = acc.SetCoins(sdk.NewCoins(ethermint.NewPhotonCoinInt64(1)))
   459  	suite.Require().NoError(err)
   460  
   461  	code := []byte{1, 2, 3}
   462  	ethAccount := ethermint.EthAccount{
   463  		BaseAccount: &auth.BaseAccount{
   464  			Address: acc.GetAddress(),
   465  		},
   466  		CodeHash: ethcrypto.Keccak256(code),
   467  	}
   468  	suite.app.AccountKeeper.SetAccount(suite.ctx, ethAccount)
   469  
   470  	storage := types.Storage{
   471  		{Key: common.BytesToHash([]byte("key1")), Value: common.BytesToHash([]byte("value1"))},
   472  		{Key: common.BytesToHash([]byte("key2")), Value: common.BytesToHash([]byte("value2"))},
   473  		{Key: common.BytesToHash([]byte("key3")), Value: common.BytesToHash([]byte("value3"))},
   474  	}
   475  	evmAcc := types.GenesisAccount{
   476  		Address: address.String(),
   477  		Code:    code,
   478  		Storage: storage,
   479  	}
   480  
   481  	initGenesis := types.GenesisState{
   482  		Params:   types.DefaultParams(),
   483  		Accounts: []types.GenesisAccount{evmAcc},
   484  	}
   485  	os.Setenv("FIBOCHAIN_EVM_IMPORT_MODE", "default")
   486  	evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper, initGenesis)
   487  
   488  	tmpPath := "./test_tmp_db"
   489  	os.Setenv("FIBOCHAIN_EVM_EXPORT_MODE", "db")
   490  	os.Setenv("FIBOCHAIN_EVM_EXPORT_PATH", tmpPath)
   491  
   492  	defer func() {
   493  		os.Setenv("FIBOCHAIN_EVM_IMPORT_MODE", "default")
   494  		os.Setenv("FIBOCHAIN_EVM_EXPORT_MODE", "default")
   495  		os.RemoveAll(tmpPath)
   496  	}()
   497  
   498  	suite.Require().NoDirExists(filepath.Join(tmpPath, "evm_bytecode.db"))
   499  	suite.Require().NoDirExists(filepath.Join(tmpPath, "evm_state.db"))
   500  	var exportState types.GenesisState
   501  	suite.Require().NotPanics(func() {
   502  		exportState = evm.ExportGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper)
   503  		suite.Require().Equal(exportState.Accounts[0].Address, evmAcc.Address)
   504  		suite.Require().Equal(exportState.Accounts[0].Code, hexutil.Bytes(nil))
   505  		suite.Require().Equal(exportState.Accounts[0].Storage, types.Storage(nil))
   506  	})
   507  	suite.Require().DirExists(filepath.Join(tmpPath, "evm_bytecode.db"))
   508  	suite.Require().DirExists(filepath.Join(tmpPath, "evm_state.db"))
   509  
   510  	evm.CloseDB()
   511  	testImport_db(suite, exportState, tmpPath, ethAccount, code, storage)
   512  }
   513  
   514  func testImport_db(suite *EvmTestSuite,
   515  	exportState types.GenesisState,
   516  	dbPath string,
   517  	ethAccount ethermint.EthAccount,
   518  	code []byte,
   519  	storage types.Storage) {
   520  	os.Setenv("FIBOCHAIN_EVM_IMPORT_MODE", "default")
   521  	suite.SetupTest() // reset
   522  
   523  	suite.app.AccountKeeper.SetAccount(suite.ctx, ethAccount)
   524  
   525  	viper.Set(sdk.FlagDBBackend, string(dbm.GoLevelDBBackend))
   526  	os.Setenv("FIBOCHAIN_EVM_IMPORT_MODE", "db")
   527  	os.Setenv("FIBOCHAIN_EVM_IMPORT_PATH", dbPath)
   528  
   529  	suite.Require().DirExists(filepath.Join(dbPath, "evm_bytecode.db"))
   530  	suite.Require().DirExists(filepath.Join(dbPath, "evm_state.db"))
   531  	suite.Require().NotPanics(func() {
   532  		evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper, exportState)
   533  		suite.Require().Equal(suite.app.EvmKeeper.GetCode(suite.ctx, ethAccount.EthAddress()), code)
   534  		suite.app.EvmKeeper.ForEachStorage(suite.ctx, ethAccount.EthAddress(), func(key, value ethcmn.Hash) bool {
   535  			suite.Require().Contains(storage, types.State{key, value})
   536  			return false
   537  		})
   538  	})
   539  }
   540  
   541  func (suite *EvmTestSuite) TestExport_files() {
   542  	viper.SetEnvPrefix("FIBOCHAIN")
   543  	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
   544  	viper.AutomaticEnv()
   545  
   546  	privkey, err := ethsecp256k1.GenerateKey()
   547  	suite.Require().NoError(err)
   548  
   549  	address := ethcmn.HexToAddress(privkey.PubKey().Address().String())
   550  	acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
   551  	suite.Require().NotNil(acc)
   552  	err = acc.SetCoins(sdk.NewCoins(ethermint.NewPhotonCoinInt64(1)))
   553  	suite.Require().NoError(err)
   554  
   555  	expectedAddrList := types.AddressList{address.Bytes()}
   556  
   557  	code := []byte{1, 2, 3}
   558  	ethAccount := ethermint.EthAccount{
   559  		BaseAccount: &auth.BaseAccount{
   560  			Address: acc.GetAddress(),
   561  		},
   562  		CodeHash: ethcrypto.Keccak256(code),
   563  	}
   564  	suite.app.AccountKeeper.SetAccount(suite.ctx, ethAccount)
   565  
   566  	storage := types.Storage{
   567  		{Key: common.BytesToHash([]byte("key1")), Value: common.BytesToHash([]byte("value1"))},
   568  		{Key: common.BytesToHash([]byte("key2")), Value: common.BytesToHash([]byte("value2"))},
   569  		{Key: common.BytesToHash([]byte("key3")), Value: common.BytesToHash([]byte("value3"))},
   570  	}
   571  	evmAcc := types.GenesisAccount{
   572  		Address: address.String(),
   573  		Code:    code,
   574  		Storage: storage,
   575  	}
   576  
   577  	initGenesis := types.GenesisState{
   578  		Params:                      types.DefaultParams(),
   579  		Accounts:                    []types.GenesisAccount{evmAcc},
   580  		ContractDeploymentWhitelist: expectedAddrList,
   581  		ContractBlockedList:         expectedAddrList,
   582  	}
   583  	os.Setenv("FIBOCHAIN_EVM_IMPORT_MODE", "default")
   584  	evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper, initGenesis)
   585  
   586  	tmpPath := "./test_tmp_db"
   587  	os.Setenv("FIBOCHAIN_EVM_EXPORT_MODE", "files")
   588  	os.Setenv("FIBOCHAIN_EVM_EXPORT_PATH", tmpPath)
   589  
   590  	defer func() {
   591  		os.Setenv("FIBOCHAIN_EVM_IMPORT_MODE", "default")
   592  		os.Setenv("FIBOCHAIN_EVM_EXPORT_MODE", "default")
   593  		os.RemoveAll(tmpPath)
   594  	}()
   595  
   596  	suite.Require().NoDirExists(filepath.Join(tmpPath, "code"))
   597  	suite.Require().NoDirExists(filepath.Join(tmpPath, "storage"))
   598  	var exportState types.GenesisState
   599  	suite.Require().NotPanics(func() {
   600  		exportState = evm.ExportGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper)
   601  		suite.Require().Equal(exportState.Accounts[0].Address, evmAcc.Address)
   602  		suite.Require().Equal(exportState.Accounts[0].Code, hexutil.Bytes(nil))
   603  		suite.Require().Equal(exportState.Accounts[0].Storage, types.Storage(nil))
   604  		suite.Require().Equal(expectedAddrList, exportState.ContractDeploymentWhitelist)
   605  		suite.Require().Equal(expectedAddrList, exportState.ContractBlockedList)
   606  	})
   607  	suite.Require().DirExists(filepath.Join(tmpPath, "code"))
   608  	suite.Require().DirExists(filepath.Join(tmpPath, "storage"))
   609  
   610  	testImport_files(suite, exportState, tmpPath, ethAccount, code, storage, expectedAddrList)
   611  }
   612  
   613  func (suite *EvmTestSuite) TestExport_files1() {
   614  	viper.SetEnvPrefix("FIBOCHAIN")
   615  	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
   616  	viper.AutomaticEnv()
   617  
   618  	privkey, err := ethsecp256k1.GenerateKey()
   619  	suite.Require().NoError(err)
   620  
   621  	privkey1, err := ethsecp256k1.GenerateKey()
   622  	suite.Require().NoError(err)
   623  	address1 := privkey1.PubKey().Address()
   624  
   625  	address := ethcmn.HexToAddress(privkey.PubKey().Address().String())
   626  	acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
   627  	suite.Require().NotNil(acc)
   628  	err = acc.SetCoins(sdk.NewCoins(ethermint.NewPhotonCoinInt64(1)))
   629  	suite.Require().NoError(err)
   630  
   631  	expectedAddrList := types.AddressList{address.Bytes()}
   632  
   633  	code := []byte{1, 2, 3}
   634  	ethAccount := ethermint.EthAccount{
   635  		BaseAccount: &auth.BaseAccount{
   636  			Address: acc.GetAddress(),
   637  		},
   638  		CodeHash: ethcrypto.Keccak256(code),
   639  	}
   640  	suite.app.AccountKeeper.SetAccount(suite.ctx, ethAccount)
   641  
   642  	storage := types.Storage{
   643  		{Key: common.BytesToHash([]byte("key1")), Value: common.BytesToHash([]byte("value1"))},
   644  		{Key: common.BytesToHash([]byte("key2")), Value: common.BytesToHash([]byte("value2"))},
   645  		{Key: common.BytesToHash([]byte("key3")), Value: common.BytesToHash([]byte("value3"))},
   646  	}
   647  	evmAcc := types.GenesisAccount{
   648  		Address: address.String(),
   649  		Code:    code,
   650  		Storage: storage,
   651  	}
   652  	expectedContractMethodBlockedList := types.BlockedContractList{
   653  		types.BlockedContract{
   654  			Address: address1.Bytes(),
   655  			BlockMethods: types.ContractMethods{
   656  				types.ContractMethod{
   657  					Sign:  "0x11111111",
   658  					Extra: "TEST1",
   659  				},
   660  			},
   661  		},
   662  	}
   663  	initGenesis := types.GenesisState{
   664  		Params:                      types.DefaultParams(),
   665  		Accounts:                    []types.GenesisAccount{evmAcc},
   666  		ContractDeploymentWhitelist: expectedAddrList,
   667  		ContractBlockedList:         expectedAddrList,
   668  		ContractMethodBlockedList:   expectedContractMethodBlockedList,
   669  	}
   670  	os.Setenv("FIBOCHAIN_EVM_IMPORT_MODE", "default")
   671  	evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper, initGenesis)
   672  
   673  	tmpPath := "./test_tmp_db"
   674  	os.Setenv("FIBOCHAIN_EVM_EXPORT_MODE", "files")
   675  	os.Setenv("FIBOCHAIN_EVM_EXPORT_PATH", tmpPath)
   676  
   677  	defer func() {
   678  		os.Setenv("FIBOCHAIN_EVM_IMPORT_MODE", "default")
   679  		os.Setenv("FIBOCHAIN_EVM_EXPORT_MODE", "default")
   680  		os.RemoveAll(tmpPath)
   681  	}()
   682  
   683  	suite.Require().NoDirExists(filepath.Join(tmpPath, "code"))
   684  	suite.Require().NoDirExists(filepath.Join(tmpPath, "storage"))
   685  	var exportState types.GenesisState
   686  	suite.Require().NotPanics(func() {
   687  		exportState = evm.ExportGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper)
   688  		suite.Require().Equal(exportState.Accounts[0].Address, evmAcc.Address)
   689  		suite.Require().Equal(exportState.Accounts[0].Code, hexutil.Bytes(nil))
   690  		suite.Require().Equal(exportState.Accounts[0].Storage, types.Storage(nil))
   691  		suite.Require().Equal(expectedAddrList, exportState.ContractDeploymentWhitelist)
   692  		suite.Require().Equal(expectedAddrList, exportState.ContractBlockedList)
   693  		suite.Require().True(types.BlockedContractListIsEqual(suite.T(), exportState.ContractMethodBlockedList, expectedContractMethodBlockedList))
   694  	})
   695  	suite.Require().DirExists(filepath.Join(tmpPath, "code"))
   696  	suite.Require().DirExists(filepath.Join(tmpPath, "storage"))
   697  
   698  	testImport_files(suite, exportState, tmpPath, ethAccount, code, storage, expectedAddrList)
   699  }
   700  
   701  func (suite *EvmTestSuite) TestExport_files2() {
   702  	viper.SetEnvPrefix("FIBOCHAIN")
   703  	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
   704  	viper.AutomaticEnv()
   705  
   706  	privkey, err := ethsecp256k1.GenerateKey()
   707  	suite.Require().NoError(err)
   708  
   709  	address := ethcmn.HexToAddress(privkey.PubKey().Address().String())
   710  	acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
   711  	suite.Require().NotNil(acc)
   712  	err = acc.SetCoins(sdk.NewCoins(ethermint.NewPhotonCoinInt64(1)))
   713  	suite.Require().NoError(err)
   714  
   715  	expectedAddrList := types.AddressList{address.Bytes()}
   716  
   717  	code := []byte{1, 2, 3}
   718  	ethAccount := ethermint.EthAccount{
   719  		BaseAccount: &auth.BaseAccount{
   720  			Address: acc.GetAddress(),
   721  		},
   722  		CodeHash: ethcrypto.Keccak256(code),
   723  	}
   724  	suite.app.AccountKeeper.SetAccount(suite.ctx, ethAccount)
   725  
   726  	storage := types.Storage{
   727  		{Key: common.BytesToHash([]byte("key1")), Value: common.BytesToHash([]byte("value1"))},
   728  		{Key: common.BytesToHash([]byte("key2")), Value: common.BytesToHash([]byte("value2"))},
   729  		{Key: common.BytesToHash([]byte("key3")), Value: common.BytesToHash([]byte("value3"))},
   730  	}
   731  	evmAcc := types.GenesisAccount{
   732  		Address: address.String(),
   733  		Code:    code,
   734  		Storage: storage,
   735  	}
   736  	expectedContractMethodBlockedList := types.BlockedContractList{
   737  		types.BlockedContract{
   738  			Address: address.Bytes(),
   739  			BlockMethods: types.ContractMethods{
   740  				types.ContractMethod{
   741  					Sign:  "0x11111111",
   742  					Extra: "TEST1",
   743  				},
   744  			},
   745  		},
   746  	}
   747  	initGenesis := types.GenesisState{
   748  		Params:                      types.DefaultParams(),
   749  		Accounts:                    []types.GenesisAccount{evmAcc},
   750  		ContractDeploymentWhitelist: expectedAddrList,
   751  		ContractBlockedList:         expectedAddrList,
   752  		ContractMethodBlockedList:   expectedContractMethodBlockedList,
   753  	}
   754  	os.Setenv("FIBOCHAIN_EVM_IMPORT_MODE", "default")
   755  	evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper, initGenesis)
   756  
   757  	tmpPath := "./test_tmp_db"
   758  	os.Setenv("FIBOCHAIN_EVM_EXPORT_MODE", "files")
   759  	os.Setenv("FIBOCHAIN_EVM_EXPORT_PATH", tmpPath)
   760  
   761  	defer func() {
   762  		os.Setenv("FIBOCHAIN_EVM_IMPORT_MODE", "default")
   763  		os.Setenv("FIBOCHAIN_EVM_EXPORT_MODE", "default")
   764  		os.RemoveAll(tmpPath)
   765  	}()
   766  
   767  	suite.Require().NoDirExists(filepath.Join(tmpPath, "code"))
   768  	suite.Require().NoDirExists(filepath.Join(tmpPath, "storage"))
   769  	var exportState types.GenesisState
   770  	suite.Require().NotPanics(func() {
   771  		exportState = evm.ExportGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper)
   772  		suite.Require().Equal(exportState.Accounts[0].Address, evmAcc.Address)
   773  		suite.Require().Equal(exportState.Accounts[0].Code, hexutil.Bytes(nil))
   774  		suite.Require().Equal(exportState.Accounts[0].Storage, types.Storage(nil))
   775  		suite.Require().Equal(expectedAddrList, exportState.ContractDeploymentWhitelist)
   776  		suite.Require().Equal(expectedAddrList, exportState.ContractBlockedList)
   777  		suite.Require().Equal(0, len(exportState.ContractMethodBlockedList))
   778  	})
   779  	suite.Require().DirExists(filepath.Join(tmpPath, "code"))
   780  	suite.Require().DirExists(filepath.Join(tmpPath, "storage"))
   781  
   782  	testImport_files(suite, exportState, tmpPath, ethAccount, code, storage, expectedAddrList)
   783  }
   784  
   785  func testImport_files(suite *EvmTestSuite,
   786  	exportState types.GenesisState,
   787  	filePath string,
   788  	ethAccount ethermint.EthAccount,
   789  	code []byte,
   790  	storage types.Storage,
   791  	expectedAddrList types.AddressList) {
   792  	os.Setenv("FIBOCHAIN_EVM_IMPORT_MODE", "default")
   793  	suite.SetupTest() // reset
   794  
   795  	suite.app.AccountKeeper.SetAccount(suite.ctx, ethAccount)
   796  
   797  	os.Setenv("FIBOCHAIN_EVM_IMPORT_MODE", "files")
   798  	os.Setenv("FIBOCHAIN_EVM_IMPORT_PATH", filePath)
   799  
   800  	suite.Require().DirExists(filepath.Join(filePath, "code"))
   801  	suite.Require().DirExists(filepath.Join(filePath, "storage"))
   802  	suite.Require().NotPanics(func() {
   803  		evm.InitGenesis(suite.ctx, *suite.app.EvmKeeper, &suite.app.AccountKeeper, exportState)
   804  		suite.Require().Equal(suite.app.EvmKeeper.GetCode(suite.ctx, ethAccount.EthAddress()), code)
   805  		suite.app.EvmKeeper.ForEachStorage(suite.ctx, ethAccount.EthAddress(), func(key, value ethcmn.Hash) bool {
   806  			suite.Require().Contains(storage, types.State{key, value})
   807  			return false
   808  		})
   809  		suite.Require().Equal(expectedAddrList, suite.stateDB.GetContractDeploymentWhitelist())
   810  		suite.Require().Equal(expectedAddrList, suite.stateDB.GetContractBlockedList())
   811  	})
   812  }