* More keeper tests x/wasm/keeper tests are extended to test various input validation. Keeper input is validated before passing to the keeper method when used within wasmd application. We cannot ensure such validation when this keeper is used outside of wasmd application. To keep it safe, fully validate keeper methods input. hackatom.wasm is loaded into memory during initialization to avoid reading file in each test separately. Once migrated to go 1.16, embed package should be used instead. Run goimport on certain files. Some comments fixed or removed. * ensure that creator address is not nil
581 lines
17 KiB
Go
581 lines
17 KiB
Go
package wasm
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"testing"
|
|
|
|
"github.com/CosmWasm/wasmd/x/wasm/keeper"
|
|
"github.com/CosmWasm/wasmd/x/wasm/types"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/cosmos/cosmos-sdk/types/module"
|
|
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
|
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
|
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
|
"github.com/dvsekhvalnov/jose2go/base64url"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
"github.com/tendermint/tendermint/crypto"
|
|
"github.com/tendermint/tendermint/crypto/ed25519"
|
|
)
|
|
|
|
type testData struct {
|
|
module module.AppModule
|
|
ctx sdk.Context
|
|
acctKeeper authkeeper.AccountKeeper
|
|
keeper Keeper
|
|
bankKeeper bankkeeper.Keeper
|
|
stakingKeeper stakingkeeper.Keeper
|
|
}
|
|
|
|
func setupTest(t *testing.T) testData {
|
|
ctx, keepers := CreateTestInput(t, false, "staking,stargate")
|
|
cdc := keeper.MakeTestCodec(t)
|
|
data := testData{
|
|
module: NewAppModule(cdc, keepers.WasmKeeper, keepers.StakingKeeper),
|
|
ctx: ctx,
|
|
acctKeeper: keepers.AccountKeeper,
|
|
keeper: *keepers.WasmKeeper,
|
|
bankKeeper: keepers.BankKeeper,
|
|
stakingKeeper: keepers.StakingKeeper,
|
|
}
|
|
return data
|
|
}
|
|
|
|
func keyPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.AccAddress) {
|
|
key := ed25519.GenPrivKey()
|
|
pub := key.PubKey()
|
|
addr := sdk.AccAddress(pub.Address())
|
|
return key, pub, addr
|
|
}
|
|
|
|
func mustLoad(path string) []byte {
|
|
bz, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return bz
|
|
}
|
|
|
|
var (
|
|
_, _, addrAcc1 = keyPubAddr()
|
|
addr1 = addrAcc1.String()
|
|
testContract = mustLoad("./keeper/testdata/hackatom.wasm")
|
|
maskContract = mustLoad("./keeper/testdata/reflect.wasm")
|
|
oldContract = mustLoad("./testdata/escrow_0.7.wasm")
|
|
)
|
|
|
|
func TestHandleCreate(t *testing.T) {
|
|
cases := map[string]struct {
|
|
msg sdk.Msg
|
|
isValid bool
|
|
}{
|
|
"empty": {
|
|
msg: &MsgStoreCode{},
|
|
isValid: false,
|
|
},
|
|
"invalid wasm": {
|
|
msg: &MsgStoreCode{
|
|
Sender: addr1,
|
|
WASMByteCode: []byte("foobar"),
|
|
},
|
|
isValid: false,
|
|
},
|
|
"valid wasm": {
|
|
msg: &MsgStoreCode{
|
|
Sender: addr1,
|
|
WASMByteCode: testContract,
|
|
},
|
|
isValid: true,
|
|
},
|
|
"other valid wasm": {
|
|
msg: &MsgStoreCode{
|
|
Sender: addr1,
|
|
WASMByteCode: maskContract,
|
|
},
|
|
isValid: true,
|
|
},
|
|
"old wasm (0.7)": {
|
|
msg: &MsgStoreCode{
|
|
Sender: addr1,
|
|
WASMByteCode: oldContract,
|
|
},
|
|
isValid: false,
|
|
},
|
|
}
|
|
|
|
for name, tc := range cases {
|
|
tc := tc
|
|
t.Run(name, func(t *testing.T) {
|
|
data := setupTest(t)
|
|
|
|
h := data.module.Route().Handler()
|
|
q := data.module.LegacyQuerierHandler(nil)
|
|
|
|
res, err := h(data.ctx, tc.msg)
|
|
if !tc.isValid {
|
|
require.Error(t, err, "%#v", res)
|
|
assertCodeList(t, q, data.ctx, 0)
|
|
assertCodeBytes(t, q, data.ctx, 1, nil)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
assertCodeList(t, q, data.ctx, 1)
|
|
})
|
|
}
|
|
}
|
|
|
|
type initMsg struct {
|
|
Verifier sdk.AccAddress `json:"verifier"`
|
|
Beneficiary sdk.AccAddress `json:"beneficiary"`
|
|
}
|
|
|
|
type state struct {
|
|
Verifier string `json:"verifier"`
|
|
Beneficiary string `json:"beneficiary"`
|
|
Funder string `json:"funder"`
|
|
}
|
|
|
|
func TestHandleInstantiate(t *testing.T) {
|
|
data := setupTest(t)
|
|
|
|
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
|
creator := createFakeFundedAccount(t, data.ctx, data.acctKeeper, data.bankKeeper, deposit)
|
|
|
|
h := data.module.Route().Handler()
|
|
q := data.module.LegacyQuerierHandler(nil)
|
|
|
|
msg := &MsgStoreCode{
|
|
Sender: creator.String(),
|
|
WASMByteCode: testContract,
|
|
}
|
|
res, err := h(data.ctx, msg)
|
|
require.NoError(t, err)
|
|
assertStoreCodeResponse(t, res.Data, 1)
|
|
|
|
_, _, bob := keyPubAddr()
|
|
_, _, fred := keyPubAddr()
|
|
|
|
initMsg := initMsg{
|
|
Verifier: fred,
|
|
Beneficiary: bob,
|
|
}
|
|
initMsgBz, err := json.Marshal(initMsg)
|
|
require.NoError(t, err)
|
|
|
|
// create with no balance is also legal
|
|
initCmd := MsgInstantiateContract{
|
|
Sender: creator.String(),
|
|
CodeID: firstCodeID,
|
|
Msg: initMsgBz,
|
|
Funds: nil,
|
|
}
|
|
res, err = h(data.ctx, &initCmd)
|
|
require.NoError(t, err)
|
|
contractBech32Addr := parseInitResponse(t, res.Data)
|
|
|
|
require.Equal(t, "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhuc53mp6", contractBech32Addr)
|
|
// this should be standard x/wasm init event, nothing from contract
|
|
require.Equal(t, 3, len(res.Events), prettyEvents(res.Events))
|
|
require.Equal(t, "message", res.Events[0].Type)
|
|
assertAttribute(t, "module", "wasm", res.Events[0].Attributes[0])
|
|
require.Equal(t, "instantiate", res.Events[1].Type)
|
|
require.Equal(t, "wasm", res.Events[2].Type)
|
|
assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[2].Attributes[0])
|
|
|
|
assertCodeList(t, q, data.ctx, 1)
|
|
assertCodeBytes(t, q, data.ctx, 1, testContract)
|
|
|
|
assertContractList(t, q, data.ctx, 1, []string{contractBech32Addr})
|
|
assertContractInfo(t, q, data.ctx, contractBech32Addr, 1, creator)
|
|
assertContractState(t, q, data.ctx, contractBech32Addr, state{
|
|
Verifier: fred.String(),
|
|
Beneficiary: bob.String(),
|
|
Funder: creator.String(),
|
|
})
|
|
}
|
|
|
|
func TestHandleExecute(t *testing.T) {
|
|
data := setupTest(t)
|
|
|
|
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
|
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
|
|
creator := createFakeFundedAccount(t, data.ctx, data.acctKeeper, data.bankKeeper, deposit.Add(deposit...))
|
|
fred := createFakeFundedAccount(t, data.ctx, data.acctKeeper, data.bankKeeper, topUp)
|
|
|
|
h := data.module.Route().Handler()
|
|
q := data.module.LegacyQuerierHandler(nil)
|
|
|
|
msg := &MsgStoreCode{
|
|
Sender: creator.String(),
|
|
WASMByteCode: testContract,
|
|
}
|
|
res, err := h(data.ctx, msg)
|
|
require.NoError(t, err)
|
|
assertStoreCodeResponse(t, res.Data, 1)
|
|
|
|
_, _, bob := keyPubAddr()
|
|
initMsg := initMsg{
|
|
Verifier: fred,
|
|
Beneficiary: bob,
|
|
}
|
|
initMsgBz, err := json.Marshal(initMsg)
|
|
require.NoError(t, err)
|
|
|
|
initCmd := MsgInstantiateContract{
|
|
Sender: creator.String(),
|
|
CodeID: firstCodeID,
|
|
Msg: initMsgBz,
|
|
Funds: deposit,
|
|
}
|
|
res, err = h(data.ctx, &initCmd)
|
|
require.NoError(t, err)
|
|
contractBech32Addr := parseInitResponse(t, res.Data)
|
|
|
|
require.Equal(t, "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhuc53mp6", contractBech32Addr)
|
|
// this should be standard x/wasm message event, init event, plus a bank send event (2), with no custom contract events
|
|
require.Equal(t, 4, len(res.Events), prettyEvents(res.Events))
|
|
require.Equal(t, "message", res.Events[0].Type)
|
|
assertAttribute(t, "module", "wasm", res.Events[0].Attributes[0])
|
|
require.Equal(t, "transfer", res.Events[1].Type)
|
|
require.Equal(t, "instantiate", res.Events[2].Type)
|
|
require.Equal(t, "wasm", res.Events[3].Type)
|
|
assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[3].Attributes[0])
|
|
|
|
// ensure bob doesn't exist
|
|
bobAcct := data.acctKeeper.GetAccount(data.ctx, bob)
|
|
require.Nil(t, bobAcct)
|
|
|
|
// ensure funder has reduced balance
|
|
creatorAcct := data.acctKeeper.GetAccount(data.ctx, creator)
|
|
require.NotNil(t, creatorAcct)
|
|
// we started at 2*deposit, should have spent one above
|
|
assert.Equal(t, deposit, data.bankKeeper.GetAllBalances(data.ctx, creatorAcct.GetAddress()))
|
|
|
|
// ensure contract has updated balance
|
|
contractAddr, _ := sdk.AccAddressFromBech32(contractBech32Addr)
|
|
contractAcct := data.acctKeeper.GetAccount(data.ctx, contractAddr)
|
|
require.NotNil(t, contractAcct)
|
|
assert.Equal(t, deposit, data.bankKeeper.GetAllBalances(data.ctx, contractAcct.GetAddress()))
|
|
|
|
execCmd := MsgExecuteContract{
|
|
Sender: fred.String(),
|
|
Contract: contractBech32Addr,
|
|
Msg: []byte(`{"release":{}}`),
|
|
Funds: topUp,
|
|
}
|
|
res, err = h(data.ctx, &execCmd)
|
|
require.NoError(t, err)
|
|
// from https://github.com/CosmWasm/cosmwasm/blob/master/contracts/hackatom/src/contract.rs#L167
|
|
assertExecuteResponse(t, res.Data, []byte{0xf0, 0x0b, 0xaa})
|
|
|
|
// this should be standard message event, plus x/wasm init event, plus 2 bank send event, plus a special event from the contract
|
|
require.Equal(t, 6, len(res.Events), prettyEvents(res.Events))
|
|
|
|
assert.Equal(t, "message", res.Events[0].Type)
|
|
assertAttribute(t, "module", "wasm", res.Events[0].Attributes[0])
|
|
|
|
require.Equal(t, "transfer", res.Events[1].Type)
|
|
require.Len(t, res.Events[1].Attributes, 3)
|
|
assertAttribute(t, "recipient", contractBech32Addr, res.Events[1].Attributes[0])
|
|
assertAttribute(t, "sender", fred.String(), res.Events[1].Attributes[1])
|
|
assertAttribute(t, "amount", "5000denom", res.Events[1].Attributes[2])
|
|
|
|
assert.Equal(t, "execute", res.Events[2].Type)
|
|
|
|
// custom contract event attribute
|
|
assert.Equal(t, "wasm", res.Events[3].Type)
|
|
assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[3].Attributes[0])
|
|
assertAttribute(t, "action", "release", res.Events[3].Attributes[1])
|
|
// custom contract event
|
|
assert.Equal(t, "wasm-hackatom", res.Events[4].Type)
|
|
assertAttribute(t, "_contract_address", contractBech32Addr, res.Events[4].Attributes[0])
|
|
assertAttribute(t, "action", "release", res.Events[4].Attributes[1])
|
|
// second transfer (this without conflicting message)
|
|
assert.Equal(t, "transfer", res.Events[5].Type)
|
|
assertAttribute(t, "recipient", bob.String(), res.Events[5].Attributes[0])
|
|
assertAttribute(t, "sender", contractBech32Addr, res.Events[5].Attributes[1])
|
|
assertAttribute(t, "amount", "105000denom", res.Events[5].Attributes[2])
|
|
// finally, standard x/wasm tag
|
|
|
|
// ensure bob now exists and got both payments released
|
|
bobAcct = data.acctKeeper.GetAccount(data.ctx, bob)
|
|
require.NotNil(t, bobAcct)
|
|
balance := data.bankKeeper.GetAllBalances(data.ctx, bobAcct.GetAddress())
|
|
assert.Equal(t, deposit.Add(topUp...), balance)
|
|
|
|
// ensure contract has updated balance
|
|
|
|
contractAcct = data.acctKeeper.GetAccount(data.ctx, contractAddr)
|
|
require.NotNil(t, contractAcct)
|
|
assert.Equal(t, sdk.Coins(nil), data.bankKeeper.GetAllBalances(data.ctx, contractAcct.GetAddress()))
|
|
|
|
// ensure all contract state is as after init
|
|
assertCodeList(t, q, data.ctx, 1)
|
|
assertCodeBytes(t, q, data.ctx, 1, testContract)
|
|
|
|
assertContractList(t, q, data.ctx, 1, []string{contractBech32Addr})
|
|
assertContractInfo(t, q, data.ctx, contractBech32Addr, 1, creator)
|
|
assertContractState(t, q, data.ctx, contractBech32Addr, state{
|
|
Verifier: fred.String(),
|
|
Beneficiary: bob.String(),
|
|
Funder: creator.String(),
|
|
})
|
|
}
|
|
|
|
func TestHandleExecuteEscrow(t *testing.T) {
|
|
data := setupTest(t)
|
|
|
|
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
|
topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000))
|
|
creator := createFakeFundedAccount(t, data.ctx, data.acctKeeper, data.bankKeeper, deposit.Add(deposit...))
|
|
fred := createFakeFundedAccount(t, data.ctx, data.acctKeeper, data.bankKeeper, topUp)
|
|
|
|
h := data.module.Route().Handler()
|
|
|
|
msg := &MsgStoreCode{
|
|
Sender: creator.String(),
|
|
WASMByteCode: testContract,
|
|
}
|
|
res, err := h(data.ctx, msg)
|
|
require.NoError(t, err)
|
|
|
|
_, _, bob := keyPubAddr()
|
|
initMsg := map[string]interface{}{
|
|
"verifier": fred.String(),
|
|
"beneficiary": bob.String(),
|
|
}
|
|
initMsgBz, err := json.Marshal(initMsg)
|
|
require.NoError(t, err)
|
|
|
|
initCmd := MsgInstantiateContract{
|
|
Sender: creator.String(),
|
|
CodeID: firstCodeID,
|
|
Msg: initMsgBz,
|
|
Funds: deposit,
|
|
}
|
|
res, err = h(data.ctx, &initCmd)
|
|
require.NoError(t, err)
|
|
contractBech32Addr := parseInitResponse(t, res.Data)
|
|
require.Equal(t, "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhuc53mp6", contractBech32Addr)
|
|
|
|
handleMsg := map[string]interface{}{
|
|
"release": map[string]interface{}{},
|
|
}
|
|
handleMsgBz, err := json.Marshal(handleMsg)
|
|
require.NoError(t, err)
|
|
|
|
execCmd := MsgExecuteContract{
|
|
Sender: fred.String(),
|
|
Contract: contractBech32Addr,
|
|
Msg: handleMsgBz,
|
|
Funds: topUp,
|
|
}
|
|
res, err = h(data.ctx, &execCmd)
|
|
require.NoError(t, err)
|
|
// from https://github.com/CosmWasm/cosmwasm/blob/master/contracts/hackatom/src/contract.rs#L167
|
|
assertExecuteResponse(t, res.Data, []byte{0xf0, 0x0b, 0xaa})
|
|
|
|
// ensure bob now exists and got both payments released
|
|
bobAcct := data.acctKeeper.GetAccount(data.ctx, bob)
|
|
require.NotNil(t, bobAcct)
|
|
balance := data.bankKeeper.GetAllBalances(data.ctx, bobAcct.GetAddress())
|
|
assert.Equal(t, deposit.Add(topUp...), balance)
|
|
|
|
// ensure contract has updated balance
|
|
contractAddr, _ := sdk.AccAddressFromBech32(contractBech32Addr)
|
|
contractAcct := data.acctKeeper.GetAccount(data.ctx, contractAddr)
|
|
require.NotNil(t, contractAcct)
|
|
assert.Equal(t, sdk.Coins(nil), data.bankKeeper.GetAllBalances(data.ctx, contractAcct.GetAddress()))
|
|
}
|
|
|
|
func TestReadWasmConfig(t *testing.T) {
|
|
defaults := DefaultWasmConfig()
|
|
specs := map[string]struct {
|
|
src AppOptionsMock
|
|
exp types.WasmConfig
|
|
}{
|
|
"set query gas limit via opts": {
|
|
src: AppOptionsMock{
|
|
"wasm.query_gas_limit": 1,
|
|
},
|
|
exp: types.WasmConfig{
|
|
SmartQueryGasLimit: 1,
|
|
MemoryCacheSize: defaults.MemoryCacheSize,
|
|
},
|
|
},
|
|
"set cache via opts": {
|
|
src: AppOptionsMock{
|
|
"wasm.memory_cache_size": 2,
|
|
},
|
|
exp: types.WasmConfig{
|
|
MemoryCacheSize: 2,
|
|
SmartQueryGasLimit: defaults.SmartQueryGasLimit,
|
|
},
|
|
},
|
|
"set debug via opts": {
|
|
src: AppOptionsMock{
|
|
"trace": true,
|
|
},
|
|
exp: types.WasmConfig{
|
|
SmartQueryGasLimit: defaults.SmartQueryGasLimit,
|
|
MemoryCacheSize: defaults.MemoryCacheSize,
|
|
ContractDebugMode: true,
|
|
},
|
|
},
|
|
"all defaults when no options set": {
|
|
exp: defaults,
|
|
},
|
|
}
|
|
for msg, spec := range specs {
|
|
t.Run(msg, func(t *testing.T) {
|
|
got, err := ReadWasmConfig(spec.src)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, spec.exp, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
type AppOptionsMock map[string]interface{}
|
|
|
|
func (a AppOptionsMock) Get(s string) interface{} {
|
|
return a[s]
|
|
}
|
|
|
|
type prettyEvent struct {
|
|
Type string
|
|
Attr []sdk.Attribute
|
|
}
|
|
|
|
func prettyEvents(evts []abci.Event) string {
|
|
res := make([]prettyEvent, len(evts))
|
|
for i, e := range evts {
|
|
res[i] = prettyEvent{
|
|
Type: e.Type,
|
|
Attr: prettyAttrs(e.Attributes),
|
|
}
|
|
}
|
|
bz, err := json.MarshalIndent(res, "", " ")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return string(bz)
|
|
}
|
|
|
|
func prettyAttrs(attrs []abci.EventAttribute) []sdk.Attribute {
|
|
pretty := make([]sdk.Attribute, len(attrs))
|
|
for i, a := range attrs {
|
|
pretty[i] = prettyAttr(a)
|
|
}
|
|
return pretty
|
|
}
|
|
|
|
func prettyAttr(attr abci.EventAttribute) sdk.Attribute {
|
|
return sdk.NewAttribute(string(attr.Key), string(attr.Value))
|
|
}
|
|
|
|
func assertAttribute(t *testing.T, key string, value string, attr abci.EventAttribute) {
|
|
t.Helper()
|
|
assert.Equal(t, key, string(attr.Key), prettyAttr(attr))
|
|
assert.Equal(t, value, string(attr.Value), prettyAttr(attr))
|
|
}
|
|
|
|
func assertCodeList(t *testing.T, q sdk.Querier, ctx sdk.Context, expectedNum int) {
|
|
bz, sdkerr := q(ctx, []string{QueryListCode}, abci.RequestQuery{})
|
|
require.NoError(t, sdkerr)
|
|
|
|
if len(bz) == 0 {
|
|
require.Equal(t, expectedNum, 0)
|
|
return
|
|
}
|
|
|
|
var res []CodeInfo
|
|
err := json.Unmarshal(bz, &res)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, expectedNum, len(res))
|
|
}
|
|
|
|
func assertCodeBytes(t *testing.T, q sdk.Querier, ctx sdk.Context, codeID uint64, expectedBytes []byte) {
|
|
path := []string{QueryGetCode, fmt.Sprintf("%d", codeID)}
|
|
bz, sdkerr := q(ctx, path, abci.RequestQuery{})
|
|
require.NoError(t, sdkerr)
|
|
|
|
if len(expectedBytes) == 0 {
|
|
require.Equal(t, len(bz), 0, "%q", string(bz))
|
|
return
|
|
}
|
|
var res map[string]interface{}
|
|
err := json.Unmarshal(bz, &res)
|
|
require.NoError(t, err)
|
|
|
|
require.Contains(t, res, "data")
|
|
b, err := base64url.Decode(res["data"].(string))
|
|
require.NoError(t, err)
|
|
assert.Equal(t, expectedBytes, b)
|
|
assert.EqualValues(t, codeID, res["id"])
|
|
}
|
|
|
|
func assertContractList(t *testing.T, q sdk.Querier, ctx sdk.Context, codeID uint64, expContractAddrs []string) {
|
|
bz, sdkerr := q(ctx, []string{QueryListContractByCode, fmt.Sprintf("%d", codeID)}, abci.RequestQuery{})
|
|
require.NoError(t, sdkerr)
|
|
|
|
if len(bz) == 0 {
|
|
require.Equal(t, len(expContractAddrs), 0)
|
|
return
|
|
}
|
|
|
|
var res []string
|
|
err := json.Unmarshal(bz, &res)
|
|
require.NoError(t, err)
|
|
|
|
var hasAddrs = make([]string, len(res))
|
|
for i, r := range res {
|
|
hasAddrs[i] = r
|
|
}
|
|
|
|
assert.Equal(t, expContractAddrs, hasAddrs)
|
|
}
|
|
|
|
func assertContractState(t *testing.T, q sdk.Querier, ctx sdk.Context, contractBech32Addr string, expected state) {
|
|
t.Helper()
|
|
path := []string{QueryGetContractState, contractBech32Addr, keeper.QueryMethodContractStateAll}
|
|
bz, sdkerr := q(ctx, path, abci.RequestQuery{})
|
|
require.NoError(t, sdkerr)
|
|
|
|
var res []Model
|
|
err := json.Unmarshal(bz, &res)
|
|
require.NoError(t, err)
|
|
require.Equal(t, 1, len(res), "#v", res)
|
|
require.Equal(t, []byte("config"), []byte(res[0].Key))
|
|
|
|
expectedBz, err := json.Marshal(expected)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, expectedBz, res[0].Value)
|
|
}
|
|
|
|
func assertContractInfo(t *testing.T, q sdk.Querier, ctx sdk.Context, contractBech32Addr string, codeID uint64, creator sdk.AccAddress) {
|
|
t.Helper()
|
|
path := []string{QueryGetContract, contractBech32Addr}
|
|
bz, sdkerr := q(ctx, path, abci.RequestQuery{})
|
|
require.NoError(t, sdkerr)
|
|
|
|
var res ContractInfo
|
|
err := json.Unmarshal(bz, &res)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, codeID, res.CodeID)
|
|
assert.Equal(t, creator.String(), res.Creator)
|
|
}
|
|
|
|
func createFakeFundedAccount(t *testing.T, ctx sdk.Context, am authkeeper.AccountKeeper, bankKeeper bankkeeper.Keeper, coins sdk.Coins) sdk.AccAddress {
|
|
t.Helper()
|
|
_, _, addr := keyPubAddr()
|
|
acc := am.NewAccountWithAddress(ctx, addr)
|
|
am.SetAccount(ctx, acc)
|
|
require.NoError(t, bankKeeper.SetBalances(ctx, addr, coins))
|
|
return addr
|
|
}
|