Skip to content

Commit

Permalink
Merge branch 'v2/develop' into whylee/v2/refactor/remove-tm-db-depend…
Browse files Browse the repository at this point in the history
…ency
  • Loading branch information
Yongwoo Lee committed May 3, 2021
2 parents 35cc38f + 62843eb commit da7363d
Show file tree
Hide file tree
Showing 34 changed files with 3,611 additions and 334 deletions.
1 change: 1 addition & 0 deletions CHANGELOG_PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Write the changes made after branching from cosmos-sdk v0.42.1.
* (global) [\#97](https://github.com/line/lbm-sdk/pull/97) Add codespace to query error
* (config) [\#114](https://github.com/line/lbm-sdk/pull/114) Add idle-timeout to rest server and rpc server config
* (x/wasm) [\#127](https://github.com/line/lbm-sdk/pull/127) Add wasm with Staragate migration completed.
* (x/wasm) [\#151](https://github.com/line/lbm-sdk/pull/151) Add contract access control.

### IMPROVEMENTS

Expand Down
61 changes: 61 additions & 0 deletions client/utils_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package client_test

import (
"strconv"
"testing"

"github.com/spf13/pflag"
"github.com/stretchr/testify/require"

"github.com/line/lbm-sdk/v2/client"
"github.com/line/lbm-sdk/v2/client/flags"
)

func TestPaginate(t *testing.T) {
Expand Down Expand Up @@ -75,3 +78,61 @@ func TestPaginate(t *testing.T) {
})
}
}

func TestReadPageRequest(t *testing.T) {

testCases := []struct {
name string
pageKey string
offset, limit, page int
countTotal bool
ok bool
}{
{
"use page ok",
"page key",
0, 100, 10,
true,
true,
},
{
"use offset ok",
"page key",
10, 100, 0,
true,
true,
},
{
"page and offset cannot be used together",
"page key",
100, 100, 10,
true,
false,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
flagSet := pflag.NewFlagSet("test flag set", pflag.ContinueOnError)
flagSet.String(flags.FlagPageKey, "default page key", "page key")
flagSet.Uint64(flags.FlagOffset, 0, "offset")
flagSet.Uint64(flags.FlagLimit, 0, "limit")
flagSet.Uint64(flags.FlagPage, 0, "page")
flagSet.Bool(flags.FlagCountTotal, false, "count total")

err := flagSet.Set(flags.FlagPageKey, tc.pageKey)
err = flagSet.Set(flags.FlagOffset, strconv.Itoa(tc.offset))
err = flagSet.Set(flags.FlagLimit, strconv.Itoa(tc.limit))
err = flagSet.Set(flags.FlagPage, strconv.Itoa(tc.page))
err = flagSet.Set(flags.FlagCountTotal, strconv.FormatBool(tc.countTotal))

pr, err := client.ReadPageRequest(flagSet)
if tc.ok {
require.NoError(t, err)
require.NotNil(t, pr)
} else {
require.Error(t, err)
}
})
}
}
74 changes: 38 additions & 36 deletions x/wasm/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,42 +99,44 @@ var (
)

type (
ProposalType = types.ProposalType
GenesisState = types.GenesisState
Code = types.Code
Contract = types.Contract
MsgStoreCode = types.MsgStoreCode
MsgStoreCodeResponse = types.MsgStoreCodeResponse
MsgInstantiateContract = types.MsgInstantiateContract
MsgInstantiateContractResponse = types.MsgInstantiateContractResponse
MsgExecuteContract = types.MsgExecuteContract
MsgExecuteContractResponse = types.MsgExecuteContractResponse
MsgMigrateContract = types.MsgMigrateContract
MsgMigrateContractResponse = types.MsgMigrateContractResponse
MsgUpdateAdmin = types.MsgUpdateAdmin
MsgUpdateAdminResponse = types.MsgUpdateAdminResponse
MsgClearAdmin = types.MsgClearAdmin
MsgWasmIBCCall = types.MsgIBCSend
MsgClearAdminResponse = types.MsgClearAdminResponse
MsgServer = types.MsgServer
Model = types.Model
CodeInfo = types.CodeInfo
ContractInfo = types.ContractInfo
CreatedAt = types.AbsoluteTxPosition
Config = types.WasmConfig
ContractInfoWithAddress = types.ContractInfoWithAddress
CodeInfoResponse = types.CodeInfoResponse
MessageHandler = keeper.DefaultMessageHandler
BankEncoder = keeper.BankEncoder
CustomEncoder = keeper.CustomEncoder
StakingEncoder = keeper.StakingEncoder
WasmEncoder = keeper.WasmEncoder
MessageEncoders = keeper.MessageEncoders
Keeper = keeper.Keeper
QueryHandler = keeper.QueryHandler
CustomQuerier = keeper.CustomQuerier
QueryPlugins = keeper.QueryPlugins
Option = keeper.Option
ProposalType = types.ProposalType
GenesisState = types.GenesisState
Code = types.Code
Contract = types.Contract
MsgStoreCode = types.MsgStoreCode
MsgStoreCodeResponse = types.MsgStoreCodeResponse
MsgInstantiateContract = types.MsgInstantiateContract
MsgInstantiateContractResponse = types.MsgInstantiateContractResponse
MsgStoreCodeAndInstantiateContract = types.MsgStoreCodeAndInstantiateContract
MsgStoreCodeAndInstantiateContractResponse = types.MsgStoreCodeAndInstantiateContractResponse
MsgExecuteContract = types.MsgExecuteContract
MsgExecuteContractResponse = types.MsgExecuteContractResponse
MsgMigrateContract = types.MsgMigrateContract
MsgMigrateContractResponse = types.MsgMigrateContractResponse
MsgUpdateAdmin = types.MsgUpdateAdmin
MsgUpdateAdminResponse = types.MsgUpdateAdminResponse
MsgClearAdmin = types.MsgClearAdmin
MsgWasmIBCCall = types.MsgIBCSend
MsgClearAdminResponse = types.MsgClearAdminResponse
MsgServer = types.MsgServer
Model = types.Model
CodeInfo = types.CodeInfo
ContractInfo = types.ContractInfo
CreatedAt = types.AbsoluteTxPosition
Config = types.WasmConfig
ContractInfoWithAddress = types.ContractInfoWithAddress
CodeInfoResponse = types.CodeInfoResponse
MessageHandler = keeper.DefaultMessageHandler
BankEncoder = keeper.BankEncoder
CustomEncoder = keeper.CustomEncoder
StakingEncoder = keeper.StakingEncoder
WasmEncoder = keeper.WasmEncoder
MessageEncoders = keeper.MessageEncoders
Keeper = keeper.Keeper
QueryHandler = keeper.QueryHandler
CustomQuerier = keeper.CustomQuerier
QueryPlugins = keeper.QueryPlugins
Option = keeper.Option

EncodeHandler = types.EncodeHandler
EncodeQuerier = types.EncodeQuerier
Expand Down
32 changes: 32 additions & 0 deletions x/wasm/client/cli/new_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,35 @@ func ClearContractAdminCmd() *cobra.Command {
flags.AddTxFlagsToCmd(cmd)
return cmd
}

// UpdateContractStatusCmd clears an admin for a contract
func UpdateContractStatusCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "update-contract-status [contract_addr_bech32] [status(Active|Inactive)]",
Short: "Clears admin for a contract to prevent further migrations",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

status := types.ContractStatusUnspecified
if err := (&status).UnmarshalText([]byte(args[1])); err != nil {
return err
}

msg := types.MsgUpdateContractStatus{
Sender: clientCtx.GetFromAddress().String(),
Contract: args[0],
Status: status,
}
if err := msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
},
}
flags.AddTxFlagsToCmd(cmd)
return cmd
}
124 changes: 124 additions & 0 deletions x/wasm/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ func GetTxCmd() *cobra.Command {
txCmd.AddCommand(
StoreCodeCmd(),
InstantiateContractCmd(),
StoreCodeAndInstantiateContractCmd(),
ExecuteContractCmd(),
MigrateContractCmd(),
UpdateContractAdminCmd(),
ClearContractAdminCmd(),
UpdateContractStatusCmd(),
)
return txCmd
}
Expand Down Expand Up @@ -213,6 +215,128 @@ func parseInstantiateArgs(rawCodeID, initMsg string, sender sdk.AccAddress, flag
return msg, nil
}

