mirror of https://github.com/certusone/wasmd.git
580 lines
21 KiB
Go
580 lines
21 KiB
Go
package keeper
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/tendermint/tendermint/libs/rand"
|
|
"io/ioutil"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
|
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
|
params2 "github.com/cosmos/cosmos-sdk/simapp/params"
|
|
"github.com/cosmos/cosmos-sdk/std"
|
|
"github.com/cosmos/cosmos-sdk/store"
|
|
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
|
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"
|
|
"github.com/cosmos/cosmos-sdk/x/auth/tx"
|
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
"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"
|
|
"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"
|
|
transfer "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer"
|
|
ibctransfertypes "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types"
|
|
ibc "github.com/cosmos/cosmos-sdk/x/ibc/core"
|
|
ibchost "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host"
|
|
ibckeeper "github.com/cosmos/cosmos-sdk/x/ibc/core/keeper"
|
|
"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"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/tendermint/tendermint/crypto"
|
|
"github.com/tendermint/tendermint/crypto/ed25519"
|
|
"github.com/tendermint/tendermint/libs/log"
|
|
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
|
dbm "github.com/tendermint/tm-db"
|
|
)
|
|
|
|
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.T) codec.Marshaler {
|
|
return MakeEncodingConfig(t).Marshaler
|
|
}
|
|
|
|
func MakeEncodingConfig(_ *testing.T) params2.EncodingConfig {
|
|
amino := codec.NewLegacyAmino()
|
|
interfaceRegistry := codectypes.NewInterfaceRegistry()
|
|
marshaler := codec.NewProtoCodec(interfaceRegistry)
|
|
txCfg := tx.NewTxConfig(marshaler, tx.DefaultSignModes)
|
|
|
|
std.RegisterInterfaces(interfaceRegistry)
|
|
std.RegisterLegacyAminoCodec(amino)
|
|
|
|
ModuleBasics.RegisterLegacyAminoCodec(amino)
|
|
ModuleBasics.RegisterInterfaces(interfaceRegistry)
|
|
return params2.EncodingConfig{
|
|
InterfaceRegistry: interfaceRegistry,
|
|
Marshaler: marshaler,
|
|
TxConfig: txCfg,
|
|
Amino: amino,
|
|
}
|
|
}
|
|
|
|
var TestingStakeParams = stakingtypes.Params{
|
|
UnbondingTime: 100,
|
|
MaxValidators: 10,
|
|
MaxEntries: 10,
|
|
HistoricalEntries: 10,
|
|
BondDenom: "stake",
|
|
}
|
|
|
|
type TestKeepers struct {
|
|
AccountKeeper authkeeper.AccountKeeper
|
|
StakingKeeper stakingkeeper.Keeper
|
|
DistKeeper distributionkeeper.Keeper
|
|
BankKeeper bankkeeper.Keeper
|
|
GovKeeper govkeeper.Keeper
|
|
WasmKeeper *Keeper
|
|
IBCKeeper *ibckeeper.Keeper
|
|
}
|
|
|
|
// CreateDefaultTestInput common settings for CreateTestInput
|
|
func CreateDefaultTestInput(t *testing.T) (sdk.Context, TestKeepers) {
|
|
return CreateTestInput(t, false, "staking", nil, nil)
|
|
}
|
|
|
|
// encoders can be nil to accept the defaults, or set it to override some of the message handlers (like default)
|
|
func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, encoders *MessageEncoders, queriers *QueryPlugins) (sdk.Context, TestKeepers) {
|
|
tempDir := t.TempDir()
|
|
|
|
keyWasm := sdk.NewKVStoreKey(types.StoreKey)
|
|
keyAcc := sdk.NewKVStoreKey(authtypes.StoreKey)
|
|
keyBank := sdk.NewKVStoreKey(banktypes.StoreKey)
|
|
keyStaking := sdk.NewKVStoreKey(stakingtypes.StoreKey)
|
|
keyDistro := sdk.NewKVStoreKey(distributiontypes.StoreKey)
|
|
keyParams := sdk.NewKVStoreKey(paramstypes.StoreKey)
|
|
tkeyParams := sdk.NewTransientStoreKey(paramstypes.TStoreKey)
|
|
keyGov := sdk.NewKVStoreKey(govtypes.StoreKey)
|
|
keyIBC := sdk.NewKVStoreKey(ibchost.StoreKey)
|
|
keyCapability := sdk.NewKVStoreKey(capabilitytypes.StoreKey)
|
|
keyCapabilityTransient := storetypes.NewMemoryStoreKey(capabilitytypes.MemStoreKey)
|
|
|
|
db := dbm.NewMemDB()
|
|
ms := store.NewCommitMultiStore(db)
|
|
ms.MountStoreWithDB(keyWasm, sdk.StoreTypeIAVL, db)
|
|
ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db)
|
|
ms.MountStoreWithDB(keyBank, sdk.StoreTypeIAVL, db)
|
|
ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
|
|
ms.MountStoreWithDB(keyStaking, sdk.StoreTypeIAVL, db)
|
|
ms.MountStoreWithDB(keyDistro, sdk.StoreTypeIAVL, db)
|
|
ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
|
|
ms.MountStoreWithDB(keyGov, sdk.StoreTypeIAVL, db)
|
|
ms.MountStoreWithDB(keyIBC, sdk.StoreTypeIAVL, db)
|
|
ms.MountStoreWithDB(keyCapability, sdk.StoreTypeIAVL, db)
|
|
ms.MountStoreWithDB(keyCapabilityTransient, 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())
|
|
encodingConfig := MakeEncodingConfig(t)
|
|
appCodec, legacyAmino := encodingConfig.Marshaler, encodingConfig.Amino
|
|
|
|
paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, keyParams, tkeyParams)
|
|
paramsKeeper.Subspace(authtypes.ModuleName)
|
|
paramsKeeper.Subspace(banktypes.ModuleName)
|
|
paramsKeeper.Subspace(stakingtypes.ModuleName)
|
|
paramsKeeper.Subspace(minttypes.ModuleName)
|
|
paramsKeeper.Subspace(distributiontypes.ModuleName)
|
|
paramsKeeper.Subspace(slashingtypes.ModuleName)
|
|
paramsKeeper.Subspace(crisistypes.ModuleName)
|
|
paramsKeeper.Subspace(ibctransfertypes.ModuleName)
|
|
paramsKeeper.Subspace(capabilitytypes.ModuleName)
|
|
paramsKeeper.Subspace(ibchost.ModuleName)
|
|
|
|
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},
|
|
}
|
|
authSubsp, _ := paramsKeeper.GetSubspace(authtypes.ModuleName)
|
|
authKeeper := authkeeper.NewAccountKeeper(
|
|
appCodec,
|
|
keyAcc, // target store
|
|
authSubsp,
|
|
authtypes.ProtoBaseAccount, // prototype
|
|
maccPerms,
|
|
)
|
|
blockedAddrs := make(map[string]bool)
|
|
for acc := range maccPerms {
|
|
allowReceivingFunds := acc != distributiontypes.ModuleName
|
|
blockedAddrs[authtypes.NewModuleAddress(acc).String()] = allowReceivingFunds
|
|
}
|
|
|
|
bankSubsp, _ := paramsKeeper.GetSubspace(banktypes.ModuleName)
|
|
bankKeeper := bankkeeper.NewBaseKeeper(
|
|
appCodec,
|
|
keyBank,
|
|
authKeeper,
|
|
bankSubsp,
|
|
blockedAddrs,
|
|
)
|
|
bankParams := banktypes.DefaultParams()
|
|
bankParams = bankParams.SetSendEnabledParam("stake", true)
|
|
bankKeeper.SetParams(ctx, bankParams)
|
|
|
|
stakingSubsp, _ := paramsKeeper.GetSubspace(stakingtypes.ModuleName)
|
|
stakingKeeper := stakingkeeper.NewKeeper(appCodec, keyStaking, authKeeper, bankKeeper, stakingSubsp)
|
|
stakingKeeper.SetParams(ctx, TestingStakeParams)
|
|
|
|
distSubsp, _ := paramsKeeper.GetSubspace(distributiontypes.ModuleName)
|
|
distKeeper := distributionkeeper.NewKeeper(appCodec, keyDistro, distSubsp, authKeeper, 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())
|
|
|
|
// 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)
|
|
err := bankKeeper.SetBalances(ctx, distrAcc.GetAddress(), sdk.NewCoins(
|
|
sdk.NewCoin("stake", sdk.NewInt(2000000)),
|
|
))
|
|
require.NoError(t, err)
|
|
authKeeper.SetModuleAccount(ctx, distrAcc)
|
|
capabilityKeeper := capabilitykeeper.NewKeeper(appCodec, keyCapability, keyCapabilityTransient)
|
|
scopedIBCKeeper := capabilityKeeper.ScopeToModule(ibchost.ModuleName)
|
|
scopedWasmKeeper := capabilityKeeper.ScopeToModule(types.ModuleName)
|
|
|
|
ibcSubsp, _ := paramsKeeper.GetSubspace(ibchost.ModuleName)
|
|
|
|
ibcKeeper := ibckeeper.NewKeeper(
|
|
appCodec, keyIBC, ibcSubsp, stakingKeeper, 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))
|
|
|
|
// Load default wasm config
|
|
wasmConfig := types.DefaultWasmConfig()
|
|
|
|
keeper := NewKeeper(
|
|
appCodec,
|
|
keyWasm,
|
|
paramsKeeper.Subspace(types.DefaultParamspace),
|
|
authKeeper,
|
|
bankKeeper,
|
|
stakingKeeper,
|
|
distKeeper,
|
|
ibcKeeper.ChannelKeeper,
|
|
&ibcKeeper.PortKeeper,
|
|
scopedWasmKeeper,
|
|
router,
|
|
tempDir,
|
|
wasmConfig,
|
|
supportedFeatures,
|
|
encoders,
|
|
queriers,
|
|
)
|
|
keeper.setParams(ctx, types.DefaultParams())
|
|
// add wasm handler so we can loop-back (contracts calling contracts)
|
|
router.AddRoute(sdk.NewRoute(types.RouterKey, TestHandler(&keeper)))
|
|
|
|
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, keyGov, paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable()), authKeeper, 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: authKeeper,
|
|
StakingKeeper: stakingKeeper,
|
|
DistKeeper: distKeeper,
|
|
WasmKeeper: &keeper,
|
|
BankKeeper: bankKeeper,
|
|
GovKeeper: govKeeper,
|
|
IBCKeeper: ibcKeeper,
|
|
}
|
|
return ctx, keepers
|
|
}
|
|
|
|
// TestHandler returns a wasm handler for tests (to avoid circular imports)
|
|
func TestHandler(k *Keeper) 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 *Keeper, 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.Source, msg.Builder, 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 *Keeper, 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.InitMsg, 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 *Keeper, 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")
|
|
}
|
|
res, err := k.Execute(ctx, contractAddr, senderAddr, msg.Msg, msg.Funds)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res.Events = ctx.EventManager().Events().ToABCIEvents()
|
|
return res, nil
|
|
}
|
|
|
|
func RandomAccountAddress(_ *testing.T) sdk.AccAddress {
|
|
_, _, addr := keyPubAddr()
|
|
return addr
|
|
}
|
|
|
|
func RandomBech32AccountAddress(t *testing.T) string {
|
|
return RandomAccountAddress(t).String()
|
|
}
|
|
|
|
type ExampleContract struct {
|
|
InitialAmount sdk.Coins
|
|
Creator crypto.PrivKey
|
|
CreatorAddr sdk.AccAddress
|
|
CodeID uint64
|
|
}
|
|
|
|
func StoreHackatomExampleContract(t *testing.T, ctx sdk.Context, keepers TestKeepers) ExampleContract {
|
|
return StoreExampleContract(t, ctx, keepers, "./testdata/hackatom.wasm")
|
|
}
|
|
|
|
func StoreBurnerExampleContract(t *testing.T, ctx sdk.Context, keepers TestKeepers) ExampleContract {
|
|
return StoreExampleContract(t, ctx, keepers, "./testdata/burner.wasm")
|
|
}
|
|
|
|
func StoreIBCReflectContract(t *testing.T, ctx sdk.Context, keepers TestKeepers) ExampleContract {
|
|
return StoreExampleContract(t, ctx, keepers, "./testdata/ibc_reflect.wasm")
|
|
}
|
|
|
|
func StoreReflectContract(t *testing.T, ctx sdk.Context, keepers TestKeepers) uint64 {
|
|
wasmCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
|
require.NoError(t, err)
|
|
|
|
_, _, creatorAddr := keyPubAddr()
|
|
codeID, err := keepers.WasmKeeper.Create(ctx, creatorAddr, wasmCode, "", "", nil)
|
|
require.NoError(t, err)
|
|
return codeID
|
|
}
|
|
|
|
func StoreExampleContract(t *testing.T, 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.WasmKeeper.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.T, ctx sdk.Context, keepers TestKeepers, mock types.WasmerEngine) ExampleContractInstance {
|
|
anyAmount := sdk.NewCoins(sdk.NewInt64Coin("denom", 1000))
|
|
creator, _, creatorAddr := keyPubAddr()
|
|
fundAccounts(t, ctx, keepers.AccountKeeper, keepers.BankKeeper, creatorAddr, anyAmount)
|
|
keepers.WasmKeeper.wasmer = mock
|
|
wasmCode := append(wasmIdent, rand.Bytes(10)...)
|
|
codeID, err := keepers.WasmKeeper.Create(ctx, creatorAddr, wasmCode, "", "", nil)
|
|
require.NoError(t, err)
|
|
contractAddr, err := keepers.WasmKeeper.Instantiate(ctx, codeID, creatorAddr, creatorAddr, []byte(`{}`), "", nil)
|
|
require.NoError(t, err)
|
|
return ExampleContractInstance{
|
|
ExampleContract: ExampleContract{InitialAmount: anyAmount, Creator: creator, CreatorAddr: creatorAddr, CodeID: codeID},
|
|
Contract: contractAddr,
|
|
}
|
|
}
|
|
|
|
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.T, 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.WasmKeeper.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.T) []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.T, 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.WasmKeeper.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.T) []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.T) []byte {
|
|
initMsgBz, err := json.Marshal(m)
|
|
require.NoError(t, err)
|
|
return initMsgBz
|
|
}
|
|
|
|
func createFakeFundedAccount(t *testing.T, ctx sdk.Context, am authkeeper.AccountKeeper, bank bankkeeper.Keeper, coins sdk.Coins) sdk.AccAddress {
|
|
_, _, addr := keyPubAddr()
|
|
fundAccounts(t, ctx, am, bank, addr, coins)
|
|
return addr
|
|
}
|
|
|
|
func fundAccounts(t *testing.T, ctx sdk.Context, am authkeeper.AccountKeeper, bank bankkeeper.Keeper, addr sdk.AccAddress, coins sdk.Coins) {
|
|
acc := am.NewAccountWithAddress(ctx, addr)
|
|
am.SetAccount(ctx, acc)
|
|
require.NoError(t, bank.SetBalances(ctx, addr, coins))
|
|
}
|
|
|
|
var keyCounter uint64 = 0
|
|
|
|
// 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
|
|
}
|