Merge pull request #346 from CosmWasm/genesis_contract_msg_326
Improve Contract initialization in genesis and tooling
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
|
||||
**Features:**
|
||||
- Make it easy to initialize contracts in genesis file with new CLI commands[\#326](https://github.com/CosmWasm/wasmd/issues/326)
|
||||
- Upgrade to WasmVM v0.13.0 [\#358](https://github.com/CosmWasm/wasmd/pull/358)
|
||||
- Upgrade to cosmos-sdk v0.40.0-rc6 [\#354](https://github.com/CosmWasm/wasmd/pull/354)
|
||||
- Upgrade to cosmos-sdk v0.40.0-rc5 [\#344](https://github.com/CosmWasm/wasmd/issues/344)
|
||||
|
||||
@@ -411,7 +411,7 @@ func NewWasmApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b
|
||||
distr.NewAppModule(appCodec, app.distrKeeper, app.accountKeeper, app.bankKeeper, app.stakingKeeper),
|
||||
staking.NewAppModule(appCodec, app.stakingKeeper, app.accountKeeper, app.bankKeeper),
|
||||
upgrade.NewAppModule(app.upgradeKeeper),
|
||||
wasm.NewAppModule(&app.wasmKeeper),
|
||||
wasm.NewAppModule(&app.wasmKeeper, app.stakingKeeper),
|
||||
evidence.NewAppModule(app.evidenceKeeper),
|
||||
ibc.NewAppModule(app.ibcKeeper),
|
||||
params.NewAppModule(app.paramsKeeper),
|
||||
@@ -433,6 +433,8 @@ func NewWasmApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b
|
||||
// NOTE: Capability module must occur first so that it can initialize any capabilities
|
||||
// so that other modules that want to create or claim capabilities afterwards in InitChain
|
||||
// can do so safely.
|
||||
// wasm module should be a the end as it can call other modules functionality direct or via message dispatching during
|
||||
// genesis phase. For example bank transfer, auth account check, staking, ...
|
||||
app.mm.SetOrderInitGenesis(
|
||||
capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName,
|
||||
slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, crisistypes.ModuleName,
|
||||
@@ -461,7 +463,7 @@ func NewWasmApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b
|
||||
distr.NewAppModule(appCodec, app.distrKeeper, app.accountKeeper, app.bankKeeper, app.stakingKeeper),
|
||||
slashing.NewAppModule(appCodec, app.slashingKeeper, app.accountKeeper, app.bankKeeper, app.stakingKeeper),
|
||||
params.NewAppModule(app.paramsKeeper),
|
||||
wasm.NewAppModule(&app.wasmKeeper),
|
||||
wasm.NewAppModule(&app.wasmKeeper, app.stakingKeeper),
|
||||
evidence.NewAppModule(app.evidenceKeeper),
|
||||
ibc.NewAppModule(app.ibcKeeper),
|
||||
transferModule,
|
||||
|
||||
26
cmd/wasmd/genwasm.go
Normal file
26
cmd/wasmd/genwasm.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
wasmcli "github.com/CosmWasm/wasmd/x/wasm/client/cli"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func AddGenesisWasmMsgCmd(defaultNodeHome string) *cobra.Command {
|
||||
txCmd := &cobra.Command{
|
||||
Use: "add-wasm-genesis-message",
|
||||
Short: "Wasm genesis subcommands",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
txCmd.AddCommand(
|
||||
wasmcli.GenesisStoreCodeCmd(defaultNodeHome),
|
||||
wasmcli.GenesisInstantiateContractCmd(defaultNodeHome),
|
||||
wasmcli.GenesisExecuteContractCmd(defaultNodeHome),
|
||||
wasmcli.GenesisListContractsCmd(defaultNodeHome),
|
||||
wasmcli.GenesisListCodesCmd(defaultNodeHome),
|
||||
)
|
||||
return txCmd
|
||||
|
||||
}
|
||||
@@ -84,6 +84,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig app.EncodingConfig) {
|
||||
genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome),
|
||||
genutilcli.ValidateGenesisCmd(app.ModuleBasics),
|
||||
AddGenesisAccountCmd(app.DefaultNodeHome),
|
||||
AddGenesisWasmMsgCmd(app.DefaultNodeHome),
|
||||
tmcli.NewCompletionCmd(rootCmd, true),
|
||||
// testnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}),
|
||||
debug.Cmd(),
|
||||
|
||||
28
contrib/local/00-genesis.sh
Executable file
28
contrib/local/00-genesis.sh
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
|
||||
BASE_ACCOUNT=$(wasmd keys show validator -a)
|
||||
|
||||
echo "-----------------------"
|
||||
echo "## Genesis CosmWasm contract"
|
||||
wasmd add-wasm-genesis-message store "$DIR/../../x/wasm/internal/keeper/testdata/hackatom.wasm" --instantiate-everybody true --builder=foo/bar:latest --run-as validator
|
||||
|
||||
echo "-----------------------"
|
||||
echo "## Genesis CosmWasm instance"
|
||||
INIT="{\"verifier\":\"$(wasmd keys show validator -a)\", \"beneficiary\":\"$(wasmd keys show fred -a)\"}"
|
||||
wasmd add-wasm-genesis-message instantiate-contract 1 "$INIT" --run-as validator --label=foobar --amount=100ustake --admin $BASE_ACCOUNT
|
||||
|
||||
echo "-----------------------"
|
||||
echo "## Genesis CosmWasm execute"
|
||||
FIRST_CONTRACT_ADDR=wasm18vd8fpwxzck93qlwghaj6arh4p7c5n89k7fvsl
|
||||
MSG='{"release":{}}'
|
||||
wasmd add-wasm-genesis-message execute $FIRST_CONTRACT_ADDR "$MSG" --run-as validator --amount=1ustake
|
||||
|
||||
echo "-----------------------"
|
||||
echo "## List Genesis CosmWasm codes"
|
||||
wasmd add-wasm-genesis-message list-codes
|
||||
|
||||
echo "-----------------------"
|
||||
echo "## List Genesis CosmWasm contracts"
|
||||
wasmd add-wasm-genesis-message list-contracts
|
||||
20
doc/proto.md
20
doc/proto.md
@@ -7,6 +7,7 @@
|
||||
- [Code](#cosmwasm.wasm.v1beta1.Code)
|
||||
- [Contract](#cosmwasm.wasm.v1beta1.Contract)
|
||||
- [GenesisState](#cosmwasm.wasm.v1beta1.GenesisState)
|
||||
- [GenesisState.GenMsgs](#cosmwasm.wasm.v1beta1.GenesisState.GenMsgs)
|
||||
- [Sequence](#cosmwasm.wasm.v1beta1.Sequence)
|
||||
|
||||
- [x/wasm/internal/types/msg.proto](#x/wasm/internal/types/msg.proto)
|
||||
@@ -116,6 +117,25 @@ GenesisState - genesis state of x/wasm
|
||||
| codes | [Code](#cosmwasm.wasm.v1beta1.Code) | repeated | |
|
||||
| contracts | [Contract](#cosmwasm.wasm.v1beta1.Contract) | repeated | |
|
||||
| sequences | [Sequence](#cosmwasm.wasm.v1beta1.Sequence) | repeated | |
|
||||
| gen_msgs | [GenesisState.GenMsgs](#cosmwasm.wasm.v1beta1.GenesisState.GenMsgs) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmwasm.wasm.v1beta1.GenesisState.GenMsgs"></a>
|
||||
|
||||
### GenesisState.GenMsgs
|
||||
GenMsgs define the messages that can be executed during genesis phase.
|
||||
The intention is to have more human readable data that is auditable.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| store_code | [MsgStoreCode](#cosmwasm.wasm.v1beta1.MsgStoreCode) | | |
|
||||
| instantiate_contract | [MsgInstantiateContract](#cosmwasm.wasm.v1beta1.MsgInstantiateContract) | | |
|
||||
| execute_contract | [MsgExecuteContract](#cosmwasm.wasm.v1beta1.MsgExecuteContract) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
489
x/wasm/client/cli/genesis_msg.go
Normal file
489
x/wasm/client/cli/genesis_msg.go
Normal file
@@ -0,0 +1,489 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
// GenesisStoreCodeCmd cli command to add a `MsgStoreCode` to the wasm section of the genesis
|
||||
// that is executed on block 0.
|
||||
func GenesisStoreCodeCmd(defaultNodeHome string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "store [wasm file] --source [source] --builder [builder] --run-as [owner_address_or_key_name]\",",
|
||||
Short: "Upload a wasm binary",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
senderAddr, err := getActorAddress(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg, err := parseStoreCodeArgs(args[0], senderAddr, cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = msg.ValidateBasic(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return alterModuleState(cmd, func(s *types.GenesisState, _ map[string]json.RawMessage) error {
|
||||
s.GenMsgs = append(s.GenMsgs, types.GenesisState_GenMsgs{
|
||||
Sum: &types.GenesisState_GenMsgs_StoreCode{StoreCode: &msg},
|
||||
})
|
||||
return nil
|
||||
})
|
||||
},
|
||||
}
|
||||
cmd.Flags().String(flagSource, "", "A valid URI reference to the contract's source code, optional")
|
||||
cmd.Flags().String(flagBuilder, "", "A valid docker tag for the build system, optional")
|
||||
cmd.Flags().String(flagRunAs, "", "The address that is stored as code creator")
|
||||
cmd.Flags().String(flagInstantiateByEverybody, "", "Everybody can instantiate a contract from the code, optional")
|
||||
cmd.Flags().String(flagInstantiateByAddress, "", "Only this address can instantiate a contract instance from the code, optional")
|
||||
|
||||
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
|
||||
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GenesisInstantiateContractCmd cli command to add a `MsgInstantiateContract` to the wasm section of the genesis
|
||||
// that is executed on block 0.
|
||||
func GenesisInstantiateContractCmd(defaultNodeHome string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "instantiate-contract [code_id_int64] [json_encoded_init_args] --label [text] --run-as [address] --admin [address,optional] --amount [coins,optional]",
|
||||
Short: "Instantiate a wasm contract",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
senderAddr, err := getActorAddress(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg, err := parseInstantiateArgs(args[0], args[1], senderAddr, cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = msg.ValidateBasic(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return alterModuleState(cmd, func(s *types.GenesisState, a map[string]json.RawMessage) error {
|
||||
// simple sanity check that sender has some balance although it may be consumed by a previous message already
|
||||
switch ok, err := hasAccountBalance(cmd, a, senderAddr, msg.InitFunds); {
|
||||
case err != nil:
|
||||
return err
|
||||
case !ok:
|
||||
return errors.New("sender has not enough account balance")
|
||||
}
|
||||
|
||||
// does code id exists?
|
||||
codeInfos, err := getAllCodes(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var codeInfo *codeMeta
|
||||
for i := range codeInfos {
|
||||
if codeInfos[i].CodeID == msg.CodeID {
|
||||
codeInfo = &codeInfos[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
if codeInfo == nil {
|
||||
return fmt.Errorf("unknown code id: %d", msg.CodeID)
|
||||
}
|
||||
// permissions correct?
|
||||
if !codeInfo.Info.InstantiateConfig.Allowed(senderAddr) {
|
||||
return fmt.Errorf("permissions were not granted for %s", senderAddr)
|
||||
}
|
||||
s.GenMsgs = append(s.GenMsgs, types.GenesisState_GenMsgs{
|
||||
Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &msg},
|
||||
})
|
||||
return nil
|
||||
})
|
||||
},
|
||||
}
|
||||
cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation")
|
||||
cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists")
|
||||
cmd.Flags().String(flagAdmin, "", "Address of an admin")
|
||||
cmd.Flags().String(flagRunAs, "", "The address that pays the init funds. It is the creator of the contract.")
|
||||
|
||||
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
|
||||
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GenesisInstantiateContractCmd cli command to add a `MsgExecuteContract` to the wasm section of the genesis
|
||||
// that is executed on block 0.
|
||||
func GenesisExecuteContractCmd(defaultNodeHome string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "execute [contract_addr_bech32] [json_encoded_send_args] --run-as [address] --amount [coins,optional]",
|
||||
Short: "Execute a command on a wasm contract",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
senderAddr, err := getActorAddress(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg, err := parseExecuteArgs(args[0], args[1], senderAddr, cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = msg.ValidateBasic(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return alterModuleState(cmd, func(s *types.GenesisState, a map[string]json.RawMessage) error {
|
||||
// simple sanity check that sender has some balance although it may be consumed by a previous message already
|
||||
switch ok, err := hasAccountBalance(cmd, a, senderAddr, msg.SentFunds); {
|
||||
case err != nil:
|
||||
return err
|
||||
case !ok:
|
||||
return errors.New("sender has not enough account balance")
|
||||
}
|
||||
|
||||
// - does contract address exists?
|
||||
if !hasContract(s, msg.Contract) {
|
||||
return fmt.Errorf("unknown contract: %s", msg.Contract)
|
||||
}
|
||||
s.GenMsgs = append(s.GenMsgs, types.GenesisState_GenMsgs{
|
||||
Sum: &types.GenesisState_GenMsgs_ExecuteContract{ExecuteContract: &msg},
|
||||
})
|
||||
return nil
|
||||
})
|
||||
},
|
||||
}
|
||||
cmd.Flags().String(flagAmount, "", "Coins to send to the contract along with command")
|
||||
cmd.Flags().String(flagRunAs, "", "The address that pays the funds.")
|
||||
|
||||
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
|
||||
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GenesisListCodesCmd cli command to list all codes stored in the genesis wasm.code section
|
||||
// as well as from messages that are queued in the wasm.genMsgs section.
|
||||
func GenesisListCodesCmd(defaultNodeHome string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "list-codes ",
|
||||
Short: "Lists all codes from genesis code dump and queued messages",
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
g, err := readGenesis(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
all, err := getAllCodes(g.wasmModuleState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return printJsonOutput(cmd, all)
|
||||
|
||||
},
|
||||
}
|
||||
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GenesisListContractsCmd cli command to list all contracts stored in the genesis wasm.contract section
|
||||
// as well as from messages that are queued in the wasm.genMsgs section.
|
||||
func GenesisListContractsCmd(defaultNodeHome string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "list-contracts ",
|
||||
Short: "Lists all contracts from genesis contract dump and queued messages",
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
g, err := readGenesis(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
state := g.wasmModuleState
|
||||
all := getAllContracts(state)
|
||||
return printJsonOutput(cmd, all)
|
||||
},
|
||||
}
|
||||
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// clientCtx marshaller works only with proto or bytes so we marshal the output ourself
|
||||
func printJsonOutput(cmd *cobra.Command, obj interface{}) error {
|
||||
clientCtx := client.GetClientContextFromCmd(cmd)
|
||||
bz, err := json.MarshalIndent(obj, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return clientCtx.PrintString(string(bz))
|
||||
}
|
||||
|
||||
type codeMeta struct {
|
||||
CodeID uint64 `json:"code_id"`
|
||||
Info types.CodeInfo `json:"info"`
|
||||
}
|
||||
|
||||
func getAllCodes(state *types.GenesisState) ([]codeMeta, error) {
|
||||
var all []codeMeta
|
||||
for _, c := range state.Codes {
|
||||
all = append(all, codeMeta{
|
||||
CodeID: c.CodeID,
|
||||
Info: c.CodeInfo,
|
||||
})
|
||||
}
|
||||
// add inflight
|
||||
seq := codeSeqValue(state)
|
||||
for _, m := range state.GenMsgs {
|
||||
if msg := m.GetStoreCode(); msg != nil {
|
||||
var accessConfig types.AccessConfig
|
||||
if msg.InstantiatePermission != nil {
|
||||
accessConfig = *msg.InstantiatePermission
|
||||
} else {
|
||||
// default
|
||||
creator, err := sdk.AccAddressFromBech32(msg.Sender)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("sender: %s", err)
|
||||
}
|
||||
accessConfig = state.Params.InstantiateDefaultPermission.With(creator)
|
||||
}
|
||||
hash := sha256.Sum256(msg.WASMByteCode)
|
||||
all = append(all, codeMeta{
|
||||
CodeID: seq,
|
||||
Info: types.CodeInfo{
|
||||
CodeHash: hash[:],
|
||||
Creator: msg.Sender,
|
||||
Source: msg.Source,
|
||||
Builder: msg.Builder,
|
||||
InstantiateConfig: accessConfig,
|
||||
},
|
||||
})
|
||||
seq++
|
||||
}
|
||||
}
|
||||
return all, nil
|
||||
}
|
||||
|
||||
type contractMeta struct {
|
||||
ContractAddress string `json:"contract_address"`
|
||||
Info types.ContractInfo `json:"info"`
|
||||
}
|
||||
|
||||
func getAllContracts(state *types.GenesisState) []contractMeta {
|
||||
var all []contractMeta
|
||||
for _, c := range state.Contracts {
|
||||
all = append(all, contractMeta{
|
||||
ContractAddress: c.ContractAddress,
|
||||
Info: c.ContractInfo,
|
||||
})
|
||||
}
|
||||
// add inflight
|
||||
seq := contractSeqValue(state)
|
||||
for _, m := range state.GenMsgs {
|
||||
if msg := m.GetInstantiateContract(); msg != nil {
|
||||
all = append(all, contractMeta{
|
||||
ContractAddress: contractAddress(msg.CodeID, seq).String(),
|
||||
Info: types.ContractInfo{
|
||||
CodeID: msg.CodeID,
|
||||
Creator: msg.Sender,
|
||||
Admin: msg.Admin,
|
||||
Label: msg.Label,
|
||||
},
|
||||
})
|
||||
seq++
|
||||
}
|
||||
}
|
||||
return all
|
||||
}
|
||||
|
||||
func hasAccountBalance(cmd *cobra.Command, a map[string]json.RawMessage, sender sdk.AccAddress, coins sdk.Coins) (bool, error) {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
cdc := clientCtx.JSONMarshaler
|
||||
var genBalIterator banktypes.GenesisBalancesIterator
|
||||
err = genutil.ValidateAccountInGenesis(a, genBalIterator, sender, coins, cdc)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func hasContract(state *types.GenesisState, contractAddr string) bool {
|
||||
for _, c := range state.Contracts {
|
||||
if c.ContractAddress == contractAddr {
|
||||
return true
|
||||
}
|
||||
}
|
||||
seq := contractSeqValue(state)
|
||||
for _, m := range state.GenMsgs {
|
||||
if msg := m.GetInstantiateContract(); msg != nil {
|
||||
if contractAddress(msg.CodeID, seq).String() == contractAddr {
|
||||
return true
|
||||
}
|
||||
seq++
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// genesisData contains raw and unmarshalled data from the genesis file
|
||||
type genesisData struct {
|
||||
genesisFile string
|
||||
genDoc *tmtypes.GenesisDoc
|
||||
appState map[string]json.RawMessage
|
||||
wasmModuleState *types.GenesisState
|
||||
}
|
||||
|
||||
func readGenesis(cmd *cobra.Command) (*genesisData, error) {
|
||||
clientCtx := client.GetClientContextFromCmd(cmd)
|
||||
serverCtx := server.GetServerContextFromCmd(cmd)
|
||||
config := serverCtx.Config
|
||||
config.SetRoot(clientCtx.HomeDir)
|
||||
|
||||
genFile := config.GenesisFile()
|
||||
appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal genesis state: %w", err)
|
||||
}
|
||||
var wasmGenesisState types.GenesisState
|
||||
if appState[types.ModuleName] != nil {
|
||||
clientCtx := client.GetClientContextFromCmd(cmd)
|
||||
clientCtx.JSONMarshaler.MustUnmarshalJSON(appState[types.ModuleName], &wasmGenesisState)
|
||||
}
|
||||
|
||||
return &genesisData{
|
||||
genesisFile: genFile,
|
||||
genDoc: genDoc,
|
||||
appState: appState,
|
||||
wasmModuleState: &wasmGenesisState,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// alterModuleState loads the genesis from the default or set home dir,
|
||||
// unmarshalls the wasm module section into the object representation
|
||||
// calls the callback function to modify it
|
||||
// and marshals the modified state back into the genesis file
|
||||
func alterModuleState(cmd *cobra.Command, callback func(s *types.GenesisState, a map[string]json.RawMessage) error) error {
|
||||
g, err := readGenesis(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := callback(g.wasmModuleState, g.appState); err != nil {
|
||||
return err
|
||||
}
|
||||
// and store update
|
||||
if err := g.wasmModuleState.ValidateBasic(); err != nil {
|
||||
return err
|
||||
}
|
||||
clientCtx := client.GetClientContextFromCmd(cmd)
|
||||
wasmGenStateBz, err := clientCtx.JSONMarshaler.MarshalJSON(g.wasmModuleState)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "marshal wasm genesis state")
|
||||
}
|
||||
|
||||
g.appState[types.ModuleName] = wasmGenStateBz
|
||||
appStateJSON, err := json.Marshal(g.appState)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(err, "marshal application genesis state")
|
||||
}
|
||||
|
||||
g.genDoc.AppState = appStateJSON
|
||||
return genutil.ExportGenesisFile(g.genDoc, g.genesisFile)
|
||||
}
|
||||
|
||||
// contractSeqValue reads the contract sequence from the genesis or
|
||||
// returns default start value used in the keeper
|
||||
func contractSeqValue(state *types.GenesisState) uint64 {
|
||||
var seq uint64 = 1
|
||||
for _, s := range state.Sequences {
|
||||
if bytes.Equal(s.IDKey, types.KeyLastInstanceID) {
|
||||
seq = s.Value
|
||||
break
|
||||
}
|
||||
}
|
||||
return seq
|
||||
}
|
||||
|
||||
// codeSeqValue reads the code sequence from the genesis or
|
||||
// returns default start value used in the keeper
|
||||
func codeSeqValue(state *types.GenesisState) uint64 {
|
||||
var seq uint64 = 1
|
||||
for _, s := range state.Sequences {
|
||||
if bytes.Equal(s.IDKey, types.KeyLastCodeID) {
|
||||
seq = s.Value
|
||||
break
|
||||
}
|
||||
}
|
||||
return seq
|
||||
}
|
||||
|
||||
// getActorAddress returns the account address for the `--run-as` flag.
|
||||
// The flag value can either be an address already or a key name where the
|
||||
// address is read from the keyring instead.
|
||||
func getActorAddress(cmd *cobra.Command) (sdk.AccAddress, error) {
|
||||
actorArg, err := cmd.Flags().GetString(flagRunAs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("run-as: %s", err.Error())
|
||||
}
|
||||
if len(actorArg) == 0 {
|
||||
return nil, errors.New("run-as address is required")
|
||||
}
|
||||
|
||||
actorAddr, err := sdk.AccAddressFromBech32(actorArg)
|
||||
if err == nil {
|
||||
return actorAddr, nil
|
||||
}
|
||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
|
||||
|
||||
homeDir := client.GetClientContextFromCmd(cmd).HomeDir
|
||||
// attempt to lookup address from Keybase if no address was provided
|
||||
kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, homeDir, inBuf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info, err := kb.Key(actorArg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get address from Keybase: %w", err)
|
||||
}
|
||||
return info.GetAddress(), nil
|
||||
}
|
||||
|
||||
// contractAddress builds a contract address. copied from keeper
|
||||
func contractAddress(codeID, instanceID uint64) sdk.AccAddress {
|
||||
// NOTE: It is possible to get a duplicate address if either codeID or instanceID
|
||||
// overflow 32 bits. This is highly improbable, but something that could be refactored.
|
||||
contractID := codeID<<32 + instanceID
|
||||
return addrFromUint64(contractID)
|
||||
}
|
||||
|
||||
// addrFromUint64 is a helper for address generation, copied from keeper
|
||||
func addrFromUint64(id uint64) sdk.AccAddress {
|
||||
addr := make([]byte, 20)
|
||||
addr[0] = 'C'
|
||||
binary.PutUvarint(addr[1:], id)
|
||||
return sdk.AccAddress(crypto.AddressHash(addr))
|
||||
}
|
||||
571
x/wasm/client/cli/genesis_msg_test.go
Normal file
571
x/wasm/client/cli/genesis_msg_test.go
Normal file
@@ -0,0 +1,571 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/internal/keeper"
|
||||
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil"
|
||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
var wasmIdent = []byte("\x00\x61\x73\x6D")
|
||||
|
||||
var myWellFundedAccount = keeper.RandomBech32AccountAddress(nil)
|
||||
|
||||
const defaultTestKeyName = "my-key-name"
|
||||
|
||||
func TestGenesisStoreCodeCmd(t *testing.T) {
|
||||
minimalWasmGenesis := types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
}
|
||||
anyValidWasmFile, err := ioutil.TempFile(t.TempDir(), "wasm")
|
||||
require.NoError(t, err)
|
||||
anyValidWasmFile.Write(wasmIdent)
|
||||
require.NoError(t, anyValidWasmFile.Close())
|
||||
|
||||
specs := map[string]struct {
|
||||
srcGenesis types.GenesisState
|
||||
mutator func(cmd *cobra.Command)
|
||||
expError bool
|
||||
}{
|
||||
"all good with actor address": {
|
||||
srcGenesis: minimalWasmGenesis,
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{anyValidWasmFile.Name()})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("source", "https://foo.bar")
|
||||
flagSet.Set("run-as", keeper.RandomBech32AccountAddress(t))
|
||||
},
|
||||
},
|
||||
"all good with key name": {
|
||||
srcGenesis: minimalWasmGenesis,
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{anyValidWasmFile.Name()})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("run-as", defaultTestKeyName)
|
||||
},
|
||||
},
|
||||
"with unknown actor key name should fail": {
|
||||
srcGenesis: minimalWasmGenesis,
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{anyValidWasmFile.Name()})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("run-as", "unknown key")
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"without actor should fail": {
|
||||
srcGenesis: minimalWasmGenesis,
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{anyValidWasmFile.Name()})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("source", "https://foo.bar")
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"invalid msg data should fail": {
|
||||
srcGenesis: minimalWasmGenesis,
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{anyValidWasmFile.Name()})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("source", "not an url")
|
||||
flagSet.Set("run-as", keeper.RandomBech32AccountAddress(t))
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
homeDir := setupGenesis(t, spec.srcGenesis)
|
||||
|
||||
// when
|
||||
cmd := GenesisStoreCodeCmd(homeDir)
|
||||
spec.mutator(cmd)
|
||||
err := executeCmdWithContext(t, homeDir, cmd)
|
||||
if spec.expError {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
// then
|
||||
moduleState := loadModuleState(t, homeDir)
|
||||
assert.Len(t, moduleState.GenMsgs, 1)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstantiateContractCmd(t *testing.T) {
|
||||
minimalWasmGenesis := types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
}
|
||||
anyValidWasmFile, err := ioutil.TempFile(t.TempDir(), "wasm")
|
||||
require.NoError(t, err)
|
||||
anyValidWasmFile.Write(wasmIdent)
|
||||
require.NoError(t, anyValidWasmFile.Close())
|
||||
|
||||
specs := map[string]struct {
|
||||
srcGenesis types.GenesisState
|
||||
mutator func(cmd *cobra.Command)
|
||||
expMsgCount int
|
||||
expError bool
|
||||
}{
|
||||
"all good with code id in genesis codes": {
|
||||
srcGenesis: types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
Codes: []types.Code{
|
||||
{
|
||||
CodeID: 1,
|
||||
CodeInfo: types.CodeInfo{
|
||||
CodeHash: []byte("a-valid-code-hash"),
|
||||
Creator: keeper.RandomBech32AccountAddress(t),
|
||||
InstantiateConfig: types.AccessConfig{
|
||||
Permission: types.AccessTypeEverybody,
|
||||
},
|
||||
},
|
||||
CodeBytes: wasmIdent,
|
||||
},
|
||||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{"1", `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("label", "testing")
|
||||
flagSet.Set("run-as", myWellFundedAccount)
|
||||
},
|
||||
expMsgCount: 1,
|
||||
},
|
||||
"all good with code id from genesis store messages without initial sequence": {
|
||||
srcGenesis: types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_StoreCode{StoreCode: types.MsgStoreCodeFixture()}},
|
||||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{"1", `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("label", "testing")
|
||||
flagSet.Set("run-as", myWellFundedAccount)
|
||||
},
|
||||
expMsgCount: 2,
|
||||
},
|
||||
"all good with code id from genesis store messages and sequence set": {
|
||||
srcGenesis: types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_StoreCode{StoreCode: types.MsgStoreCodeFixture()}},
|
||||
},
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastCodeID, Value: 100},
|
||||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{"100", `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("label", "testing")
|
||||
flagSet.Set("run-as", myWellFundedAccount)
|
||||
},
|
||||
expMsgCount: 2,
|
||||
},
|
||||
"fails with codeID not existing in codes": {
|
||||
srcGenesis: minimalWasmGenesis,
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{"2", `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("label", "testing")
|
||||
flagSet.Set("run-as", myWellFundedAccount)
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"fails when instantiation permissions not granted": {
|
||||
srcGenesis: types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_StoreCode{StoreCode: types.MsgStoreCodeFixture(func(code *types.MsgStoreCode) {
|
||||
code.InstantiatePermission = &types.AllowNobody
|
||||
})}},
|
||||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{"1", `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("label", "testing")
|
||||
flagSet.Set("run-as", myWellFundedAccount)
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"fails without a sender balance": {
|
||||
srcGenesis: types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
Codes: []types.Code{
|
||||
{
|
||||
CodeID: 1,
|
||||
CodeInfo: types.CodeInfo{
|
||||
CodeHash: []byte("a-valid-code-hash"),
|
||||
Creator: keeper.RandomBech32AccountAddress(t),
|
||||
InstantiateConfig: types.AccessConfig{
|
||||
Permission: types.AccessTypeEverybody,
|
||||
},
|
||||
},
|
||||
CodeBytes: wasmIdent,
|
||||
},
|
||||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{"1", `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("label", "testing")
|
||||
flagSet.Set("run-as", keeper.RandomBech32AccountAddress(t))
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
homeDir := setupGenesis(t, spec.srcGenesis)
|
||||
|
||||
// when
|
||||
cmd := GenesisInstantiateContractCmd(homeDir)
|
||||
spec.mutator(cmd)
|
||||
err := executeCmdWithContext(t, homeDir, cmd)
|
||||
if spec.expError {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
// then
|
||||
moduleState := loadModuleState(t, homeDir)
|
||||
assert.Len(t, moduleState.GenMsgs, spec.expMsgCount)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExecuteContractCmd(t *testing.T) {
|
||||
const firstContractAddress = "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5"
|
||||
minimalWasmGenesis := types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
}
|
||||
anyValidWasmFile, err := ioutil.TempFile(t.TempDir(), "wasm")
|
||||
require.NoError(t, err)
|
||||
anyValidWasmFile.Write(wasmIdent)
|
||||
require.NoError(t, anyValidWasmFile.Close())
|
||||
|
||||
specs := map[string]struct {
|
||||
srcGenesis types.GenesisState
|
||||
mutator func(cmd *cobra.Command)
|
||||
expMsgCount int
|
||||
expError bool
|
||||
}{
|
||||
"all good with contract in genesis contracts": {
|
||||
srcGenesis: types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
Codes: []types.Code{
|
||||
{
|
||||
CodeID: 1,
|
||||
CodeInfo: types.CodeInfoFixture(),
|
||||
CodeBytes: wasmIdent,
|
||||
},
|
||||
},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: firstContractAddress,
|
||||
ContractInfo: types.ContractInfoFixture(func(info *types.ContractInfo) {
|
||||
info.Created = nil
|
||||
}),
|
||||
ContractState: []types.Model{},
|
||||
},
|
||||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{firstContractAddress, `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("run-as", myWellFundedAccount)
|
||||
},
|
||||
expMsgCount: 1,
|
||||
},
|
||||
"all good with contract from genesis store messages without initial sequence": {
|
||||
srcGenesis: types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
Codes: []types.Code{
|
||||
{
|
||||
CodeID: 1,
|
||||
CodeInfo: types.CodeInfoFixture(),
|
||||
CodeBytes: wasmIdent,
|
||||
},
|
||||
},
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: types.MsgInstantiateContractFixture()}},
|
||||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{firstContractAddress, `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("run-as", myWellFundedAccount)
|
||||
},
|
||||
expMsgCount: 2,
|
||||
},
|
||||
"all good with contract from genesis store messages and contract sequence set": {
|
||||
srcGenesis: types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
Codes: []types.Code{
|
||||
{
|
||||
CodeID: 1,
|
||||
CodeInfo: types.CodeInfoFixture(),
|
||||
CodeBytes: wasmIdent,
|
||||
},
|
||||
},
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: types.MsgInstantiateContractFixture()}},
|
||||
},
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastInstanceID, Value: 100},
|
||||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{"cosmos1weh0k0l6t6v4jkmkde8e90tzkw2c59g42ccl62", `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("run-as", myWellFundedAccount)
|
||||
},
|
||||
expMsgCount: 2,
|
||||
},
|
||||
"fails with unknown contract address": {
|
||||
srcGenesis: minimalWasmGenesis,
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{keeper.RandomBech32AccountAddress(t), `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("run-as", myWellFundedAccount)
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"fails without enough sender balance": {
|
||||
srcGenesis: types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
Codes: []types.Code{
|
||||
{
|
||||
CodeID: 1,
|
||||
CodeInfo: types.CodeInfoFixture(),
|
||||
CodeBytes: wasmIdent,
|
||||
},
|
||||
},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: firstContractAddress,
|
||||
ContractInfo: types.ContractInfoFixture(func(info *types.ContractInfo) {
|
||||
info.Created = nil
|
||||
}),
|
||||
ContractState: []types.Model{},
|
||||
},
|
||||
},
|
||||
},
|
||||
mutator: func(cmd *cobra.Command) {
|
||||
cmd.SetArgs([]string{firstContractAddress, `{}`})
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("run-as", keeper.RandomBech32AccountAddress(t))
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
homeDir := setupGenesis(t, spec.srcGenesis)
|
||||
cmd := GenesisExecuteContractCmd(homeDir)
|
||||
spec.mutator(cmd)
|
||||
|
||||
// when
|
||||
err := executeCmdWithContext(t, homeDir, cmd)
|
||||
if spec.expError {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
// then
|
||||
moduleState := loadModuleState(t, homeDir)
|
||||
assert.Len(t, moduleState.GenMsgs, spec.expMsgCount)
|
||||
})
|
||||
}
|
||||
}
|
||||
func TestGetAllContracts(t *testing.T) {
|
||||
specs := map[string]struct {
|
||||
src types.GenesisState
|
||||
exp []contractMeta
|
||||
}{
|
||||
"read from contracts state": {
|
||||
src: types.GenesisState{
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: "first-contract",
|
||||
ContractInfo: types.ContractInfo{Label: "first"},
|
||||
},
|
||||
{
|
||||
ContractAddress: "second-contract",
|
||||
ContractInfo: types.ContractInfo{Label: "second"},
|
||||
},
|
||||
},
|
||||
},
|
||||
exp: []contractMeta{
|
||||
{
|
||||
ContractAddress: "first-contract",
|
||||
Info: types.ContractInfo{Label: "first"},
|
||||
},
|
||||
{
|
||||
ContractAddress: "second-contract",
|
||||
Info: types.ContractInfo{Label: "second"},
|
||||
},
|
||||
},
|
||||
},
|
||||
"read from message state": {
|
||||
src: types.GenesisState{
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Label: "first"}}},
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Label: "second"}}},
|
||||
},
|
||||
},
|
||||
exp: []contractMeta{
|
||||
{
|
||||
ContractAddress: contractAddress(0, 1).String(),
|
||||
Info: types.ContractInfo{Label: "first"},
|
||||
},
|
||||
{
|
||||
ContractAddress: contractAddress(0, 2).String(),
|
||||
Info: types.ContractInfo{Label: "second"},
|
||||
},
|
||||
},
|
||||
},
|
||||
"read from message state with contract sequence": {
|
||||
src: types.GenesisState{
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastInstanceID, Value: 100},
|
||||
},
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Label: "hundred"}}},
|
||||
},
|
||||
},
|
||||
exp: []contractMeta{
|
||||
{
|
||||
ContractAddress: contractAddress(0, 100).String(),
|
||||
Info: types.ContractInfo{Label: "hundred"},
|
||||
},
|
||||
},
|
||||
},
|
||||
"read from contract and message state with contract sequence": {
|
||||
src: types.GenesisState{
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: "first-contract",
|
||||
ContractInfo: types.ContractInfo{Label: "first"},
|
||||
},
|
||||
},
|
||||
Sequences: []types.Sequence{
|
||||
{IDKey: types.KeyLastInstanceID, Value: 100},
|
||||
},
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Label: "hundred"}}},
|
||||
},
|
||||
},
|
||||
exp: []contractMeta{
|
||||
{
|
||||
ContractAddress: "first-contract",
|
||||
Info: types.ContractInfo{Label: "first"},
|
||||
},
|
||||
{
|
||||
ContractAddress: contractAddress(0, 100).String(),
|
||||
Info: types.ContractInfo{Label: "hundred"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
got := getAllContracts(&spec.src)
|
||||
assert.Equal(t, spec.exp, got)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func setupGenesis(t *testing.T, wasmGenesis types.GenesisState) string {
|
||||
appCodec := keeper.MakeEncodingConfig(t).Marshaler
|
||||
homeDir := t.TempDir()
|
||||
|
||||
require.NoError(t, os.Mkdir(path.Join(homeDir, "config"), 0700))
|
||||
genFilename := path.Join(homeDir, "config", "genesis.json")
|
||||
appState := make(map[string]json.RawMessage)
|
||||
appState[types.ModuleName] = appCodec.MustMarshalJSON(&wasmGenesis)
|
||||
|
||||
bankGenesis := banktypes.DefaultGenesisState()
|
||||
bankGenesis.Balances = append(bankGenesis.Balances, banktypes.Balance{
|
||||
// add a balance for the default sender account
|
||||
Address: myWellFundedAccount,
|
||||
Coins: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10000000000))),
|
||||
})
|
||||
appState[banktypes.ModuleName] = appCodec.MustMarshalJSON(bankGenesis)
|
||||
appState[stakingtypes.ModuleName] = appCodec.MustMarshalJSON(stakingtypes.DefaultGenesisState())
|
||||
|
||||
appStateBz, err := json.Marshal(appState)
|
||||
require.NoError(t, err)
|
||||
genDoc := tmtypes.GenesisDoc{
|
||||
ChainID: "testing",
|
||||
AppState: appStateBz,
|
||||
}
|
||||
err = genutil.ExportGenesisFile(&genDoc, genFilename)
|
||||
require.NoError(t, err)
|
||||
|
||||
return homeDir
|
||||
}
|
||||
|
||||
func executeCmdWithContext(t *testing.T, homeDir string, cmd *cobra.Command) error {
|
||||
logger := log.NewNopLogger()
|
||||
cfg, err := genutiltest.CreateDefaultTendermintConfig(homeDir)
|
||||
require.NoError(t, err)
|
||||
appCodec := keeper.MakeEncodingConfig(t).Marshaler
|
||||
serverCtx := server.NewContext(viper.New(), cfg, logger)
|
||||
clientCtx := client.Context{}.WithJSONMarshaler(appCodec).WithHomeDir(homeDir)
|
||||
|
||||
ctx := context.Background()
|
||||
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
|
||||
ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx)
|
||||
flagSet := cmd.Flags()
|
||||
flagSet.Set("home", homeDir)
|
||||
flagSet.Set(flags.FlagKeyringBackend, keyring.BackendTest)
|
||||
|
||||
mockIn := testutil.ApplyMockIODiscardOutErr(cmd)
|
||||
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, homeDir, mockIn)
|
||||
require.NoError(t, err)
|
||||
_, err = kb.NewAccount(defaultTestKeyName, testutil.TestMnemonic, "", sdk.FullFundraiserPath, hd.Secp256k1)
|
||||
require.NoError(t, err)
|
||||
return cmd.ExecuteContext(ctx)
|
||||
}
|
||||
|
||||
func loadModuleState(t *testing.T, homeDir string) types.GenesisState {
|
||||
genFilename := path.Join(homeDir, "config", "genesis.json")
|
||||
appState, _, err := genutiltypes.GenesisStateFromGenFile(genFilename)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, appState, types.ModuleName)
|
||||
|
||||
appCodec := keeper.MakeEncodingConfig(t).Marshaler
|
||||
var moduleState types.GenesisState
|
||||
require.NoError(t, appCodec.UnmarshalJSON(appState[types.ModuleName], &moduleState))
|
||||
return moduleState
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
@@ -9,7 +11,6 @@ import (
|
||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func ProposalStoreCodeCmd() *cobra.Command {
|
||||
@@ -23,27 +24,44 @@ func ProposalStoreCodeCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
src, err := parseStoreCodeArgs(args, clientCtx)
|
||||
src, err := parseStoreCodeArgs(args[0], clientCtx.FromAddress, cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(viper.GetString(flagRunAs)) == 0 {
|
||||
runAs, err := cmd.Flags().GetString(flagRunAs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("run-as: %s", err)
|
||||
}
|
||||
if len(runAs) == 0 {
|
||||
return errors.New("run-as address is required")
|
||||
}
|
||||
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
|
||||
if err != nil {
|
||||
return fmt.Errorf("proposal title: %s", err)
|
||||
}
|
||||
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
|
||||
if err != nil {
|
||||
return fmt.Errorf("proposal description: %s", err)
|
||||
}
|
||||
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
deposit, err := sdk.ParseCoinsNormalized(depositArg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
content := types.StoreCodeProposal{
|
||||
Title: viper.GetString(cli.FlagTitle),
|
||||
Description: viper.GetString(cli.FlagDescription),
|
||||
RunAs: viper.GetString(flagRunAs),
|
||||
Title: proposalTitle,
|
||||
Description: proposalDescr,
|
||||
RunAs: runAs,
|
||||
WASMByteCode: src.WASMByteCode,
|
||||
Source: src.Source,
|
||||
Builder: src.Builder,
|
||||
InstantiatePermission: src.InstantiatePermission,
|
||||
}
|
||||
|
||||
deposit, err := sdk.ParseCoinsNormalized(viper.GetString(cli.FlagDeposit))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -83,17 +101,39 @@ func ProposalInstantiateContractCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
src, err := parseInstantiateArgs(args, clientCtx)
|
||||
src, err := parseInstantiateArgs(args[0], args[1], clientCtx.FromAddress, cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(viper.GetString(flagRunAs)) == 0 {
|
||||
return errors.New("creator address is required")
|
||||
|
||||
runAs, err := cmd.Flags().GetString(flagRunAs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("run-as: %s", err)
|
||||
}
|
||||
if len(runAs) == 0 {
|
||||
return errors.New("run-as address is required")
|
||||
}
|
||||
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
|
||||
if err != nil {
|
||||
return fmt.Errorf("proposal title: %s", err)
|
||||
}
|
||||
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
|
||||
if err != nil {
|
||||
return fmt.Errorf("proposal description: %s", err)
|
||||
}
|
||||
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
deposit, err := sdk.ParseCoinsNormalized(depositArg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
content := types.InstantiateContractProposal{
|
||||
Title: viper.GetString(cli.FlagTitle),
|
||||
Description: viper.GetString(cli.FlagDescription),
|
||||
RunAs: viper.GetString(flagRunAs),
|
||||
Title: proposalTitle,
|
||||
Description: proposalDescr,
|
||||
RunAs: runAs,
|
||||
Admin: src.Admin,
|
||||
CodeID: src.CodeID,
|
||||
Label: src.Label,
|
||||
@@ -101,11 +141,6 @@ func ProposalInstantiateContractCmd() *cobra.Command {
|
||||
InitFunds: src.InitFunds,
|
||||
}
|
||||
|
||||
deposit, err := sdk.ParseCoinsNormalized(viper.GetString(cli.FlagDeposit))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -148,22 +183,37 @@ func ProposalMigrateContractCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(viper.GetString(flagRunAs)) == 0 {
|
||||
runAs, err := cmd.Flags().GetString(flagRunAs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("run-as: %s", err)
|
||||
}
|
||||
if len(runAs) == 0 {
|
||||
return errors.New("run-as address is required")
|
||||
}
|
||||
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
|
||||
if err != nil {
|
||||
return fmt.Errorf("proposal title: %s", err)
|
||||
}
|
||||
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
|
||||
if err != nil {
|
||||
return fmt.Errorf("proposal description: %s", err)
|
||||
}
|
||||
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
deposit, err := sdk.ParseCoinsNormalized(depositArg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
content := types.MigrateContractProposal{
|
||||
Title: viper.GetString(cli.FlagTitle),
|
||||
Description: viper.GetString(cli.FlagDescription),
|
||||
Title: proposalTitle,
|
||||
Description: proposalDescr,
|
||||
Contract: src.Contract,
|
||||
CodeID: src.CodeID,
|
||||
MigrateMsg: src.MigrateMsg,
|
||||
RunAs: viper.GetString(flagRunAs),
|
||||
}
|
||||
|
||||
deposit, err := sdk.ParseCoinsNormalized(viper.GetString(cli.FlagDeposit))
|
||||
if err != nil {
|
||||
return err
|
||||
RunAs: runAs,
|
||||
}
|
||||
|
||||
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
|
||||
@@ -205,18 +255,30 @@ func ProposalUpdateContractAdminCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
content := types.UpdateAdminProposal{
|
||||
Title: viper.GetString(cli.FlagTitle),
|
||||
Description: viper.GetString(cli.FlagDescription),
|
||||
Contract: src.Contract,
|
||||
NewAdmin: src.NewAdmin,
|
||||
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
|
||||
if err != nil {
|
||||
return fmt.Errorf("proposal title: %s", err)
|
||||
}
|
||||
|
||||
deposit, err := sdk.ParseCoinsNormalized(viper.GetString(cli.FlagDeposit))
|
||||
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
|
||||
if err != nil {
|
||||
return fmt.Errorf("proposal description: %s", err)
|
||||
}
|
||||
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
|
||||
if err != nil {
|
||||
return fmt.Errorf("deposit: %s", err)
|
||||
}
|
||||
deposit, err := sdk.ParseCoinsNormalized(depositArg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
content := types.UpdateAdminProposal{
|
||||
Title: proposalTitle,
|
||||
Description: proposalDescr,
|
||||
Contract: src.Contract,
|
||||
NewAdmin: src.NewAdmin,
|
||||
}
|
||||
|
||||
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -249,17 +311,29 @@ func ProposalClearContractAdminCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
content := types.ClearAdminProposal{
|
||||
Title: viper.GetString(cli.FlagTitle),
|
||||
Description: viper.GetString(cli.FlagDescription),
|
||||
Contract: args[0],
|
||||
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
|
||||
if err != nil {
|
||||
return fmt.Errorf("proposal title: %s", err)
|
||||
}
|
||||
|
||||
deposit, err := sdk.ParseCoinsNormalized(viper.GetString(cli.FlagDeposit))
|
||||
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
|
||||
if err != nil {
|
||||
return fmt.Errorf("proposal description: %s", err)
|
||||
}
|
||||
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
|
||||
if err != nil {
|
||||
return fmt.Errorf("deposit: %s", err)
|
||||
}
|
||||
deposit, err := sdk.ParseCoinsNormalized(depositArg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
content := types.ClearAdminProposal{
|
||||
Title: proposalTitle,
|
||||
Description: proposalDescr,
|
||||
Contract: args[0],
|
||||
}
|
||||
|
||||
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -47,7 +47,6 @@ func GetCmdListCode() *cobra.Command {
|
||||
Long: "List all wasm bytecode on the chain",
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -83,7 +82,6 @@ func GetCmdListContractByCode() *cobra.Command {
|
||||
Long: "List wasm all bytecode on the chain for given code id",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -125,7 +123,6 @@ func GetCmdQueryCode() *cobra.Command {
|
||||
Long: "Downloads wasm bytecode for given code id",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -218,7 +215,6 @@ func GetCmdGetContractStateAll() *cobra.Command {
|
||||
Long: "Prints out all internal state of a contract given its address",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -260,7 +256,6 @@ func GetCmdGetContractStateRaw() *cobra.Command {
|
||||
Long: "Prints out internal state for of a contract given its address",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -302,7 +297,6 @@ func GetCmdGetContractStateSmart() *cobra.Command {
|
||||
Long: "Calls contract with given address with query data and prints the returned result",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
@@ -13,7 +14,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -56,8 +57,7 @@ func StoreCodeCmd() *cobra.Command {
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
|
||||
msg, err := parseStoreCodeArgs(args, clientCtx)
|
||||
msg, err := parseStoreCodeArgs(args[0], clientCtx.GetFromAddress(), cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -76,8 +76,8 @@ func StoreCodeCmd() *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func parseStoreCodeArgs(args []string, cliCtx client.Context) (types.MsgStoreCode, error) {
|
||||
wasm, err := ioutil.ReadFile(args[0])
|
||||
func parseStoreCodeArgs(file string, sender sdk.AccAddress, flags *flag.FlagSet) (types.MsgStoreCode, error) {
|
||||
wasm, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return types.MsgStoreCode{}, err
|
||||
}
|
||||
@@ -94,23 +94,48 @@ func parseStoreCodeArgs(args []string, cliCtx client.Context) (types.MsgStoreCod
|
||||
}
|
||||
|
||||
var perm *types.AccessConfig
|
||||
if onlyAddrStr := viper.GetString(flagInstantiateByAddress); onlyAddrStr != "" {
|
||||
onlyAddrStr, err := flags.GetString(flagInstantiateByAddress)
|
||||
if err != nil {
|
||||
return types.MsgStoreCode{}, fmt.Errorf("instantiate by address: %s", err)
|
||||
}
|
||||
if onlyAddrStr != "" {
|
||||
allowedAddr, err := sdk.AccAddressFromBech32(onlyAddrStr)
|
||||
if err != nil {
|
||||
return types.MsgStoreCode{}, sdkerrors.Wrap(err, flagInstantiateByAddress)
|
||||
}
|
||||
x := types.AccessTypeOnlyAddress.With(allowedAddr)
|
||||
perm = &x
|
||||
} else if everybody := viper.GetBool(flagInstantiateByEverybody); everybody {
|
||||
perm = &types.AllowEverybody
|
||||
} else {
|
||||
everybodyStr, err := flags.GetString(flagInstantiateByEverybody)
|
||||
if err != nil {
|
||||
return types.MsgStoreCode{}, fmt.Errorf("instantiate by everybody: %s", err)
|
||||
}
|
||||
if everybodyStr != "" {
|
||||
ok, err := strconv.ParseBool(everybodyStr)
|
||||
if err != nil {
|
||||
return types.MsgStoreCode{}, fmt.Errorf("boolean value expected for instantiate by everybody: %s", err)
|
||||
}
|
||||
if ok {
|
||||
perm = &types.AllowEverybody
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
source, err := flags.GetString(flagSource)
|
||||
if err != nil {
|
||||
return types.MsgStoreCode{}, fmt.Errorf("source: %s", err)
|
||||
}
|
||||
builder, err := flags.GetString(flagBuilder)
|
||||
if err != nil {
|
||||
return types.MsgStoreCode{}, fmt.Errorf("builder: %s", err)
|
||||
}
|
||||
|
||||
msg := types.MsgStoreCode{
|
||||
Sender: cliCtx.GetFromAddress().String(),
|
||||
Sender: sender.String(),
|
||||
WASMByteCode: wasm,
|
||||
Source: viper.GetString(flagSource),
|
||||
Builder: viper.GetString(flagBuilder),
|
||||
Source: source,
|
||||
Builder: builder,
|
||||
InstantiatePermission: perm,
|
||||
}
|
||||
return msg, nil
|
||||
@@ -126,7 +151,7 @@ func InstantiateContractCmd() *cobra.Command {
|
||||
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
|
||||
msg, err := parseInstantiateArgs(args, clientCtx)
|
||||
msg, err := parseInstantiateArgs(args[0], args[1], clientCtx.GetFromAddress(), cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -144,29 +169,36 @@ func InstantiateContractCmd() *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func parseInstantiateArgs(args []string, cliCtx client.Context) (types.MsgInstantiateContract, error) {
|
||||
func parseInstantiateArgs(rawCodeID, initMsg string, sender sdk.AccAddress, flags *flag.FlagSet) (types.MsgInstantiateContract, error) {
|
||||
// get the id of the code to instantiate
|
||||
codeID, err := strconv.ParseUint(args[0], 10, 64)
|
||||
codeID, err := strconv.ParseUint(rawCodeID, 10, 64)
|
||||
if err != nil {
|
||||
return types.MsgInstantiateContract{}, err
|
||||
}
|
||||
|
||||
amounstStr := viper.GetString(flagAmount)
|
||||
amount, err := sdk.ParseCoinsNormalized(amounstStr)
|
||||
amountStr, err := flags.GetString(flagAmount)
|
||||
if err != nil {
|
||||
return types.MsgInstantiateContract{}, err
|
||||
return types.MsgInstantiateContract{}, fmt.Errorf("amount: %s", err)
|
||||
}
|
||||
amount, err := sdk.ParseCoinsNormalized(amountStr)
|
||||
if err != nil {
|
||||
return types.MsgInstantiateContract{}, fmt.Errorf("amount: %s", err)
|
||||
}
|
||||
label, err := flags.GetString(flagLabel)
|
||||
if err != nil {
|
||||
return types.MsgInstantiateContract{}, fmt.Errorf("label: %s", err)
|
||||
}
|
||||
|
||||
label := viper.GetString(flagLabel)
|
||||
if label == "" {
|
||||
return types.MsgInstantiateContract{}, fmt.Errorf("Label is required on all contracts")
|
||||
return types.MsgInstantiateContract{}, errors.New("label is required on all contracts")
|
||||
}
|
||||
adminStr, err := flags.GetString(flagAdmin)
|
||||
if err != nil {
|
||||
return types.MsgInstantiateContract{}, fmt.Errorf("admin: %s", err)
|
||||
}
|
||||
|
||||
initMsg := args[1]
|
||||
adminStr := viper.GetString(flagAdmin)
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
msg := types.MsgInstantiateContract{
|
||||
Sender: cliCtx.GetFromAddress().String(),
|
||||
Sender: sender.String(),
|
||||
CodeID: codeID,
|
||||
Label: label,
|
||||
InitFunds: amount,
|
||||
@@ -179,29 +211,16 @@ func parseInstantiateArgs(args []string, cliCtx client.Context) (types.MsgInstan
|
||||
// ExecuteContractCmd will instantiate a contract from previously uploaded code.
|
||||
func ExecuteContractCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "execute [contract_addr_bech32] [json_encoded_send_args]",
|
||||
Use: "execute [contract_addr_bech32] [json_encoded_send_args] --amount [coins,optional]",
|
||||
Short: "Execute a command on a wasm contract",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
|
||||
// get the id of the code to instantiate
|
||||
amounstStr := viper.GetString(flagAmount)
|
||||
amount, err := sdk.ParseCoinsNormalized(amounstStr)
|
||||
msg, err := parseExecuteArgs(args[0], args[1], clientCtx.GetFromAddress(), cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
execMsg := args[1]
|
||||
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
msg := types.MsgExecuteContract{
|
||||
Sender: clientCtx.GetFromAddress().String(),
|
||||
Contract: args[0],
|
||||
SentFunds: amount,
|
||||
Msg: []byte(execMsg),
|
||||
}
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -213,3 +232,22 @@ func ExecuteContractCmd() *cobra.Command {
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func parseExecuteArgs(contractAddr string, execMsg string, sender sdk.AccAddress, flags *flag.FlagSet) (types.MsgExecuteContract, error) {
|
||||
amountStr, err := flags.GetString(flagAmount)
|
||||
if err != nil {
|
||||
return types.MsgExecuteContract{}, fmt.Errorf("amount: %s", err)
|
||||
}
|
||||
|
||||
amount, err := sdk.ParseCoinsNormalized(amountStr)
|
||||
if err != nil {
|
||||
return types.MsgExecuteContract{}, err
|
||||
}
|
||||
|
||||
return types.MsgExecuteContract{
|
||||
Sender: sender.String(),
|
||||
Contract: contractAddr,
|
||||
SentFunds: amount,
|
||||
Msg: []byte(execMsg),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ func TestGovRestHandlers(t *testing.T) {
|
||||
"fees": []dict{{"denom": "ustake", "amount": "1000000"}},
|
||||
}
|
||||
)
|
||||
encodingConfig := keeper.MakeEncodingConfig()
|
||||
encodingConfig := keeper.MakeEncodingConfig(t)
|
||||
clientCtx := client.Context{}.
|
||||
WithJSONMarshaler(encodingConfig.Marshaler).
|
||||
WithTxConfig(encodingConfig.TxConfig).
|
||||
|
||||
@@ -79,7 +79,7 @@ func TestInitGenesis(t *testing.T) {
|
||||
q2 := newData.module.LegacyQuerierHandler(nil)
|
||||
|
||||
// initialize new app with genstate
|
||||
InitGenesis(newData.ctx, &newData.keeper, *genState)
|
||||
InitGenesis(newData.ctx, &newData.keeper, *genState, newData.stakingKeeper, newData.module.Route().Handler())
|
||||
|
||||
// run same checks again on newdata, to make sure it was reinitialized correctly
|
||||
assertCodeList(t, q2, newData.ctx, 1)
|
||||
|
||||
@@ -4,21 +4,25 @@ import (
|
||||
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
// authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
// "github.com/CosmWasm/wasmd/x/wasm/internal/types"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
)
|
||||
|
||||
// ValidatorSetSource is a subset of the staking keeper
|
||||
type ValidatorSetSource interface {
|
||||
ApplyAndReturnValidatorSetUpdates(sdk.Context) (updates []abci.ValidatorUpdate, err error)
|
||||
}
|
||||
|
||||
// InitGenesis sets supply information for genesis.
|
||||
//
|
||||
// CONTRACT: all types of accounts must have been already initialized/created
|
||||
func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState) error {
|
||||
func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState, stakingKeeper ValidatorSetSource, msgHandler sdk.Handler) ([]abci.ValidatorUpdate, error) {
|
||||
keeper.setParams(ctx, data.Params)
|
||||
|
||||
var maxCodeID uint64
|
||||
for i, code := range data.Codes {
|
||||
err := keeper.importCode(ctx, code.CodeID, code.CodeInfo, code.CodeBytes)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrapf(err, "code %d with id: %d", i, code.CodeID)
|
||||
return nil, sdkerrors.Wrapf(err, "code %d with id: %d", i, code.CodeID)
|
||||
}
|
||||
if code.CodeID > maxCodeID {
|
||||
maxCodeID = code.CodeID
|
||||
@@ -29,11 +33,11 @@ func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState) error
|
||||
for i, contract := range data.Contracts {
|
||||
contractAddr, err := sdk.AccAddressFromBech32(contract.ContractAddress)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrapf(err, "address in contract number %d", i)
|
||||
return nil, sdkerrors.Wrapf(err, "address in contract number %d", i)
|
||||
}
|
||||
err = keeper.importContract(ctx, contractAddr, &contract.ContractInfo, contract.ContractState)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrapf(err, "contract number %d", i)
|
||||
return nil, sdkerrors.Wrapf(err, "contract number %d", i)
|
||||
}
|
||||
maxContractID = i + 1 // not ideal but max(contractID) is not persisted otherwise
|
||||
}
|
||||
@@ -41,19 +45,32 @@ func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState) error
|
||||
for i, seq := range data.Sequences {
|
||||
err := keeper.importAutoIncrementID(ctx, seq.IDKey, seq.Value)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrapf(err, "sequence number %d", i)
|
||||
return nil, sdkerrors.Wrapf(err, "sequence number %d", i)
|
||||
}
|
||||
}
|
||||
|
||||
// sanity check seq values
|
||||
if keeper.peekAutoIncrementID(ctx, types.KeyLastCodeID) <= maxCodeID {
|
||||
return sdkerrors.Wrapf(types.ErrInvalid, "seq %s must be greater %d ", string(types.KeyLastCodeID), maxCodeID)
|
||||
return nil, sdkerrors.Wrapf(types.ErrInvalid, "seq %s must be greater %d ", string(types.KeyLastCodeID), maxCodeID)
|
||||
}
|
||||
if keeper.peekAutoIncrementID(ctx, types.KeyLastInstanceID) <= uint64(maxContractID) {
|
||||
return sdkerrors.Wrapf(types.ErrInvalid, "seq %s must be greater %d ", string(types.KeyLastInstanceID), maxContractID)
|
||||
return nil, sdkerrors.Wrapf(types.ErrInvalid, "seq %s must be greater %d ", string(types.KeyLastInstanceID), maxContractID)
|
||||
}
|
||||
|
||||
return nil
|
||||
if len(data.GenMsgs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
for _, genTx := range data.GenMsgs {
|
||||
msg := genTx.AsMsg()
|
||||
if msg == nil {
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "unknown message")
|
||||
}
|
||||
_, err := msgHandler(ctx, msg)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(err, "genesis")
|
||||
}
|
||||
}
|
||||
return stakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||
}
|
||||
|
||||
// ExportGenesis returns a GenesisState for a given context and keeper.
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
@@ -24,7 +25,9 @@ import (
|
||||
fuzz "github.com/google/gofuzz"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
"github.com/tendermint/tendermint/proto/tendermint/crypto"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
)
|
||||
@@ -96,7 +99,7 @@ func TestGenesisExportImport(t *testing.T) {
|
||||
var importState wasmTypes.GenesisState
|
||||
err = json.Unmarshal(exportedGenesis, &importState)
|
||||
require.NoError(t, err)
|
||||
InitGenesis(dstCtx, dstKeeper, importState)
|
||||
InitGenesis(dstCtx, dstKeeper, importState, &StakingKeeperMock{}, TestHandler(dstKeeper))
|
||||
|
||||
// compare whole DB
|
||||
for j := range srcStoreKeys {
|
||||
@@ -126,14 +129,16 @@ func TestGenesisExportImport(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFailFastImport(t *testing.T) {
|
||||
func TestGenesisInit(t *testing.T) {
|
||||
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
|
||||
require.NoError(t, err)
|
||||
|
||||
myCodeInfo := wasmTypes.CodeInfoFixture(wasmTypes.WithSHA256CodeHash(wasmCode))
|
||||
specs := map[string]struct {
|
||||
src types.GenesisState
|
||||
expSuccess bool
|
||||
src types.GenesisState
|
||||
stakingMock StakingKeeperMock
|
||||
msgHandlerMock MockMsgHandler
|
||||
expSuccess bool
|
||||
}{
|
||||
"happy path: code info correct": {
|
||||
src: types.GenesisState{
|
||||
@@ -355,19 +360,51 @@ func TestFailFastImport(t *testing.T) {
|
||||
Params: types.DefaultParams(),
|
||||
},
|
||||
},
|
||||
"validator set update called for any genesis messages": {
|
||||
src: wasmTypes.GenesisState{
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_StoreCode{
|
||||
StoreCode: types.MsgStoreCodeFixture(),
|
||||
}},
|
||||
},
|
||||
Params: types.DefaultParams(),
|
||||
},
|
||||
stakingMock: StakingKeeperMock{expCalls: 1, validatorUpdate: []abci.ValidatorUpdate{
|
||||
{PubKey: crypto.PublicKey{Sum: &crypto.PublicKey_Ed25519{
|
||||
Ed25519: []byte("a valid key")}},
|
||||
Power: 100,
|
||||
},
|
||||
}},
|
||||
msgHandlerMock: MockMsgHandler{expCalls: 1, expMsg: types.MsgStoreCodeFixture()},
|
||||
expSuccess: true,
|
||||
},
|
||||
"validator set update not called on genesis msg handler errors": {
|
||||
src: wasmTypes.GenesisState{
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{Sum: &types.GenesisState_GenMsgs_StoreCode{
|
||||
StoreCode: types.MsgStoreCodeFixture(),
|
||||
}},
|
||||
},
|
||||
Params: types.DefaultParams(),
|
||||
},
|
||||
msgHandlerMock: MockMsgHandler{expCalls: 1, err: errors.New("test error response")},
|
||||
stakingMock: StakingKeeperMock{expCalls: 0},
|
||||
},
|
||||
}
|
||||
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
keeper, ctx, _ := setupKeeper(t)
|
||||
|
||||
require.NoError(t, types.ValidateGenesis(spec.src))
|
||||
got := InitGenesis(ctx, keeper, spec.src)
|
||||
if spec.expSuccess {
|
||||
require.NoError(t, got)
|
||||
gotValidatorSet, gotErr := InitGenesis(ctx, keeper, spec.src, &spec.stakingMock, spec.msgHandlerMock.Handle)
|
||||
if !spec.expSuccess {
|
||||
require.Error(t, gotErr)
|
||||
return
|
||||
}
|
||||
require.Error(t, got)
|
||||
require.NoError(t, gotErr)
|
||||
spec.msgHandlerMock.verifyCalls(t)
|
||||
spec.stakingMock.verifyCalls(t)
|
||||
assert.Equal(t, spec.stakingMock.validatorUpdate, gotValidatorSet)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -433,7 +470,7 @@ func TestImportContractWithCodeHistoryReset(t *testing.T) {
|
||||
ctx = ctx.WithBlockHeight(0).WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||
|
||||
// when
|
||||
err = InitGenesis(ctx, keeper, importState)
|
||||
_, err = InitGenesis(ctx, keeper, importState, &StakingKeeperMock{}, TestHandler(keeper))
|
||||
require.NoError(t, err)
|
||||
|
||||
// verify wasm code
|
||||
@@ -482,6 +519,76 @@ func TestImportContractWithCodeHistoryReset(t *testing.T) {
|
||||
assert.Equal(t, expHistory, keeper.GetContractHistory(ctx, contractAddr))
|
||||
}
|
||||
|
||||
func TestSupportedGenMsgTypes(t *testing.T) {
|
||||
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
|
||||
require.NoError(t, err)
|
||||
var (
|
||||
myAddress sdk.AccAddress = bytes.Repeat([]byte{1}, sdk.AddrLen)
|
||||
verifierAddress sdk.AccAddress = bytes.Repeat([]byte{2}, sdk.AddrLen)
|
||||
beneficiaryAddress sdk.AccAddress = bytes.Repeat([]byte{3}, sdk.AddrLen)
|
||||
)
|
||||
const denom = "stake"
|
||||
importState := types.GenesisState{
|
||||
Params: types.DefaultParams(),
|
||||
GenMsgs: []types.GenesisState_GenMsgs{
|
||||
{
|
||||
Sum: &types.GenesisState_GenMsgs_StoreCode{
|
||||
StoreCode: &types.MsgStoreCode{
|
||||
Sender: myAddress.String(),
|
||||
WASMByteCode: wasmCode,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Sum: &types.GenesisState_GenMsgs_InstantiateContract{
|
||||
InstantiateContract: &types.MsgInstantiateContract{
|
||||
Sender: myAddress.String(),
|
||||
CodeID: 1,
|
||||
Label: "testing",
|
||||
InitMsg: HackatomExampleInitMsg{
|
||||
Verifier: verifierAddress,
|
||||
Beneficiary: beneficiaryAddress,
|
||||
}.GetBytes(t),
|
||||
InitFunds: sdk.NewCoins(sdk.NewCoin(denom, sdk.NewInt(10))),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Sum: &types.GenesisState_GenMsgs_ExecuteContract{
|
||||
ExecuteContract: &types.MsgExecuteContract{
|
||||
Sender: verifierAddress.String(),
|
||||
Contract: contractAddress(1, 1).String(),
|
||||
Msg: []byte(`{"release":{}}`),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
require.NoError(t, importState.ValidateBasic())
|
||||
ctx, keepers := CreateDefaultTestInput(t)
|
||||
keeper := keepers.WasmKeeper
|
||||
ctx = ctx.WithBlockHeight(0).WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||
fundAccounts(t, ctx, keepers.AccountKeeper, keepers.BankKeeper, myAddress, sdk.NewCoins(sdk.NewCoin(denom, sdk.NewInt(100))))
|
||||
// when
|
||||
_, err = InitGenesis(ctx, keeper, importState, &StakingKeeperMock{}, TestHandler(keeper))
|
||||
require.NoError(t, err)
|
||||
|
||||
// verify code stored
|
||||
gotWasmCode, err := keeper.GetByteCode(ctx, 1)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, wasmCode, gotWasmCode)
|
||||
codeInfo := keeper.GetCodeInfo(ctx, 1)
|
||||
require.NotNil(t, codeInfo)
|
||||
|
||||
// verify contract instantiated
|
||||
cInfo := keeper.GetContractInfo(ctx, contractAddress(1, 1))
|
||||
require.NotNil(t, cInfo)
|
||||
|
||||
// verify contract executed
|
||||
gotBalance := keepers.BankKeeper.GetBalance(ctx, beneficiaryAddress, denom)
|
||||
assert.Equal(t, sdk.NewCoin(denom, sdk.NewInt(10)), gotBalance)
|
||||
}
|
||||
|
||||
func setupKeeper(t *testing.T) (*Keeper, sdk.Context, []sdk.StoreKey) {
|
||||
t.Helper()
|
||||
tempDir, err := ioutil.TempDir("", "wasm")
|
||||
@@ -505,10 +612,46 @@ func setupKeeper(t *testing.T) (*Keeper, sdk.Context, []sdk.StoreKey) {
|
||||
Time: time.Date(2020, time.April, 22, 12, 0, 0, 0, time.UTC),
|
||||
}, false, log.NewNopLogger())
|
||||
|
||||
encodingConfig := MakeEncodingConfig()
|
||||
encodingConfig := MakeEncodingConfig(t)
|
||||
wasmConfig := wasmTypes.DefaultWasmConfig()
|
||||
pk := paramskeeper.NewKeeper(encodingConfig.Marshaler, encodingConfig.Amino, keyParams, tkeyParams)
|
||||
|
||||
srcKeeper := NewKeeper(encodingConfig.Marshaler, keyWasm, pk.Subspace(wasmTypes.DefaultParamspace), authkeeper.AccountKeeper{}, nil, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, tempDir, wasmConfig, "", nil, nil)
|
||||
return &srcKeeper, ctx, []sdk.StoreKey{keyWasm, keyParams}
|
||||
}
|
||||
|
||||
type StakingKeeperMock struct {
|
||||
err error
|
||||
validatorUpdate []abci.ValidatorUpdate
|
||||
expCalls int
|
||||
gotCalls int
|
||||
}
|
||||
|
||||
func (s *StakingKeeperMock) ApplyAndReturnValidatorSetUpdates(_ sdk.Context) ([]abci.ValidatorUpdate, error) {
|
||||
s.gotCalls++
|
||||
return s.validatorUpdate, s.err
|
||||
}
|
||||
|
||||
func (s *StakingKeeperMock) verifyCalls(t *testing.T) {
|
||||
assert.Equal(t, s.expCalls, s.gotCalls, "number calls")
|
||||
}
|
||||
|
||||
type MockMsgHandler struct {
|
||||
result *sdk.Result
|
||||
err error
|
||||
expCalls int
|
||||
gotCalls int
|
||||
expMsg sdk.Msg
|
||||
gotMsg sdk.Msg
|
||||
}
|
||||
|
||||
func (m *MockMsgHandler) Handle(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
|
||||
m.gotCalls++
|
||||
m.gotMsg = msg
|
||||
return m.result, m.err
|
||||
}
|
||||
|
||||
func (m *MockMsgHandler) verifyCalls(t *testing.T) {
|
||||
assert.Equal(t, m.expMsg, m.gotMsg, "message param")
|
||||
assert.Equal(t, m.expCalls, m.gotCalls, "number calls")
|
||||
}
|
||||
|
||||
@@ -628,14 +628,17 @@ func (k Keeper) generateContractAddress(ctx sdk.Context, codeID uint64) sdk.AccA
|
||||
return contractAddress(codeID, instanceID)
|
||||
}
|
||||
|
||||
// contractAddress builds an sdk account address for a contract.
|
||||
// Intentionally kept private as this is module internal logic.
|
||||
func contractAddress(codeID, instanceID uint64) sdk.AccAddress {
|
||||
// NOTE: It is possible to get a duplicate address if either codeID or instanceID
|
||||
// overflow 32 bits. This is highly improbable, but something that could be refactored.
|
||||
contractID := codeID<<32 + instanceID
|
||||
return addrFromUint64(contractID)
|
||||
|
||||
}
|
||||
|
||||
// GetNextCodeID reads the next sequence id used for storing wasm code.
|
||||
// Read only operation.
|
||||
func (k Keeper) GetNextCodeID(ctx sdk.Context) uint64 {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := store.Get(types.KeyLastCodeID)
|
||||
|
||||
@@ -72,7 +72,7 @@ func mustParse(t *testing.T, data []byte, res interface{}) {
|
||||
const MaskFeatures = "staking,mask"
|
||||
|
||||
func TestMaskReflectContractSend(t *testing.T) {
|
||||
cdc := MakeTestCodec()
|
||||
cdc := MakeTestCodec(t)
|
||||
ctx, keepers := CreateTestInput(t, false, MaskFeatures, maskEncoders(cdc), nil)
|
||||
accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper
|
||||
|
||||
@@ -154,7 +154,7 @@ func TestMaskReflectContractSend(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaskReflectCustomMsg(t *testing.T) {
|
||||
cdc := MakeTestCodec()
|
||||
cdc := MakeTestCodec(t)
|
||||
ctx, keepers := CreateTestInput(t, false, MaskFeatures, maskEncoders(cdc), maskPlugins())
|
||||
accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper
|
||||
|
||||
@@ -248,7 +248,7 @@ func TestMaskReflectCustomMsg(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaskReflectCustomQuery(t *testing.T) {
|
||||
cdc := MakeTestCodec()
|
||||
cdc := MakeTestCodec(t)
|
||||
ctx, keepers := CreateTestInput(t, false, MaskFeatures, maskEncoders(cdc), maskPlugins())
|
||||
accKeeper, keeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper
|
||||
|
||||
@@ -302,7 +302,7 @@ type maskState struct {
|
||||
}
|
||||
|
||||
func TestMaskReflectWasmQueries(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, MaskFeatures, maskEncoders(MakeTestCodec()), nil)
|
||||
ctx, keepers := CreateTestInput(t, false, MaskFeatures, maskEncoders(MakeTestCodec(t)), nil)
|
||||
accKeeper, keeper := keepers.AccountKeeper, keepers.WasmKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
@@ -373,7 +373,7 @@ func TestMaskReflectWasmQueries(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWasmRawQueryWithNil(t *testing.T) {
|
||||
ctx, keepers := CreateTestInput(t, false, MaskFeatures, maskEncoders(MakeTestCodec()), nil)
|
||||
ctx, keepers := CreateTestInput(t, false, MaskFeatures, maskEncoders(MakeTestCodec(t)), nil)
|
||||
accKeeper, keeper := keepers.AccountKeeper, keepers.WasmKeeper
|
||||
|
||||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -84,10 +83,11 @@ var ModuleBasics = module.NewBasicManager(
|
||||
transfer.AppModuleBasic{},
|
||||
)
|
||||
|
||||
func MakeTestCodec() codec.Marshaler {
|
||||
return MakeEncodingConfig().Marshaler
|
||||
func MakeTestCodec(t *testing.T) codec.Marshaler {
|
||||
return MakeEncodingConfig(t).Marshaler
|
||||
}
|
||||
func MakeEncodingConfig() params2.EncodingConfig {
|
||||
|
||||
func MakeEncodingConfig(_ *testing.T) params2.EncodingConfig {
|
||||
amino := codec.NewLegacyAmino()
|
||||
interfaceRegistry := codectypes.NewInterfaceRegistry()
|
||||
marshaler := codec.NewProtoCodec(interfaceRegistry)
|
||||
@@ -123,11 +123,14 @@ type TestKeepers struct {
|
||||
WasmKeeper *Keeper
|
||||
}
|
||||
|
||||
// CreateDefaultTestInput common settings for CreateTestInput
|
||||
func CreateDefaultTestInput(t *testing.T) (sdk.Context, TestKeepers) {
|
||||
return CreateTestInput(t, false, "staking", nil, nil)
|
||||
}
|
||||
|
||||
// encoders can be nil to accept the defaults, or set it to override some of the message handlers (like default)
|
||||
func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, encoders *MessageEncoders, queriers *QueryPlugins) (sdk.Context, TestKeepers) {
|
||||
tempDir, err := ioutil.TempDir("", "wasm")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { os.RemoveAll(tempDir) })
|
||||
tempDir := t.TempDir()
|
||||
|
||||
keyWasm := sdk.NewKVStoreKey(types.StoreKey)
|
||||
keyAcc := sdk.NewKVStoreKey(authtypes.StoreKey)
|
||||
@@ -154,7 +157,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc
|
||||
Height: 1234567,
|
||||
Time: time.Date(2020, time.April, 22, 12, 0, 0, 0, time.UTC),
|
||||
}, isCheckTx, log.NewNopLogger())
|
||||
encodingConfig := MakeEncodingConfig()
|
||||
encodingConfig := MakeEncodingConfig(t)
|
||||
appCodec, legacyAmino := encodingConfig.Marshaler, encodingConfig.Amino
|
||||
|
||||
paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, keyParams, tkeyParams)
|
||||
@@ -216,7 +219,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc
|
||||
// set some funds ot pay out validatores, based on code from:
|
||||
// https://github.com/cosmos/cosmos-sdk/blob/fea231556aee4d549d7551a6190389c4328194eb/x/distribution/keeper/keeper_test.go#L50-L57
|
||||
distrAcc := distKeeper.GetDistributionAccount(ctx)
|
||||
err = bankKeeper.SetBalances(ctx, distrAcc.GetAddress(), sdk.NewCoins(
|
||||
err := bankKeeper.SetBalances(ctx, distrAcc.GetAddress(), sdk.NewCoins(
|
||||
sdk.NewCoin("stake", sdk.NewInt(2000000)),
|
||||
))
|
||||
require.NoError(t, err)
|
||||
@@ -282,14 +285,13 @@ func CreateTestInput(t *testing.T, isCheckTx bool, supportedFeatures string, enc
|
||||
func TestHandler(k *Keeper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
|
||||
ctx = ctx.WithEventManager(sdk.NewEventManager())
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case *types.MsgStoreCode:
|
||||
return handleStoreCode(ctx, k, msg)
|
||||
case *types.MsgInstantiateContract:
|
||||
return handleInstantiate(ctx, k, msg)
|
||||
|
||||
case *types.MsgExecuteContract:
|
||||
return handleExecute(ctx, k, msg)
|
||||
|
||||
default:
|
||||
errMsg := fmt.Sprintf("unrecognized wasm message type: %T", msg)
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg)
|
||||
@@ -297,15 +299,34 @@ func TestHandler(k *Keeper) sdk.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
func handleStoreCode(ctx sdk.Context, k *Keeper, msg *types.MsgStoreCode) (*sdk.Result, error) {
|
||||
senderAddr, err := sdk.AccAddressFromBech32(msg.Sender)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(err, "sender")
|
||||
}
|
||||
codeID, err := k.Create(ctx, senderAddr, msg.WASMByteCode, msg.Source, msg.Builder, msg.InstantiatePermission)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &sdk.Result{
|
||||
Data: []byte(fmt.Sprintf("%d", codeID)),
|
||||
Events: ctx.EventManager().ABCIEvents(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func handleInstantiate(ctx sdk.Context, k *Keeper, msg *types.MsgInstantiateContract) (*sdk.Result, error) {
|
||||
senderAddr, err := sdk.AccAddressFromBech32(msg.Sender)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(err, "sender")
|
||||
}
|
||||
adminAddr, err := sdk.AccAddressFromBech32(msg.Admin)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(err, "admin")
|
||||
var adminAddr sdk.AccAddress
|
||||
if msg.Admin != "" {
|
||||
if adminAddr, err = sdk.AccAddressFromBech32(msg.Admin); err != nil {
|
||||
return nil, sdkerrors.Wrap(err, "admin")
|
||||
}
|
||||
}
|
||||
|
||||
contractAddr, err := k.Instantiate(ctx, msg.CodeID, senderAddr, adminAddr, msg.InitMsg, msg.Label, msg.InitFunds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -32,6 +32,11 @@ func (s GenesisState) ValidateBasic() error {
|
||||
return sdkerrors.Wrapf(err, "sequence: %d", i)
|
||||
}
|
||||
}
|
||||
for i := range s.GenMsgs {
|
||||
if err := s.GenMsgs[i].ValidateBasic(); err != nil {
|
||||
return sdkerrors.Wrapf(err, "gen message: %d", i)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -67,6 +72,28 @@ func (c Contract) ValidateBasic() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AsMsg returns the underlying cosmos-sdk message instance. Null when can not be mapped to a known type.
|
||||
func (m GenesisState_GenMsgs) AsMsg() sdk.Msg {
|
||||
if msg := m.GetStoreCode(); msg != nil {
|
||||
return msg
|
||||
}
|
||||
if msg := m.GetInstantiateContract(); msg != nil {
|
||||
return msg
|
||||
}
|
||||
if msg := m.GetExecuteContract(); msg != nil {
|
||||
return msg
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m GenesisState_GenMsgs) ValidateBasic() error {
|
||||
msg := m.AsMsg()
|
||||
if msg == nil {
|
||||
return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "unknown message")
|
||||
}
|
||||
return msg.ValidateBasic()
|
||||
}
|
||||
|
||||
// ValidateGenesis performs basic validation of supply genesis data returning an
|
||||
// error for any failed validation criteria.
|
||||
func ValidateGenesis(data GenesisState) error {
|
||||
|
||||
@@ -25,10 +25,11 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// GenesisState - genesis state of x/wasm
|
||||
type GenesisState struct {
|
||||
Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
|
||||
Codes []Code `protobuf:"bytes,2,rep,name=codes,proto3" json:"codes,omitempty"`
|
||||
Contracts []Contract `protobuf:"bytes,3,rep,name=contracts,proto3" json:"contracts,omitempty"`
|
||||
Sequences []Sequence `protobuf:"bytes,4,rep,name=sequences,proto3" json:"sequences,omitempty"`
|
||||
Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
|
||||
Codes []Code `protobuf:"bytes,2,rep,name=codes,proto3" json:"codes,omitempty"`
|
||||
Contracts []Contract `protobuf:"bytes,3,rep,name=contracts,proto3" json:"contracts,omitempty"`
|
||||
Sequences []Sequence `protobuf:"bytes,4,rep,name=sequences,proto3" json:"sequences,omitempty"`
|
||||
GenMsgs []GenesisState_GenMsgs `protobuf:"bytes,5,rep,name=gen_msgs,json=genMsgs,proto3" json:"gen_msgs,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GenesisState) Reset() { *m = GenesisState{} }
|
||||
@@ -92,6 +93,115 @@ func (m *GenesisState) GetSequences() []Sequence {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GenesisState) GetGenMsgs() []GenesisState_GenMsgs {
|
||||
if m != nil {
|
||||
return m.GenMsgs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenMsgs define the messages that can be executed during genesis phase.
|
||||
// The intention is to have more human readable data that is auditable.
|
||||
type GenesisState_GenMsgs struct {
|
||||
// sum is a single message
|
||||
//
|
||||
// Types that are valid to be assigned to Sum:
|
||||
// *GenesisState_GenMsgs_StoreCode
|
||||
// *GenesisState_GenMsgs_InstantiateContract
|
||||
// *GenesisState_GenMsgs_ExecuteContract
|
||||
Sum isGenesisState_GenMsgs_Sum `protobuf_oneof:"sum"`
|
||||
}
|
||||
|
||||
func (m *GenesisState_GenMsgs) Reset() { *m = GenesisState_GenMsgs{} }
|
||||
func (m *GenesisState_GenMsgs) String() string { return proto.CompactTextString(m) }
|
||||
func (*GenesisState_GenMsgs) ProtoMessage() {}
|
||||
func (*GenesisState_GenMsgs) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_52f9f2715025dba8, []int{0, 0}
|
||||
}
|
||||
func (m *GenesisState_GenMsgs) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *GenesisState_GenMsgs) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_GenesisState_GenMsgs.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *GenesisState_GenMsgs) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GenesisState_GenMsgs.Merge(m, src)
|
||||
}
|
||||
func (m *GenesisState_GenMsgs) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *GenesisState_GenMsgs) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GenesisState_GenMsgs.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GenesisState_GenMsgs proto.InternalMessageInfo
|
||||
|
||||
type isGenesisState_GenMsgs_Sum interface {
|
||||
isGenesisState_GenMsgs_Sum()
|
||||
MarshalTo([]byte) (int, error)
|
||||
Size() int
|
||||
}
|
||||
|
||||
type GenesisState_GenMsgs_StoreCode struct {
|
||||
StoreCode *MsgStoreCode `protobuf:"bytes,1,opt,name=store_code,json=storeCode,proto3,oneof" json:"store_code,omitempty"`
|
||||
}
|
||||
type GenesisState_GenMsgs_InstantiateContract struct {
|
||||
InstantiateContract *MsgInstantiateContract `protobuf:"bytes,2,opt,name=instantiate_contract,json=instantiateContract,proto3,oneof" json:"instantiate_contract,omitempty"`
|
||||
}
|
||||
type GenesisState_GenMsgs_ExecuteContract struct {
|
||||
ExecuteContract *MsgExecuteContract `protobuf:"bytes,3,opt,name=execute_contract,json=executeContract,proto3,oneof" json:"execute_contract,omitempty"`
|
||||
}
|
||||
|
||||
func (*GenesisState_GenMsgs_StoreCode) isGenesisState_GenMsgs_Sum() {}
|
||||
func (*GenesisState_GenMsgs_InstantiateContract) isGenesisState_GenMsgs_Sum() {}
|
||||
func (*GenesisState_GenMsgs_ExecuteContract) isGenesisState_GenMsgs_Sum() {}
|
||||
|
||||
func (m *GenesisState_GenMsgs) GetSum() isGenesisState_GenMsgs_Sum {
|
||||
if m != nil {
|
||||
return m.Sum
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GenesisState_GenMsgs) GetStoreCode() *MsgStoreCode {
|
||||
if x, ok := m.GetSum().(*GenesisState_GenMsgs_StoreCode); ok {
|
||||
return x.StoreCode
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GenesisState_GenMsgs) GetInstantiateContract() *MsgInstantiateContract {
|
||||
if x, ok := m.GetSum().(*GenesisState_GenMsgs_InstantiateContract); ok {
|
||||
return x.InstantiateContract
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GenesisState_GenMsgs) GetExecuteContract() *MsgExecuteContract {
|
||||
if x, ok := m.GetSum().(*GenesisState_GenMsgs_ExecuteContract); ok {
|
||||
return x.ExecuteContract
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// XXX_OneofWrappers is for the internal use of the proto package.
|
||||
func (*GenesisState_GenMsgs) XXX_OneofWrappers() []interface{} {
|
||||
return []interface{}{
|
||||
(*GenesisState_GenMsgs_StoreCode)(nil),
|
||||
(*GenesisState_GenMsgs_InstantiateContract)(nil),
|
||||
(*GenesisState_GenMsgs_ExecuteContract)(nil),
|
||||
}
|
||||
}
|
||||
|
||||
// Code struct encompasses CodeInfo and CodeBytes
|
||||
type Code struct {
|
||||
CodeID uint64 `protobuf:"varint,1,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"`
|
||||
@@ -269,6 +379,7 @@ func (m *Sequence) GetValue() uint64 {
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*GenesisState)(nil), "cosmwasm.wasm.v1beta1.GenesisState")
|
||||
proto.RegisterType((*GenesisState_GenMsgs)(nil), "cosmwasm.wasm.v1beta1.GenesisState.GenMsgs")
|
||||
proto.RegisterType((*Code)(nil), "cosmwasm.wasm.v1beta1.Code")
|
||||
proto.RegisterType((*Contract)(nil), "cosmwasm.wasm.v1beta1.Contract")
|
||||
proto.RegisterType((*Sequence)(nil), "cosmwasm.wasm.v1beta1.Sequence")
|
||||
@@ -279,39 +390,47 @@ func init() {
|
||||
}
|
||||
|
||||
var fileDescriptor_52f9f2715025dba8 = []byte{
|
||||
// 510 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x93, 0xc1, 0x6f, 0xd3, 0x3e,
|
||||
0x14, 0xc7, 0x9b, 0x2e, 0xcd, 0xaf, 0xf5, 0xfa, 0x63, 0xc8, 0x0c, 0x11, 0x6d, 0x2c, 0x29, 0xed,
|
||||
0xa5, 0x48, 0x28, 0x61, 0xe3, 0xc8, 0x89, 0x6c, 0x12, 0xca, 0x26, 0x10, 0xca, 0x0e, 0x48, 0xbb,
|
||||
0x54, 0x6e, 0xfc, 0x56, 0x22, 0x9a, 0xb8, 0xc4, 0xee, 0x58, 0xfe, 0x09, 0xc4, 0x9f, 0xb5, 0x1b,
|
||||
0x3d, 0x72, 0xaa, 0x50, 0x7a, 0xe3, 0xaf, 0x40, 0x76, 0xd2, 0x2c, 0x48, 0xeb, 0xb8, 0xa4, 0xf5,
|
||||
0xf3, 0xf7, 0x7d, 0xfc, 0xde, 0xf7, 0xd9, 0x68, 0x70, 0xed, 0x7e, 0x25, 0x3c, 0x76, 0xa3, 0x44,
|
||||
0x40, 0x9a, 0x90, 0xa9, 0x2b, 0xb2, 0x19, 0x70, 0x77, 0x02, 0x09, 0xf0, 0x88, 0x3b, 0xb3, 0x94,
|
||||
0x09, 0x86, 0x1f, 0x87, 0x8c, 0xc7, 0x52, 0xe6, 0xa8, 0xcf, 0xd5, 0xe1, 0x18, 0x04, 0x39, 0xdc,
|
||||
0xdb, 0x9d, 0xb0, 0x09, 0x53, 0x0a, 0x57, 0xfe, 0x2b, 0xc4, 0x7b, 0xcf, 0xee, 0x26, 0xaa, 0x6f,
|
||||
0x21, 0xe9, 0xff, 0x68, 0xa2, 0xee, 0xdb, 0xe2, 0x84, 0x73, 0x41, 0x04, 0xe0, 0xd7, 0xc8, 0x98,
|
||||
0x91, 0x94, 0xc4, 0xdc, 0xd4, 0x7a, 0xda, 0x70, 0xfb, 0xe8, 0xc0, 0xb9, 0xf3, 0x44, 0xe7, 0x83,
|
||||
0x12, 0x79, 0xfa, 0xcd, 0xd2, 0x6e, 0x04, 0x65, 0x0a, 0x3e, 0x45, 0xad, 0x90, 0x51, 0xe0, 0x66,
|
||||
0xb3, 0xb7, 0x35, 0xdc, 0x3e, 0xda, 0xdf, 0x90, 0x7b, 0xcc, 0x28, 0x78, 0x4f, 0x64, 0xe6, 0xef,
|
||||
0xa5, 0xbd, 0xa3, 0x32, 0x5e, 0xb0, 0x38, 0x12, 0x10, 0xcf, 0x44, 0x16, 0x14, 0x08, 0x7c, 0x81,
|
||||
0x3a, 0x21, 0x4b, 0x44, 0x4a, 0x42, 0xc1, 0xcd, 0x2d, 0xc5, 0xb3, 0x37, 0xf2, 0x0a, 0x9d, 0xb7,
|
||||
0x5f, 0x32, 0x1f, 0x55, 0x99, 0x35, 0xee, 0x2d, 0x4e, 0xb2, 0x39, 0x7c, 0x99, 0x43, 0x12, 0x02,
|
||||
0x37, 0xf5, 0x7b, 0xd9, 0xe7, 0xa5, 0xee, 0x96, 0x5d, 0x65, 0xd6, 0xd9, 0x55, 0xb0, 0xff, 0x4d,
|
||||
0x43, 0xba, 0x6c, 0x10, 0x0f, 0xd0, 0x7f, 0xb2, 0x93, 0x51, 0x44, 0x95, 0x95, 0xba, 0x87, 0xf2,
|
||||
0xa5, 0x6d, 0xc8, 0x2d, 0xff, 0x24, 0x30, 0xe4, 0x96, 0x4f, 0xb1, 0x27, 0xbb, 0x94, 0xa2, 0xe4,
|
||||
0x92, 0x99, 0x4d, 0xe5, 0xb8, 0x7d, 0x8f, 0x6b, 0x7e, 0x72, 0xc9, 0x4a, 0xcf, 0xdb, 0x61, 0xb9,
|
||||
0xc6, 0x07, 0x08, 0x29, 0xc6, 0x38, 0x13, 0x20, 0xad, 0xd2, 0x86, 0xdd, 0x40, 0x51, 0x3d, 0x19,
|
||||
0xe8, 0x2f, 0x34, 0xd4, 0x5e, 0x3b, 0x84, 0x9f, 0xa3, 0x87, 0x6b, 0x1b, 0x46, 0x84, 0xd2, 0x14,
|
||||
0x78, 0x31, 0xe8, 0x4e, 0xb0, 0xb3, 0x8e, 0xbf, 0x29, 0xc2, 0xf8, 0x3d, 0xfa, 0xbf, 0x92, 0xd6,
|
||||
0xca, 0x1b, 0xfc, 0x63, 0x08, 0xb5, 0x12, 0xbb, 0x61, 0x2d, 0x86, 0x7d, 0xf4, 0xa0, 0xe2, 0x71,
|
||||
0x79, 0xd7, 0xca, 0xa9, 0x3e, 0xdd, 0x00, 0x7c, 0xc7, 0x28, 0x4c, 0x4b, 0x52, 0x55, 0x89, 0xba,
|
||||
0xa4, 0x7d, 0x0f, 0xb5, 0xd7, 0x73, 0xc1, 0x3d, 0x64, 0x44, 0x74, 0xf4, 0x19, 0x32, 0xd5, 0x47,
|
||||
0xd7, 0xeb, 0xe4, 0x4b, 0xbb, 0xe5, 0x9f, 0x9c, 0x41, 0x16, 0xb4, 0x22, 0x7a, 0x06, 0x19, 0xde,
|
||||
0x45, 0xad, 0x2b, 0x32, 0x9d, 0x83, 0x6a, 0x40, 0x0f, 0x8a, 0x85, 0x77, 0x7a, 0x93, 0x5b, 0xda,
|
||||
0x22, 0xb7, 0xb4, 0x5f, 0xb9, 0xa5, 0x7d, 0x5f, 0x59, 0x8d, 0xc5, 0xca, 0x6a, 0xfc, 0x5c, 0x59,
|
||||
0x8d, 0x8b, 0x97, 0x93, 0x48, 0x7c, 0x9a, 0x8f, 0x9d, 0x90, 0xc5, 0xee, 0x31, 0xe3, 0xf1, 0x47,
|
||||
0xf9, 0x86, 0x64, 0x69, 0xd4, 0xbd, 0x2e, 0x7f, 0xff, 0x7e, 0x51, 0x63, 0x43, 0x3d, 0xa6, 0x57,
|
||||
0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x56, 0x37, 0xff, 0x93, 0xc3, 0x03, 0x00, 0x00,
|
||||
// 639 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x94, 0xc1, 0x6e, 0xd3, 0x40,
|
||||
0x10, 0x86, 0xe3, 0x26, 0x4e, 0x93, 0x6d, 0xa0, 0xd5, 0xb6, 0x88, 0x28, 0xa5, 0x71, 0x49, 0x2e,
|
||||
0xad, 0x80, 0x98, 0x96, 0x23, 0x27, 0xdc, 0x22, 0x9a, 0x56, 0x45, 0xc8, 0x95, 0x40, 0xea, 0x25,
|
||||
0x72, 0xec, 0xa9, 0xb1, 0xa8, 0xbd, 0x21, 0xb3, 0x29, 0xf5, 0x4b, 0x20, 0xc4, 0x53, 0xf5, 0xd8,
|
||||
0x23, 0xa7, 0x08, 0xa5, 0x37, 0x9e, 0x02, 0xed, 0x7a, 0xed, 0xba, 0x22, 0x2e, 0x17, 0x27, 0x3b,
|
||||
0xfe, 0xff, 0xcf, 0x33, 0xb3, 0xb3, 0x4b, 0xba, 0x97, 0xe6, 0x37, 0x07, 0x43, 0x33, 0x88, 0x38,
|
||||
0x8c, 0x23, 0xe7, 0xdc, 0xe4, 0xf1, 0x08, 0xd0, 0xf4, 0x21, 0x02, 0x0c, 0xb0, 0x37, 0x1a, 0x33,
|
||||
0xce, 0xe8, 0x23, 0x97, 0x61, 0x28, 0x64, 0x3d, 0xf9, 0xb8, 0xd8, 0x19, 0x02, 0x77, 0x76, 0x5a,
|
||||
0x6b, 0x3e, 0xf3, 0x99, 0x54, 0x98, 0xe2, 0x5f, 0x22, 0x6e, 0x3d, 0x9d, 0x4f, 0x94, 0x4f, 0x25,
|
||||
0x31, 0xe6, 0x4b, 0x42, 0xf4, 0x13, 0x41, 0xe7, 0x4a, 0x27, 0x8d, 0x77, 0x49, 0x0a, 0x27, 0xdc,
|
||||
0xe1, 0x40, 0x5f, 0x93, 0xea, 0xc8, 0x19, 0x3b, 0x21, 0x36, 0xb5, 0x4d, 0x6d, 0x6b, 0x69, 0x77,
|
||||
0xa3, 0x37, 0x37, 0xa5, 0xde, 0x07, 0x29, 0xb2, 0x2a, 0x57, 0x53, 0xa3, 0x64, 0x2b, 0x0b, 0x3d,
|
||||
0x24, 0xba, 0xcb, 0x3c, 0xc0, 0xe6, 0xc2, 0x66, 0x79, 0x6b, 0x69, 0x77, 0xbd, 0xc0, 0xbb, 0xc7,
|
||||
0x3c, 0xb0, 0x1e, 0x0b, 0xe7, 0x9f, 0xa9, 0xb1, 0x2c, 0x1d, 0xcf, 0x59, 0x18, 0x70, 0x08, 0x47,
|
||||
0x3c, 0xb6, 0x13, 0x04, 0x3d, 0x25, 0x75, 0x97, 0x45, 0x7c, 0xec, 0xb8, 0x1c, 0x9b, 0x65, 0xc9,
|
||||
0x33, 0x0a, 0x79, 0x89, 0xce, 0x5a, 0x57, 0xcc, 0xd5, 0xcc, 0x99, 0xe3, 0xde, 0xe2, 0x04, 0x1b,
|
||||
0xe1, 0xeb, 0x04, 0x22, 0x17, 0xb0, 0x59, 0xb9, 0x97, 0x7d, 0xa2, 0x74, 0xb7, 0xec, 0xcc, 0x99,
|
||||
0x67, 0x67, 0x41, 0x3a, 0x24, 0x35, 0x1f, 0xa2, 0x41, 0x88, 0x3e, 0x36, 0x75, 0x89, 0x7e, 0x56,
|
||||
0x80, 0xce, 0xf7, 0x5d, 0x2c, 0x8e, 0xd1, 0x47, 0xab, 0xa5, 0x3e, 0x43, 0x53, 0x48, 0xee, 0x2b,
|
||||
0x8b, 0x7e, 0x22, 0x6a, 0xfd, 0x5c, 0x20, 0x8b, 0xca, 0x40, 0xf7, 0x09, 0x41, 0xce, 0xc6, 0x30,
|
||||
0x10, 0x6d, 0x53, 0x9b, 0xd6, 0x2d, 0xf8, 0xe2, 0x31, 0xfa, 0x27, 0x42, 0x2b, 0x36, 0xe0, 0xa0,
|
||||
0x64, 0xd7, 0x31, 0x5d, 0xd0, 0x21, 0x59, 0x0b, 0x22, 0xe4, 0x4e, 0xc4, 0x03, 0x87, 0x0b, 0x56,
|
||||
0xd2, 0xaa, 0xe6, 0x82, 0xe4, 0xbd, 0x28, 0xe6, 0xf5, 0x6f, 0x5d, 0xe9, 0x36, 0x1c, 0x94, 0xec,
|
||||
0xd5, 0xe0, 0xdf, 0x30, 0xfd, 0x48, 0x56, 0xe0, 0x12, 0xdc, 0x49, 0x9e, 0x5f, 0x96, 0xfc, 0xed,
|
||||
0x62, 0xfe, 0xdb, 0xc4, 0x91, 0x63, 0x2f, 0xc3, 0xdd, 0x90, 0xa5, 0x93, 0x32, 0x4e, 0xc2, 0xce,
|
||||
0x77, 0x8d, 0x54, 0x64, 0x2d, 0x5d, 0xb2, 0x28, 0x7a, 0x31, 0x08, 0x3c, 0xd9, 0x8e, 0x8a, 0x45,
|
||||
0x66, 0x53, 0xa3, 0x2a, 0x5e, 0xf5, 0xf7, 0xed, 0xaa, 0x78, 0xd5, 0xf7, 0xa8, 0x25, 0xc6, 0x4b,
|
||||
0x88, 0xa2, 0x33, 0xa6, 0xaa, 0x34, 0xee, 0x19, 0xd7, 0x7e, 0x74, 0xc6, 0xd4, 0xb0, 0xd7, 0x5c,
|
||||
0xb5, 0xa6, 0x1b, 0x84, 0x48, 0xc6, 0x30, 0xe6, 0x80, 0xb2, 0x94, 0x86, 0x2d, 0xa9, 0x96, 0x08,
|
||||
0x74, 0xae, 0x35, 0x52, 0xcb, 0x8a, 0xdf, 0x26, 0x2b, 0x69, 0xd1, 0x03, 0xc7, 0xf3, 0xc6, 0x80,
|
||||
0xc9, 0x09, 0xab, 0xdb, 0xcb, 0x69, 0xfc, 0x4d, 0x12, 0xa6, 0xef, 0xc9, 0x83, 0x4c, 0x9a, 0x4b,
|
||||
0xaf, 0xfb, 0x9f, 0xe9, 0xcf, 0xa5, 0xd8, 0x70, 0x73, 0x31, 0xda, 0x27, 0x0f, 0x33, 0x1e, 0x8a,
|
||||
0x61, 0x53, 0xc7, 0xe9, 0x49, 0x51, 0xd7, 0x99, 0x07, 0xe7, 0x8a, 0x94, 0x65, 0x22, 0xa7, 0xb4,
|
||||
0x63, 0x91, 0x5a, 0x7a, 0x20, 0xe8, 0x26, 0xa9, 0x06, 0xde, 0xe0, 0x0b, 0xc4, 0xb2, 0x8e, 0x86,
|
||||
0x55, 0x9f, 0x4d, 0x0d, 0xbd, 0xbf, 0x7f, 0x04, 0xb1, 0xad, 0x07, 0xde, 0x11, 0xc4, 0x74, 0x8d,
|
||||
0xe8, 0x17, 0xce, 0xf9, 0x04, 0x64, 0x01, 0x15, 0x3b, 0x59, 0x58, 0x87, 0x57, 0xb3, 0xb6, 0x76,
|
||||
0x3d, 0x6b, 0x6b, 0xbf, 0x67, 0x6d, 0xed, 0xc7, 0x4d, 0xbb, 0x74, 0x7d, 0xd3, 0x2e, 0xfd, 0xba,
|
||||
0x69, 0x97, 0x4e, 0x5f, 0xfa, 0x01, 0xff, 0x3c, 0x19, 0xf6, 0x5c, 0x16, 0x9a, 0x7b, 0x0c, 0xc3,
|
||||
0x4f, 0xe2, 0xea, 0x12, 0xa9, 0x79, 0xe6, 0xa5, 0xfa, 0xbd, 0x7b, 0x91, 0x0d, 0xab, 0xf2, 0x16,
|
||||
0x7b, 0xf5, 0x37, 0x00, 0x00, 0xff, 0xff, 0xc2, 0xba, 0x9d, 0x7b, 0x5d, 0x05, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *GenesisState) Marshal() (dAtA []byte, err error) {
|
||||
@@ -334,6 +453,20 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.GenMsgs) > 0 {
|
||||
for iNdEx := len(m.GenMsgs) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.GenMsgs[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x2a
|
||||
}
|
||||
}
|
||||
if len(m.Sequences) > 0 {
|
||||
for iNdEx := len(m.Sequences) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
@@ -389,6 +522,101 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *GenesisState_GenMsgs) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *GenesisState_GenMsgs) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *GenesisState_GenMsgs) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.Sum != nil {
|
||||
{
|
||||
size := m.Sum.Size()
|
||||
i -= size
|
||||
if _, err := m.Sum.MarshalTo(dAtA[i:]); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *GenesisState_GenMsgs_StoreCode) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *GenesisState_GenMsgs_StoreCode) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
if m.StoreCode != nil {
|
||||
{
|
||||
size, err := m.StoreCode.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
func (m *GenesisState_GenMsgs_InstantiateContract) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *GenesisState_GenMsgs_InstantiateContract) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
if m.InstantiateContract != nil {
|
||||
{
|
||||
size, err := m.InstantiateContract.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
func (m *GenesisState_GenMsgs_ExecuteContract) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *GenesisState_GenMsgs_ExecuteContract) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
if m.ExecuteContract != nil {
|
||||
{
|
||||
size, err := m.ExecuteContract.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
func (m *Code) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
@@ -560,9 +788,63 @@ func (m *GenesisState) Size() (n int) {
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
if len(m.GenMsgs) > 0 {
|
||||
for _, e := range m.GenMsgs {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *GenesisState_GenMsgs) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.Sum != nil {
|
||||
n += m.Sum.Size()
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *GenesisState_GenMsgs_StoreCode) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.StoreCode != nil {
|
||||
l = m.StoreCode.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
func (m *GenesisState_GenMsgs_InstantiateContract) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.InstantiateContract != nil {
|
||||
l = m.InstantiateContract.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
func (m *GenesisState_GenMsgs_ExecuteContract) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.ExecuteContract != nil {
|
||||
l = m.ExecuteContract.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
func (m *Code) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
@@ -788,6 +1070,198 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 5:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field GenMsgs", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.GenMsgs = append(m.GenMsgs, GenesisState_GenMsgs{})
|
||||
if err := m.GenMsgs[len(m.GenMsgs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenesis(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *GenesisState_GenMsgs) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: GenMsgs: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: GenMsgs: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field StoreCode", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
v := &MsgStoreCode{}
|
||||
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
m.Sum = &GenesisState_GenMsgs_StoreCode{v}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field InstantiateContract", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
v := &MsgInstantiateContract{}
|
||||
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
m.Sum = &GenesisState_GenMsgs_InstantiateContract{v}
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ExecuteContract", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
v := &MsgExecuteContract{}
|
||||
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
m.Sum = &GenesisState_GenMsgs_ExecuteContract{v}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenesis(dAtA[iNdEx:])
|
||||
|
||||
@@ -3,6 +3,7 @@ package cosmwasm.wasm.v1beta1;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "x/wasm/internal/types/types.proto";
|
||||
import "x/wasm/internal/types/msg.proto";
|
||||
|
||||
option go_package = "github.com/CosmWasm/wasmd/x/wasmd/internal/types";
|
||||
|
||||
@@ -12,6 +13,18 @@ message GenesisState {
|
||||
repeated Code codes = 2 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "codes,omitempty"];
|
||||
repeated Contract contracts = 3 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "contracts,omitempty"];
|
||||
repeated Sequence sequences = 4 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "sequences,omitempty"];
|
||||
repeated GenMsgs gen_msgs = 5 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "gen_msgs,omitempty"];
|
||||
|
||||
// GenMsgs define the messages that can be executed during genesis phase in order.
|
||||
// The intention is to have more human readable data that is auditable.
|
||||
message GenMsgs {
|
||||
// sum is a single message
|
||||
oneof sum {
|
||||
MsgStoreCode store_code = 1;
|
||||
MsgInstantiateContract instantiate_contract = 2;
|
||||
MsgExecuteContract execute_contract = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Code struct encompasses CodeInfo and CodeBytes
|
||||
|
||||
@@ -39,6 +39,30 @@ func TestValidateGenesisState(t *testing.T) {
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"genesis store code message invalid": {
|
||||
srcMutator: func(s *GenesisState) {
|
||||
s.GenMsgs[0].GetStoreCode().WASMByteCode = nil
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"genesis instantiate contract message invalid": {
|
||||
srcMutator: func(s *GenesisState) {
|
||||
s.GenMsgs[1].GetInstantiateContract().CodeID = 0
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"genesis execute contract message invalid": {
|
||||
srcMutator: func(s *GenesisState) {
|
||||
s.GenMsgs[2].GetExecuteContract().Sender = "invalid"
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"genesis invalid message type": {
|
||||
srcMutator: func(s *GenesisState) {
|
||||
s.GenMsgs[0].Sum = nil
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
|
||||
@@ -14,6 +14,7 @@ func GenesisFixture(mutators ...func(*GenesisState)) GenesisState {
|
||||
numCodes = 2
|
||||
numContracts = 2
|
||||
numSequences = 2
|
||||
numMsg = 3
|
||||
)
|
||||
|
||||
fixture := GenesisState{
|
||||
@@ -34,6 +35,11 @@ func GenesisFixture(mutators ...func(*GenesisState)) GenesisState {
|
||||
Value: uint64(i),
|
||||
}
|
||||
}
|
||||
fixture.GenMsgs = []GenesisState_GenMsgs{
|
||||
{Sum: &GenesisState_GenMsgs_StoreCode{StoreCode: MsgStoreCodeFixture()}},
|
||||
{Sum: &GenesisState_GenMsgs_InstantiateContract{InstantiateContract: MsgInstantiateContractFixture()}},
|
||||
{Sum: &GenesisState_GenMsgs_ExecuteContract{ExecuteContract: MsgExecuteContractFixture()}},
|
||||
}
|
||||
for _, m := range mutators {
|
||||
m(&fixture)
|
||||
}
|
||||
@@ -120,6 +126,61 @@ func WithSHA256CodeHash(wasmCode []byte) func(info *CodeInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
func MsgStoreCodeFixture(mutators ...func(*MsgStoreCode)) *MsgStoreCode {
|
||||
var wasmIdent = []byte("\x00\x61\x73\x6D")
|
||||
const anyAddress = "cosmos1qyqszqgpqyqszqgpqyqszqgpqyqszqgpjnp7du"
|
||||
r := &MsgStoreCode{
|
||||
Sender: anyAddress,
|
||||
WASMByteCode: wasmIdent,
|
||||
Source: "https://example.com/code",
|
||||
Builder: "foo/bar:latest",
|
||||
InstantiatePermission: &AllowEverybody,
|
||||
}
|
||||
for _, m := range mutators {
|
||||
m(r)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func MsgInstantiateContractFixture(mutators ...func(*MsgInstantiateContract)) *MsgInstantiateContract {
|
||||
const anyAddress = "cosmos1qyqszqgpqyqszqgpqyqszqgpqyqszqgpjnp7du"
|
||||
r := &MsgInstantiateContract{
|
||||
Sender: anyAddress,
|
||||
Admin: anyAddress,
|
||||
CodeID: 1,
|
||||
Label: "testing",
|
||||
InitMsg: []byte(`{"foo":"bar"}`),
|
||||
InitFunds: sdk.Coins{{
|
||||
Denom: "stake",
|
||||
Amount: sdk.NewInt(1),
|
||||
}},
|
||||
}
|
||||
for _, m := range mutators {
|
||||
m(r)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func MsgExecuteContractFixture(mutators ...func(*MsgExecuteContract)) *MsgExecuteContract {
|
||||
const (
|
||||
anyAddress = "cosmos1qyqszqgpqyqszqgpqyqszqgpqyqszqgpjnp7du"
|
||||
firstContractAddress = "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5"
|
||||
)
|
||||
r := &MsgExecuteContract{
|
||||
Sender: anyAddress,
|
||||
Contract: firstContractAddress,
|
||||
Msg: []byte(`{"do":"something"}`),
|
||||
SentFunds: sdk.Coins{{
|
||||
Denom: "stake",
|
||||
Amount: sdk.NewInt(1),
|
||||
}},
|
||||
}
|
||||
for _, m := range mutators {
|
||||
m(r)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func StoreCodeProposalFixture(mutators ...func(*StoreCodeProposal)) *StoreCodeProposal {
|
||||
const anyAddress = "cosmos1qyqszqgpqyqszqgpqyqszqgpqyqszqgpjnp7du"
|
||||
p := &StoreCodeProposal{
|
||||
|
||||
@@ -94,14 +94,16 @@ func (b AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry)
|
||||
// AppModule implements an application module for the wasm module.
|
||||
type AppModule struct {
|
||||
AppModuleBasic
|
||||
keeper *Keeper
|
||||
keeper *Keeper
|
||||
validatorSetSource keeper.ValidatorSetSource
|
||||
}
|
||||
|
||||
// NewAppModule creates a new AppModule object
|
||||
func NewAppModule(keeper *Keeper) AppModule {
|
||||
func NewAppModule(keeper *Keeper, validatorSetSource keeper.ValidatorSetSource) AppModule {
|
||||
return AppModule{
|
||||
AppModuleBasic: AppModuleBasic{},
|
||||
keeper: keeper,
|
||||
AppModuleBasic: AppModuleBasic{},
|
||||
keeper: keeper,
|
||||
validatorSetSource: validatorSetSource,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,10 +133,11 @@ func (AppModule) QuerierRoute() string {
|
||||
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, data json.RawMessage) []abci.ValidatorUpdate {
|
||||
var genesisState GenesisState
|
||||
cdc.MustUnmarshalJSON(data, &genesisState)
|
||||
if err := InitGenesis(ctx, am.keeper, genesisState); err != nil {
|
||||
validators, err := InitGenesis(ctx, am.keeper, genesisState, am.validatorSetSource, am.Route().Handler())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return []abci.ValidatorUpdate{}
|
||||
return validators
|
||||
}
|
||||
|
||||
// ExportGenesis returns the exported genesis state as raw bytes for the wasm
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
"github.com/dvsekhvalnov/jose2go/base64url"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -22,23 +23,24 @@ import (
|
||||
)
|
||||
|
||||
type testData struct {
|
||||
module module.AppModule
|
||||
ctx sdk.Context
|
||||
acctKeeper authkeeper.AccountKeeper
|
||||
keeper Keeper
|
||||
bankKeeper bankkeeper.Keeper
|
||||
module module.AppModule
|
||||
ctx sdk.Context
|
||||
acctKeeper authkeeper.AccountKeeper
|
||||
keeper Keeper
|
||||
bankKeeper bankkeeper.Keeper
|
||||
stakingKeeper stakingkeeper.Keeper
|
||||
}
|
||||
|
||||
// returns a cleanup function, which must be defered on
|
||||
func setupTest(t *testing.T) testData {
|
||||
ctx, keepers := CreateTestInput(t, false, "staking", nil, nil)
|
||||
acctKeeper, wasmKeeper, bankKeeper := keepers.AccountKeeper, keepers.WasmKeeper, keepers.BankKeeper
|
||||
data := testData{
|
||||
module: NewAppModule(wasmKeeper),
|
||||
ctx: ctx,
|
||||
acctKeeper: acctKeeper,
|
||||
keeper: *wasmKeeper,
|
||||
bankKeeper: bankKeeper,
|
||||
module: NewAppModule(keepers.WasmKeeper, keepers.StakingKeeper),
|
||||
ctx: ctx,
|
||||
acctKeeper: keepers.AccountKeeper,
|
||||
keeper: *keepers.WasmKeeper,
|
||||
bankKeeper: keepers.BankKeeper,
|
||||
stakingKeeper: keepers.StakingKeeper,
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user