// StoreCodeAndInstantiatecontractcmd will upload code and instantiate a contract using it
func StoreCodeAndInstantiateContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "store-instantiate [wasm file] [json_encoded_init_args] --source [source] --builder [builder] --label [text] --admin [address,optional] --amount [coins,optional]",
Short: "Upload a wasm binary and instantiate a wasm contract from the code",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
msg, err := parseStoreCodeAndInstantiateContractArgs(args[0], args[1], clientCtx.GetFromAddress(), cmd.Flags())
if err != nil {
return err
}
if err = msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
},
}

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(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(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")
flags.AddTxFlagsToCmd(cmd)
return cmd
}

func parseStoreCodeAndInstantiateContractArgs(file string, initMsg string, sender sdk.AccAddress, flags *flag.FlagSet) (types.MsgStoreCodeAndInstantiateContract, error) {
wasm, err := ioutil.ReadFile(file)
if err != nil {
return types.MsgStoreCodeAndInstantiateContract{}, err
}

// gzip the wasm file
if wasmUtils.IsWasm(wasm) {
wasm, err = wasmUtils.GzipIt(wasm)

if err != nil {
return types.MsgStoreCodeAndInstantiateContract{}, err
}
} else if !wasmUtils.IsGzip(wasm) {
return types.MsgStoreCodeAndInstantiateContract{}, fmt.Errorf("invalid input file. Use wasm binary or gzip")
}

var perm *types.AccessConfig
onlyAddrStr, err := flags.GetString(flagInstantiateByAddress)
if err != nil {
return types.MsgStoreCodeAndInstantiateContract{}, fmt.Errorf("instantiate by address: %s", err)
}
if onlyAddrStr != "" {
allowedAddr, err := sdk.AccAddressFromBech32(onlyAddrStr)
if err != nil {
return types.MsgStoreCodeAndInstantiateContract{}, sdkerrors.Wrap(err, flagInstantiateByAddress)
}
x := types.AccessTypeOnlyAddress.With(allowedAddr)
perm = &x
} else {
everybodyStr, err := flags.GetString(flagInstantiateByEverybody)
if err != nil {
return types.MsgStoreCodeAndInstantiateContract{}, fmt.Errorf("instantiate by everybody: %s", err)
}
if everybodyStr != "" {
ok, err := strconv.ParseBool(everybodyStr)
if err != nil {
return types.MsgStoreCodeAndInstantiateContract{}, 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.MsgStoreCodeAndInstantiateContract{}, fmt.Errorf("source: %s", err)
}
builder, err := flags.GetString(flagBuilder)
if err != nil {
return types.MsgStoreCodeAndInstantiateContract{}, fmt.Errorf("builder: %s", err)
}

amountStr, err := flags.GetString(flagAmount)
if err != nil {
return types.MsgStoreCodeAndInstantiateContract{}, fmt.Errorf("amount: %s", err)
}
amount, err := sdk.ParseCoinsNormalized(amountStr)
if err != nil {
return types.MsgStoreCodeAndInstantiateContract{}, fmt.Errorf("amount: %s", err)
}
label, err := flags.GetString(flagLabel)
if err != nil {
return types.MsgStoreCodeAndInstantiateContract{}, fmt.Errorf("label: %s", err)
}
if label == "" {
return types.MsgStoreCodeAndInstantiateContract{}, errors.New("label is required on all contracts")
}
adminStr, err := flags.GetString(flagAdmin)
if err != nil {
return types.MsgStoreCodeAndInstantiateContract{}, fmt.Errorf("admin: %s", err)
}

msg := types.MsgStoreCodeAndInstantiateContract{
Sender: sender.String(),
WASMByteCode: wasm,
Source: source,
Builder: builder,
InstantiatePermission: perm,
Label: label,
Funds: amount,
InitMsg: []byte(initMsg),
Admin: adminStr,
}
return msg, nil
}

// ExecuteContractCmd will instantiate a contract from previously uploaded code.
func ExecuteContractCmd() *cobra.Command {
cmd := &cobra.Command{
Expand Down
Loading

0 comments on commit da7363d

Please sign in to comment.