Fix wasm simulations (#870)
* Fix wasm simulations + make functions compatible with tgrade * Fix lint issues * Fix simulation setup * Make simulations store msg pass * Use default values params to make operations succeed * Normalize wasm store * Add simulations to circleci config * Run simulation in temp dir * Store sim logs * Increase circleci machine type * Extract reflect contract api into helper * Add execute msg to simulations * Embed refect wasm contract Co-authored-by: Pino' Surace <pino.surace@live.it>
This commit is contained in:
@@ -116,6 +116,19 @@ jobs:
|
|||||||
cd ./benchmarks
|
cd ./benchmarks
|
||||||
go test -bench .
|
go test -bench .
|
||||||
|
|
||||||
|
simulations:
|
||||||
|
executor: golang
|
||||||
|
parallelism: 1
|
||||||
|
resource_class: large
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: Run simulations
|
||||||
|
command: |
|
||||||
|
make test-sim-multi-seed-short
|
||||||
|
- store_artifacts:
|
||||||
|
path: /tmp
|
||||||
|
|
||||||
upload-coverage:
|
upload-coverage:
|
||||||
executor: golang
|
executor: golang
|
||||||
steps:
|
steps:
|
||||||
@@ -218,3 +231,6 @@ workflows:
|
|||||||
- benchmark:
|
- benchmark:
|
||||||
requires:
|
requires:
|
||||||
- test-cover
|
- test-cover
|
||||||
|
- simulations:
|
||||||
|
requires:
|
||||||
|
- setup-dependencies
|
||||||
|
|||||||
@@ -458,7 +458,6 @@ func NewWasmApp(
|
|||||||
transferModule := transfer.NewAppModule(app.transferKeeper)
|
transferModule := transfer.NewAppModule(app.transferKeeper)
|
||||||
transferIBCModule := transfer.NewIBCModule(app.transferKeeper)
|
transferIBCModule := transfer.NewIBCModule(app.transferKeeper)
|
||||||
|
|
||||||
_ = app.getSubspace(icahosttypes.SubModuleName)
|
|
||||||
app.icaHostKeeper = icahostkeeper.NewKeeper(
|
app.icaHostKeeper = icahostkeeper.NewKeeper(
|
||||||
appCodec,
|
appCodec,
|
||||||
keys[icahosttypes.StoreKey],
|
keys[icahosttypes.StoreKey],
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const (
|
|||||||
DefaultWeightCommunitySpendProposal int = 5
|
DefaultWeightCommunitySpendProposal int = 5
|
||||||
DefaultWeightTextProposal int = 5
|
DefaultWeightTextProposal int = 5
|
||||||
DefaultWeightParamChangeProposal int = 5
|
DefaultWeightParamChangeProposal int = 5
|
||||||
DefaultWeightMsgStoreCode int = 100
|
DefaultWeightMsgStoreCode int = 50
|
||||||
DefaultWeightMsgInstantiateContract int = 100
|
DefaultWeightMsgInstantiateContract int = 100
|
||||||
|
DefaultWeightMsgExecuteContract int = 100
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,11 +6,17 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/store"
|
||||||
|
"github.com/cosmos/cosmos-sdk/store/prefix"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
"github.com/cosmos/cosmos-sdk/simapp"
|
"github.com/cosmos/cosmos-sdk/simapp"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/types/kv"
|
"github.com/cosmos/cosmos-sdk/types/kv"
|
||||||
|
"github.com/cosmos/cosmos-sdk/types/module"
|
||||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
|
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
|
||||||
@@ -118,7 +124,7 @@ func TestAppImportExport(t *testing.T) {
|
|||||||
t,
|
t,
|
||||||
os.Stdout,
|
os.Stdout,
|
||||||
app.BaseApp,
|
app.BaseApp,
|
||||||
simapp.AppStateFn(app.AppCodec(), app.SimulationManager()),
|
AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||||
simtypes.RandomAccounts,
|
simtypes.RandomAccounts,
|
||||||
simapp.SimulationOperations(app, app.AppCodec(), config),
|
simapp.SimulationOperations(app, app.AppCodec(), config),
|
||||||
app.ModuleAccountAddrs(),
|
app.ModuleAccountAddrs(),
|
||||||
@@ -190,6 +196,37 @@ func TestAppImportExport(t *testing.T) {
|
|||||||
// delete persistent tx counter value
|
// delete persistent tx counter value
|
||||||
ctxA.KVStore(app.keys[wasm.StoreKey]).Delete(wasmtypes.TXCounterPrefix)
|
ctxA.KVStore(app.keys[wasm.StoreKey]).Delete(wasmtypes.TXCounterPrefix)
|
||||||
|
|
||||||
|
// reset contract code index in source DB for comparison with dest DB
|
||||||
|
dropContractHistory := func(s store.KVStore, keys ...[]byte) {
|
||||||
|
for _, key := range keys {
|
||||||
|
prefixStore := prefix.NewStore(s, key)
|
||||||
|
iter := prefixStore.Iterator(nil, nil)
|
||||||
|
for ; iter.Valid(); iter.Next() {
|
||||||
|
prefixStore.Delete(iter.Key())
|
||||||
|
}
|
||||||
|
iter.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prefixes := [][]byte{wasmtypes.ContractCodeHistoryElementPrefix, wasmtypes.ContractByCodeIDAndCreatedSecondaryIndexPrefix}
|
||||||
|
dropContractHistory(ctxA.KVStore(app.keys[wasm.StoreKey]), prefixes...)
|
||||||
|
dropContractHistory(ctxB.KVStore(newApp.keys[wasm.StoreKey]), prefixes...)
|
||||||
|
|
||||||
|
normalizeContractInfo := func(ctx sdk.Context, app *WasmApp) {
|
||||||
|
var index uint64
|
||||||
|
app.wasmKeeper.IterateContractInfo(ctx, func(address sdk.AccAddress, info wasmtypes.ContractInfo) bool {
|
||||||
|
created := &wasmtypes.AbsoluteTxPosition{
|
||||||
|
BlockHeight: uint64(0),
|
||||||
|
TxIndex: index,
|
||||||
|
}
|
||||||
|
info.Created = created
|
||||||
|
store := ctx.KVStore(app.keys[wasm.StoreKey])
|
||||||
|
store.Set(wasmtypes.GetContractAddressKey(address), app.appCodec.MustMarshal(&info))
|
||||||
|
index++
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
normalizeContractInfo(ctxA, app)
|
||||||
|
normalizeContractInfo(ctxB, newApp)
|
||||||
// diff both stores
|
// diff both stores
|
||||||
for _, skp := range storeKeysPrefixes {
|
for _, skp := range storeKeysPrefixes {
|
||||||
storeA := ctxA.KVStore(skp.A)
|
storeA := ctxA.KVStore(skp.A)
|
||||||
@@ -215,7 +252,7 @@ func TestFullAppSimulation(t *testing.T) {
|
|||||||
require.NoError(t, os.RemoveAll(dir))
|
require.NoError(t, os.RemoveAll(dir))
|
||||||
}()
|
}()
|
||||||
encConf := MakeEncodingConfig()
|
encConf := MakeEncodingConfig()
|
||||||
app := NewWasmApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue,
|
app := NewWasmApp(logger, db, nil, true, map[int64]bool{}, t.TempDir(), simapp.FlagPeriodValue,
|
||||||
encConf, wasm.EnableAllProposals, simapp.EmptyAppOptions{}, nil, fauxMerkleModeOpt)
|
encConf, wasm.EnableAllProposals, simapp.EmptyAppOptions{}, nil, fauxMerkleModeOpt)
|
||||||
require.Equal(t, "WasmApp", app.Name())
|
require.Equal(t, "WasmApp", app.Name())
|
||||||
|
|
||||||
@@ -224,7 +261,7 @@ func TestFullAppSimulation(t *testing.T) {
|
|||||||
t,
|
t,
|
||||||
os.Stdout,
|
os.Stdout,
|
||||||
app.BaseApp,
|
app.BaseApp,
|
||||||
simapp.AppStateFn(app.appCodec, app.SimulationManager()),
|
AppStateFn(app.appCodec, app.SimulationManager()),
|
||||||
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||||
simapp.SimulationOperations(app, app.AppCodec(), config),
|
simapp.SimulationOperations(app, app.AppCodec(), config),
|
||||||
app.ModuleAccountAddrs(),
|
app.ModuleAccountAddrs(),
|
||||||
@@ -241,3 +278,15 @@ func TestFullAppSimulation(t *testing.T) {
|
|||||||
simapp.PrintStats(db)
|
simapp.PrintStats(db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AppStateFn returns the initial application state using a genesis or the simulation parameters.
|
||||||
|
// It panics if the user provides files for both of them.
|
||||||
|
// If a file is not given for the genesis or the sim params, it creates a randomized one.
|
||||||
|
func AppStateFn(codec codec.Codec, manager *module.SimulationManager) simtypes.AppStateFn {
|
||||||
|
// quick hack to setup app state genesis with our app modules
|
||||||
|
simapp.ModuleBasics = ModuleBasics
|
||||||
|
if simapp.FlagGenesisTimeValue == 0 { // always set to have a block time
|
||||||
|
simapp.FlagGenesisTimeValue = time.Now().Unix()
|
||||||
|
}
|
||||||
|
return simapp.AppStateFn(codec, manager)
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
|
|
||||||
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
@@ -16,62 +14,17 @@ import (
|
|||||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
|
||||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReflectInitMsg is {}
|
// ReflectInitMsg is {}
|
||||||
|
|
||||||
// ReflectHandleMsg is used to encode handle messages
|
func buildReflectQuery(t *testing.T, query *testdata.ReflectQueryMsg) []byte {
|
||||||
type ReflectHandleMsg struct {
|
|
||||||
Reflect *reflectPayload `json:"reflect_msg,omitempty"`
|
|
||||||
ReflectSubMsg *reflectSubPayload `json:"reflect_sub_msg,omitempty"`
|
|
||||||
Change *ownerPayload `json:"change_owner,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ownerPayload struct {
|
|
||||||
Owner sdk.Address `json:"owner"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type reflectPayload struct {
|
|
||||||
Msgs []wasmvmtypes.CosmosMsg `json:"msgs"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type reflectSubPayload struct {
|
|
||||||
Msgs []wasmvmtypes.SubMsg `json:"msgs"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReflectQueryMsg is used to encode query messages
|
|
||||||
type ReflectQueryMsg struct {
|
|
||||||
Owner *struct{} `json:"owner,omitempty"`
|
|
||||||
Capitalized *Text `json:"capitalized,omitempty"`
|
|
||||||
Chain *ChainQuery `json:"chain,omitempty"`
|
|
||||||
SubMsgResult *SubCall `json:"sub_msg_result,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChainQuery struct {
|
|
||||||
Request *wasmvmtypes.QueryRequest `json:"request,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Text struct {
|
|
||||||
Text string `json:"text"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SubCall struct {
|
|
||||||
ID uint64 `json:"id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type OwnerResponse struct {
|
|
||||||
Owner string `json:"owner,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChainResponse struct {
|
|
||||||
Data []byte `json:"data,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildReflectQuery(t *testing.T, query *ReflectQueryMsg) []byte {
|
|
||||||
bz, err := json.Marshal(query)
|
bz, err := json.Marshal(query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return bz
|
return bz
|
||||||
@@ -94,9 +47,7 @@ func TestReflectContractSend(t *testing.T) {
|
|||||||
_, _, bob := keyPubAddr()
|
_, _, bob := keyPubAddr()
|
||||||
|
|
||||||
// upload reflect code
|
// upload reflect code
|
||||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
reflectID, err := keeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||||
require.NoError(t, err)
|
|
||||||
reflectID, err := keeper.Create(ctx, creator, reflectCode, nil)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, uint64(1), reflectID)
|
require.Equal(t, uint64(1), reflectID)
|
||||||
|
|
||||||
@@ -148,8 +99,8 @@ func TestReflectContractSend(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
reflectSend := ReflectHandleMsg{
|
reflectSend := testdata.ReflectHandleMsg{
|
||||||
Reflect: &reflectPayload{
|
Reflect: &testdata.ReflectPayload{
|
||||||
Msgs: msgs,
|
Msgs: msgs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -176,9 +127,7 @@ func TestReflectCustomMsg(t *testing.T) {
|
|||||||
_, _, fred := keyPubAddr()
|
_, _, fred := keyPubAddr()
|
||||||
|
|
||||||
// upload code
|
// upload code
|
||||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
codeID, err := keeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||||
require.NoError(t, err)
|
|
||||||
codeID, err := keeper.Create(ctx, creator, reflectCode, nil)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, uint64(1), codeID)
|
require.Equal(t, uint64(1), codeID)
|
||||||
|
|
||||||
@@ -189,8 +138,8 @@ func TestReflectCustomMsg(t *testing.T) {
|
|||||||
require.NotEmpty(t, contractAddr)
|
require.NotEmpty(t, contractAddr)
|
||||||
|
|
||||||
// set owner to bob
|
// set owner to bob
|
||||||
transfer := ReflectHandleMsg{
|
transfer := testdata.ReflectHandleMsg{
|
||||||
Change: &ownerPayload{
|
ChangeOwner: &testdata.OwnerPayload{
|
||||||
Owner: bob,
|
Owner: bob,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -216,8 +165,8 @@ func TestReflectCustomMsg(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
reflectSend := ReflectHandleMsg{
|
reflectSend := testdata.ReflectHandleMsg{
|
||||||
Reflect: &reflectPayload{
|
Reflect: &testdata.ReflectPayload{
|
||||||
Msgs: msgs,
|
Msgs: msgs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -240,8 +189,8 @@ func TestReflectCustomMsg(t *testing.T) {
|
|||||||
}
|
}
|
||||||
opaque, err := toReflectRawMsg(cdc, sdkSendMsg)
|
opaque, err := toReflectRawMsg(cdc, sdkSendMsg)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
reflectOpaque := ReflectHandleMsg{
|
reflectOpaque := testdata.ReflectHandleMsg{
|
||||||
Reflect: &reflectPayload{
|
Reflect: &testdata.ReflectPayload{
|
||||||
Msgs: []wasmvmtypes.CosmosMsg{opaque},
|
Msgs: []wasmvmtypes.CosmosMsg{opaque},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -267,9 +216,7 @@ func TestMaskReflectCustomQuery(t *testing.T) {
|
|||||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||||
|
|
||||||
// upload code
|
// upload code
|
||||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||||
require.NoError(t, err)
|
|
||||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, uint64(1), codeID)
|
require.Equal(t, uint64(1), codeID)
|
||||||
|
|
||||||
@@ -280,21 +227,21 @@ func TestMaskReflectCustomQuery(t *testing.T) {
|
|||||||
require.NotEmpty(t, contractAddr)
|
require.NotEmpty(t, contractAddr)
|
||||||
|
|
||||||
// let's perform a normal query of state
|
// let's perform a normal query of state
|
||||||
ownerQuery := ReflectQueryMsg{
|
ownerQuery := testdata.ReflectQueryMsg{
|
||||||
Owner: &struct{}{},
|
Owner: &struct{}{},
|
||||||
}
|
}
|
||||||
ownerQueryBz, err := json.Marshal(ownerQuery)
|
ownerQueryBz, err := json.Marshal(ownerQuery)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
ownerRes, err := keeper.QuerySmart(ctx, contractAddr, ownerQueryBz)
|
ownerRes, err := keeper.QuerySmart(ctx, contractAddr, ownerQueryBz)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
var res OwnerResponse
|
var res testdata.OwnerResponse
|
||||||
err = json.Unmarshal(ownerRes, &res)
|
err = json.Unmarshal(ownerRes, &res)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, res.Owner, creator.String())
|
assert.Equal(t, res.Owner, creator.String())
|
||||||
|
|
||||||
// and now making use of the custom querier callbacks
|
// and now making use of the custom querier callbacks
|
||||||
customQuery := ReflectQueryMsg{
|
customQuery := testdata.ReflectQueryMsg{
|
||||||
Capitalized: &Text{
|
Capitalized: &testdata.Text{
|
||||||
Text: "all Caps noW",
|
Text: "all Caps noW",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -319,9 +266,7 @@ func TestReflectStargateQuery(t *testing.T) {
|
|||||||
creator := keepers.Faucet.NewFundedAccount(ctx, funds...)
|
creator := keepers.Faucet.NewFundedAccount(ctx, funds...)
|
||||||
|
|
||||||
// upload code
|
// upload code
|
||||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||||
require.NoError(t, err)
|
|
||||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, uint64(1), codeID)
|
require.Equal(t, uint64(1), codeID)
|
||||||
|
|
||||||
@@ -338,13 +283,13 @@ func TestReflectStargateQuery(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
simpleQueryBz, err := json.Marshal(ReflectQueryMsg{
|
simpleQueryBz, err := json.Marshal(testdata.ReflectQueryMsg{
|
||||||
Chain: &ChainQuery{Request: &bankQuery},
|
Chain: &testdata.ChainQuery{Request: &bankQuery},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
simpleRes, err := keeper.QuerySmart(ctx, contractAddr, simpleQueryBz)
|
simpleRes, err := keeper.QuerySmart(ctx, contractAddr, simpleQueryBz)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
var simpleChain ChainResponse
|
var simpleChain testdata.ChainResponse
|
||||||
mustParse(t, simpleRes, &simpleChain)
|
mustParse(t, simpleRes, &simpleChain)
|
||||||
var simpleBalance wasmvmtypes.AllBalancesResponse
|
var simpleBalance wasmvmtypes.AllBalancesResponse
|
||||||
mustParse(t, simpleChain.Data, &simpleBalance)
|
mustParse(t, simpleChain.Data, &simpleBalance)
|
||||||
@@ -363,9 +308,7 @@ func TestReflectInvalidStargateQuery(t *testing.T) {
|
|||||||
creator := keepers.Faucet.NewFundedAccount(ctx, funds...)
|
creator := keepers.Faucet.NewFundedAccount(ctx, funds...)
|
||||||
|
|
||||||
// upload code
|
// upload code
|
||||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||||
require.NoError(t, err)
|
|
||||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, uint64(1), codeID)
|
require.Equal(t, uint64(1), codeID)
|
||||||
|
|
||||||
@@ -385,8 +328,8 @@ func TestReflectInvalidStargateQuery(t *testing.T) {
|
|||||||
Data: protoQueryBin,
|
Data: protoQueryBin,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
protoQueryBz, err := json.Marshal(ReflectQueryMsg{
|
protoQueryBz, err := json.Marshal(testdata.ReflectQueryMsg{
|
||||||
Chain: &ChainQuery{Request: &protoRequest},
|
Chain: &testdata.ChainQuery{Request: &protoRequest},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -402,8 +345,8 @@ func TestReflectInvalidStargateQuery(t *testing.T) {
|
|||||||
Data: []byte{},
|
Data: []byte{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
protoQueryBz, err = json.Marshal(ReflectQueryMsg{
|
protoQueryBz, err = json.Marshal(testdata.ReflectQueryMsg{
|
||||||
Chain: &ChainQuery{Request: &protoRequest},
|
Chain: &testdata.ChainQuery{Request: &protoRequest},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -419,8 +362,8 @@ func TestReflectInvalidStargateQuery(t *testing.T) {
|
|||||||
Data: []byte{},
|
Data: []byte{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
protoQueryBz, err = json.Marshal(ReflectQueryMsg{
|
protoQueryBz, err = json.Marshal(testdata.ReflectQueryMsg{
|
||||||
Chain: &ChainQuery{Request: &protoRequest},
|
Chain: &testdata.ChainQuery{Request: &protoRequest},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -443,9 +386,7 @@ func TestMaskReflectWasmQueries(t *testing.T) {
|
|||||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||||
|
|
||||||
// upload reflect code
|
// upload reflect code
|
||||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
reflectID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||||
require.NoError(t, err)
|
|
||||||
reflectID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, uint64(1), reflectID)
|
require.Equal(t, uint64(1), reflectID)
|
||||||
|
|
||||||
@@ -456,10 +397,10 @@ func TestMaskReflectWasmQueries(t *testing.T) {
|
|||||||
require.NotEmpty(t, reflectAddr)
|
require.NotEmpty(t, reflectAddr)
|
||||||
|
|
||||||
// for control, let's make some queries directly on the reflect
|
// for control, let's make some queries directly on the reflect
|
||||||
ownerQuery := buildReflectQuery(t, &ReflectQueryMsg{Owner: &struct{}{}})
|
ownerQuery := buildReflectQuery(t, &testdata.ReflectQueryMsg{Owner: &struct{}{}})
|
||||||
res, err := keeper.QuerySmart(ctx, reflectAddr, ownerQuery)
|
res, err := keeper.QuerySmart(ctx, reflectAddr, ownerQuery)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
var ownerRes OwnerResponse
|
var ownerRes testdata.OwnerResponse
|
||||||
mustParse(t, res, &ownerRes)
|
mustParse(t, res, &ownerRes)
|
||||||
require.Equal(t, ownerRes.Owner, creator.String())
|
require.Equal(t, ownerRes.Owner, creator.String())
|
||||||
|
|
||||||
@@ -471,7 +412,7 @@ func TestMaskReflectWasmQueries(t *testing.T) {
|
|||||||
require.Equal(t, stateRes.Owner, creator.String())
|
require.Equal(t, stateRes.Owner, creator.String())
|
||||||
|
|
||||||
// now, let's reflect a smart query into the x/wasm handlers and see if we get the same result
|
// now, let's reflect a smart query into the x/wasm handlers and see if we get the same result
|
||||||
reflectOwnerQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Wasm: &wasmvmtypes.WasmQuery{
|
reflectOwnerQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Wasm: &wasmvmtypes.WasmQuery{
|
||||||
Smart: &wasmvmtypes.SmartQuery{
|
Smart: &wasmvmtypes.SmartQuery{
|
||||||
ContractAddr: reflectAddr.String(),
|
ContractAddr: reflectAddr.String(),
|
||||||
Msg: ownerQuery,
|
Msg: ownerQuery,
|
||||||
@@ -481,14 +422,14 @@ func TestMaskReflectWasmQueries(t *testing.T) {
|
|||||||
res, err = keeper.QuerySmart(ctx, reflectAddr, reflectOwnerBin)
|
res, err = keeper.QuerySmart(ctx, reflectAddr, reflectOwnerBin)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
// first we pull out the data from chain response, before parsing the original response
|
// first we pull out the data from chain response, before parsing the original response
|
||||||
var reflectRes ChainResponse
|
var reflectRes testdata.ChainResponse
|
||||||
mustParse(t, res, &reflectRes)
|
mustParse(t, res, &reflectRes)
|
||||||
var reflectOwnerRes OwnerResponse
|
var reflectOwnerRes testdata.OwnerResponse
|
||||||
mustParse(t, reflectRes.Data, &reflectOwnerRes)
|
mustParse(t, reflectRes.Data, &reflectOwnerRes)
|
||||||
require.Equal(t, reflectOwnerRes.Owner, creator.String())
|
require.Equal(t, reflectOwnerRes.Owner, creator.String())
|
||||||
|
|
||||||
// and with queryRaw
|
// and with queryRaw
|
||||||
reflectStateQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Wasm: &wasmvmtypes.WasmQuery{
|
reflectStateQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Wasm: &wasmvmtypes.WasmQuery{
|
||||||
Raw: &wasmvmtypes.RawQuery{
|
Raw: &wasmvmtypes.RawQuery{
|
||||||
ContractAddr: reflectAddr.String(),
|
ContractAddr: reflectAddr.String(),
|
||||||
Key: configKey,
|
Key: configKey,
|
||||||
@@ -498,7 +439,7 @@ func TestMaskReflectWasmQueries(t *testing.T) {
|
|||||||
res, err = keeper.QuerySmart(ctx, reflectAddr, reflectStateBin)
|
res, err = keeper.QuerySmart(ctx, reflectAddr, reflectStateBin)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
// first we pull out the data from chain response, before parsing the original response
|
// first we pull out the data from chain response, before parsing the original response
|
||||||
var reflectRawRes ChainResponse
|
var reflectRawRes testdata.ChainResponse
|
||||||
mustParse(t, res, &reflectRawRes)
|
mustParse(t, res, &reflectRawRes)
|
||||||
// now, with the raw data, we can parse it into state
|
// now, with the raw data, we can parse it into state
|
||||||
var reflectStateRes reflectState
|
var reflectStateRes reflectState
|
||||||
@@ -515,9 +456,7 @@ func TestWasmRawQueryWithNil(t *testing.T) {
|
|||||||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||||
|
|
||||||
// upload reflect code
|
// upload reflect code
|
||||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
reflectID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||||
require.NoError(t, err)
|
|
||||||
reflectID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, uint64(1), reflectID)
|
require.Equal(t, uint64(1), reflectID)
|
||||||
|
|
||||||
@@ -533,7 +472,7 @@ func TestWasmRawQueryWithNil(t *testing.T) {
|
|||||||
require.Nil(t, raw)
|
require.Nil(t, raw)
|
||||||
|
|
||||||
// and with queryRaw
|
// and with queryRaw
|
||||||
reflectQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Wasm: &wasmvmtypes.WasmQuery{
|
reflectQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Wasm: &wasmvmtypes.WasmQuery{
|
||||||
Raw: &wasmvmtypes.RawQuery{
|
Raw: &wasmvmtypes.RawQuery{
|
||||||
ContractAddr: reflectAddr.String(),
|
ContractAddr: reflectAddr.String(),
|
||||||
Key: missingKey,
|
Key: missingKey,
|
||||||
@@ -544,7 +483,7 @@ func TestWasmRawQueryWithNil(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// first we pull out the data from chain response, before parsing the original response
|
// first we pull out the data from chain response, before parsing the original response
|
||||||
var reflectRawRes ChainResponse
|
var reflectRawRes testdata.ChainResponse
|
||||||
mustParse(t, res, &reflectRawRes)
|
mustParse(t, res, &reflectRawRes)
|
||||||
// and make sure there is no data
|
// and make sure there is no data
|
||||||
require.Empty(t, reflectRawRes.Data)
|
require.Empty(t, reflectRawRes.Data)
|
||||||
@@ -629,8 +568,8 @@ func fromReflectRawMsg(cdc codec.Codec) CustomEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type reflectCustomQuery struct {
|
type reflectCustomQuery struct {
|
||||||
Ping *struct{} `json:"ping,omitempty"`
|
Ping *struct{} `json:"ping,omitempty"`
|
||||||
Capitalized *Text `json:"capitalized,omitempty"`
|
Capitalized *testdata.Text `json:"capitalized,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is from the go code back to the contract (capitalized or ping)
|
// this is from the go code back to the contract (capitalized or ping)
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
|
|
||||||
|
|
||||||
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
||||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||||
@@ -21,6 +19,9 @@ import (
|
|||||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
|
||||||
|
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StakingInitMsg struct {
|
type StakingInitMsg struct {
|
||||||
@@ -35,12 +36,12 @@ type StakingInitMsg struct {
|
|||||||
|
|
||||||
// StakingHandleMsg is used to encode handle messages
|
// StakingHandleMsg is used to encode handle messages
|
||||||
type StakingHandleMsg struct {
|
type StakingHandleMsg struct {
|
||||||
Transfer *transferPayload `json:"transfer,omitempty"`
|
Transfer *transferPayload `json:"transfer,omitempty"`
|
||||||
Bond *struct{} `json:"bond,omitempty"`
|
Bond *struct{} `json:"bond,omitempty"`
|
||||||
Unbond *unbondPayload `json:"unbond,omitempty"`
|
Unbond *unbondPayload `json:"unbond,omitempty"`
|
||||||
Claim *struct{} `json:"claim,omitempty"`
|
Claim *struct{} `json:"claim,omitempty"`
|
||||||
Reinvest *struct{} `json:"reinvest,omitempty"`
|
Reinvest *struct{} `json:"reinvest,omitempty"`
|
||||||
Change *ownerPayload `json:"change_owner,omitempty"`
|
Change *testdata.OwnerPayload `json:"change_owner,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type transferPayload struct {
|
type transferPayload struct {
|
||||||
@@ -446,9 +447,7 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||||||
creator := initInfo.faucet.NewFundedAccount(ctx, deposit...)
|
creator := initInfo.faucet.NewFundedAccount(ctx, deposit...)
|
||||||
|
|
||||||
// upload mask code
|
// upload mask code
|
||||||
maskCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
maskID, err := initInfo.contractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||||
require.NoError(t, err)
|
|
||||||
maskID, err := initInfo.contractKeeper.Create(ctx, creator, maskCode, nil)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, uint64(2), maskID)
|
require.Equal(t, uint64(2), maskID)
|
||||||
|
|
||||||
@@ -459,21 +458,21 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||||||
|
|
||||||
// STEP 3: now, let's reflect some queries.
|
// STEP 3: now, let's reflect some queries.
|
||||||
// let's get the bonded denom
|
// let's get the bonded denom
|
||||||
reflectBondedQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
|
reflectBondedQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
|
||||||
BondedDenom: &struct{}{},
|
BondedDenom: &struct{}{},
|
||||||
}}}}
|
}}}}
|
||||||
reflectBondedBin := buildReflectQuery(t, &reflectBondedQuery)
|
reflectBondedBin := buildReflectQuery(t, &reflectBondedQuery)
|
||||||
res, err := keeper.QuerySmart(ctx, maskAddr, reflectBondedBin)
|
res, err := keeper.QuerySmart(ctx, maskAddr, reflectBondedBin)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
// first we pull out the data from chain response, before parsing the original response
|
// first we pull out the data from chain response, before parsing the original response
|
||||||
var reflectRes ChainResponse
|
var reflectRes testdata.ChainResponse
|
||||||
mustParse(t, res, &reflectRes)
|
mustParse(t, res, &reflectRes)
|
||||||
var bondedRes wasmvmtypes.BondedDenomResponse
|
var bondedRes wasmvmtypes.BondedDenomResponse
|
||||||
mustParse(t, reflectRes.Data, &bondedRes)
|
mustParse(t, reflectRes.Data, &bondedRes)
|
||||||
assert.Equal(t, "stake", bondedRes.Denom)
|
assert.Equal(t, "stake", bondedRes.Denom)
|
||||||
|
|
||||||
// now, let's reflect a smart query into the x/wasm handlers and see if we get the same result
|
// now, let's reflect a smart query into the x/wasm handlers and see if we get the same result
|
||||||
reflectAllValidatorsQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
|
reflectAllValidatorsQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
|
||||||
AllValidators: &wasmvmtypes.AllValidatorsQuery{},
|
AllValidators: &wasmvmtypes.AllValidatorsQuery{},
|
||||||
}}}}
|
}}}}
|
||||||
reflectAllValidatorsBin := buildReflectQuery(t, &reflectAllValidatorsQuery)
|
reflectAllValidatorsBin := buildReflectQuery(t, &reflectAllValidatorsQuery)
|
||||||
@@ -492,7 +491,7 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||||||
require.Contains(t, valInfo.MaxChangeRate, "0.010")
|
require.Contains(t, valInfo.MaxChangeRate, "0.010")
|
||||||
|
|
||||||
// find a validator
|
// find a validator
|
||||||
reflectValidatorQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
|
reflectValidatorQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
|
||||||
Validator: &wasmvmtypes.ValidatorQuery{
|
Validator: &wasmvmtypes.ValidatorQuery{
|
||||||
Address: valAddr.String(),
|
Address: valAddr.String(),
|
||||||
},
|
},
|
||||||
@@ -514,7 +513,7 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||||||
|
|
||||||
// missing validator
|
// missing validator
|
||||||
noVal := sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address())
|
noVal := sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address())
|
||||||
reflectNoValidatorQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
|
reflectNoValidatorQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
|
||||||
Validator: &wasmvmtypes.ValidatorQuery{
|
Validator: &wasmvmtypes.ValidatorQuery{
|
||||||
Address: noVal.String(),
|
Address: noVal.String(),
|
||||||
},
|
},
|
||||||
@@ -529,7 +528,7 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||||||
require.Nil(t, noValidatorRes.Validator)
|
require.Nil(t, noValidatorRes.Validator)
|
||||||
|
|
||||||
// test to get all my delegations
|
// test to get all my delegations
|
||||||
reflectAllDelegationsQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
|
reflectAllDelegationsQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
|
||||||
AllDelegations: &wasmvmtypes.AllDelegationsQuery{
|
AllDelegations: &wasmvmtypes.AllDelegationsQuery{
|
||||||
Delegator: contractAddr.String(),
|
Delegator: contractAddr.String(),
|
||||||
},
|
},
|
||||||
@@ -552,7 +551,7 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||||||
require.Equal(t, funds[0].Amount.String(), delInfo.Amount.Amount)
|
require.Equal(t, funds[0].Amount.String(), delInfo.Amount.Amount)
|
||||||
|
|
||||||
// test to get one delegations
|
// test to get one delegations
|
||||||
reflectDelegationQuery := ReflectQueryMsg{Chain: &ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
|
reflectDelegationQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
|
||||||
Delegation: &wasmvmtypes.DelegationQuery{
|
Delegation: &wasmvmtypes.DelegationQuery{
|
||||||
Validator: valAddr.String(),
|
Validator: valAddr.String(),
|
||||||
Delegator: contractAddr.String(),
|
Delegator: contractAddr.String(),
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
|
|
||||||
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
|
||||||
|
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// test handing of submessages, very closely related to the reflect_test
|
// test handing of submessages, very closely related to the reflect_test
|
||||||
@@ -31,9 +31,7 @@ func TestDispatchSubMsgSuccessCase(t *testing.T) {
|
|||||||
_, _, fred := keyPubAddr()
|
_, _, fred := keyPubAddr()
|
||||||
|
|
||||||
// upload code
|
// upload code
|
||||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||||
require.NoError(t, err)
|
|
||||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, uint64(1), codeID)
|
require.Equal(t, uint64(1), codeID)
|
||||||
|
|
||||||
@@ -59,8 +57,8 @@ func TestDispatchSubMsgSuccessCase(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
reflectSend := ReflectHandleMsg{
|
reflectSend := testdata.ReflectHandleMsg{
|
||||||
ReflectSubMsg: &reflectSubPayload{
|
ReflectSubMsg: &testdata.ReflectSubPayload{
|
||||||
Msgs: []wasmvmtypes.SubMsg{{
|
Msgs: []wasmvmtypes.SubMsg{{
|
||||||
ID: 7,
|
ID: 7,
|
||||||
Msg: msg,
|
Msg: msg,
|
||||||
@@ -80,8 +78,8 @@ func TestDispatchSubMsgSuccessCase(t *testing.T) {
|
|||||||
checkAccount(t, ctx, accKeeper, bankKeeper, creator, creatorBalance)
|
checkAccount(t, ctx, accKeeper, bankKeeper, creator, creatorBalance)
|
||||||
|
|
||||||
// query the reflect state to ensure the result was stored
|
// query the reflect state to ensure the result was stored
|
||||||
query := ReflectQueryMsg{
|
query := testdata.ReflectQueryMsg{
|
||||||
SubMsgResult: &SubCall{ID: 7},
|
SubMsgResult: &testdata.SubCall{ID: 7},
|
||||||
}
|
}
|
||||||
queryBz, err := json.Marshal(query)
|
queryBz, err := json.Marshal(query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -122,9 +120,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) {
|
|||||||
uploader := keepers.Faucet.NewFundedAccount(ctx, contractStart.Add(contractStart...)...)
|
uploader := keepers.Faucet.NewFundedAccount(ctx, contractStart.Add(contractStart...)...)
|
||||||
|
|
||||||
// upload code
|
// upload code
|
||||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
reflectID, err := keepers.ContractKeeper.Create(ctx, uploader, testdata.ReflectContractWasm(), nil)
|
||||||
require.NoError(t, err)
|
|
||||||
reflectID, err := keepers.ContractKeeper.Create(ctx, uploader, reflectCode, nil)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// create hackatom contract for testing (for infinite loop)
|
// create hackatom contract for testing (for infinite loop)
|
||||||
@@ -300,8 +296,8 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
msg := tc.msg(contractAddr.String(), empty.String())
|
msg := tc.msg(contractAddr.String(), empty.String())
|
||||||
reflectSend := ReflectHandleMsg{
|
reflectSend := testdata.ReflectHandleMsg{
|
||||||
ReflectSubMsg: &reflectSubPayload{
|
ReflectSubMsg: &testdata.ReflectSubPayload{
|
||||||
Msgs: []wasmvmtypes.SubMsg{{
|
Msgs: []wasmvmtypes.SubMsg{{
|
||||||
ID: tc.submsgID,
|
ID: tc.submsgID,
|
||||||
Msg: msg,
|
Msg: msg,
|
||||||
@@ -331,8 +327,8 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// query the reply
|
// query the reply
|
||||||
query := ReflectQueryMsg{
|
query := testdata.ReflectQueryMsg{
|
||||||
SubMsgResult: &SubCall{ID: tc.submsgID},
|
SubMsgResult: &testdata.SubCall{ID: tc.submsgID},
|
||||||
}
|
}
|
||||||
queryBz, err := json.Marshal(query)
|
queryBz, err := json.Marshal(query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -381,9 +377,7 @@ func TestDispatchSubMsgEncodeToNoSdkMsg(t *testing.T) {
|
|||||||
_, _, fred := keyPubAddr()
|
_, _, fred := keyPubAddr()
|
||||||
|
|
||||||
// upload code
|
// upload code
|
||||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||||
require.NoError(t, err)
|
|
||||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// creator instantiates a contract and gives it tokens
|
// creator instantiates a contract and gives it tokens
|
||||||
@@ -403,8 +397,8 @@ func TestDispatchSubMsgEncodeToNoSdkMsg(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
reflectSend := ReflectHandleMsg{
|
reflectSend := testdata.ReflectHandleMsg{
|
||||||
ReflectSubMsg: &reflectSubPayload{
|
ReflectSubMsg: &testdata.ReflectSubPayload{
|
||||||
Msgs: []wasmvmtypes.SubMsg{{
|
Msgs: []wasmvmtypes.SubMsg{{
|
||||||
ID: 7,
|
ID: 7,
|
||||||
Msg: msg,
|
Msg: msg,
|
||||||
@@ -418,8 +412,8 @@ func TestDispatchSubMsgEncodeToNoSdkMsg(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// query the reflect state to ensure the result was stored
|
// query the reflect state to ensure the result was stored
|
||||||
query := ReflectQueryMsg{
|
query := testdata.ReflectQueryMsg{
|
||||||
SubMsgResult: &SubCall{ID: 7},
|
SubMsgResult: &testdata.SubCall{ID: 7},
|
||||||
}
|
}
|
||||||
queryBz, err := json.Marshal(query)
|
queryBz, err := json.Marshal(query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -449,9 +443,7 @@ func TestDispatchSubMsgConditionalReplyOn(t *testing.T) {
|
|||||||
_, _, fred := keyPubAddr()
|
_, _, fred := keyPubAddr()
|
||||||
|
|
||||||
// upload code
|
// upload code
|
||||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||||
require.NoError(t, err)
|
|
||||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// creator instantiates a contract and gives it tokens
|
// creator instantiates a contract and gives it tokens
|
||||||
@@ -529,8 +521,8 @@ func TestDispatchSubMsgConditionalReplyOn(t *testing.T) {
|
|||||||
subMsg.ReplyOn = wasmvmtypes.ReplyError
|
subMsg.ReplyOn = wasmvmtypes.ReplyError
|
||||||
}
|
}
|
||||||
|
|
||||||
reflectSend := ReflectHandleMsg{
|
reflectSend := testdata.ReflectHandleMsg{
|
||||||
ReflectSubMsg: &reflectSubPayload{
|
ReflectSubMsg: &testdata.ReflectSubPayload{
|
||||||
Msgs: []wasmvmtypes.SubMsg{subMsg},
|
Msgs: []wasmvmtypes.SubMsg{subMsg},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -545,8 +537,8 @@ func TestDispatchSubMsgConditionalReplyOn(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// query the reflect state to check if the result was stored
|
// query the reflect state to check if the result was stored
|
||||||
query := ReflectQueryMsg{
|
query := testdata.ReflectQueryMsg{
|
||||||
SubMsgResult: &SubCall{ID: id},
|
SubMsgResult: &testdata.SubCall{ID: id},
|
||||||
}
|
}
|
||||||
queryBz, err := json.Marshal(query)
|
queryBz, err := json.Marshal(query)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
"github.com/cosmos/cosmos-sdk/std"
|
"github.com/cosmos/cosmos-sdk/std"
|
||||||
@@ -72,7 +74,7 @@ import (
|
|||||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ModuleBasics = module.NewBasicManager(
|
var moduleBasics = module.NewBasicManager(
|
||||||
auth.AppModuleBasic{},
|
auth.AppModuleBasic{},
|
||||||
bank.AppModuleBasic{},
|
bank.AppModuleBasic{},
|
||||||
capability.AppModuleBasic{},
|
capability.AppModuleBasic{},
|
||||||
@@ -103,8 +105,8 @@ func MakeEncodingConfig(_ testing.TB) wasmappparams.EncodingConfig {
|
|||||||
std.RegisterInterfaces(interfaceRegistry)
|
std.RegisterInterfaces(interfaceRegistry)
|
||||||
std.RegisterLegacyAminoCodec(amino)
|
std.RegisterLegacyAminoCodec(amino)
|
||||||
|
|
||||||
ModuleBasics.RegisterLegacyAminoCodec(amino)
|
moduleBasics.RegisterLegacyAminoCodec(amino)
|
||||||
ModuleBasics.RegisterInterfaces(interfaceRegistry)
|
moduleBasics.RegisterInterfaces(interfaceRegistry)
|
||||||
// add wasmd types
|
// add wasmd types
|
||||||
types.RegisterInterfaces(interfaceRegistry)
|
types.RegisterInterfaces(interfaceRegistry)
|
||||||
types.RegisterLegacyAminoCodec(amino)
|
types.RegisterLegacyAminoCodec(amino)
|
||||||
@@ -545,11 +547,8 @@ func StoreIBCReflectContract(t testing.TB, ctx sdk.Context, keepers TestKeepers)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StoreReflectContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) uint64 {
|
func StoreReflectContract(t testing.TB, ctx sdk.Context, keepers TestKeepers) uint64 {
|
||||||
wasmCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
_, _, creatorAddr := keyPubAddr()
|
_, _, creatorAddr := keyPubAddr()
|
||||||
codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, wasmCode, nil)
|
codeID, err := keepers.ContractKeeper.Create(ctx, creatorAddr, testdata.ReflectContractWasm(), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return codeID
|
return codeID
|
||||||
}
|
}
|
||||||
|
|||||||
62
x/wasm/keeper/testdata/reflect.go
vendored
Normal file
62
x/wasm/keeper/testdata/reflect.go
vendored
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package testdata
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
|
||||||
|
typwasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed reflect.wasm
|
||||||
|
var reflectContract []byte
|
||||||
|
|
||||||
|
func ReflectContractWasm() []byte {
|
||||||
|
return reflectContract
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReflectHandleMsg is used to encode handle messages
|
||||||
|
type ReflectHandleMsg struct {
|
||||||
|
Reflect *ReflectPayload `json:"reflect_msg,omitempty"`
|
||||||
|
ReflectSubMsg *ReflectSubPayload `json:"reflect_sub_msg,omitempty"`
|
||||||
|
ChangeOwner *OwnerPayload `json:"change_owner,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OwnerPayload struct {
|
||||||
|
Owner types.Address `json:"owner"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReflectPayload struct {
|
||||||
|
Msgs []typwasmvmtypes.CosmosMsg `json:"msgs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReflectSubPayload struct {
|
||||||
|
Msgs []typwasmvmtypes.SubMsg `json:"msgs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReflectQueryMsg is used to encode query messages
|
||||||
|
type ReflectQueryMsg struct {
|
||||||
|
Owner *struct{} `json:"owner,omitempty"`
|
||||||
|
Capitalized *Text `json:"capitalized,omitempty"`
|
||||||
|
Chain *ChainQuery `json:"chain,omitempty"`
|
||||||
|
SubMsgResult *SubCall `json:"sub_msg_result,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChainQuery struct {
|
||||||
|
Request *typwasmvmtypes.QueryRequest `json:"request,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Text struct {
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SubCall struct {
|
||||||
|
ID uint64 `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OwnerResponse struct {
|
||||||
|
Owner string `json:"owner,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChainResponse struct {
|
||||||
|
Data []byte `json:"data,omitempty"`
|
||||||
|
}
|
||||||
@@ -13,7 +13,6 @@ import (
|
|||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/types/module"
|
"github.com/cosmos/cosmos-sdk/types/module"
|
||||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||||
simKeeper "github.com/cosmos/cosmos-sdk/x/simulation"
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
@@ -105,7 +104,7 @@ type AppModule struct {
|
|||||||
keeper *Keeper
|
keeper *Keeper
|
||||||
validatorSetSource keeper.ValidatorSetSource
|
validatorSetSource keeper.ValidatorSetSource
|
||||||
accountKeeper types.AccountKeeper // for simulation
|
accountKeeper types.AccountKeeper // for simulation
|
||||||
bankKeeper simKeeper.BankKeeper
|
bankKeeper simulation.BankKeeper
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConsensusVersion is a sequence number for state-breaking change of the
|
// ConsensusVersion is a sequence number for state-breaking change of the
|
||||||
@@ -120,7 +119,7 @@ func NewAppModule(
|
|||||||
keeper *Keeper,
|
keeper *Keeper,
|
||||||
validatorSetSource keeper.ValidatorSetSource,
|
validatorSetSource keeper.ValidatorSetSource,
|
||||||
ak types.AccountKeeper,
|
ak types.AccountKeeper,
|
||||||
bk simKeeper.BankKeeper,
|
bk simulation.BankKeeper,
|
||||||
) AppModule {
|
) AppModule {
|
||||||
return AppModule{
|
return AppModule{
|
||||||
AppModuleBasic: AppModuleBasic{},
|
AppModuleBasic: AppModuleBasic{},
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/types/module"
|
"github.com/cosmos/cosmos-sdk/types/module"
|
||||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||||
@@ -66,7 +68,7 @@ var (
|
|||||||
_, _, addrAcc1 = keyPubAddr()
|
_, _, addrAcc1 = keyPubAddr()
|
||||||
addr1 = addrAcc1.String()
|
addr1 = addrAcc1.String()
|
||||||
testContract = mustLoad("./keeper/testdata/hackatom.wasm")
|
testContract = mustLoad("./keeper/testdata/hackatom.wasm")
|
||||||
maskContract = mustLoad("./keeper/testdata/reflect.wasm")
|
maskContract = testdata.ReflectContractWasm()
|
||||||
oldContract = mustLoad("./testdata/escrow_0.7.wasm")
|
oldContract = mustLoad("./testdata/escrow_0.7.wasm")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
// RandomizeGenState generates a random GenesisState for wasm
|
// RandomizeGenState generates a random GenesisState for wasm
|
||||||
func RandomizedGenState(simstate *module.SimulationState) {
|
func RandomizedGenState(simstate *module.SimulationState) {
|
||||||
params := RandomParams(simstate.Rand)
|
params := types.DefaultParams()
|
||||||
wasmGenesis := types.GenesisState{
|
wasmGenesis := types.GenesisState{
|
||||||
Params: params,
|
Params: params,
|
||||||
Codes: nil,
|
Codes: nil,
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
package simulation
|
package simulation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
|
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
||||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
|
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/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/types/module"
|
||||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||||
|
|
||||||
"github.com/CosmWasm/wasmd/app/params"
|
"github.com/CosmWasm/wasmd/app/params"
|
||||||
|
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
|
||||||
|
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
|
||||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,6 +25,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
OpWeightMsgStoreCode = "op_weight_msg_store_code"
|
OpWeightMsgStoreCode = "op_weight_msg_store_code"
|
||||||
OpWeightMsgInstantiateContract = "op_weight_msg_instantiate_contract"
|
OpWeightMsgInstantiateContract = "op_weight_msg_instantiate_contract"
|
||||||
|
OpWeightMsgExecuteContract = "op_weight_msg_execute_contract"
|
||||||
OpReflectContractPath = "op_reflect_contract_path"
|
OpReflectContractPath = "op_reflect_contract_path"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -27,18 +33,26 @@ const (
|
|||||||
type WasmKeeper interface {
|
type WasmKeeper interface {
|
||||||
GetParams(ctx sdk.Context) types.Params
|
GetParams(ctx sdk.Context) types.Params
|
||||||
IterateCodeInfos(ctx sdk.Context, cb func(uint64, types.CodeInfo) bool)
|
IterateCodeInfos(ctx sdk.Context, cb func(uint64, types.CodeInfo) bool)
|
||||||
|
IterateContractInfo(ctx sdk.Context, cb func(sdk.AccAddress, types.ContractInfo) bool)
|
||||||
|
QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []byte) ([]byte, error)
|
||||||
|
PeekAutoIncrementID(ctx sdk.Context, lastIDKey []byte) uint64
|
||||||
|
}
|
||||||
|
type BankKeeper interface {
|
||||||
|
simulation.BankKeeper
|
||||||
|
IsSendEnabledCoin(ctx sdk.Context, coin sdk.Coin) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// WeightedOperations returns all the operations from the module with their respective weights
|
// WeightedOperations returns all the operations from the module with their respective weights
|
||||||
func WeightedOperations(
|
func WeightedOperations(
|
||||||
simstate *module.SimulationState,
|
simstate *module.SimulationState,
|
||||||
ak types.AccountKeeper,
|
ak types.AccountKeeper,
|
||||||
bk simulation.BankKeeper,
|
bk BankKeeper,
|
||||||
wasmKeeper WasmKeeper,
|
wasmKeeper WasmKeeper,
|
||||||
) simulation.WeightedOperations {
|
) simulation.WeightedOperations {
|
||||||
var (
|
var (
|
||||||
weightMsgStoreCode int
|
weightMsgStoreCode int
|
||||||
weightMsgInstantiateContract int
|
weightMsgInstantiateContract int
|
||||||
|
weightMsgExecuteContract int
|
||||||
wasmContractPath string
|
wasmContractPath string
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -53,32 +67,53 @@ func WeightedOperations(
|
|||||||
weightMsgInstantiateContract = params.DefaultWeightMsgInstantiateContract
|
weightMsgInstantiateContract = params.DefaultWeightMsgInstantiateContract
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgExecuteContract, &weightMsgInstantiateContract, nil,
|
||||||
|
func(_ *rand.Rand) {
|
||||||
|
weightMsgExecuteContract = params.DefaultWeightMsgExecuteContract
|
||||||
|
},
|
||||||
|
)
|
||||||
simstate.AppParams.GetOrGenerate(simstate.Cdc, OpReflectContractPath, &wasmContractPath, nil,
|
simstate.AppParams.GetOrGenerate(simstate.Cdc, OpReflectContractPath, &wasmContractPath, nil,
|
||||||
func(_ *rand.Rand) {
|
func(_ *rand.Rand) {
|
||||||
// simulations are run from the `app` folder
|
wasmContractPath = ""
|
||||||
wasmContractPath = "../x/wasm/keeper/testdata/reflect.wasm"
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
wasmBz, err := ioutil.ReadFile(wasmContractPath)
|
var wasmBz []byte
|
||||||
if err != nil {
|
if wasmContractPath == "" {
|
||||||
panic(err)
|
wasmBz = testdata.ReflectContractWasm()
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
wasmBz, err = ioutil.ReadFile(wasmContractPath)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return simulation.WeightedOperations{
|
return simulation.WeightedOperations{
|
||||||
simulation.NewWeightedOperation(
|
simulation.NewWeightedOperation(
|
||||||
weightMsgStoreCode,
|
weightMsgStoreCode,
|
||||||
SimulateMsgStoreCode(ak, bk, wasmKeeper, wasmBz),
|
SimulateMsgStoreCode(ak, bk, wasmKeeper, wasmBz, 5_000_000),
|
||||||
),
|
),
|
||||||
simulation.NewWeightedOperation(
|
simulation.NewWeightedOperation(
|
||||||
weightMsgInstantiateContract,
|
weightMsgInstantiateContract,
|
||||||
SimulateMsgInstantiateContract(ak, bk, wasmKeeper),
|
SimulateMsgInstantiateContract(ak, bk, wasmKeeper, DefaultSimulationCodeIDSelector),
|
||||||
|
),
|
||||||
|
simulation.NewWeightedOperation(
|
||||||
|
weightMsgExecuteContract,
|
||||||
|
SimulateMsgExecuteContract(
|
||||||
|
ak,
|
||||||
|
bk,
|
||||||
|
wasmKeeper,
|
||||||
|
DefaultSimulationExecuteContractSelector,
|
||||||
|
DefaultSimulationExecuteSenderSelector,
|
||||||
|
DefaultSimulationExecutePayloader,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SimulateMsgStoreCode generates a MsgStoreCode with random values
|
// SimulateMsgStoreCode generates a MsgStoreCode with random values
|
||||||
func SimulateMsgStoreCode(ak types.AccountKeeper, bk simulation.BankKeeper, wasmKeeper WasmKeeper, wasmBz []byte) simtypes.Operation {
|
func SimulateMsgStoreCode(ak types.AccountKeeper, bk simulation.BankKeeper, wasmKeeper WasmKeeper, wasmBz []byte, gas uint64) simtypes.Operation {
|
||||||
return func(
|
return func(
|
||||||
r *rand.Rand,
|
r *rand.Rand,
|
||||||
app *baseapp.BaseApp,
|
app *baseapp.BaseApp,
|
||||||
@@ -90,15 +125,15 @@ func SimulateMsgStoreCode(ak types.AccountKeeper, bk simulation.BankKeeper, wasm
|
|||||||
return simtypes.NoOpMsg(types.ModuleName, types.MsgStoreCode{}.Type(), "no chain permission"), nil, nil
|
return simtypes.NoOpMsg(types.ModuleName, types.MsgStoreCode{}.Type(), "no chain permission"), nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &types.AccessConfig{
|
|
||||||
Permission: types.AccessTypeEverybody,
|
|
||||||
}
|
|
||||||
|
|
||||||
simAccount, _ := simtypes.RandomAcc(r, accs)
|
simAccount, _ := simtypes.RandomAcc(r, accs)
|
||||||
|
|
||||||
|
permission := wasmKeeper.GetParams(ctx).InstantiateDefaultPermission
|
||||||
|
config := permission.With(simAccount.Address)
|
||||||
|
|
||||||
msg := types.MsgStoreCode{
|
msg := types.MsgStoreCode{
|
||||||
Sender: simAccount.Address.String(),
|
Sender: simAccount.Address.String(),
|
||||||
WASMByteCode: wasmBz,
|
WASMByteCode: wasmBz,
|
||||||
InstantiatePermission: config,
|
InstantiatePermission: &config,
|
||||||
}
|
}
|
||||||
|
|
||||||
txCtx := simulation.OperationInput{
|
txCtx := simulation.OperationInput{
|
||||||
@@ -115,12 +150,28 @@ func SimulateMsgStoreCode(ak types.AccountKeeper, bk simulation.BankKeeper, wasm
|
|||||||
ModuleName: types.ModuleName,
|
ModuleName: types.ModuleName,
|
||||||
}
|
}
|
||||||
|
|
||||||
return simulation.GenAndDeliverTxWithRandFees(txCtx)
|
return GenAndDeliverTxWithRandFees(txCtx, gas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CodeIDSelector returns code id to be used in simulations
|
||||||
|
type CodeIDSelector = func(ctx sdk.Context, wasmKeeper WasmKeeper) uint64
|
||||||
|
|
||||||
|
// DefaultSimulationCodeIDSelector picks the first code id
|
||||||
|
func DefaultSimulationCodeIDSelector(ctx sdk.Context, wasmKeeper WasmKeeper) uint64 {
|
||||||
|
var codeID uint64
|
||||||
|
wasmKeeper.IterateCodeInfos(ctx, func(u uint64, info types.CodeInfo) bool {
|
||||||
|
if info.InstantiateConfig.Permission != types.AccessTypeEverybody {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
codeID = u
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return codeID
|
||||||
|
}
|
||||||
|
|
||||||
// SimulateMsgInstantiateContract generates a MsgInstantiateContract with random values
|
// SimulateMsgInstantiateContract generates a MsgInstantiateContract with random values
|
||||||
func SimulateMsgInstantiateContract(ak types.AccountKeeper, bk simulation.BankKeeper, wasmKeeper WasmKeeper) simtypes.Operation {
|
func SimulateMsgInstantiateContract(ak types.AccountKeeper, bk BankKeeper, wasmKeeper WasmKeeper, codeSelector CodeIDSelector) simtypes.Operation {
|
||||||
return func(
|
return func(
|
||||||
r *rand.Rand,
|
r *rand.Rand,
|
||||||
app *baseapp.BaseApp,
|
app *baseapp.BaseApp,
|
||||||
@@ -130,20 +181,17 @@ func SimulateMsgInstantiateContract(ak types.AccountKeeper, bk simulation.BankKe
|
|||||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||||
simAccount, _ := simtypes.RandomAcc(r, accs)
|
simAccount, _ := simtypes.RandomAcc(r, accs)
|
||||||
|
|
||||||
var codeID uint64
|
codeID := codeSelector(ctx, wasmKeeper)
|
||||||
wasmKeeper.IterateCodeInfos(ctx, func(u uint64, info types.CodeInfo) bool {
|
|
||||||
if info.InstantiateConfig.Permission != types.AccessTypeEverybody {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
codeID = u
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
if codeID == 0 {
|
if codeID == 0 {
|
||||||
return simtypes.NoOpMsg(types.ModuleName, types.MsgInstantiateContract{}.Type(), "no codes with permission available"), nil, nil
|
return simtypes.NoOpMsg(types.ModuleName, types.MsgInstantiateContract{}.Type(), "no codes with permission available"), nil, nil
|
||||||
}
|
}
|
||||||
|
deposit := sdk.Coins{}
|
||||||
spendable := bk.SpendableCoins(ctx, simAccount.Address)
|
spendableCoins := bk.SpendableCoins(ctx, simAccount.Address)
|
||||||
|
for _, v := range spendableCoins {
|
||||||
|
if bk.IsSendEnabledCoin(ctx, v) {
|
||||||
|
deposit = deposit.Add(simtypes.RandSubsetCoins(r, sdk.NewCoins(v))...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
msg := types.MsgInstantiateContract{
|
msg := types.MsgInstantiateContract{
|
||||||
Sender: simAccount.Address.String(),
|
Sender: simAccount.Address.String(),
|
||||||
@@ -151,23 +199,154 @@ func SimulateMsgInstantiateContract(ak types.AccountKeeper, bk simulation.BankKe
|
|||||||
CodeID: codeID,
|
CodeID: codeID,
|
||||||
Label: simtypes.RandStringOfLength(r, 10),
|
Label: simtypes.RandStringOfLength(r, 10),
|
||||||
Msg: []byte(`{}`),
|
Msg: []byte(`{}`),
|
||||||
Funds: simtypes.RandSubsetCoins(r, spendable),
|
Funds: deposit,
|
||||||
}
|
}
|
||||||
|
|
||||||
txCtx := simulation.OperationInput{
|
txCtx := simulation.OperationInput{
|
||||||
R: r,
|
R: r,
|
||||||
App: app,
|
App: app,
|
||||||
TxGen: simappparams.MakeTestEncodingConfig().TxConfig,
|
TxGen: simappparams.MakeTestEncodingConfig().TxConfig,
|
||||||
Cdc: nil,
|
Cdc: nil,
|
||||||
Msg: &msg,
|
Msg: &msg,
|
||||||
MsgType: msg.Type(),
|
MsgType: msg.Type(),
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
SimAccount: simAccount,
|
SimAccount: simAccount,
|
||||||
AccountKeeper: ak,
|
AccountKeeper: ak,
|
||||||
Bankkeeper: bk,
|
Bankkeeper: bk,
|
||||||
ModuleName: types.ModuleName,
|
ModuleName: types.ModuleName,
|
||||||
|
CoinsSpentInMsg: deposit,
|
||||||
}
|
}
|
||||||
|
|
||||||
return simulation.GenAndDeliverTxWithRandFees(txCtx)
|
return simulation.GenAndDeliverTxWithRandFees(txCtx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MsgExecuteContractSelector returns contract address to be used in simulations
|
||||||
|
type MsgExecuteContractSelector = func(ctx sdk.Context, wasmKeeper WasmKeeper) sdk.AccAddress
|
||||||
|
|
||||||
|
// MsgExecutePayloader extension point to modify msg with custom payload
|
||||||
|
type MsgExecutePayloader func(msg *types.MsgExecuteContract) error
|
||||||
|
|
||||||
|
// MsgExecuteSenderSelector extension point that returns the sender address
|
||||||
|
type MsgExecuteSenderSelector func(wasmKeeper WasmKeeper, ctx sdk.Context, contractAddr sdk.AccAddress, accs []simtypes.Account) (simtypes.Account, error)
|
||||||
|
|
||||||
|
// SimulateMsgExecuteContract create a execute message a reflect contract instance
|
||||||
|
func SimulateMsgExecuteContract(
|
||||||
|
ak types.AccountKeeper,
|
||||||
|
bk BankKeeper,
|
||||||
|
wasmKeeper WasmKeeper,
|
||||||
|
contractSelector MsgExecuteContractSelector,
|
||||||
|
senderSelector MsgExecuteSenderSelector,
|
||||||
|
payloader MsgExecutePayloader,
|
||||||
|
) simtypes.Operation {
|
||||||
|
return func(
|
||||||
|
r *rand.Rand,
|
||||||
|
app *baseapp.BaseApp,
|
||||||
|
ctx sdk.Context,
|
||||||
|
accs []simtypes.Account,
|
||||||
|
chainID string,
|
||||||
|
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||||
|
contractAddr := contractSelector(ctx, wasmKeeper)
|
||||||
|
if contractAddr == nil {
|
||||||
|
return simtypes.NoOpMsg(types.ModuleName, types.MsgExecuteContract{}.Type(), "no contract instance available"), nil, nil
|
||||||
|
}
|
||||||
|
simAccount, err := senderSelector(wasmKeeper, ctx, contractAddr, accs)
|
||||||
|
if err != nil {
|
||||||
|
return simtypes.NoOpMsg(types.ModuleName, types.MsgExecuteContract{}.Type(), "query contract owner"), nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
deposit := sdk.Coins{}
|
||||||
|
spendableCoins := bk.SpendableCoins(ctx, simAccount.Address)
|
||||||
|
for _, v := range spendableCoins {
|
||||||
|
if bk.IsSendEnabledCoin(ctx, v) {
|
||||||
|
deposit = deposit.Add(simtypes.RandSubsetCoins(r, sdk.NewCoins(v))...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if deposit.IsZero() {
|
||||||
|
return simtypes.NoOpMsg(types.ModuleName, types.MsgExecuteContract{}.Type(), "broke account"), nil, nil
|
||||||
|
}
|
||||||
|
msg := types.MsgExecuteContract{
|
||||||
|
Sender: simAccount.Address.String(),
|
||||||
|
Contract: contractAddr.String(),
|
||||||
|
Funds: deposit,
|
||||||
|
}
|
||||||
|
if err := payloader(&msg); err != nil {
|
||||||
|
return simtypes.NoOpMsg(types.ModuleName, types.MsgExecuteContract{}.Type(), "contract execute payload"), nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
txCtx := simulation.OperationInput{
|
||||||
|
R: r,
|
||||||
|
App: app,
|
||||||
|
TxGen: simappparams.MakeTestEncodingConfig().TxConfig,
|
||||||
|
Cdc: nil,
|
||||||
|
Msg: &msg,
|
||||||
|
MsgType: msg.Type(),
|
||||||
|
Context: ctx,
|
||||||
|
SimAccount: simAccount,
|
||||||
|
AccountKeeper: ak,
|
||||||
|
Bankkeeper: bk,
|
||||||
|
ModuleName: types.ModuleName,
|
||||||
|
CoinsSpentInMsg: deposit,
|
||||||
|
}
|
||||||
|
return simulation.GenAndDeliverTxWithRandFees(txCtx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultSimulationExecuteContractSelector picks the first contract address
|
||||||
|
func DefaultSimulationExecuteContractSelector(ctx sdk.Context, wasmKeeper WasmKeeper) sdk.AccAddress {
|
||||||
|
var r sdk.AccAddress
|
||||||
|
wasmKeeper.IterateContractInfo(ctx, func(address sdk.AccAddress, info types.ContractInfo) bool {
|
||||||
|
r = address
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultSimulationExecuteSenderSelector queries reflect contract for owner address and selects accounts
|
||||||
|
func DefaultSimulationExecuteSenderSelector(wasmKeeper WasmKeeper, ctx sdk.Context, contractAddr sdk.AccAddress, accs []simtypes.Account) (simtypes.Account, error) {
|
||||||
|
var none simtypes.Account
|
||||||
|
bz, err := json.Marshal(testdata.ReflectQueryMsg{Owner: &struct{}{}})
|
||||||
|
if err != nil {
|
||||||
|
return none, sdkerrors.Wrap(err, "build smart query")
|
||||||
|
}
|
||||||
|
got, err := wasmKeeper.QuerySmart(ctx, contractAddr, bz)
|
||||||
|
if err != nil {
|
||||||
|
return none, sdkerrors.Wrap(err, "exec smart query")
|
||||||
|
}
|
||||||
|
var ownerRes testdata.OwnerResponse
|
||||||
|
if err := json.Unmarshal(got, &ownerRes); err != nil || ownerRes.Owner == "" {
|
||||||
|
return none, sdkerrors.Wrap(err, "parse smart query response")
|
||||||
|
}
|
||||||
|
ownerAddr, err := sdk.AccAddressFromBech32(ownerRes.Owner)
|
||||||
|
if err != nil {
|
||||||
|
return none, sdkerrors.Wrap(err, "parse contract owner address")
|
||||||
|
}
|
||||||
|
simAccount, ok := simtypes.FindAccount(accs, ownerAddr)
|
||||||
|
if !ok {
|
||||||
|
return none, sdkerrors.Wrap(err, "unknown contract owner address")
|
||||||
|
}
|
||||||
|
return simAccount, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultSimulationExecutePayloader implements a bank msg to send the
|
||||||
|
// tokens from contract account back to original sender
|
||||||
|
func DefaultSimulationExecutePayloader(msg *types.MsgExecuteContract) error {
|
||||||
|
reflectSend := testdata.ReflectHandleMsg{
|
||||||
|
Reflect: &testdata.ReflectPayload{
|
||||||
|
Msgs: []wasmvmtypes.CosmosMsg{{
|
||||||
|
Bank: &wasmvmtypes.BankMsg{
|
||||||
|
Send: &wasmvmtypes.SendMsg{
|
||||||
|
ToAddress: msg.Sender, //
|
||||||
|
Amount: wasmkeeper.ConvertSdkCoinsToWasmCoins(msg.Funds),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
reflectSendBz, err := json.Marshal(reflectSend)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
msg.Msg = reflectSendBz
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func ParamChanges(r *rand.Rand, cdc codec.Codec) []simtypes.ParamChange {
|
func ParamChanges(r *rand.Rand, cdc codec.Codec) []simtypes.ParamChange {
|
||||||
params := RandomParams(r)
|
params := types.DefaultParams()
|
||||||
return []simtypes.ParamChange{
|
return []simtypes.ParamChange{
|
||||||
simulation.NewSimParamChange(types.ModuleName, string(types.ParamStoreKeyUploadAccess),
|
simulation.NewSimParamChange(types.ModuleName, string(types.ParamStoreKeyUploadAccess),
|
||||||
func(r *rand.Rand) string {
|
func(r *rand.Rand) string {
|
||||||
@@ -30,13 +30,3 @@ func ParamChanges(r *rand.Rand, cdc codec.Codec) []simtypes.ParamChange {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func RandomParams(r *rand.Rand) types.Params {
|
|
||||||
permissionType := types.AccessType(simtypes.RandIntBetween(r, 1, 3))
|
|
||||||
account, _ := simtypes.RandomAcc(r, simtypes.RandomAccounts(r, 10))
|
|
||||||
accessConfig := permissionType.With(account.Address)
|
|
||||||
return types.Params{
|
|
||||||
CodeUploadAccess: accessConfig,
|
|
||||||
InstantiateDefaultPermission: accessConfig.Permission,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
53
x/wasm/simulation/sim_utils.go
Normal file
53
x/wasm/simulation/sim_utils.go
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package simulation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cosmos/cosmos-sdk/simapp/helpers"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GenAndDeliverTxWithRandFees generates a transaction with a random fee and delivers it.
|
||||||
|
func GenAndDeliverTxWithRandFees(txCtx simulation.OperationInput, gas uint64) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||||
|
account := txCtx.AccountKeeper.GetAccount(txCtx.Context, txCtx.SimAccount.Address)
|
||||||
|
spendable := txCtx.Bankkeeper.SpendableCoins(txCtx.Context, account.GetAddress())
|
||||||
|
|
||||||
|
var fees sdk.Coins
|
||||||
|
var err error
|
||||||
|
|
||||||
|
coins, hasNeg := spendable.SafeSub(txCtx.CoinsSpentInMsg)
|
||||||
|
if hasNeg {
|
||||||
|
return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "message doesn't leave room for fees"), nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fees, err = simtypes.RandomFees(txCtx.R, txCtx.Context, coins)
|
||||||
|
if err != nil {
|
||||||
|
return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to generate fees"), nil, err
|
||||||
|
}
|
||||||
|
return GenAndDeliverTx(txCtx, fees, gas)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenAndDeliverTx generates a transactions and delivers it.
|
||||||
|
func GenAndDeliverTx(txCtx simulation.OperationInput, fees sdk.Coins, gas uint64) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||||
|
account := txCtx.AccountKeeper.GetAccount(txCtx.Context, txCtx.SimAccount.Address)
|
||||||
|
tx, err := helpers.GenTx(
|
||||||
|
txCtx.TxGen,
|
||||||
|
[]sdk.Msg{txCtx.Msg},
|
||||||
|
fees,
|
||||||
|
gas,
|
||||||
|
txCtx.Context.ChainID(),
|
||||||
|
[]uint64{account.GetAccountNumber()},
|
||||||
|
[]uint64{account.GetSequence()},
|
||||||
|
txCtx.SimAccount.PrivKey,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to generate mock tx"), nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err = txCtx.App.Deliver(txCtx.TxGen.TxEncoder(), tx)
|
||||||
|
if err != nil {
|
||||||
|
return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to deliver tx"), nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return simtypes.NewOperationMsg(txCtx.Msg, true, "", txCtx.Cdc), nil, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user