github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/app_upgrade_test.go (about)

     1  package app
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"path/filepath"
     9  	"strconv"
    10  	"testing"
    11  
    12  	ibccommon "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/common"
    13  
    14  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/cli"
    15  	"github.com/fibonacci-chain/fbc/libs/tm-db/common"
    16  	"github.com/fibonacci-chain/fbc/x/wasm"
    17  	wasmkeeper "github.com/fibonacci-chain/fbc/x/wasm/keeper"
    18  	"github.com/spf13/viper"
    19  
    20  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context"
    21  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/mpt"
    22  	cosmost "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/types"
    23  	capabilityModule "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability"
    24  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/genutil"
    25  	"github.com/fibonacci-chain/fbc/libs/system/trace"
    26  	commonversion "github.com/fibonacci-chain/fbc/x/common/version"
    27  	"github.com/gorilla/mux"
    28  	"github.com/spf13/cobra"
    29  	"github.com/stretchr/testify/require"
    30  
    31  	"github.com/fibonacci-chain/fbc/app/ante"
    32  	fbchaincodec "github.com/fibonacci-chain/fbc/app/codec"
    33  	"github.com/fibonacci-chain/fbc/app/refund"
    34  	bam "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/baseapp"
    35  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    36  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    37  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/module"
    38  	upgradetypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/upgrade"
    39  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/version"
    40  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
    41  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank"
    42  	capabilitykeeper "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/keeper"
    43  	capabilitytypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/types"
    44  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/crisis"
    45  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/mint"
    46  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/supply"
    47  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/upgrade"
    48  	"github.com/fibonacci-chain/fbc/libs/iavl"
    49  	ibctransfer "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/transfer"
    50  	ibctransferkeeper "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/transfer/keeper"
    51  	ibctransfertypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/transfer/types"
    52  	ibc "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core"
    53  	ibcclient "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client"
    54  	ibcporttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/05-port/types"
    55  	ibchost "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host"
    56  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    57  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
    58  	tmos "github.com/fibonacci-chain/fbc/libs/tendermint/libs/os"
    59  	tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types"
    60  	dbm "github.com/fibonacci-chain/fbc/libs/tm-db"
    61  	"github.com/fibonacci-chain/fbc/x/ammswap"
    62  	"github.com/fibonacci-chain/fbc/x/dex"
    63  	distr "github.com/fibonacci-chain/fbc/x/distribution"
    64  	"github.com/fibonacci-chain/fbc/x/erc20"
    65  	"github.com/fibonacci-chain/fbc/x/evidence"
    66  	"github.com/fibonacci-chain/fbc/x/evm"
    67  	evmtypes "github.com/fibonacci-chain/fbc/x/evm/types"
    68  	"github.com/fibonacci-chain/fbc/x/farm"
    69  	"github.com/fibonacci-chain/fbc/x/gov"
    70  	"github.com/fibonacci-chain/fbc/x/gov/keeper"
    71  	"github.com/fibonacci-chain/fbc/x/order"
    72  	"github.com/fibonacci-chain/fbc/x/params"
    73  	"github.com/fibonacci-chain/fbc/x/slashing"
    74  	"github.com/fibonacci-chain/fbc/x/staking"
    75  	"github.com/fibonacci-chain/fbc/x/token"
    76  
    77  	fbchain "github.com/fibonacci-chain/fbc/app/types"
    78  )
    79  
    80  var (
    81  	_ upgradetypes.UpgradeModule = (*SimpleBaseUpgradeModule)(nil)
    82  
    83  	test_prefix       = "upgrade_module_"
    84  	blockModules      map[string]struct{}
    85  	defaultDenyFilter cosmost.StoreFilter = func(module string, h int64, store cosmost.CommitKVStore) bool {
    86  		_, exist := blockModules[module]
    87  		if !exist {
    88  			return false
    89  		}
    90  		return true
    91  	}
    92  )
    93  
    94  type SimpleBaseUpgradeModule struct {
    95  	t                  *testing.T
    96  	h                  int64
    97  	taskExecuteHeight  int64
    98  	taskExecutedNotify func()
    99  	appModule          module.AppModuleBasic
   100  	storeKey           *sdk.KVStoreKey
   101  }
   102  
   103  func (b *SimpleBaseUpgradeModule) CommitFilter() *cosmost.StoreFilter {
   104  	if b.UpgradeHeight() == 0 {
   105  		return &defaultDenyFilter
   106  	}
   107  	var ret cosmost.StoreFilter
   108  	ret = func(module string, h int64, store cosmost.CommitKVStore) bool {
   109  		if b.appModule.Name() != module {
   110  			return false
   111  		}
   112  		if b.h == h {
   113  			store.SetUpgradeVersion(h)
   114  			return false
   115  		}
   116  		if b.h > h {
   117  			return false
   118  		}
   119  
   120  		return true
   121  	}
   122  	return &ret
   123  }
   124  
   125  func (b *SimpleBaseUpgradeModule) PruneFilter() *cosmost.StoreFilter {
   126  	if b.UpgradeHeight() == 0 {
   127  		return &defaultDenyFilter
   128  	}
   129  
   130  	var ret cosmost.StoreFilter
   131  	ret = func(module string, h int64, store cosmost.CommitKVStore) bool {
   132  		if b.appModule.Name() != module {
   133  			return false
   134  		}
   135  		if b.h >= h {
   136  			return false
   137  		}
   138  
   139  		return true
   140  	}
   141  	return &ret
   142  }
   143  
   144  func (b *SimpleBaseUpgradeModule) VersionFilter() *cosmost.VersionFilter {
   145  	//todo ywmet
   146  	return nil
   147  }
   148  
   149  func NewSimpleBaseUpgradeModule(t *testing.T, h int64, appModule module.AppModuleBasic, taskExecutedNotify func()) *SimpleBaseUpgradeModule {
   150  	return &SimpleBaseUpgradeModule{t: t, h: h, appModule: appModule, taskExecutedNotify: taskExecutedNotify, taskExecuteHeight: h + 1}
   151  }
   152  
   153  func (b *SimpleBaseUpgradeModule) ModuleName() string {
   154  	return b.appModule.Name()
   155  }
   156  
   157  func (b *SimpleBaseUpgradeModule) RegisterTask() upgradetypes.HeightTask {
   158  	return upgradetypes.NewHeightTask(0, func(ctx sdk.Context) error {
   159  		b.taskExecutedNotify()
   160  		store := ctx.KVStore(b.storeKey)
   161  		height := ctx.BlockHeight()
   162  		require.Equal(b.t, b.taskExecuteHeight, height)
   163  		store.Set([]byte(test_prefix+b.ModuleName()), []byte(strconv.Itoa(int(height))))
   164  		return nil
   165  	})
   166  }
   167  
   168  func (b *SimpleBaseUpgradeModule) UpgradeHeight() int64 {
   169  	return b.h
   170  }
   171  
   172  func (b *SimpleBaseUpgradeModule) RegisterParam() params.ParamSet {
   173  	return nil
   174  }
   175  
   176  var (
   177  	_ module.AppModuleBasic = (*simpleDefaultAppModuleBasic)(nil)
   178  )
   179  
   180  type simpleDefaultAppModuleBasic struct {
   181  	name string
   182  }
   183  
   184  func (s *simpleDefaultAppModuleBasic) Name() string {
   185  	return s.name
   186  }
   187  
   188  func (s *simpleDefaultAppModuleBasic) RegisterCodec(c *codec.Codec) {}
   189  
   190  func (s *simpleDefaultAppModuleBasic) DefaultGenesis() json.RawMessage { return nil }
   191  
   192  func (s *simpleDefaultAppModuleBasic) ValidateGenesis(message json.RawMessage) error { return nil }
   193  
   194  func (s *simpleDefaultAppModuleBasic) RegisterRESTRoutes(context context.CLIContext, router *mux.Router) {
   195  	return
   196  }
   197  
   198  func (s *simpleDefaultAppModuleBasic) GetTxCmd(c *codec.Codec) *cobra.Command { return nil }
   199  
   200  func (s *simpleDefaultAppModuleBasic) GetQueryCmd(c *codec.Codec) *cobra.Command { return nil }
   201  
   202  var (
   203  	_ module.AppModule = (*simpleAppModule)(nil)
   204  )
   205  
   206  type simpleAppModule struct {
   207  	*SimpleBaseUpgradeModule
   208  	*simpleDefaultAppModuleBasic
   209  }
   210  
   211  func newSimpleAppModule(t *testing.T, hh int64, name string, notify func()) *simpleAppModule {
   212  	ret := &simpleAppModule{}
   213  	ret.simpleDefaultAppModuleBasic = &simpleDefaultAppModuleBasic{name: name}
   214  	ret.SimpleBaseUpgradeModule = NewSimpleBaseUpgradeModule(t, hh, ret, notify)
   215  	return ret
   216  }
   217  
   218  func (s2 *simpleAppModule) InitGenesis(s sdk.Context, message json.RawMessage) []abci.ValidatorUpdate {
   219  	return nil
   220  }
   221  
   222  func (s2 *simpleAppModule) ExportGenesis(s sdk.Context) json.RawMessage {
   223  	return nil
   224  }
   225  
   226  func (s2 *simpleAppModule) RegisterInvariants(registry sdk.InvariantRegistry) { return }
   227  
   228  func (s2 *simpleAppModule) Route() string {
   229  	return ""
   230  }
   231  
   232  func (s2 *simpleAppModule) NewHandler() sdk.Handler { return nil }
   233  
   234  func (s2 *simpleAppModule) QuerierRoute() string {
   235  	return ""
   236  }
   237  
   238  func (s2 *simpleAppModule) NewQuerierHandler() sdk.Querier {
   239  	return nil
   240  }
   241  
   242  func (s2 *simpleAppModule) BeginBlock(s sdk.Context, block abci.RequestBeginBlock) {
   243  }
   244  
   245  func (s2 *simpleAppModule) EndBlock(s sdk.Context, block abci.RequestEndBlock) []abci.ValidatorUpdate {
   246  	return nil
   247  }
   248  
   249  func setupModuleBasics(bs ...module.AppModule) *module.Manager {
   250  	basis := []module.AppModule{}
   251  	for _, v := range bs {
   252  		basis = append(basis, v)
   253  	}
   254  	return module.NewManager(
   255  		basis...,
   256  	)
   257  }
   258  
   259  type testSimApp struct {
   260  	*FBChainApp
   261  	// the module manager
   262  }
   263  
   264  type TestSimAppOption func(a *testSimApp)
   265  type MangerOption func(m *module.Manager)
   266  
   267  func newTestFbcChainApp(
   268  	logger log.Logger,
   269  	db dbm.DB,
   270  	traceStore io.Writer,
   271  	loadLatest bool,
   272  	skipUpgradeHeights map[int64]bool,
   273  	invCheckPeriod uint,
   274  	keys map[string]*sdk.KVStoreKey,
   275  	ops ...TestSimAppOption,
   276  ) *testSimApp {
   277  	logger.Info("Starting FBC",
   278  		"GenesisHeight", tmtypes.GetStartBlockHeight(),
   279  		"MercuryHeight", tmtypes.GetMercuryHeight(),
   280  		"VenusHeight", tmtypes.GetVenusHeight(),
   281  	)
   282  	onceLog.Do(func() {
   283  		iavl.SetLogger(logger.With("module", "iavl"))
   284  		logStartingFlags(logger)
   285  	})
   286  
   287  	codecProxy, interfaceReg := fbchaincodec.MakeCodecSuit(ModuleBasics)
   288  
   289  	// NOTE we use custom fbchaintransaction decoder that supports the sdk.Tx interface instead of sdk.StdTx
   290  	bApp := bam.NewBaseApp(appName, logger, db, evm.TxDecoder(codecProxy))
   291  
   292  	bApp.SetCommitMultiStoreTracer(traceStore)
   293  	bApp.SetAppVersion(version.Version)
   294  	bApp.SetStartLogHandler(trace.StartTxLog)
   295  	bApp.SetEndLogHandler(trace.StopTxLog)
   296  
   297  	bApp.SetInterfaceRegistry(interfaceReg)
   298  
   299  	tkeys := sdk.NewTransientStoreKeys(params.TStoreKey)
   300  	memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
   301  
   302  	ret := &testSimApp{}
   303  	app := &FBChainApp{
   304  		BaseApp:        bApp,
   305  		invCheckPeriod: invCheckPeriod,
   306  		keys:           keys,
   307  		tkeys:          tkeys,
   308  		subspaces:      make(map[string]params.Subspace),
   309  		heightTasks:    make(map[int64]*upgradetypes.HeightTasks),
   310  	}
   311  	ret.FBChainApp = app
   312  	bApp.SetInterceptors(makeInterceptors())
   313  
   314  	// init params keeper and subspaces
   315  	app.ParamsKeeper = params.NewKeeper(codecProxy.GetCdc(), keys[params.StoreKey], tkeys[params.TStoreKey], logger)
   316  	app.subspaces[auth.ModuleName] = app.ParamsKeeper.Subspace(auth.DefaultParamspace)
   317  	app.subspaces[bank.ModuleName] = app.ParamsKeeper.Subspace(bank.DefaultParamspace)
   318  	app.subspaces[staking.ModuleName] = app.ParamsKeeper.Subspace(staking.DefaultParamspace)
   319  	app.subspaces[mint.ModuleName] = app.ParamsKeeper.Subspace(mint.DefaultParamspace)
   320  	app.subspaces[distr.ModuleName] = app.ParamsKeeper.Subspace(distr.DefaultParamspace)
   321  	app.subspaces[slashing.ModuleName] = app.ParamsKeeper.Subspace(slashing.DefaultParamspace)
   322  	app.subspaces[gov.ModuleName] = app.ParamsKeeper.Subspace(gov.DefaultParamspace)
   323  	app.subspaces[crisis.ModuleName] = app.ParamsKeeper.Subspace(crisis.DefaultParamspace)
   324  	app.subspaces[evidence.ModuleName] = app.ParamsKeeper.Subspace(evidence.DefaultParamspace)
   325  	app.subspaces[evm.ModuleName] = app.ParamsKeeper.Subspace(evm.DefaultParamspace)
   326  	app.subspaces[token.ModuleName] = app.ParamsKeeper.Subspace(token.DefaultParamspace)
   327  	app.subspaces[dex.ModuleName] = app.ParamsKeeper.Subspace(dex.DefaultParamspace)
   328  	app.subspaces[order.ModuleName] = app.ParamsKeeper.Subspace(order.DefaultParamspace)
   329  	app.subspaces[ammswap.ModuleName] = app.ParamsKeeper.Subspace(ammswap.DefaultParamspace)
   330  	app.subspaces[farm.ModuleName] = app.ParamsKeeper.Subspace(farm.DefaultParamspace)
   331  	app.subspaces[ibchost.ModuleName] = app.ParamsKeeper.Subspace(ibchost.ModuleName)
   332  	app.subspaces[ibctransfertypes.ModuleName] = app.ParamsKeeper.Subspace(ibctransfertypes.ModuleName)
   333  	app.subspaces[erc20.ModuleName] = app.ParamsKeeper.Subspace(erc20.DefaultParamspace)
   334  	app.subspaces[wasm.ModuleName] = app.ParamsKeeper.Subspace(wasm.ModuleName)
   335  
   336  	//proxy := codec.NewMarshalProxy(cc, cdc)
   337  	app.marshal = codecProxy
   338  	// use custom fbchainaccount for contracts
   339  	app.AccountKeeper = auth.NewAccountKeeper(
   340  		codecProxy.GetCdc(), keys[auth.StoreKey], keys[mpt.StoreKey], app.subspaces[auth.ModuleName], fbchain.ProtoAccount,
   341  	)
   342  
   343  	bankKeeper := bank.NewBaseKeeperWithMarshal(
   344  		&app.AccountKeeper, codecProxy, app.subspaces[bank.ModuleName], app.ModuleAccountAddrs(),
   345  	)
   346  	app.BankKeeper = &bankKeeper
   347  	app.ParamsKeeper.SetBankKeeper(app.BankKeeper)
   348  	app.SupplyKeeper = supply.NewKeeper(
   349  		codecProxy.GetCdc(), keys[supply.StoreKey], &app.AccountKeeper, bank.NewBankKeeperAdapter(app.BankKeeper), maccPerms,
   350  	)
   351  
   352  	stakingKeeper := staking.NewKeeper(
   353  		codecProxy, keys[staking.StoreKey], app.SupplyKeeper, app.subspaces[staking.ModuleName],
   354  	)
   355  	app.ParamsKeeper.SetStakingKeeper(stakingKeeper)
   356  	app.MintKeeper = mint.NewKeeper(
   357  		codecProxy.GetCdc(), keys[mint.StoreKey], app.subspaces[mint.ModuleName], &stakingKeeper,
   358  		app.SupplyKeeper, auth.FeeCollectorName, farm.MintFarmingAccount,
   359  	)
   360  	app.DistrKeeper = distr.NewKeeper(
   361  		codecProxy.GetCdc(), keys[distr.StoreKey], app.subspaces[distr.ModuleName], &stakingKeeper,
   362  		app.SupplyKeeper, auth.FeeCollectorName, app.ModuleAccountAddrs(),
   363  	)
   364  	app.SlashingKeeper = slashing.NewKeeper(
   365  		codecProxy.GetCdc(), keys[slashing.StoreKey], &stakingKeeper, app.subspaces[slashing.ModuleName],
   366  	)
   367  	app.CrisisKeeper = crisis.NewKeeper(
   368  		app.subspaces[crisis.ModuleName], invCheckPeriod, app.SupplyKeeper, auth.FeeCollectorName,
   369  	)
   370  	app.UpgradeKeeper = upgrade.NewKeeper(skipUpgradeHeights, keys[upgrade.StoreKey], app.marshal.GetCdc())
   371  	app.ParamsKeeper.RegisterSignal(evmtypes.SetEvmParamsNeedUpdate)
   372  	app.EvmKeeper = evm.NewKeeper(
   373  		app.marshal.GetCdc(), keys[evm.StoreKey], app.subspaces[evm.ModuleName], &app.AccountKeeper, app.SupplyKeeper, app.BankKeeper, &stakingKeeper, logger)
   374  	(&bankKeeper).SetInnerTxKeeper(app.EvmKeeper)
   375  
   376  	app.TokenKeeper = token.NewKeeper(app.BankKeeper, app.subspaces[token.ModuleName], auth.FeeCollectorName, app.SupplyKeeper,
   377  		keys[token.StoreKey], keys[token.KeyLock], app.marshal.GetCdc(), false, &app.AccountKeeper)
   378  
   379  	app.DexKeeper = dex.NewKeeper(auth.FeeCollectorName, app.SupplyKeeper, app.subspaces[dex.ModuleName], app.TokenKeeper, &stakingKeeper,
   380  		app.BankKeeper, app.keys[dex.StoreKey], app.keys[dex.TokenPairStoreKey], app.marshal.GetCdc())
   381  
   382  	app.OrderKeeper = order.NewKeeper(
   383  		app.TokenKeeper, app.SupplyKeeper, app.DexKeeper, app.subspaces[order.ModuleName], auth.FeeCollectorName,
   384  		app.keys[order.OrderStoreKey], app.marshal.GetCdc(), false, orderMetrics)
   385  
   386  	app.SwapKeeper = ammswap.NewKeeper(app.SupplyKeeper, app.TokenKeeper, app.marshal.GetCdc(), app.keys[ammswap.StoreKey], app.subspaces[ammswap.ModuleName])
   387  
   388  	app.FarmKeeper = farm.NewKeeper(auth.FeeCollectorName, app.SupplyKeeper, app.TokenKeeper, app.SwapKeeper, *app.EvmKeeper, app.subspaces[farm.StoreKey],
   389  		app.keys[farm.StoreKey], app.marshal.GetCdc())
   390  
   391  	// create evidence keeper with router
   392  	evidenceKeeper := evidence.NewKeeper(
   393  		codecProxy.GetCdc(), keys[evidence.StoreKey], app.subspaces[evidence.ModuleName], &app.StakingKeeper, app.SlashingKeeper,
   394  	)
   395  	evidenceRouter := evidence.NewRouter()
   396  	evidenceKeeper.SetRouter(evidenceRouter)
   397  	app.EvidenceKeeper = *evidenceKeeper
   398  
   399  	// add capability keeper and ScopeToModule for ibc module
   400  	app.CapabilityKeeper = capabilitykeeper.NewKeeper(codecProxy, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey])
   401  	scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName)
   402  	scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName)
   403  	// NOTE: the IBC mock keeper and application module is used only for testing core IBC. Do
   404  	// note replicate if you do not need to test core IBC or light clients.
   405  	scopedIBCMockKeeper := app.CapabilityKeeper.ScopeToModule("mock")
   406  
   407  	v2keeper := ibc.NewKeeper(
   408  		codecProxy, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), &stakingKeeper, app.UpgradeKeeper, &scopedIBCKeeper, interfaceReg,
   409  	)
   410  	v4Keeper := ibc.NewV4Keeper(v2keeper)
   411  	facadedKeeper := ibc.NewFacadedKeeper(v2keeper)
   412  	facadedKeeper.RegisterKeeper(ibccommon.DefaultFactory(tmtypes.HigherThanVenus4, ibc.IBCV4, v4Keeper))
   413  	app.IBCKeeper = facadedKeeper
   414  
   415  	// Create Transfer Keepers
   416  	app.TransferKeeper = ibctransferkeeper.NewKeeper(
   417  		codecProxy, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName),
   418  		app.IBCKeeper.V2Keeper.ChannelKeeper, &app.IBCKeeper.V2Keeper.PortKeeper,
   419  		app.SupplyKeeper, supply.NewSupplyKeeperAdapter(app.SupplyKeeper), scopedTransferKeeper, interfaceReg,
   420  	)
   421  	ibctransfertypes.SetMarshal(codecProxy)
   422  
   423  	app.Erc20Keeper = erc20.NewKeeper(app.marshal.GetCdc(), app.keys[erc20.ModuleName], app.subspaces[erc20.ModuleName],
   424  		app.AccountKeeper, app.SupplyKeeper, app.BankKeeper, app.EvmKeeper, app.TransferKeeper)
   425  
   426  	// register the proposal types
   427  	// 3.register the proposal types
   428  	govRouter := gov.NewRouter()
   429  	govRouter.AddRoute(gov.RouterKey, gov.ProposalHandler).
   430  		AddRoute(params.RouterKey, params.NewParamChangeProposalHandler(&app.ParamsKeeper)).
   431  		AddRoute(distr.RouterKey, distr.NewDistributionProposalHandler(app.DistrKeeper)).
   432  		AddRoute(dex.RouterKey, dex.NewProposalHandler(&app.DexKeeper)).
   433  		AddRoute(farm.RouterKey, farm.NewManageWhiteListProposalHandler(&app.FarmKeeper)).
   434  		AddRoute(evm.RouterKey, evm.NewManageContractDeploymentWhitelistProposalHandler(app.EvmKeeper)).
   435  		AddRoute(mint.RouterKey, mint.NewManageTreasuresProposalHandler(&app.MintKeeper)).
   436  		AddRoute(ibchost.RouterKey, ibcclient.NewClientUpdateProposalHandler(app.IBCKeeper.V2Keeper.ClientKeeper)).
   437  		AddRoute(erc20.RouterKey, erc20.NewProposalHandler(&app.Erc20Keeper))
   438  	govProposalHandlerRouter := keeper.NewProposalHandlerRouter()
   439  	govProposalHandlerRouter.AddRoute(params.RouterKey, &app.ParamsKeeper).
   440  		AddRoute(dex.RouterKey, &app.DexKeeper).
   441  		AddRoute(farm.RouterKey, &app.FarmKeeper).
   442  		AddRoute(evm.RouterKey, app.EvmKeeper).
   443  		AddRoute(mint.RouterKey, &app.MintKeeper).
   444  		AddRoute(erc20.RouterKey, &app.Erc20Keeper)
   445  	app.GovKeeper = gov.NewKeeper(
   446  		app.marshal.GetCdc(), app.keys[gov.StoreKey], app.ParamsKeeper, app.subspaces[gov.DefaultParamspace],
   447  		app.SupplyKeeper, &stakingKeeper, gov.DefaultParamspace, govRouter,
   448  		app.BankKeeper, govProposalHandlerRouter, auth.FeeCollectorName,
   449  	)
   450  	app.ParamsKeeper.SetGovKeeper(app.GovKeeper)
   451  	app.DexKeeper.SetGovKeeper(app.GovKeeper)
   452  	app.FarmKeeper.SetGovKeeper(app.GovKeeper)
   453  	app.EvmKeeper.SetGovKeeper(app.GovKeeper)
   454  	app.MintKeeper.SetGovKeeper(app.GovKeeper)
   455  	app.Erc20Keeper.SetGovKeeper(app.GovKeeper)
   456  
   457  	// Set EVM hooks
   458  	app.EvmKeeper.SetHooks(evm.NewLogProcessEvmHook(erc20.NewSendToIbcEventHandler(app.Erc20Keeper),
   459  		erc20.NewSendNative20ToIbcEventHandler(app.Erc20Keeper)))
   460  	// Set IBC hooks
   461  	app.TransferKeeper = *app.TransferKeeper.SetHooks(erc20.NewIBCTransferHooks(app.Erc20Keeper))
   462  	transferModule := ibctransfer.NewAppModule(app.TransferKeeper, codecProxy)
   463  
   464  	// Create static IBC router, add transfer route, then set and seal it
   465  	ibcRouter := ibcporttypes.NewRouter()
   466  	ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule)
   467  	//ibcRouter.AddRoute(ibcmock.ModuleName, mockModule)
   468  	app.IBCKeeper.V2Keeper.SetRouter(ibcRouter)
   469  
   470  	// register the staking hooks
   471  	// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
   472  	app.StakingKeeper = *stakingKeeper.SetHooks(
   473  		staking.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
   474  	)
   475  
   476  	homeDir := viper.GetString(cli.HomeFlag)
   477  	wasmDir := filepath.Join(homeDir, "wasm")
   478  	wasmConfig, err := wasm.ReadWasmConfig()
   479  	if err != nil {
   480  		panic(fmt.Sprintf("error while reading wasm config: %s", err))
   481  	}
   482  
   483  	// The last arguments can contain custom message handlers, and custom query handlers,
   484  	// if we want to allow any custom callbacks
   485  	supportedFeatures := wasm.SupportedFeatures
   486  	app.WasmKeeper = wasm.NewKeeper(
   487  		app.marshal,
   488  		keys[wasm.StoreKey],
   489  		app.subspaces[wasm.ModuleName],
   490  		&app.AccountKeeper,
   491  		bank.NewBankKeeperAdapter(app.BankKeeper),
   492  		app.IBCKeeper.V2Keeper.ChannelKeeper,
   493  		&app.IBCKeeper.V2Keeper.PortKeeper,
   494  		nil,
   495  		app.TransferKeeper,
   496  		app.MsgServiceRouter(),
   497  		app.GRPCQueryRouter(),
   498  		wasmDir,
   499  		wasmConfig,
   500  		supportedFeatures,
   501  	)
   502  
   503  	app.mm = module.NewManager(
   504  		genutil.NewAppModule(app.AccountKeeper, app.StakingKeeper, app.BaseApp.DeliverTx),
   505  		auth.NewAppModule(app.AccountKeeper),
   506  		bank.NewAppModule(app.BankKeeper, app.AccountKeeper, app.SupplyKeeper),
   507  		crisis.NewAppModule(&app.CrisisKeeper),
   508  		supply.NewAppModule(app.SupplyKeeper, app.AccountKeeper),
   509  		gov.NewAppModule(app.GovKeeper, app.SupplyKeeper),
   510  		mint.NewAppModule(app.MintKeeper),
   511  		slashing.NewAppModule(app.SlashingKeeper, app.AccountKeeper, app.StakingKeeper),
   512  		distr.NewAppModule(app.DistrKeeper, app.SupplyKeeper),
   513  		staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper),
   514  		evidence.NewAppModule(app.EvidenceKeeper),
   515  		evm.NewAppModule(app.EvmKeeper, &app.AccountKeeper),
   516  		token.NewAppModule(commonversion.ProtocolVersionV0, app.TokenKeeper, app.SupplyKeeper),
   517  		dex.NewAppModule(commonversion.ProtocolVersionV0, app.DexKeeper, app.SupplyKeeper),
   518  		order.NewAppModule(commonversion.ProtocolVersionV0, app.OrderKeeper, app.SupplyKeeper),
   519  		ammswap.NewAppModule(app.SwapKeeper),
   520  		farm.NewAppModule(app.FarmKeeper),
   521  		params.NewAppModule(app.ParamsKeeper),
   522  		// ibc
   523  		ibc.NewAppModule(app.IBCKeeper),
   524  		capabilityModule.NewAppModule(codecProxy, *app.CapabilityKeeper),
   525  		transferModule,
   526  		erc20.NewAppModule(app.Erc20Keeper),
   527  		wasm.NewAppModule(*app.marshal, &app.WasmKeeper),
   528  	)
   529  
   530  	for _, opt := range ops {
   531  		opt(ret)
   532  	}
   533  
   534  	// create the simulation manager and define the order of the modules for deterministic simulations
   535  	//
   536  	// NOTE: this is not required apps that don't use the simulator for fuzz testing
   537  	// transactions
   538  	app.sm = module.NewSimulationManager(
   539  		auth.NewAppModule(app.AccountKeeper),
   540  		bank.NewAppModule(app.BankKeeper, app.AccountKeeper, app.SupplyKeeper),
   541  		supply.NewAppModule(app.SupplyKeeper, app.AccountKeeper),
   542  		gov.NewAppModule(app.GovKeeper, app.SupplyKeeper),
   543  		mint.NewAppModule(app.MintKeeper),
   544  		staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper),
   545  		distr.NewAppModule(app.DistrKeeper, app.SupplyKeeper),
   546  		slashing.NewAppModule(app.SlashingKeeper, app.AccountKeeper, app.StakingKeeper),
   547  		params.NewAppModule(app.ParamsKeeper), // NOTE: only used for simulation to generate randomized param change proposals
   548  		ibc.NewAppModule(app.IBCKeeper),
   549  		wasm.NewAppModule(*app.marshal, &app.WasmKeeper),
   550  	)
   551  
   552  	app.sm.RegisterStoreDecoders()
   553  
   554  	// initialize stores
   555  	app.MountKVStores(keys)
   556  	app.MountTransientStores(tkeys)
   557  	app.MountMemoryStores(memKeys)
   558  
   559  	// initialize BaseApp
   560  	app.SetInitChainer(app.InitChainer)
   561  	app.SetBeginBlocker(app.BeginBlocker)
   562  	app.SetAnteHandler(ante.NewAnteHandler(app.AccountKeeper, app.EvmKeeper, app.SupplyKeeper, validateMsgHook(app.OrderKeeper), wasmkeeper.HandlerOption{
   563  		WasmConfig:        &wasmConfig,
   564  		TXCounterStoreKey: keys[wasm.StoreKey],
   565  	}, app.IBCKeeper, app.StakingKeeper, app.ParamsKeeper))
   566  	app.SetEndBlocker(app.EndBlocker)
   567  	app.SetGasRefundHandler(refund.NewGasRefundHandler(app.AccountKeeper, app.SupplyKeeper, app.EvmKeeper))
   568  	app.SetAccNonceHandler(NewAccNonceHandler(app.AccountKeeper))
   569  	app.SetEvmSysContractAddressHandler(NewEvmSysContractAddressHandler(app.EvmKeeper))
   570  	app.SetUpdateFeeCollectorAccHandler(updateFeeCollectorHandler(app.BankKeeper, app.SupplyKeeper))
   571  	app.SetParallelTxLogHandlers(fixLogForParallelTxHandler(app.EvmKeeper))
   572  	app.SetEvmWatcherCollector(app.EvmKeeper.Watcher.Collect)
   573  
   574  	if loadLatest {
   575  		err := app.LoadLatestVersion(app.keys[bam.MainStoreKey])
   576  		if err != nil {
   577  			tmos.Exit(err.Error())
   578  		}
   579  	}
   580  
   581  	app.ScopedIBCKeeper = scopedIBCKeeper
   582  	app.ScopedTransferKeeper = scopedTransferKeeper
   583  
   584  	// NOTE: the IBC mock keeper and application module is used only for testing core IBC. Do
   585  	// note replicate if you do not need to test core IBC or light clients.
   586  	app.ScopedIBCMockKeeper = scopedIBCMockKeeper
   587  
   588  	return ret
   589  }
   590  
   591  func newTestSimApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, keys map[string]*sdk.KVStoreKey, ops ...TestSimAppOption) *testSimApp {
   592  	return newTestFbcChainApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, 0, keys, ops...)
   593  }
   594  
   595  type UpgradeCase struct {
   596  	name     string
   597  	upgradeH int64
   598  }
   599  
   600  func createCases(moduleCount int, beginHeight int) []UpgradeCase {
   601  	ret := make([]UpgradeCase, moduleCount)
   602  	for i := 0; i < moduleCount; i++ {
   603  		ret[i] = UpgradeCase{
   604  			name:     "m_" + strconv.Itoa(i),
   605  			upgradeH: int64(beginHeight + i),
   606  		}
   607  	}
   608  	return ret
   609  }
   610  
   611  func newRecordMemDB() *RecordMemDB {
   612  	ret := &RecordMemDB{}
   613  	ret.db = dbm.NewMemDB()
   614  	return ret
   615  }
   616  
   617  func TestUpgradeWithConcreteHeight(t *testing.T) {
   618  	db := newRecordMemDB()
   619  
   620  	cases := createCases(5, 10)
   621  	m := make(map[string]int)
   622  	count := 0
   623  	maxHeight := int64(0)
   624  
   625  	modules := make([]*simpleAppModule, 0)
   626  	for _, ca := range cases {
   627  		c := ca
   628  		m[c.name] = 0
   629  		if maxHeight < c.upgradeH {
   630  			maxHeight = c.upgradeH
   631  		}
   632  		modules = append(modules, newSimpleAppModule(t, c.upgradeH, c.name, func() {
   633  			m[c.name]++
   634  			count++
   635  		}))
   636  	}
   637  
   638  	app := setupTestApp(db, cases, modules)
   639  
   640  	genesisState := ModuleBasics.DefaultGenesis()
   641  	stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
   642  	require.NoError(t, err)
   643  	// Initialize the chain
   644  	app.InitChain(
   645  		abci.RequestInitChain{
   646  			Validators:    []abci.ValidatorUpdate{},
   647  			AppStateBytes: stateBytes,
   648  		},
   649  	)
   650  	app.Commit(abci.RequestCommit{})
   651  
   652  	for i := int64(2); i < maxHeight+5; i++ {
   653  		header := abci.Header{Height: i}
   654  		app.BeginBlock(abci.RequestBeginBlock{Header: header})
   655  		app.Commit(abci.RequestCommit{})
   656  	}
   657  	for _, v := range m {
   658  		require.Equal(t, 1, v)
   659  	}
   660  	require.Equal(t, count, len(cases))
   661  }
   662  
   663  func setupTestApp(db dbm.DB, cases []UpgradeCase, modules []*simpleAppModule) *testSimApp {
   664  	keys := createKeysByCases(cases)
   665  	for _, m := range modules {
   666  		m.storeKey = keys[m.Name()]
   667  	}
   668  	app := newTestSimApp("demo", log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, func(txBytes []byte, height ...int64) (sdk.Tx, error) {
   669  		return nil, nil
   670  	}, keys, func(a *testSimApp) {
   671  		for _, m := range modules {
   672  			a.mm.Modules[m.Name()] = m
   673  			a.mm.OrderBeginBlockers = append(a.mm.OrderEndBlockers, m.Name())
   674  			a.mm.OrderEndBlockers = append(a.mm.OrderEndBlockers, m.Name())
   675  			a.mm.OrderInitGenesis = append(a.mm.OrderInitGenesis, m.Name())
   676  			a.mm.OrderExportGenesis = append(a.mm.OrderExportGenesis, m.Name())
   677  		}
   678  	}, func(a *testSimApp) {
   679  		a.setupUpgradeModules()
   680  	})
   681  	return app
   682  }
   683  
   684  func createKeysByCases(caseas []UpgradeCase) map[string]*sdk.KVStoreKey {
   685  	caseKeys := make([]string, 0)
   686  	for _, c := range caseas {
   687  		caseKeys = append(caseKeys, c.name)
   688  	}
   689  	caseKeys = append(caseKeys, bam.MainStoreKey, auth.StoreKey, staking.StoreKey,
   690  		supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey,
   691  		gov.StoreKey, params.StoreKey, upgrade.StoreKey, evidence.StoreKey,
   692  		evm.StoreKey, token.StoreKey, token.KeyLock, dex.StoreKey, dex.TokenPairStoreKey,
   693  		order.OrderStoreKey, ammswap.StoreKey, farm.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey,
   694  		ibchost.StoreKey,
   695  		erc20.StoreKey, wasm.StoreKey)
   696  	keys := sdk.NewKVStoreKeys(
   697  		caseKeys...,
   698  	)
   699  	return keys
   700  }
   701  
   702  // /
   703  type RecordMemDB struct {
   704  	db *dbm.MemDB
   705  	common.PlaceHolder
   706  }
   707  
   708  func (d *RecordMemDB) Get(bytes []byte) ([]byte, error) {
   709  	return d.db.Get(bytes)
   710  }
   711  
   712  func (d *RecordMemDB) GetUnsafeValue(key []byte, processor dbm.UnsafeValueProcessor) (interface{}, error) {
   713  	return d.db.GetUnsafeValue(key, processor)
   714  }
   715  
   716  func (d *RecordMemDB) Has(key []byte) (bool, error) {
   717  	return d.db.Has(key)
   718  }
   719  
   720  func (d *RecordMemDB) SetSync(bytes []byte, bytes2 []byte) error {
   721  	return d.db.SetSync(bytes, bytes2)
   722  }
   723  
   724  func (d *RecordMemDB) Delete(bytes []byte) error {
   725  	return d.db.Delete(bytes)
   726  }
   727  
   728  func (d *RecordMemDB) DeleteSync(bytes []byte) error {
   729  	return d.db.DeleteSync(bytes)
   730  }
   731  
   732  func (d *RecordMemDB) Iterator(start, end []byte) (dbm.Iterator, error) {
   733  	return d.db.Iterator(start, end)
   734  }
   735  
   736  func (d *RecordMemDB) ReverseIterator(start, end []byte) (dbm.Iterator, error) {
   737  	return d.db.ReverseIterator(start, end)
   738  }
   739  
   740  func (d *RecordMemDB) Close() error {
   741  	return d.db.Close()
   742  }
   743  
   744  func (d *RecordMemDB) NewBatch() dbm.Batch {
   745  	return d.db.NewBatch()
   746  }
   747  
   748  func (d *RecordMemDB) Print() error {
   749  	return d.db.Print()
   750  }
   751  
   752  func (d *RecordMemDB) Stats() map[string]string {
   753  	return d.db.Stats()
   754  }
   755  
   756  func (d *RecordMemDB) Set(key []byte, value []byte) error {
   757  	return d.db.Set(key, value)
   758  }
   759  
   760  func TestErc20InitGenesis(t *testing.T) {
   761  	db := newRecordMemDB()
   762  
   763  	cases := createCases(1, 1)
   764  	m := make(map[string]int)
   765  	count := 0
   766  	maxHeight := int64(0)
   767  	veneus1H := 10
   768  	tmtypes.UnittestOnlySetMilestoneVenus1Height(10)
   769  
   770  	modules := make([]*simpleAppModule, 0)
   771  	for _, ca := range cases {
   772  		c := ca
   773  		m[c.name] = 0
   774  		if maxHeight < c.upgradeH {
   775  			maxHeight = c.upgradeH
   776  		}
   777  		modules = append(modules, newSimpleAppModule(t, c.upgradeH, c.name, func() {
   778  			m[c.name]++
   779  			count++
   780  		}))
   781  	}
   782  
   783  	app := setupTestApp(db, cases, modules)
   784  
   785  	genesisState := ModuleBasics.DefaultGenesis()
   786  	stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
   787  	require.NoError(t, err)
   788  	// Initialize the chain
   789  	app.InitChain(
   790  		abci.RequestInitChain{
   791  			Validators:    []abci.ValidatorUpdate{},
   792  			AppStateBytes: stateBytes,
   793  		},
   794  	)
   795  	app.Commit(abci.RequestCommit{})
   796  
   797  	for i := int64(2); i < int64(veneus1H+5); i++ {
   798  		header := abci.Header{Height: i}
   799  		app.BeginBlock(abci.RequestBeginBlock{Header: header})
   800  		if i <= int64(veneus1H) {
   801  			_, found := app.Erc20Keeper.GetImplementTemplateContract(app.GetDeliverStateCtx())
   802  			require.Equal(t, found, false)
   803  			_, found = app.Erc20Keeper.GetProxyTemplateContract(app.GetDeliverStateCtx())
   804  			require.Equal(t, found, false)
   805  		}
   806  		if i >= int64(veneus1H+2) {
   807  			_, found := app.Erc20Keeper.GetImplementTemplateContract(app.GetDeliverStateCtx())
   808  			require.Equal(t, found, true)
   809  			_, found = app.Erc20Keeper.GetProxyTemplateContract(app.GetDeliverStateCtx())
   810  			require.Equal(t, found, true)
   811  		}
   812  		app.Commit(abci.RequestCommit{})
   813  
   814  	}
   815  
   816  }