github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/wasm/keeper/test_common.go (about)

     1  package keeper
     2  
     3  import (
     4  	"encoding/binary"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/fibonacci-chain/fbc/x/wasm/keeper/testdata"
    13  
    14  	fbexchaincodec "github.com/fibonacci-chain/fbc/app/codec"
    15  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/baseapp"
    16  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client"
    17  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    18  	interfacetypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec/types"
    19  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store"
    20  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/mpt"
    21  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    22  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
    23  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/module"
    24  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
    25  	cosmoscryptocodec "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/ibc-tx"
    26  	ibc_tx "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/ibc-tx"
    27  	authkeeper "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/keeper"
    28  	authtypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/types"
    29  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank"
    30  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability"
    31  	capabilitykeeper "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/keeper"
    32  	capabilitytypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/types"
    33  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/crisis"
    34  	crisistypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/crisis"
    35  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/evidence"
    36  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/mint"
    37  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/slashing"
    38  	slashingtypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/slashing"
    39  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/supply"
    40  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/upgrade"
    41  	upgradekeeper "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/upgrade"
    42  	upgradetypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/upgrade"
    43  	"github.com/fibonacci-chain/fbc/x/ammswap"
    44  	dex "github.com/fibonacci-chain/fbc/x/dex/types"
    45  	distr "github.com/fibonacci-chain/fbc/x/distribution"
    46  	"github.com/fibonacci-chain/fbc/x/erc20"
    47  	"github.com/fibonacci-chain/fbc/x/evm"
    48  	"github.com/fibonacci-chain/fbc/x/farm"
    49  	"github.com/fibonacci-chain/fbc/x/order"
    50  	"github.com/fibonacci-chain/fbc/x/staking"
    51  	token "github.com/fibonacci-chain/fbc/x/token/types"
    52  
    53  	fbexchain "github.com/fibonacci-chain/fbc/app/types"
    54  
    55  	//upgradeclient "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/upgrade/client"
    56  	"github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/transfer"
    57  	ibctransfertypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/transfer/types"
    58  	ibc "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core"
    59  	ibchost "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host"
    60  	ibckeeper "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/keeper"
    61  	tmproto "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    62  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto"
    63  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/ed25519"
    64  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
    65  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/rand"
    66  	dbm "github.com/fibonacci-chain/fbc/libs/tm-db"
    67  	"github.com/fibonacci-chain/fbc/x/distribution"
    68  	distrclient "github.com/fibonacci-chain/fbc/x/distribution/client"
    69  	distributionkeeper "github.com/fibonacci-chain/fbc/x/distribution/keeper"
    70  	distributiontypes "github.com/fibonacci-chain/fbc/x/distribution/types"
    71  	"github.com/fibonacci-chain/fbc/x/gov"
    72  	govkeeper "github.com/fibonacci-chain/fbc/x/gov/keeper"
    73  	govtypes "github.com/fibonacci-chain/fbc/x/gov/types"
    74  	"github.com/fibonacci-chain/fbc/x/params"
    75  	paramproposal "github.com/fibonacci-chain/fbc/x/params"
    76  	paramskeeper "github.com/fibonacci-chain/fbc/x/params"
    77  	paramstypes "github.com/fibonacci-chain/fbc/x/params"
    78  	paramsclient "github.com/fibonacci-chain/fbc/x/params/client"
    79  	stakingkeeper "github.com/fibonacci-chain/fbc/x/staking/keeper"
    80  	stakingtypes "github.com/fibonacci-chain/fbc/x/staking/types"
    81  	"github.com/fibonacci-chain/fbc/x/wasm/keeper/wasmtesting"
    82  	"github.com/fibonacci-chain/fbc/x/wasm/types"
    83  	"github.com/stretchr/testify/require"
    84  )
    85  
    86  // EncodingConfig specifies the concrete encoding types to use for a given app.
    87  // This is provided for compatibility between protobuf and amino implementations.
    88  type EncodingConfig struct {
    89  	InterfaceRegistry interfacetypes.InterfaceRegistry
    90  	Marshaler         codec.CodecProxy
    91  	TxConfig          client.TxConfig
    92  	Amino             *codec.Codec
    93  }
    94  
    95  var moduleBasics = module.NewBasicManager(
    96  	auth.AppModuleBasic{},
    97  	bank.AppModuleBasic{},
    98  	capability.AppModuleBasic{},
    99  	staking.AppModuleBasic{},
   100  	mint.AppModuleBasic{},
   101  	distribution.AppModuleBasic{},
   102  	supply.AppModuleBasic{},
   103  	gov.NewAppModuleBasic(
   104  		paramsclient.ProposalHandler, distrclient.ChangeDistributionTypeProposalHandler,
   105  		paramsclient.ProposalHandler, distrclient.CommunityPoolSpendProposalHandler,
   106  	),
   107  	params.AppModuleBasic{},
   108  	crisis.AppModuleBasic{},
   109  	slashing.AppModuleBasic{},
   110  	ibc.AppModuleBasic{},
   111  	upgrade.AppModuleBasic{},
   112  	evidence.AppModuleBasic{},
   113  	transfer.AppModuleBasic{},
   114  )
   115  
   116  func MakeTestCodec(t testing.TB) codec.CodecProxy {
   117  	return MakeEncodingConfig(t).Marshaler
   118  }
   119  
   120  func MakeEncodingConfig(_ testing.TB) EncodingConfig {
   121  	codecProxy, interfaceReg := fbexchaincodec.MakeCodecSuit(moduleBasics)
   122  	txConfig := ibc_tx.NewTxConfig(codecProxy.GetProtocMarshal(), ibc_tx.DefaultSignModes)
   123  	encodingConfig := EncodingConfig{
   124  		InterfaceRegistry: interfaceReg,
   125  		Marshaler:         *codecProxy,
   126  		Amino:             codecProxy.GetCdc(),
   127  		TxConfig:          txConfig}
   128  	amino := encodingConfig.Amino
   129  	interfaceRegistry := encodingConfig.InterfaceRegistry
   130  	cosmoscryptocodec.PubKeyRegisterInterfaces(interfaceReg)
   131  	// add wasmd types
   132  	types.RegisterInterfaces(interfaceRegistry)
   133  	types.RegisterLegacyAminoCodec(amino)
   134  
   135  	return encodingConfig
   136  }
   137  
   138  var TestingStakeParams = stakingtypes.Params{
   139  	UnbondingTime:      100,
   140  	MaxValidators:      10,
   141  	Epoch:              10,
   142  	MaxValsToAddShares: 1,
   143  	MinDelegation:      sdk.OneDec(),
   144  	MinSelfDelegation:  sdk.OneDec(),
   145  	HistoricalEntries:  10,
   146  }
   147  
   148  type TestFaucet struct {
   149  	t                testing.TB
   150  	bankKeeper       bank.Keeper
   151  	supplyKeeper     supply.Keeper
   152  	sender           sdk.AccAddress
   153  	balance          sdk.Coins
   154  	minterModuleName string
   155  }
   156  
   157  func NewTestFaucet(t testing.TB, ctx sdk.Context, bankKeeper bank.Keeper, supplyKeeper supply.Keeper, minterModuleName string, initialAmount ...sdk.Coin) *TestFaucet {
   158  	require.NotEmpty(t, initialAmount)
   159  	r := &TestFaucet{t: t, bankKeeper: bankKeeper, minterModuleName: minterModuleName, supplyKeeper: supplyKeeper}
   160  	_, _, addr := keyPubAddr()
   161  	r.sender = addr
   162  	r.Mint(ctx, addr, initialAmount...)
   163  	r.balance = initialAmount
   164  	return r
   165  }
   166  
   167  func (f *TestFaucet) Mint(parentCtx sdk.Context, addr sdk.AccAddress, amounts ...sdk.Coin) {
   168  	require.NotEmpty(f.t, amounts)
   169  	ctx := parentCtx.SetEventManager(sdk.NewEventManager()) // discard all faucet related events
   170  
   171  	err := f.supplyKeeper.MintCoins(*ctx, f.minterModuleName, amounts)
   172  	require.NoError(f.t, err)
   173  	err = f.supplyKeeper.SendCoinsFromModuleToAccount(*ctx, f.minterModuleName, addr, amounts)
   174  	require.NoError(f.t, err)
   175  	f.balance = f.balance.Add(amounts...)
   176  }
   177  
   178  func (f *TestFaucet) Fund(parentCtx sdk.Context, receiver sdk.AccAddress, amounts ...sdk.Coin) {
   179  	require.NotEmpty(f.t, amounts)
   180  	// ensure faucet is always filled
   181  	if !f.balance.IsAllGTE(amounts) {
   182  		f.Mint(parentCtx, f.sender, amounts...)
   183  	}
   184  	ctx := parentCtx.SetEventManager(sdk.NewEventManager()) // discard all faucet related events
   185  	err := f.bankKeeper.SendCoins(*ctx, f.sender, receiver, amounts)
   186  	require.NoError(f.t, err)
   187  	f.balance = f.balance.Sub(amounts)
   188  }
   189  
   190  func (f *TestFaucet) NewFundedAccount(ctx sdk.Context, amounts ...sdk.Coin) sdk.AccAddress {
   191  	_, _, addr := keyPubAddr()
   192  	f.Fund(ctx, addr, amounts...)
   193  	return addr
   194  }
   195  
   196  type TestKeepers struct {
   197  	AccountKeeper  authkeeper.AccountKeeper
   198  	supplyKeepr    supply.Keeper
   199  	StakingKeeper  stakingkeeper.Keeper
   200  	DistKeeper     distributionkeeper.Keeper
   201  	BankKeeper     bank.Keeper
   202  	GovKeeper      govkeeper.Keeper
   203  	ContractKeeper types.ContractOpsKeeper
   204  	WasmKeeper     *Keeper
   205  	IBCKeeper      *ibckeeper.Keeper
   206  	Router         *baseapp.Router
   207  	EncodingConfig EncodingConfig
   208  	Faucet         *TestFaucet
   209  	MultiStore     sdk.CommitMultiStore
   210  }
   211  
   212  // CreateDefaultTestInput common settings for CreateTestInput
   213  func CreateDefaultTestInput(t testing.TB) (sdk.Context, TestKeepers) {
   214  	return CreateTestInput(t, false, "staking")
   215  }
   216  
   217  // CreateTestInput encoders can be nil to accept the defaults, or set it to override some of the message handlers (like default)
   218  func CreateTestInput(t testing.TB, isCheckTx bool, supportedFeatures string, opts ...Option) (sdk.Context, TestKeepers) {
   219  	// Load default wasm config
   220  	return createTestInput(t, isCheckTx, supportedFeatures, types.DefaultWasmConfig(), dbm.NewMemDB(), opts...)
   221  }
   222  
   223  // encoders can be nil to accept the defaults, or set it to override some of the message handlers (like default)
   224  func createTestInput(
   225  	t testing.TB,
   226  	isCheckTx bool,
   227  	supportedFeatures string,
   228  	wasmConfig types.WasmConfig,
   229  	db dbm.DB,
   230  	opts ...Option,
   231  ) (sdk.Context, TestKeepers) {
   232  	tempDir := t.TempDir()
   233  	t.Cleanup(func() {
   234  		os.RemoveAll(tempDir)
   235  	})
   236  
   237  	keys := sdk.NewKVStoreKeys(
   238  		auth.StoreKey, staking.StoreKey,
   239  		supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey,
   240  		gov.StoreKey, params.StoreKey, upgrade.StoreKey, evidence.StoreKey,
   241  		evm.StoreKey, token.StoreKey, token.KeyLock, dex.StoreKey, dex.TokenPairStoreKey,
   242  		order.OrderStoreKey, ammswap.StoreKey, farm.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey,
   243  		ibchost.StoreKey,
   244  		erc20.StoreKey,
   245  		mpt.StoreKey,
   246  		types.StoreKey,
   247  	)
   248  	ms := store.NewCommitMultiStore(db)
   249  	for _, v := range keys {
   250  		ms.MountStoreWithDB(v, sdk.StoreTypeIAVL, db)
   251  	}
   252  	tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey)
   253  	for _, v := range tkeys {
   254  		ms.MountStoreWithDB(v, sdk.StoreTypeTransient, db)
   255  	}
   256  
   257  	memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
   258  	for _, v := range memKeys {
   259  		ms.MountStoreWithDB(v, sdk.StoreTypeMemory, db)
   260  	}
   261  
   262  	require.NoError(t, ms.LoadLatestVersion())
   263  
   264  	ctx := sdk.NewContext(ms, tmproto.Header{
   265  		Height: 1234567,
   266  		Time:   time.Date(2020, time.April, 22, 12, 0, 0, 0, time.UTC),
   267  	}, isCheckTx, log.NewNopLogger())
   268  	ctx = types.WithTXCounter(ctx, 0)
   269  
   270  	encodingConfig := MakeEncodingConfig(t)
   271  	appCodec, legacyAmino := encodingConfig.Marshaler, encodingConfig.Amino
   272  
   273  	paramsKeeper := paramskeeper.NewKeeper(
   274  		legacyAmino,
   275  		keys[paramstypes.StoreKey],
   276  		tkeys[paramstypes.TStoreKey],
   277  		ctx.Logger(),
   278  	)
   279  	for _, m := range []string{authtypes.ModuleName,
   280  		bank.ModuleName,
   281  		stakingtypes.ModuleName,
   282  		mint.ModuleName,
   283  		distributiontypes.ModuleName,
   284  		slashingtypes.ModuleName,
   285  		crisistypes.ModuleName,
   286  		ibctransfertypes.ModuleName,
   287  		capabilitytypes.ModuleName,
   288  		ibchost.ModuleName,
   289  		govtypes.ModuleName,
   290  		types.ModuleName,
   291  	} {
   292  		paramsKeeper.Subspace(m)
   293  	}
   294  	subspace := func(m string) paramstypes.Subspace {
   295  		r, ok := paramsKeeper.GetSubspace(m)
   296  		require.True(t, ok)
   297  		return r
   298  	}
   299  	maccPerms := map[string][]string{ // module account permissions
   300  		auth.FeeCollectorName:       nil,
   301  		distr.ModuleName:            nil,
   302  		mint.ModuleName:             {supply.Minter},
   303  		staking.BondedPoolName:      {supply.Burner, supply.Staking},
   304  		staking.NotBondedPoolName:   {supply.Burner, supply.Staking},
   305  		gov.ModuleName:              nil,
   306  		token.ModuleName:            {supply.Minter, supply.Burner},
   307  		dex.ModuleName:              nil,
   308  		order.ModuleName:            nil,
   309  		ammswap.ModuleName:          {supply.Minter, supply.Burner},
   310  		farm.ModuleName:             nil,
   311  		farm.YieldFarmingAccount:    nil,
   312  		farm.MintFarmingAccount:     {supply.Burner},
   313  		ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
   314  		erc20.ModuleName:            {authtypes.Minter, authtypes.Burner},
   315  		types.ModuleName:            nil,
   316  	}
   317  	accountKeeper := auth.NewAccountKeeper(legacyAmino, keys[authtypes.StoreKey], keys[mpt.StoreKey], subspace(authtypes.ModuleName), fbexchain.ProtoAccount)
   318  	blockedAddrs := make(map[string]bool)
   319  	for acc := range maccPerms {
   320  		blockedAddrs[authtypes.NewModuleAddress(acc).String()] = true
   321  	}
   322  	bankKeeper := bank.NewBaseKeeperWithMarshal(
   323  		&accountKeeper, &appCodec, subspace(bank.ModuleName), blockedAddrs,
   324  	)
   325  	bankKeeper.SetSendEnabled(ctx, true)
   326  
   327  	supplyKeeper := supply.NewKeeper(
   328  		legacyAmino, keys[supply.StoreKey], &accountKeeper, bank.NewBankKeeperAdapter(bankKeeper), maccPerms,
   329  	)
   330  	stakingKeeper := stakingkeeper.NewKeeper(
   331  		&appCodec,
   332  		keys[stakingtypes.StoreKey],
   333  		supplyKeeper,
   334  		subspace(stakingtypes.ModuleName),
   335  	)
   336  	stakingKeeper.SetParams(ctx, TestingStakeParams)
   337  
   338  	distKeeper := distributionkeeper.NewKeeper(
   339  		legacyAmino,
   340  		keys[distributiontypes.StoreKey],
   341  		subspace(distributiontypes.ModuleName),
   342  		stakingKeeper,
   343  		supplyKeeper,
   344  		authtypes.FeeCollectorName,
   345  		blockedAddrs,
   346  	)
   347  	distKeeper.SetParams(ctx, distributiontypes.DefaultParams())
   348  	stakingKeeper.SetHooks(distKeeper.Hooks())
   349  
   350  	// set genesis items required for distribution
   351  	distKeeper.SetFeePool(ctx, distributiontypes.InitialFeePool())
   352  
   353  	upgradeKeeper := upgradekeeper.NewKeeper(
   354  		map[int64]bool{},
   355  		keys[upgradetypes.StoreKey],
   356  		legacyAmino,
   357  	)
   358  
   359  	faucet := NewTestFaucet(t, ctx, bankKeeper, supplyKeeper, mint.ModuleName, sdk.NewCoin("stake", sdk.NewInt(100_000_000_000)))
   360  
   361  	// set some funds ot pay out validatores, based on code from:
   362  	// https://github.com/fibonacci-chain/fbc/libs/cosmos-sdk/blob/fea231556aee4d549d7551a6190389c4328194eb/x/distribution/keeper/keeper_test.go#L50-L57
   363  	distrAcc := distKeeper.GetDistributionAccount(ctx)
   364  	faucet.Fund(ctx, distrAcc.GetAddress(), sdk.NewCoin("stake", sdk.NewInt(2000000)))
   365  
   366  	supplyKeeper.SetModuleAccount(ctx, distrAcc)
   367  
   368  	capabilityKeeper := capabilitykeeper.NewKeeper(
   369  		&appCodec,
   370  		keys[capabilitytypes.StoreKey],
   371  		memKeys[capabilitytypes.MemStoreKey],
   372  	)
   373  	scopedIBCKeeper := capabilityKeeper.ScopeToModule(ibchost.ModuleName)
   374  	scopedWasmKeeper := capabilityKeeper.ScopeToModule(types.ModuleName)
   375  
   376  	ibcKeeper := ibckeeper.NewKeeper(
   377  		&appCodec,
   378  		keys[ibchost.StoreKey],
   379  		subspace(ibchost.ModuleName),
   380  		stakingKeeper,
   381  		upgradeKeeper,
   382  		&scopedIBCKeeper,
   383  		encodingConfig.InterfaceRegistry,
   384  	)
   385  
   386  	router := baseapp.NewRouter()
   387  	bh := bank.NewHandler(bankKeeper)
   388  	router.AddRoute(bank.RouterKey, bh)
   389  	sh := staking.NewHandler(stakingKeeper)
   390  	router.AddRoute(stakingtypes.RouterKey, sh)
   391  	dh := distribution.NewHandler(distKeeper)
   392  	router.AddRoute(distributiontypes.RouterKey, dh)
   393  
   394  	querier := baseapp.NewGRPCQueryRouter()
   395  	querier.SetInterfaceRegistry(encodingConfig.InterfaceRegistry)
   396  	msgRouter := baseapp.NewMsgServiceRouter()
   397  	msgRouter.SetInterfaceRegistry(encodingConfig.InterfaceRegistry)
   398  
   399  	cfg := sdk.GetConfig()
   400  	cfg.SetAddressVerifier(types.VerifyAddressLen())
   401  
   402  	keeper := NewKeeper(
   403  		&appCodec,
   404  		keys[types.StoreKey],
   405  		subspace(types.ModuleName),
   406  		&accountKeeper,
   407  		bank.NewBankKeeperAdapter(bankKeeper),
   408  		ibcKeeper.ChannelKeeper,
   409  		&ibcKeeper.PortKeeper,
   410  		scopedWasmKeeper,
   411  		wasmtesting.MockIBCTransferKeeper{},
   412  		msgRouter,
   413  		querier,
   414  		tempDir,
   415  		wasmConfig,
   416  		supportedFeatures,
   417  		opts...,
   418  	)
   419  	keeper.SetParams(ctx, types.TestParams())
   420  	// add wasm handler so we can loop-back (contracts calling contracts)
   421  	contractKeeper := NewDefaultPermissionKeeper(&keeper)
   422  	router.AddRoute(types.RouterKey, TestHandler(contractKeeper))
   423  
   424  	am := module.NewManager( // minimal module set that we use for message/ query tests
   425  		bank.NewAppModule(bankKeeper, accountKeeper, supplyKeeper),
   426  		staking.NewAppModule(stakingKeeper, accountKeeper, supplyKeeper),
   427  		distribution.NewAppModule(distKeeper, supplyKeeper),
   428  		supply.NewAppModule(supplyKeeper, accountKeeper),
   429  	)
   430  	configurator := module.NewConfigurator(legacyAmino, msgRouter, querier)
   431  	am.RegisterServices(configurator)
   432  	types.RegisterMsgServer(msgRouter, NewMsgServerImpl(NewDefaultPermissionKeeper(keeper)))
   433  	types.RegisterQueryServer(querier, NewGrpcQuerier(appCodec, keys[types.ModuleName], keeper, keeper.queryGasLimit))
   434  
   435  	govRouter := gov.NewRouter().
   436  		AddRoute(govtypes.RouterKey, govtypes.ProposalHandler).
   437  		AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(&paramsKeeper)).
   438  		AddRoute(distributiontypes.RouterKey, distribution.NewDistributionProposalHandler(distKeeper))
   439  	//AddRoute(types.RouterKey, NewWasmProposalHandler(&keeper, types.EnableAllProposals))
   440  
   441  	govProposalHandlerRouter := govkeeper.NewProposalHandlerRouter()
   442  	govProposalHandlerRouter.AddRoute(params.RouterKey, &paramsKeeper)
   443  
   444  	govKeeper := gov.NewKeeper(
   445  		legacyAmino, keys[govtypes.StoreKey], paramsKeeper, subspace(govtypes.ModuleName),
   446  		supplyKeeper, &stakingKeeper, gov.DefaultParamspace, govRouter,
   447  		bankKeeper, govProposalHandlerRouter, auth.FeeCollectorName,
   448  	)
   449  
   450  	//govKeeper.SetProposalID(ctx, govtypes.DefaultStartingProposalID)
   451  	//govKeeper.SetDepositParams(ctx, govtypes.DefaultDepositParams())
   452  	//govKeeper.SetVotingParams(ctx, govtypes.DefaultVotingParams())
   453  	//govKeeper.SetTallyParams(ctx, govtypes.DefaultTallyParams())
   454  
   455  	keepers := TestKeepers{
   456  		AccountKeeper:  accountKeeper,
   457  		StakingKeeper:  stakingKeeper,
   458  		supplyKeepr:    supplyKeeper,
   459  		DistKeeper:     distKeeper,
   460  		ContractKeeper: contractKeeper,
   461  		WasmKeeper:     &keeper,
   462  		BankKeeper:     bankKeeper,
   463  		GovKeeper:      govKeeper,
   464  		IBCKeeper:      ibcKeeper,
   465  		Router:         router,
   466  		EncodingConfig: encodingConfig,
   467  		Faucet:         faucet,
   468  		MultiStore:     ms,
   469  	}
   470  	return ctx, keepers
   471  }
   472  
   473  // TestHandler returns a wasm handler for tests (to avoid circular imports)
   474  func TestHandler(k types.ContractOpsKeeper) sdk.Handler {
   475  	return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
   476  		ctx = *ctx.SetEventManager(sdk.NewEventManager())
   477  		switch msg := msg.(type) {
   478  		case *types.MsgStoreCode:
   479  			return handleStoreCode(ctx, k, msg)
   480  		case *types.MsgInstantiateContract:
   481  			return handleInstantiate(ctx, k, msg)
   482  		case *types.MsgExecuteContract:
   483  			return handleExecute(ctx, k, msg)
   484  		default:
   485  			errMsg := fmt.Sprintf("unrecognized wasm message type: %T", msg)
   486  			return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg)
   487  		}
   488  	}
   489  }
   490  
   491  func handleStoreCode(ctx sdk.Context, k types.ContractOpsKeeper, msg *types.MsgStoreCode) (*sdk.Result, error) {
   492  	senderAddr, err := sdk.AccAddressFromBech32(msg.Sender)
   493  	if err != nil {
   494  		return nil, sdkerrors.Wrap(err, "sender")
   495  	}
   496  	codeID, err := k.Create(ctx, senderAddr, msg.WASMByteCode, msg.InstantiatePermission)
   497  	if err != nil {
   498  		return nil, err
   499  	}
   500  
   501  	return &sdk.Result{
   502  		Data:   []byte(fmt.Sprintf("%d", codeID)),
   503  		Events: ctx.EventManager().Events(),
   504  	}, nil
   505  }
   506  
   507  func handleInstantiate(ctx sdk.Context, k types.ContractOpsKeeper, msg *types.MsgInstantiateContract) (*sdk.Result, error) {
   508  	senderAddr, err := sdk.AccAddressFromBech32(msg.Sender)
   509  	if err != nil {
   510  		return nil, sdkerrors.Wrap(err, "sender")
   511  	}
   512  	var adminAddr sdk.AccAddress
   513  	if msg.Admin != "" {
   514  		if adminAddr, err = sdk.AccAddressFromBech32(msg.Admin); err != nil {
   515  			return nil, sdkerrors.Wrap(err, "admin")
   516  		}
   517  	}
   518  
   519  	contractAddr, _, err := k.Instantiate(ctx, msg.CodeID, senderAddr, adminAddr, msg.Msg, msg.Label, sdk.CoinAdaptersToCoins(msg.Funds))
   520  	if err != nil {
   521  		return nil, err
   522  	}
   523  
   524  	return &sdk.Result{
   525  		Data:   contractAddr,
   526  		Events: ctx.EventManager().Events(),
   527  	}, nil
   528  }
   529  
   530  func handleExecute(ctx sdk.Context, k types.ContractOpsKeeper, msg *types.MsgExecuteContract) (*sdk.Result, error) {
   531  	senderAddr, err := sdk.AccAddressFromBech32(msg.Sender)
   532  	if err != nil {
   533  		return nil, sdkerrors.Wrap(err, "sender")
   534  	}
   535  	contractAddr, err := sdk.AccAddressFromBech32(msg.Contract)
   536  	if err != nil {
   537  		return nil, sdkerrors.Wrap(err, "admin")
   538  	}
   539  	data, err := k.Execute(ctx, contractAddr, senderAddr, msg.Msg, sdk.CoinAdaptersToCoins(msg.Funds))
   540  	if err != nil {
   541  		return nil, err
   542  	}
   543  
   544  	return &sdk.Result{
   545  		Data:   data,
   546  		Events: ctx.EventManager().Events(),
   547  	}, nil
   548  }
   549  
   550  var PubKeyCache = make(map[string]crypto.PubKey)
   551  
   552  func RandomAccountAddress(_ testing.TB) sdk.AccAddress {
   553  	_, pub, addr := keyPubAddr()
   554  	PubKeyCache[addr.String()] = pub
   555  	return addr
   556  }
   557  
   558  func RandomBech32AccountAddress(t testing.TB) string {
   559  	return RandomAccountAddress(t).String()
   560  }
   561  
   562  type ExampleContract struct {
   563  	InitialAmount sdk.Coins
   564  	Creator       crypto.PrivKey
   565  	CreatorAddr   sdk.AccAddress
   566  	CodeID        uint64
   567  }
   568  
   569  func StoreHackatomExampleContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) ExampleContract {
   570  	return StoreExampleContract(t, ctx, keepers, "./testdata/hackatom.wasm")
   571  }
   572  
   573  func StoreBurnerExampleContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) ExampleContract {
   574  	return StoreExampleContract(t, ctx, keepers, "./testdata/burner.wasm")
   575  }
   576  
   577  func StoreIBCReflectContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) ExampleContract {
   578  	return StoreExampleContract(t, ctx, keepers, "./testdata/ibc_reflect.wasm")
   579  }
   580  
   581  func StoreReflectContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) uint64 {
   582  	_, _, creatorAddr := keyPubAddr()
   583  	codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, testdata.ReflectContractWasm(), nil)
   584  	require.NoError(t, err)
   585  	return codeID
   586  }
   587  
   588  func StoreExampleContract(t testing.TB, ctx sdk.Context, keepers TestKeepers, wasmFile string) ExampleContract {
   589  	anyAmount := sdk.NewCoins(sdk.NewInt64Coin("denom", 1000))
   590  	creator, _, creatorAddr := keyPubAddr()
   591  	fundAccounts(t, ctx, keepers.AccountKeeper, keepers.BankKeeper, keepers.supplyKeepr, creatorAddr, anyAmount)
   592  
   593  	wasmCode, err := ioutil.ReadFile(wasmFile)
   594  	require.NoError(t, err)
   595  
   596  	codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, wasmCode, nil)
   597  	require.NoError(t, err)
   598  	return ExampleContract{anyAmount, creator, creatorAddr, codeID}
   599  }
   600  
   601  var wasmIdent = []byte("\x00\x61\x73\x6D")
   602  
   603  type ExampleContractInstance struct {
   604  	ExampleContract
   605  	Contract sdk.AccAddress
   606  }
   607  
   608  // SeedNewContractInstance sets the mock wasmerEngine in keeper and calls store + instantiate to init the contract's metadata
   609  func SeedNewContractInstance(t testing.TB, ctx sdk.Context, keepers TestKeepers, mock types.WasmerEngine) ExampleContractInstance {
   610  	t.Helper()
   611  	exampleContract := StoreRandomContract(t, ctx, keepers, mock)
   612  	contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, exampleContract.CodeID, exampleContract.CreatorAddr, exampleContract.CreatorAddr, []byte(`{}`), "", nil)
   613  	require.NoError(t, err)
   614  	return ExampleContractInstance{
   615  		ExampleContract: exampleContract,
   616  		Contract:        contractAddr,
   617  	}
   618  }
   619  
   620  // StoreRandomContract sets the mock wasmerEngine in keeper and calls store
   621  func StoreRandomContract(t testing.TB, ctx sdk.Context, keepers TestKeepers, mock types.WasmerEngine) ExampleContract {
   622  	return StoreRandomContractWithAccessConfig(t, ctx, keepers, mock, nil)
   623  }
   624  
   625  func StoreRandomContractWithAccessConfig(
   626  	t testing.TB, ctx sdk.Context,
   627  	keepers TestKeepers,
   628  	mock types.WasmerEngine,
   629  	cfg *types.AccessConfig,
   630  ) ExampleContract {
   631  	t.Helper()
   632  	anyAmount := sdk.NewCoins(sdk.NewInt64Coin("denom", 1000))
   633  	creator, _, creatorAddr := keyPubAddr()
   634  	fundAccounts(t, ctx, keepers.AccountKeeper, keepers.BankKeeper, keepers.supplyKeepr, creatorAddr, anyAmount)
   635  	keepers.WasmKeeper.wasmVM = mock
   636  	wasmCode := append(wasmIdent, rand.Bytes(10)...) //nolint:gocritic
   637  	codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, wasmCode, cfg)
   638  	require.NoError(t, err)
   639  	exampleContract := ExampleContract{InitialAmount: anyAmount, Creator: creator, CreatorAddr: creatorAddr, CodeID: codeID}
   640  	return exampleContract
   641  }
   642  
   643  type HackatomExampleInstance struct {
   644  	ExampleContract
   645  	Contract        sdk.AccAddress
   646  	Verifier        crypto.PrivKey
   647  	VerifierAddr    sdk.AccAddress
   648  	Beneficiary     crypto.PrivKey
   649  	BeneficiaryAddr sdk.AccAddress
   650  }
   651  
   652  // InstantiateHackatomExampleContract load and instantiate the "./testdata/hackatom.wasm" contract
   653  func InstantiateHackatomExampleContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) HackatomExampleInstance {
   654  	contract := StoreHackatomExampleContract(t, ctx, keepers)
   655  
   656  	verifier, _, verifierAddr := keyPubAddr()
   657  	fundAccounts(t, ctx, keepers.AccountKeeper, keepers.BankKeeper, keepers.supplyKeepr, verifierAddr, contract.InitialAmount)
   658  
   659  	beneficiary, _, beneficiaryAddr := keyPubAddr()
   660  	initMsgBz := HackatomExampleInitMsg{
   661  		Verifier:    verifierAddr,
   662  		Beneficiary: beneficiaryAddr,
   663  	}.GetBytes(t)
   664  	initialAmount := sdk.NewCoins(sdk.NewInt64Coin("denom", 100))
   665  
   666  	adminAddr := contract.CreatorAddr
   667  	contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, contract.CodeID, contract.CreatorAddr, adminAddr, initMsgBz, "demo contract to query", initialAmount)
   668  	require.NoError(t, err)
   669  	return HackatomExampleInstance{
   670  		ExampleContract: contract,
   671  		Contract:        contractAddr,
   672  		Verifier:        verifier,
   673  		VerifierAddr:    verifierAddr,
   674  		Beneficiary:     beneficiary,
   675  		BeneficiaryAddr: beneficiaryAddr,
   676  	}
   677  }
   678  
   679  type HackatomExampleInitMsg struct {
   680  	Verifier    sdk.AccAddress `json:"verifier"`
   681  	Beneficiary sdk.AccAddress `json:"beneficiary"`
   682  }
   683  
   684  func (m HackatomExampleInitMsg) GetBytes(t testing.TB) []byte {
   685  	initMsgBz, err := json.Marshal(m)
   686  	require.NoError(t, err)
   687  	return initMsgBz
   688  }
   689  
   690  type IBCReflectExampleInstance struct {
   691  	Contract      sdk.AccAddress
   692  	Admin         sdk.AccAddress
   693  	CodeID        uint64
   694  	ReflectCodeID uint64
   695  }
   696  
   697  // InstantiateIBCReflectContract load and instantiate the "./testdata/ibc_reflect.wasm" contract
   698  func InstantiateIBCReflectContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) IBCReflectExampleInstance {
   699  	reflectID := StoreReflectContract(t, ctx, keepers)
   700  	ibcReflectID := StoreIBCReflectContract(t, ctx, keepers).CodeID
   701  
   702  	initMsgBz := IBCReflectInitMsg{
   703  		ReflectCodeID: reflectID,
   704  	}.GetBytes(t)
   705  	adminAddr := RandomAccountAddress(t)
   706  
   707  	contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, ibcReflectID, adminAddr, adminAddr, initMsgBz, "ibc-reflect-factory", nil)
   708  	require.NoError(t, err)
   709  	return IBCReflectExampleInstance{
   710  		Admin:         adminAddr,
   711  		Contract:      contractAddr,
   712  		CodeID:        ibcReflectID,
   713  		ReflectCodeID: reflectID,
   714  	}
   715  }
   716  
   717  type IBCReflectInitMsg struct {
   718  	ReflectCodeID uint64 `json:"reflect_code_id"`
   719  }
   720  
   721  func (m IBCReflectInitMsg) GetBytes(t testing.TB) []byte {
   722  	initMsgBz, err := json.Marshal(m)
   723  	require.NoError(t, err)
   724  	return initMsgBz
   725  }
   726  
   727  type BurnerExampleInitMsg struct {
   728  	Payout sdk.AccAddress `json:"payout"`
   729  }
   730  
   731  func (m BurnerExampleInitMsg) GetBytes(t testing.TB) []byte {
   732  	initMsgBz, err := json.Marshal(m)
   733  	require.NoError(t, err)
   734  	return initMsgBz
   735  }
   736  
   737  func fundAccounts(t testing.TB, ctx sdk.Context, am authkeeper.AccountKeeper, bank bank.Keeper, supplyKeeper supply.Keeper, addr sdk.AccAddress, coins sdk.Coins) {
   738  	acc := am.NewAccountWithAddress(ctx, addr)
   739  	am.SetAccount(ctx, acc)
   740  	NewTestFaucet(t, ctx, bank, supplyKeeper, mint.ModuleName, coins...).Fund(ctx, addr, coins...)
   741  }
   742  
   743  var keyCounter uint64
   744  
   745  // we need to make this deterministic (same every test run), as encoded address size and thus gas cost,
   746  // depends on the actual bytes (due to ugly CanonicalAddress encoding)
   747  func keyPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.AccAddress) {
   748  	keyCounter++
   749  	seed := make([]byte, 8)
   750  	binary.BigEndian.PutUint64(seed, keyCounter)
   751  
   752  	key := ed25519.GenPrivKeyFromSecret(seed)
   753  	pub := key.PubKey()
   754  	addr := sdk.AccAddress(pub.Address())
   755  	return key, pub, addr
   756  }