package keeper import ( "encoding/binary" "encoding/json" "fmt" "io/ioutil" "testing" "time" "github.com/CosmWasm/wasmd/x/wasm/keeper/testdata" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/std" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/auth" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" "github.com/cosmos/cosmos-sdk/x/bank" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/capability" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" "github.com/cosmos/cosmos-sdk/x/crisis" crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" "github.com/cosmos/cosmos-sdk/x/distribution" distrclient "github.com/cosmos/cosmos-sdk/x/distribution/client" distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/cosmos/cosmos-sdk/x/evidence" evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" "github.com/cosmos/cosmos-sdk/x/feegrant" "github.com/cosmos/cosmos-sdk/x/gov" govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/mint" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/cosmos/cosmos-sdk/x/params" paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" paramproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal" "github.com/cosmos/cosmos-sdk/x/slashing" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/cosmos/cosmos-sdk/x/staking" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/cosmos-sdk/x/upgrade" upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/cosmos/ibc-go/v3/modules/apps/transfer" ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" ibc "github.com/cosmos/ibc-go/v3/modules/core" ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/rand" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" dbm "github.com/tendermint/tm-db" wasmappparams "github.com/CosmWasm/wasmd/app/params" "github.com/CosmWasm/wasmd/x/wasm/keeper/wasmtesting" "github.com/CosmWasm/wasmd/x/wasm/types" ) var moduleBasics = module.NewBasicManager( auth.AppModuleBasic{}, bank.AppModuleBasic{}, capability.AppModuleBasic{}, staking.AppModuleBasic{}, mint.AppModuleBasic{}, distribution.AppModuleBasic{}, gov.NewAppModuleBasic( paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, ), params.AppModuleBasic{}, crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, ibc.AppModuleBasic{}, upgrade.AppModuleBasic{}, evidence.AppModuleBasic{}, transfer.AppModuleBasic{}, ) func MakeTestCodec(t testing.TB) codec.Codec { return MakeEncodingConfig(t).Marshaler } func MakeEncodingConfig(_ testing.TB) wasmappparams.EncodingConfig { encodingConfig := wasmappparams.MakeEncodingConfig() amino := encodingConfig.Amino interfaceRegistry := encodingConfig.InterfaceRegistry std.RegisterInterfaces(interfaceRegistry) std.RegisterLegacyAminoCodec(amino) moduleBasics.RegisterLegacyAminoCodec(amino) moduleBasics.RegisterInterfaces(interfaceRegistry) // add wasmd types types.RegisterInterfaces(interfaceRegistry) types.RegisterLegacyAminoCodec(amino) return encodingConfig } var TestingStakeParams = stakingtypes.Params{ UnbondingTime: 100, MaxValidators: 10, MaxEntries: 10, HistoricalEntries: 10, BondDenom: "stake", } type TestFaucet struct { t testing.TB bankKeeper bankkeeper.Keeper sender sdk.AccAddress balance sdk.Coins minterModuleName string } func NewTestFaucet(t testing.TB, ctx sdk.Context, bankKeeper bankkeeper.Keeper, minterModuleName string, initialAmount ...sdk.Coin) *TestFaucet { require.NotEmpty(t, initialAmount) r := &TestFaucet{t: t, bankKeeper: bankKeeper, minterModuleName: minterModuleName} _, _, addr := keyPubAddr() r.sender = addr r.Mint(ctx, addr, initialAmount...) r.balance = initialAmount return r } func (f *TestFaucet) Mint(parentCtx sdk.Context, addr sdk.AccAddress, amounts ...sdk.Coin) { require.NotEmpty(f.t, amounts) ctx := parentCtx.WithEventManager(sdk.NewEventManager()) // discard all faucet related events err := f.bankKeeper.MintCoins(ctx, f.minterModuleName, amounts) require.NoError(f.t, err) err = f.bankKeeper.SendCoinsFromModuleToAccount(ctx, f.minterModuleName, addr, amounts) require.NoError(f.t, err) f.balance = f.balance.Add(amounts...) } func (f *TestFaucet) Fund(parentCtx sdk.Context, receiver sdk.AccAddress, amounts ...sdk.Coin) { require.NotEmpty(f.t, amounts) // ensure faucet is always filled if !f.balance.IsAllGTE(amounts) { f.Mint(parentCtx, f.sender, amounts...) } ctx := parentCtx.WithEventManager(sdk.NewEventManager()) // discard all faucet related events err := f.bankKeeper.SendCoins(ctx, f.sender, receiver, amounts) require.NoError(f.t, err) f.balance = f.balance.Sub(amounts) } func (f *TestFaucet) NewFundedAccount(ctx sdk.Context, amounts ...sdk.Coin) sdk.AccAddress { _, _, addr := keyPubAddr() f.Fund(ctx, addr, amounts...) return addr } type TestKeepers struct { AccountKeeper authkeeper.AccountKeeper StakingKeeper stakingkeeper.Keeper DistKeeper distributionkeeper.Keeper BankKeeper bankkeeper.Keeper GovKeeper govkeeper.Keeper ContractKeeper types.ContractOpsKeeper WasmKeeper *Keeper IBCKeeper *ibckeeper.Keeper Router *baseapp.Router EncodingConfig wasmappparams.EncodingConfig Faucet *TestFaucet MultiStore sdk.CommitMultiStore } // CreateDefaultTestInput common settings for CreateTestInput func CreateDefaultTestInput(t testing.TB) (sdk.Context, TestKeepers) { return CreateTestInput(t, false, "staking") } // CreateTestInput encoders can be nil to accept the defaults, or set it to override some of the message handlers (like default) func CreateTestInput(t testing.TB, isCheckTx bool, supportedFeatures string, opts ...Option) (sdk.Context, TestKeepers) { // Load default wasm config return createTestInput(t, isCheckTx, supportedFeatures, types.DefaultWasmConfig(), dbm.NewMemDB(), opts...) } // encoders can be nil to accept the defaults, or set it to override some of the message handlers (like default) func createTestInput( t testing.TB, isCheckTx bool, supportedFeatures string, wasmConfig types.WasmConfig, db dbm.DB, opts ...Option, ) (sdk.Context, TestKeepers) { tempDir := t.TempDir() keys := sdk.NewKVStoreKeys( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, minttypes.StoreKey, distributiontypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, feegrant.StoreKey, authzkeeper.StoreKey, types.StoreKey, ) ms := store.NewCommitMultiStore(db) for _, v := range keys { ms.MountStoreWithDB(v, sdk.StoreTypeIAVL, db) } tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) for _, v := range tkeys { ms.MountStoreWithDB(v, sdk.StoreTypeTransient, db) } memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) for _, v := range memKeys { ms.MountStoreWithDB(v, sdk.StoreTypeMemory, db) } require.NoError(t, ms.LoadLatestVersion()) ctx := sdk.NewContext(ms, tmproto.Header{ Height: 1234567, Time: time.Date(2020, time.April, 22, 12, 0, 0, 0, time.UTC), }, isCheckTx, log.NewNopLogger()) ctx = types.WithTXCounter(ctx, 0) encodingConfig := MakeEncodingConfig(t) appCodec, legacyAmino := encodingConfig.Marshaler, encodingConfig.Amino paramsKeeper := paramskeeper.NewKeeper( appCodec, legacyAmino, keys[paramstypes.StoreKey], tkeys[paramstypes.TStoreKey], ) for _, m := range []string{ authtypes.ModuleName, banktypes.ModuleName, stakingtypes.ModuleName, minttypes.ModuleName, distributiontypes.ModuleName, slashingtypes.ModuleName, crisistypes.ModuleName, ibctransfertypes.ModuleName, capabilitytypes.ModuleName, ibchost.ModuleName, govtypes.ModuleName, types.ModuleName, } { paramsKeeper.Subspace(m) } subspace := func(m string) paramstypes.Subspace { r, ok := paramsKeeper.GetSubspace(m) require.True(t, ok) return r } maccPerms := map[string][]string{ // module account permissions authtypes.FeeCollectorName: nil, distributiontypes.ModuleName: nil, minttypes.ModuleName: {authtypes.Minter}, stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, govtypes.ModuleName: {authtypes.Burner}, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, types.ModuleName: {authtypes.Burner}, } accountKeeper := authkeeper.NewAccountKeeper( appCodec, keys[authtypes.StoreKey], // target store subspace(authtypes.ModuleName), authtypes.ProtoBaseAccount, // prototype maccPerms, ) blockedAddrs := make(map[string]bool) for acc := range maccPerms { blockedAddrs[authtypes.NewModuleAddress(acc).String()] = true } bankKeeper := bankkeeper.NewBaseKeeper( appCodec, keys[banktypes.StoreKey], accountKeeper, subspace(banktypes.ModuleName), blockedAddrs, ) bankKeeper.SetParams(ctx, banktypes.DefaultParams()) stakingKeeper := stakingkeeper.NewKeeper( appCodec, keys[stakingtypes.StoreKey], accountKeeper, bankKeeper, nil, // TODO initialize wormhole keeper subspace(stakingtypes.ModuleName), ) stakingKeeper.SetParams(ctx, TestingStakeParams) distKeeper := distributionkeeper.NewKeeper( appCodec, keys[distributiontypes.StoreKey], subspace(distributiontypes.ModuleName), accountKeeper, bankKeeper, stakingKeeper, authtypes.FeeCollectorName, nil, ) distKeeper.SetParams(ctx, distributiontypes.DefaultParams()) stakingKeeper.SetHooks(distKeeper.Hooks()) // set genesis items required for distribution distKeeper.SetFeePool(ctx, distributiontypes.InitialFeePool()) upgradeKeeper := upgradekeeper.NewKeeper( map[int64]bool{}, keys[upgradetypes.StoreKey], appCodec, tempDir, nil, ) faucet := NewTestFaucet(t, ctx, bankKeeper, minttypes.ModuleName, sdk.NewCoin("stake", sdk.NewInt(100_000_000_000))) // set some funds ot pay out validatores, based on code from: // https://github.com/cosmos/cosmos-sdk/blob/fea231556aee4d549d7551a6190389c4328194eb/x/distribution/keeper/keeper_test.go#L50-L57 distrAcc := distKeeper.GetDistributionAccount(ctx) faucet.Fund(ctx, distrAcc.GetAddress(), sdk.NewCoin("stake", sdk.NewInt(2000000))) accountKeeper.SetModuleAccount(ctx, distrAcc) capabilityKeeper := capabilitykeeper.NewKeeper( appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey], ) scopedIBCKeeper := capabilityKeeper.ScopeToModule(ibchost.ModuleName) scopedWasmKeeper := capabilityKeeper.ScopeToModule(types.ModuleName) ibcKeeper := ibckeeper.NewKeeper( appCodec, keys[ibchost.StoreKey], subspace(ibchost.ModuleName), stakingKeeper, upgradeKeeper, scopedIBCKeeper, ) router := baseapp.NewRouter() bh := bank.NewHandler(bankKeeper) router.AddRoute(sdk.NewRoute(banktypes.RouterKey, bh)) sh := staking.NewHandler(stakingKeeper) router.AddRoute(sdk.NewRoute(stakingtypes.RouterKey, sh)) dh := distribution.NewHandler(distKeeper) router.AddRoute(sdk.NewRoute(distributiontypes.RouterKey, dh)) querier := baseapp.NewGRPCQueryRouter() querier.SetInterfaceRegistry(encodingConfig.InterfaceRegistry) msgRouter := baseapp.NewMsgServiceRouter() msgRouter.SetInterfaceRegistry(encodingConfig.InterfaceRegistry) cfg := sdk.GetConfig() cfg.SetAddressVerifier(types.VerifyAddressLen()) keeper := NewKeeper( appCodec, keys[types.StoreKey], subspace(types.ModuleName), accountKeeper, bankKeeper, stakingKeeper, distKeeper, ibcKeeper.ChannelKeeper, &ibcKeeper.PortKeeper, scopedWasmKeeper, wasmtesting.MockIBCTransferKeeper{}, msgRouter, querier, tempDir, wasmConfig, supportedFeatures, opts..., ) keeper.SetParams(ctx, types.DefaultParams()) // add wasm handler so we can loop-back (contracts calling contracts) contractKeeper := NewDefaultPermissionKeeper(&keeper) router.AddRoute(sdk.NewRoute(types.RouterKey, TestHandler(contractKeeper))) am := module.NewManager( // minimal module set that we use for message/ query tests bank.NewAppModule(appCodec, bankKeeper, accountKeeper), // TODO initialize wormhole keeper staking.NewAppModule(appCodec, stakingKeeper, accountKeeper, bankKeeper, nil), distribution.NewAppModule(appCodec, distKeeper, accountKeeper, bankKeeper, stakingKeeper), ) am.RegisterServices(module.NewConfigurator(appCodec, msgRouter, querier)) types.RegisterMsgServer(msgRouter, NewMsgServerImpl(NewDefaultPermissionKeeper(keeper))) types.RegisterQueryServer(querier, NewGrpcQuerier(appCodec, keys[types.ModuleName], keeper, keeper.queryGasLimit)) govRouter := govtypes.NewRouter(). AddRoute(govtypes.RouterKey, govtypes.ProposalHandler). AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(paramsKeeper)). AddRoute(distributiontypes.RouterKey, distribution.NewCommunityPoolSpendProposalHandler(distKeeper)). AddRoute(types.RouterKey, NewWasmProposalHandler(&keeper, types.EnableAllProposals)) govKeeper := govkeeper.NewKeeper( appCodec, keys[govtypes.StoreKey], subspace(govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable()), accountKeeper, bankKeeper, stakingKeeper, govRouter, ) govKeeper.SetProposalID(ctx, govtypes.DefaultStartingProposalID) govKeeper.SetDepositParams(ctx, govtypes.DefaultDepositParams()) govKeeper.SetVotingParams(ctx, govtypes.DefaultVotingParams()) govKeeper.SetTallyParams(ctx, govtypes.DefaultTallyParams()) keepers := TestKeepers{ AccountKeeper: accountKeeper, StakingKeeper: stakingKeeper, DistKeeper: distKeeper, ContractKeeper: contractKeeper, WasmKeeper: &keeper, BankKeeper: bankKeeper, GovKeeper: govKeeper, IBCKeeper: ibcKeeper, Router: router, EncodingConfig: encodingConfig, Faucet: faucet, MultiStore: ms, } return ctx, keepers } // TestHandler returns a wasm handler for tests (to avoid circular imports) func TestHandler(k types.ContractOpsKeeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { case *types.MsgStoreCode: return handleStoreCode(ctx, k, msg) case *types.MsgInstantiateContract: return handleInstantiate(ctx, k, msg) case *types.MsgExecuteContract: return handleExecute(ctx, k, msg) default: errMsg := fmt.Sprintf("unrecognized wasm message type: %T", msg) return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg) } } } func handleStoreCode(ctx sdk.Context, k types.ContractOpsKeeper, msg *types.MsgStoreCode) (*sdk.Result, error) { senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { return nil, sdkerrors.Wrap(err, "sender") } codeID, err := k.Create(ctx, senderAddr, msg.WASMByteCode, msg.InstantiatePermission) if err != nil { return nil, err } return &sdk.Result{ Data: []byte(fmt.Sprintf("%d", codeID)), Events: ctx.EventManager().ABCIEvents(), }, nil } func handleInstantiate(ctx sdk.Context, k types.ContractOpsKeeper, msg *types.MsgInstantiateContract) (*sdk.Result, error) { senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { return nil, sdkerrors.Wrap(err, "sender") } var adminAddr sdk.AccAddress if msg.Admin != "" { if adminAddr, err = sdk.AccAddressFromBech32(msg.Admin); err != nil { return nil, sdkerrors.Wrap(err, "admin") } } contractAddr, _, err := k.Instantiate(ctx, msg.CodeID, senderAddr, adminAddr, msg.Msg, msg.Label, msg.Funds) if err != nil { return nil, err } return &sdk.Result{ Data: contractAddr, Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } func handleExecute(ctx sdk.Context, k types.ContractOpsKeeper, msg *types.MsgExecuteContract) (*sdk.Result, error) { senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { return nil, sdkerrors.Wrap(err, "sender") } contractAddr, err := sdk.AccAddressFromBech32(msg.Contract) if err != nil { return nil, sdkerrors.Wrap(err, "admin") } data, err := k.Execute(ctx, contractAddr, senderAddr, msg.Msg, msg.Funds) if err != nil { return nil, err } return &sdk.Result{ Data: data, Events: ctx.EventManager().Events().ToABCIEvents(), }, nil } func RandomAccountAddress(_ testing.TB) sdk.AccAddress { _, _, addr := keyPubAddr() return addr } func RandomBech32AccountAddress(t testing.TB) string { return RandomAccountAddress(t).String() } type ExampleContract struct { InitialAmount sdk.Coins Creator crypto.PrivKey CreatorAddr sdk.AccAddress CodeID uint64 } func StoreHackatomExampleContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) ExampleContract { return StoreExampleContract(t, ctx, keepers, "./testdata/hackatom.wasm") } func StoreBurnerExampleContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) ExampleContract { return StoreExampleContract(t, ctx, keepers, "./testdata/burner.wasm") } func StoreIBCReflectContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) ExampleContract { return StoreExampleContract(t, ctx, keepers, "./testdata/ibc_reflect.wasm") } func StoreReflectContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) uint64 { _, _, creatorAddr := keyPubAddr() codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, testdata.ReflectContractWasm(), nil) require.NoError(t, err) return codeID } func StoreExampleContract(t testing.TB, ctx sdk.Context, keepers TestKeepers, wasmFile string) ExampleContract { anyAmount := sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)) creator, _, creatorAddr := keyPubAddr() fundAccounts(t, ctx, keepers.AccountKeeper, keepers.BankKeeper, creatorAddr, anyAmount) wasmCode, err := ioutil.ReadFile(wasmFile) require.NoError(t, err) codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, wasmCode, nil) require.NoError(t, err) return ExampleContract{anyAmount, creator, creatorAddr, codeID} } var wasmIdent = []byte("\x00\x61\x73\x6D") type ExampleContractInstance struct { ExampleContract Contract sdk.AccAddress } // SeedNewContractInstance sets the mock wasmerEngine in keeper and calls store + instantiate to init the contract's metadata func SeedNewContractInstance(t testing.TB, ctx sdk.Context, keepers TestKeepers, mock types.WasmerEngine) ExampleContractInstance { t.Helper() exampleContract := StoreRandomContract(t, ctx, keepers, mock) contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, exampleContract.CodeID, exampleContract.CreatorAddr, exampleContract.CreatorAddr, []byte(`{}`), "", nil) require.NoError(t, err) return ExampleContractInstance{ ExampleContract: exampleContract, Contract: contractAddr, } } // StoreRandomContract sets the mock wasmerEngine in keeper and calls store func StoreRandomContract(t testing.TB, ctx sdk.Context, keepers TestKeepers, mock types.WasmerEngine) ExampleContract { return StoreRandomContractWithAccessConfig(t, ctx, keepers, mock, nil) } func StoreRandomContractWithAccessConfig( t testing.TB, ctx sdk.Context, keepers TestKeepers, mock types.WasmerEngine, cfg *types.AccessConfig, ) ExampleContract { t.Helper() anyAmount := sdk.NewCoins(sdk.NewInt64Coin("denom", 1000)) creator, _, creatorAddr := keyPubAddr() fundAccounts(t, ctx, keepers.AccountKeeper, keepers.BankKeeper, creatorAddr, anyAmount) keepers.WasmKeeper.wasmVM = mock wasmCode := append(wasmIdent, rand.Bytes(10)...) //nolint:gocritic codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, wasmCode, cfg) require.NoError(t, err) exampleContract := ExampleContract{InitialAmount: anyAmount, Creator: creator, CreatorAddr: creatorAddr, CodeID: codeID} return exampleContract } type HackatomExampleInstance struct { ExampleContract Contract sdk.AccAddress Verifier crypto.PrivKey VerifierAddr sdk.AccAddress Beneficiary crypto.PrivKey BeneficiaryAddr sdk.AccAddress } // InstantiateHackatomExampleContract load and instantiate the "./testdata/hackatom.wasm" contract func InstantiateHackatomExampleContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) HackatomExampleInstance { contract := StoreHackatomExampleContract(t, ctx, keepers) verifier, _, verifierAddr := keyPubAddr() fundAccounts(t, ctx, keepers.AccountKeeper, keepers.BankKeeper, verifierAddr, contract.InitialAmount) beneficiary, _, beneficiaryAddr := keyPubAddr() initMsgBz := HackatomExampleInitMsg{ Verifier: verifierAddr, Beneficiary: beneficiaryAddr, }.GetBytes(t) initialAmount := sdk.NewCoins(sdk.NewInt64Coin("denom", 100)) adminAddr := contract.CreatorAddr contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, contract.CodeID, contract.CreatorAddr, adminAddr, initMsgBz, "demo contract to query", initialAmount) require.NoError(t, err) return HackatomExampleInstance{ ExampleContract: contract, Contract: contractAddr, Verifier: verifier, VerifierAddr: verifierAddr, Beneficiary: beneficiary, BeneficiaryAddr: beneficiaryAddr, } } type HackatomExampleInitMsg struct { Verifier sdk.AccAddress `json:"verifier"` Beneficiary sdk.AccAddress `json:"beneficiary"` } func (m HackatomExampleInitMsg) GetBytes(t testing.TB) []byte { initMsgBz, err := json.Marshal(m) require.NoError(t, err) return initMsgBz } type IBCReflectExampleInstance struct { Contract sdk.AccAddress Admin sdk.AccAddress CodeID uint64 ReflectCodeID uint64 } // InstantiateIBCReflectContract load and instantiate the "./testdata/ibc_reflect.wasm" contract func InstantiateIBCReflectContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) IBCReflectExampleInstance { reflectID := StoreReflectContract(t, ctx, keepers) ibcReflectID := StoreIBCReflectContract(t, ctx, keepers).CodeID initMsgBz := IBCReflectInitMsg{ ReflectCodeID: reflectID, }.GetBytes(t) adminAddr := RandomAccountAddress(t) contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, ibcReflectID, adminAddr, adminAddr, initMsgBz, "ibc-reflect-factory", nil) require.NoError(t, err) return IBCReflectExampleInstance{ Admin: adminAddr, Contract: contractAddr, CodeID: ibcReflectID, ReflectCodeID: reflectID, } } type IBCReflectInitMsg struct { ReflectCodeID uint64 `json:"reflect_code_id"` } func (m IBCReflectInitMsg) GetBytes(t testing.TB) []byte { initMsgBz, err := json.Marshal(m) require.NoError(t, err) return initMsgBz } type BurnerExampleInitMsg struct { Payout sdk.AccAddress `json:"payout"` } func (m BurnerExampleInitMsg) GetBytes(t testing.TB) []byte { initMsgBz, err := json.Marshal(m) require.NoError(t, err) return initMsgBz } func fundAccounts(t testing.TB, ctx sdk.Context, am authkeeper.AccountKeeper, bank bankkeeper.Keeper, addr sdk.AccAddress, coins sdk.Coins) { acc := am.NewAccountWithAddress(ctx, addr) am.SetAccount(ctx, acc) NewTestFaucet(t, ctx, bank, minttypes.ModuleName, coins...).Fund(ctx, addr, coins...) } var keyCounter uint64 // we need to make this deterministic (same every test run), as encoded address size and thus gas cost, // depends on the actual bytes (due to ugly CanonicalAddress encoding) func keyPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.AccAddress) { keyCounter++ seed := make([]byte, 8) binary.BigEndian.PutUint64(seed, keyCounter) key := ed25519.GenPrivKeyFromSecret(seed) pub := key.PubKey() addr := sdk.AccAddress(pub.Address()) return key, pub, addr }