mirror of https://github.com/certusone/wasmd.git
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:
parent
34e078346b
commit
2a9c5c1ea5
|
@ -116,6 +116,19 @@ jobs:
|
|||
cd ./benchmarks
|
||||
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:
|
||||
executor: golang
|
||||
steps:
|
||||
|
@ -218,3 +231,6 @@ workflows:
|
|||
- benchmark:
|
||||
requires:
|
||||
- test-cover
|
||||
- simulations:
|
||||
requires:
|
||||
- setup-dependencies
|
||||
|
|
|
@ -458,7 +458,6 @@ func NewWasmApp(
|
|||
transferModule := transfer.NewAppModule(app.transferKeeper)
|
||||
transferIBCModule := transfer.NewIBCModule(app.transferKeeper)
|
||||
|
||||
_ = app.getSubspace(icahosttypes.SubModuleName)
|
||||
app.icaHostKeeper = icahostkeeper.NewKeeper(
|
||||
appCodec,
|
||||
keys[icahosttypes.StoreKey],
|
||||
|
|
|
@ -20,6 +20,7 @@ const (
|
|||
DefaultWeightCommunitySpendProposal int = 5
|
||||
DefaultWeightTextProposal int = 5
|
||||
DefaultWeightParamChangeProposal int = 5
|
||||
DefaultWeightMsgStoreCode int = 100
|
||||
DefaultWeightMsgStoreCode int = 50
|
||||
DefaultWeightMsgInstantiateContract int = 100
|
||||
DefaultWeightMsgExecuteContract int = 100
|
||||
)
|
||||
|
|
|
@ -6,11 +6,17 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"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/codec"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/kv"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
|
||||
|
@ -118,7 +124,7 @@ func TestAppImportExport(t *testing.T) {
|
|||
t,
|
||||
os.Stdout,
|
||||
app.BaseApp,
|
||||
simapp.AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||
AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||
simtypes.RandomAccounts,
|
||||
simapp.SimulationOperations(app, app.AppCodec(), config),
|
||||
app.ModuleAccountAddrs(),
|
||||
|
@ -190,6 +196,37 @@ func TestAppImportExport(t *testing.T) {
|
|||
// delete persistent tx counter value
|
||||
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
|
||||
for _, skp := range storeKeysPrefixes {
|
||||
storeA := ctxA.KVStore(skp.A)
|
||||
|
@ -215,7 +252,7 @@ func TestFullAppSimulation(t *testing.T) {
|
|||
require.NoError(t, os.RemoveAll(dir))
|
||||
}()
|
||||
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)
|
||||
require.Equal(t, "WasmApp", app.Name())
|
||||
|
||||
|
@ -224,7 +261,7 @@ func TestFullAppSimulation(t *testing.T) {
|
|||
t,
|
||||
os.Stdout,
|
||||
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
|
||||
simapp.SimulationOperations(app, app.AppCodec(), config),
|
||||
app.ModuleAccountAddrs(),
|
||||
|
@ -241,3 +278,15 @@ func TestFullAppSimulation(t *testing.T) {
|
|||
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"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
||||
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
|
@ -16,62 +14,17 @@ import (
|
|||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
)
|
||||
|
||||
// ReflectInitMsg is {}
|
||||
|
||||
// ReflectHandleMsg is used to encode handle messages
|
||||
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 {
|
||||
func buildReflectQuery(t *testing.T, query *testdata.ReflectQueryMsg) []byte {
|
||||
bz, err := json.Marshal(query)
|
||||
require.NoError(t, err)
|
||||
return bz
|
||||
|
@ -94,9 +47,7 @@ func TestReflectContractSend(t *testing.T) {
|
|||
_, _, bob := keyPubAddr()
|
||||
|
||||
// upload reflect code
|
||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
||||
require.NoError(t, err)
|
||||
reflectID, err := keeper.Create(ctx, creator, reflectCode, nil)
|
||||
reflectID, err := keeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), reflectID)
|
||||
|
||||
|
@ -148,8 +99,8 @@ func TestReflectContractSend(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}}
|
||||
reflectSend := ReflectHandleMsg{
|
||||
Reflect: &reflectPayload{
|
||||
reflectSend := testdata.ReflectHandleMsg{
|
||||
Reflect: &testdata.ReflectPayload{
|
||||
Msgs: msgs,
|
||||
},
|
||||
}
|
||||
|
@ -176,9 +127,7 @@ func TestReflectCustomMsg(t *testing.T) {
|
|||
_, _, fred := keyPubAddr()
|
||||
|
||||
// upload code
|
||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
||||
require.NoError(t, err)
|
||||
codeID, err := keeper.Create(ctx, creator, reflectCode, nil)
|
||||
codeID, err := keeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), codeID)
|
||||
|
||||
|
@ -189,8 +138,8 @@ func TestReflectCustomMsg(t *testing.T) {
|
|||
require.NotEmpty(t, contractAddr)
|
||||
|
||||
// set owner to bob
|
||||
transfer := ReflectHandleMsg{
|
||||
Change: &ownerPayload{
|
||||
transfer := testdata.ReflectHandleMsg{
|
||||
ChangeOwner: &testdata.OwnerPayload{
|
||||
Owner: bob,
|
||||
},
|
||||
}
|
||||
|
@ -216,8 +165,8 @@ func TestReflectCustomMsg(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}}
|
||||
reflectSend := ReflectHandleMsg{
|
||||
Reflect: &reflectPayload{
|
||||
reflectSend := testdata.ReflectHandleMsg{
|
||||
Reflect: &testdata.ReflectPayload{
|
||||
Msgs: msgs,
|
||||
},
|
||||
}
|
||||
|
@ -240,8 +189,8 @@ func TestReflectCustomMsg(t *testing.T) {
|
|||
}
|
||||
opaque, err := toReflectRawMsg(cdc, sdkSendMsg)
|
||||
require.NoError(t, err)
|
||||
reflectOpaque := ReflectHandleMsg{
|
||||
Reflect: &reflectPayload{
|
||||
reflectOpaque := testdata.ReflectHandleMsg{
|
||||
Reflect: &testdata.ReflectPayload{
|
||||
Msgs: []wasmvmtypes.CosmosMsg{opaque},
|
||||
},
|
||||
}
|
||||
|
@ -267,9 +216,7 @@ func TestMaskReflectCustomQuery(t *testing.T) {
|
|||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
|
||||
// upload code
|
||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
||||
require.NoError(t, err)
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), codeID)
|
||||
|
||||
|
@ -280,21 +227,21 @@ func TestMaskReflectCustomQuery(t *testing.T) {
|
|||
require.NotEmpty(t, contractAddr)
|
||||
|
||||
// let's perform a normal query of state
|
||||
ownerQuery := ReflectQueryMsg{
|
||||
ownerQuery := testdata.ReflectQueryMsg{
|
||||
Owner: &struct{}{},
|
||||
}
|
||||
ownerQueryBz, err := json.Marshal(ownerQuery)
|
||||
require.NoError(t, err)
|
||||
ownerRes, err := keeper.QuerySmart(ctx, contractAddr, ownerQueryBz)
|
||||
require.NoError(t, err)
|
||||
var res OwnerResponse
|
||||
var res testdata.OwnerResponse
|
||||
err = json.Unmarshal(ownerRes, &res)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, res.Owner, creator.String())
|
||||
|
||||
// and now making use of the custom querier callbacks
|
||||
customQuery := ReflectQueryMsg{
|
||||
Capitalized: &Text{
|
||||
customQuery := testdata.ReflectQueryMsg{
|
||||
Capitalized: &testdata.Text{
|
||||
Text: "all Caps noW",
|
||||
},
|
||||
}
|
||||
|
@ -319,9 +266,7 @@ func TestReflectStargateQuery(t *testing.T) {
|
|||
creator := keepers.Faucet.NewFundedAccount(ctx, funds...)
|
||||
|
||||
// upload code
|
||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
||||
require.NoError(t, err)
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), codeID)
|
||||
|
||||
|
@ -338,13 +283,13 @@ func TestReflectStargateQuery(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
simpleQueryBz, err := json.Marshal(ReflectQueryMsg{
|
||||
Chain: &ChainQuery{Request: &bankQuery},
|
||||
simpleQueryBz, err := json.Marshal(testdata.ReflectQueryMsg{
|
||||
Chain: &testdata.ChainQuery{Request: &bankQuery},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
simpleRes, err := keeper.QuerySmart(ctx, contractAddr, simpleQueryBz)
|
||||
require.NoError(t, err)
|
||||
var simpleChain ChainResponse
|
||||
var simpleChain testdata.ChainResponse
|
||||
mustParse(t, simpleRes, &simpleChain)
|
||||
var simpleBalance wasmvmtypes.AllBalancesResponse
|
||||
mustParse(t, simpleChain.Data, &simpleBalance)
|
||||
|
@ -363,9 +308,7 @@ func TestReflectInvalidStargateQuery(t *testing.T) {
|
|||
creator := keepers.Faucet.NewFundedAccount(ctx, funds...)
|
||||
|
||||
// upload code
|
||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
||||
require.NoError(t, err)
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), codeID)
|
||||
|
||||
|
@ -385,8 +328,8 @@ func TestReflectInvalidStargateQuery(t *testing.T) {
|
|||
Data: protoQueryBin,
|
||||
},
|
||||
}
|
||||
protoQueryBz, err := json.Marshal(ReflectQueryMsg{
|
||||
Chain: &ChainQuery{Request: &protoRequest},
|
||||
protoQueryBz, err := json.Marshal(testdata.ReflectQueryMsg{
|
||||
Chain: &testdata.ChainQuery{Request: &protoRequest},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -402,8 +345,8 @@ func TestReflectInvalidStargateQuery(t *testing.T) {
|
|||
Data: []byte{},
|
||||
},
|
||||
}
|
||||
protoQueryBz, err = json.Marshal(ReflectQueryMsg{
|
||||
Chain: &ChainQuery{Request: &protoRequest},
|
||||
protoQueryBz, err = json.Marshal(testdata.ReflectQueryMsg{
|
||||
Chain: &testdata.ChainQuery{Request: &protoRequest},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -419,8 +362,8 @@ func TestReflectInvalidStargateQuery(t *testing.T) {
|
|||
Data: []byte{},
|
||||
},
|
||||
}
|
||||
protoQueryBz, err = json.Marshal(ReflectQueryMsg{
|
||||
Chain: &ChainQuery{Request: &protoRequest},
|
||||
protoQueryBz, err = json.Marshal(testdata.ReflectQueryMsg{
|
||||
Chain: &testdata.ChainQuery{Request: &protoRequest},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -443,9 +386,7 @@ func TestMaskReflectWasmQueries(t *testing.T) {
|
|||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
|
||||
// upload reflect code
|
||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
||||
require.NoError(t, err)
|
||||
reflectID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
||||
reflectID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), reflectID)
|
||||
|
||||
|
@ -456,10 +397,10 @@ func TestMaskReflectWasmQueries(t *testing.T) {
|
|||
require.NotEmpty(t, reflectAddr)
|
||||
|
||||
// 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)
|
||||
require.NoError(t, err)
|
||||
var ownerRes OwnerResponse
|
||||
var ownerRes testdata.OwnerResponse
|
||||
mustParse(t, res, &ownerRes)
|
||||
require.Equal(t, ownerRes.Owner, creator.String())
|
||||
|
||||
|
@ -471,7 +412,7 @@ func TestMaskReflectWasmQueries(t *testing.T) {
|
|||
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
|
||||
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{
|
||||
ContractAddr: reflectAddr.String(),
|
||||
Msg: ownerQuery,
|
||||
|
@ -481,14 +422,14 @@ func TestMaskReflectWasmQueries(t *testing.T) {
|
|||
res, err = keeper.QuerySmart(ctx, reflectAddr, reflectOwnerBin)
|
||||
require.NoError(t, err)
|
||||
// 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)
|
||||
var reflectOwnerRes OwnerResponse
|
||||
var reflectOwnerRes testdata.OwnerResponse
|
||||
mustParse(t, reflectRes.Data, &reflectOwnerRes)
|
||||
require.Equal(t, reflectOwnerRes.Owner, creator.String())
|
||||
|
||||
// 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{
|
||||
ContractAddr: reflectAddr.String(),
|
||||
Key: configKey,
|
||||
|
@ -498,7 +439,7 @@ func TestMaskReflectWasmQueries(t *testing.T) {
|
|||
res, err = keeper.QuerySmart(ctx, reflectAddr, reflectStateBin)
|
||||
require.NoError(t, err)
|
||||
// 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)
|
||||
// now, with the raw data, we can parse it into state
|
||||
var reflectStateRes reflectState
|
||||
|
@ -515,9 +456,7 @@ func TestWasmRawQueryWithNil(t *testing.T) {
|
|||
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)
|
||||
|
||||
// upload reflect code
|
||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
||||
require.NoError(t, err)
|
||||
reflectID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
||||
reflectID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), reflectID)
|
||||
|
||||
|
@ -533,7 +472,7 @@ func TestWasmRawQueryWithNil(t *testing.T) {
|
|||
require.Nil(t, raw)
|
||||
|
||||
// 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{
|
||||
ContractAddr: reflectAddr.String(),
|
||||
Key: missingKey,
|
||||
|
@ -544,7 +483,7 @@ func TestWasmRawQueryWithNil(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// 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)
|
||||
// and make sure there is no data
|
||||
require.Empty(t, reflectRawRes.Data)
|
||||
|
@ -629,8 +568,8 @@ func fromReflectRawMsg(cdc codec.Codec) CustomEncoder {
|
|||
}
|
||||
|
||||
type reflectCustomQuery struct {
|
||||
Ping *struct{} `json:"ping,omitempty"`
|
||||
Capitalized *Text `json:"capitalized,omitempty"`
|
||||
Ping *struct{} `json:"ping,omitempty"`
|
||||
Capitalized *testdata.Text `json:"capitalized,omitempty"`
|
||||
}
|
||||
|
||||
// this is from the go code back to the contract (capitalized or ping)
|
||||
|
|
|
@ -5,8 +5,6 @@ import (
|
|||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
|
||||
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
|
@ -21,6 +19,9 @@ import (
|
|||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
|
||||
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
)
|
||||
|
||||
type StakingInitMsg struct {
|
||||
|
@ -35,12 +36,12 @@ type StakingInitMsg struct {
|
|||
|
||||
// StakingHandleMsg is used to encode handle messages
|
||||
type StakingHandleMsg struct {
|
||||
Transfer *transferPayload `json:"transfer,omitempty"`
|
||||
Bond *struct{} `json:"bond,omitempty"`
|
||||
Unbond *unbondPayload `json:"unbond,omitempty"`
|
||||
Claim *struct{} `json:"claim,omitempty"`
|
||||
Reinvest *struct{} `json:"reinvest,omitempty"`
|
||||
Change *ownerPayload `json:"change_owner,omitempty"`
|
||||
Transfer *transferPayload `json:"transfer,omitempty"`
|
||||
Bond *struct{} `json:"bond,omitempty"`
|
||||
Unbond *unbondPayload `json:"unbond,omitempty"`
|
||||
Claim *struct{} `json:"claim,omitempty"`
|
||||
Reinvest *struct{} `json:"reinvest,omitempty"`
|
||||
Change *testdata.OwnerPayload `json:"change_owner,omitempty"`
|
||||
}
|
||||
|
||||
type transferPayload struct {
|
||||
|
@ -446,9 +447,7 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||
creator := initInfo.faucet.NewFundedAccount(ctx, deposit...)
|
||||
|
||||
// upload mask code
|
||||
maskCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
||||
require.NoError(t, err)
|
||||
maskID, err := initInfo.contractKeeper.Create(ctx, creator, maskCode, nil)
|
||||
maskID, err := initInfo.contractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(2), maskID)
|
||||
|
||||
|
@ -459,21 +458,21 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||
|
||||
// STEP 3: now, let's reflect some queries.
|
||||
// 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{}{},
|
||||
}}}}
|
||||
reflectBondedBin := buildReflectQuery(t, &reflectBondedQuery)
|
||||
res, err := keeper.QuerySmart(ctx, maskAddr, reflectBondedBin)
|
||||
require.NoError(t, err)
|
||||
// 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)
|
||||
var bondedRes wasmvmtypes.BondedDenomResponse
|
||||
mustParse(t, reflectRes.Data, &bondedRes)
|
||||
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
|
||||
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{},
|
||||
}}}}
|
||||
reflectAllValidatorsBin := buildReflectQuery(t, &reflectAllValidatorsQuery)
|
||||
|
@ -492,7 +491,7 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||
require.Contains(t, valInfo.MaxChangeRate, "0.010")
|
||||
|
||||
// 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{
|
||||
Address: valAddr.String(),
|
||||
},
|
||||
|
@ -514,7 +513,7 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||
|
||||
// missing validator
|
||||
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{
|
||||
Address: noVal.String(),
|
||||
},
|
||||
|
@ -529,7 +528,7 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||
require.Nil(t, noValidatorRes.Validator)
|
||||
|
||||
// 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{
|
||||
Delegator: contractAddr.String(),
|
||||
},
|
||||
|
@ -552,7 +551,7 @@ func TestQueryStakingInfo(t *testing.T) {
|
|||
require.Equal(t, funds[0].Amount.String(), delInfo.Amount.Amount)
|
||||
|
||||
// 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{
|
||||
Validator: valAddr.String(),
|
||||
Delegator: contractAddr.String(),
|
||||
|
|
|
@ -7,13 +7,13 @@ import (
|
|||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"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
|
||||
|
@ -31,9 +31,7 @@ func TestDispatchSubMsgSuccessCase(t *testing.T) {
|
|||
_, _, fred := keyPubAddr()
|
||||
|
||||
// upload code
|
||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
||||
require.NoError(t, err)
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(1), codeID)
|
||||
|
||||
|
@ -59,8 +57,8 @@ func TestDispatchSubMsgSuccessCase(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
reflectSend := ReflectHandleMsg{
|
||||
ReflectSubMsg: &reflectSubPayload{
|
||||
reflectSend := testdata.ReflectHandleMsg{
|
||||
ReflectSubMsg: &testdata.ReflectSubPayload{
|
||||
Msgs: []wasmvmtypes.SubMsg{{
|
||||
ID: 7,
|
||||
Msg: msg,
|
||||
|
@ -80,8 +78,8 @@ func TestDispatchSubMsgSuccessCase(t *testing.T) {
|
|||
checkAccount(t, ctx, accKeeper, bankKeeper, creator, creatorBalance)
|
||||
|
||||
// query the reflect state to ensure the result was stored
|
||||
query := ReflectQueryMsg{
|
||||
SubMsgResult: &SubCall{ID: 7},
|
||||
query := testdata.ReflectQueryMsg{
|
||||
SubMsgResult: &testdata.SubCall{ID: 7},
|
||||
}
|
||||
queryBz, err := json.Marshal(query)
|
||||
require.NoError(t, err)
|
||||
|
@ -122,9 +120,7 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) {
|
|||
uploader := keepers.Faucet.NewFundedAccount(ctx, contractStart.Add(contractStart...)...)
|
||||
|
||||
// upload code
|
||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
||||
require.NoError(t, err)
|
||||
reflectID, err := keepers.ContractKeeper.Create(ctx, uploader, reflectCode, nil)
|
||||
reflectID, err := keepers.ContractKeeper.Create(ctx, uploader, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// create hackatom contract for testing (for infinite loop)
|
||||
|
@ -300,8 +296,8 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
msg := tc.msg(contractAddr.String(), empty.String())
|
||||
reflectSend := ReflectHandleMsg{
|
||||
ReflectSubMsg: &reflectSubPayload{
|
||||
reflectSend := testdata.ReflectHandleMsg{
|
||||
ReflectSubMsg: &testdata.ReflectSubPayload{
|
||||
Msgs: []wasmvmtypes.SubMsg{{
|
||||
ID: tc.submsgID,
|
||||
Msg: msg,
|
||||
|
@ -331,8 +327,8 @@ func TestDispatchSubMsgErrorHandling(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// query the reply
|
||||
query := ReflectQueryMsg{
|
||||
SubMsgResult: &SubCall{ID: tc.submsgID},
|
||||
query := testdata.ReflectQueryMsg{
|
||||
SubMsgResult: &testdata.SubCall{ID: tc.submsgID},
|
||||
}
|
||||
queryBz, err := json.Marshal(query)
|
||||
require.NoError(t, err)
|
||||
|
@ -381,9 +377,7 @@ func TestDispatchSubMsgEncodeToNoSdkMsg(t *testing.T) {
|
|||
_, _, fred := keyPubAddr()
|
||||
|
||||
// upload code
|
||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
||||
require.NoError(t, err)
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// creator instantiates a contract and gives it tokens
|
||||
|
@ -403,8 +397,8 @@ func TestDispatchSubMsgEncodeToNoSdkMsg(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
reflectSend := ReflectHandleMsg{
|
||||
ReflectSubMsg: &reflectSubPayload{
|
||||
reflectSend := testdata.ReflectHandleMsg{
|
||||
ReflectSubMsg: &testdata.ReflectSubPayload{
|
||||
Msgs: []wasmvmtypes.SubMsg{{
|
||||
ID: 7,
|
||||
Msg: msg,
|
||||
|
@ -418,8 +412,8 @@ func TestDispatchSubMsgEncodeToNoSdkMsg(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// query the reflect state to ensure the result was stored
|
||||
query := ReflectQueryMsg{
|
||||
SubMsgResult: &SubCall{ID: 7},
|
||||
query := testdata.ReflectQueryMsg{
|
||||
SubMsgResult: &testdata.SubCall{ID: 7},
|
||||
}
|
||||
queryBz, err := json.Marshal(query)
|
||||
require.NoError(t, err)
|
||||
|
@ -449,9 +443,7 @@ func TestDispatchSubMsgConditionalReplyOn(t *testing.T) {
|
|||
_, _, fred := keyPubAddr()
|
||||
|
||||
// upload code
|
||||
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
||||
require.NoError(t, err)
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
|
||||
codeID, err := keepers.ContractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// creator instantiates a contract and gives it tokens
|
||||
|
@ -529,8 +521,8 @@ func TestDispatchSubMsgConditionalReplyOn(t *testing.T) {
|
|||
subMsg.ReplyOn = wasmvmtypes.ReplyError
|
||||
}
|
||||
|
||||
reflectSend := ReflectHandleMsg{
|
||||
ReflectSubMsg: &reflectSubPayload{
|
||||
reflectSend := testdata.ReflectHandleMsg{
|
||||
ReflectSubMsg: &testdata.ReflectSubPayload{
|
||||
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 := ReflectQueryMsg{
|
||||
SubMsgResult: &SubCall{ID: id},
|
||||
query := testdata.ReflectQueryMsg{
|
||||
SubMsgResult: &testdata.SubCall{ID: id},
|
||||
}
|
||||
queryBz, err := json.Marshal(query)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -8,6 +8,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/std"
|
||||
|
@ -72,7 +74,7 @@ import (
|
|||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
)
|
||||
|
||||
var ModuleBasics = module.NewBasicManager(
|
||||
var moduleBasics = module.NewBasicManager(
|
||||
auth.AppModuleBasic{},
|
||||
bank.AppModuleBasic{},
|
||||
capability.AppModuleBasic{},
|
||||
|
@ -103,8 +105,8 @@ func MakeEncodingConfig(_ testing.TB) wasmappparams.EncodingConfig {
|
|||
std.RegisterInterfaces(interfaceRegistry)
|
||||
std.RegisterLegacyAminoCodec(amino)
|
||||
|
||||
ModuleBasics.RegisterLegacyAminoCodec(amino)
|
||||
ModuleBasics.RegisterInterfaces(interfaceRegistry)
|
||||
moduleBasics.RegisterLegacyAminoCodec(amino)
|
||||
moduleBasics.RegisterInterfaces(interfaceRegistry)
|
||||
// add wasmd types
|
||||
types.RegisterInterfaces(interfaceRegistry)
|
||||
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 {
|
||||
wasmCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, 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)
|
||||
return codeID
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
simKeeper "github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cast"
|
||||
|
@ -105,7 +104,7 @@ type AppModule struct {
|
|||
keeper *Keeper
|
||||
validatorSetSource keeper.ValidatorSetSource
|
||||
accountKeeper types.AccountKeeper // for simulation
|
||||
bankKeeper simKeeper.BankKeeper
|
||||
bankKeeper simulation.BankKeeper
|
||||
}
|
||||
|
||||
// ConsensusVersion is a sequence number for state-breaking change of the
|
||||
|
@ -120,7 +119,7 @@ func NewAppModule(
|
|||
keeper *Keeper,
|
||||
validatorSetSource keeper.ValidatorSetSource,
|
||||
ak types.AccountKeeper,
|
||||
bk simKeeper.BankKeeper,
|
||||
bk simulation.BankKeeper,
|
||||
) AppModule {
|
||||
return AppModule{
|
||||
AppModuleBasic: AppModuleBasic{},
|
||||
|
|
|
@ -6,6 +6,8 @@ import (
|
|||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
|
@ -66,7 +68,7 @@ var (
|
|||
_, _, addrAcc1 = keyPubAddr()
|
||||
addr1 = addrAcc1.String()
|
||||
testContract = mustLoad("./keeper/testdata/hackatom.wasm")
|
||||
maskContract = mustLoad("./keeper/testdata/reflect.wasm")
|
||||
maskContract = testdata.ReflectContractWasm()
|
||||
oldContract = mustLoad("./testdata/escrow_0.7.wasm")
|
||||
)
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
// RandomizeGenState generates a random GenesisState for wasm
|
||||
func RandomizedGenState(simstate *module.SimulationState) {
|
||||
params := RandomParams(simstate.Rand)
|
||||
params := types.DefaultParams()
|
||||
wasmGenesis := types.GenesisState{
|
||||
Params: params,
|
||||
Codes: nil,
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
|
||||
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
|
@ -20,6 +25,7 @@ import (
|
|||
const (
|
||||
OpWeightMsgStoreCode = "op_weight_msg_store_code"
|
||||
OpWeightMsgInstantiateContract = "op_weight_msg_instantiate_contract"
|
||||
OpWeightMsgExecuteContract = "op_weight_msg_execute_contract"
|
||||
OpReflectContractPath = "op_reflect_contract_path"
|
||||
)
|
||||
|
||||
|
@ -27,18 +33,26 @@ const (
|
|||
type WasmKeeper interface {
|
||||
GetParams(ctx sdk.Context) types.Params
|
||||
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
|
||||
func WeightedOperations(
|
||||
simstate *module.SimulationState,
|
||||
ak types.AccountKeeper,
|
||||
bk simulation.BankKeeper,
|
||||
bk BankKeeper,
|
||||
wasmKeeper WasmKeeper,
|
||||
) simulation.WeightedOperations {
|
||||
var (
|
||||
weightMsgStoreCode int
|
||||
weightMsgInstantiateContract int
|
||||
weightMsgExecuteContract int
|
||||
wasmContractPath string
|
||||
)
|
||||
|
||||
|
@ -53,32 +67,53 @@ func WeightedOperations(
|
|||
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,
|
||||
func(_ *rand.Rand) {
|
||||
// simulations are run from the `app` folder
|
||||
wasmContractPath = "../x/wasm/keeper/testdata/reflect.wasm"
|
||||
wasmContractPath = ""
|
||||
},
|
||||
)
|
||||
|
||||
wasmBz, err := ioutil.ReadFile(wasmContractPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
var wasmBz []byte
|
||||
if wasmContractPath == "" {
|
||||
wasmBz = testdata.ReflectContractWasm()
|
||||
} else {
|
||||
var err error
|
||||
wasmBz, err = ioutil.ReadFile(wasmContractPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return simulation.WeightedOperations{
|
||||
simulation.NewWeightedOperation(
|
||||
weightMsgStoreCode,
|
||||
SimulateMsgStoreCode(ak, bk, wasmKeeper, wasmBz),
|
||||
SimulateMsgStoreCode(ak, bk, wasmKeeper, wasmBz, 5_000_000),
|
||||
),
|
||||
simulation.NewWeightedOperation(
|
||||
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
|
||||
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(
|
||||
r *rand.Rand,
|
||||
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
|
||||
}
|
||||
|
||||
config := &types.AccessConfig{
|
||||
Permission: types.AccessTypeEverybody,
|
||||
}
|
||||
|
||||
simAccount, _ := simtypes.RandomAcc(r, accs)
|
||||
|
||||
permission := wasmKeeper.GetParams(ctx).InstantiateDefaultPermission
|
||||
config := permission.With(simAccount.Address)
|
||||
|
||||
msg := types.MsgStoreCode{
|
||||
Sender: simAccount.Address.String(),
|
||||
WASMByteCode: wasmBz,
|
||||
InstantiatePermission: config,
|
||||
InstantiatePermission: &config,
|
||||
}
|
||||
|
||||
txCtx := simulation.OperationInput{
|
||||
|
@ -115,12 +150,28 @@ func SimulateMsgStoreCode(ak types.AccountKeeper, bk simulation.BankKeeper, wasm
|
|||
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
|
||||
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(
|
||||
r *rand.Rand,
|
||||
app *baseapp.BaseApp,
|
||||
|
@ -130,20 +181,17 @@ func SimulateMsgInstantiateContract(ak types.AccountKeeper, bk simulation.BankKe
|
|||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
simAccount, _ := simtypes.RandomAcc(r, accs)
|
||||
|
||||
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
|
||||
})
|
||||
|
||||
codeID := codeSelector(ctx, wasmKeeper)
|
||||
if codeID == 0 {
|
||||
return simtypes.NoOpMsg(types.ModuleName, types.MsgInstantiateContract{}.Type(), "no codes with permission available"), nil, nil
|
||||
}
|
||||
|
||||
spendable := bk.SpendableCoins(ctx, simAccount.Address)
|
||||
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))...)
|
||||
}
|
||||
}
|
||||
|
||||
msg := types.MsgInstantiateContract{
|
||||
Sender: simAccount.Address.String(),
|
||||
|
@ -151,23 +199,154 @@ func SimulateMsgInstantiateContract(ak types.AccountKeeper, bk simulation.BankKe
|
|||
CodeID: codeID,
|
||||
Label: simtypes.RandStringOfLength(r, 10),
|
||||
Msg: []byte(`{}`),
|
||||
Funds: simtypes.RandSubsetCoins(r, spendable),
|
||||
Funds: deposit,
|
||||
}
|
||||
|
||||
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,
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
params := RandomParams(r)
|
||||
params := types.DefaultParams()
|
||||
return []simtypes.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, string(types.ParamStoreKeyUploadAccess),
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue