Skip to content

Commit

Permalink
feat(module): scaffold parameters for a module (#1716)
Browse files Browse the repository at this point in the history
* add params structure

* add missing params file

* add testutil/keeper

* add integration test for params

* fix ibc testutil keeper

* add params test for ibc

* use types.DefaultParams for TestParamsQuery

* fix identantion for plush files

* add param tests for keeper

* fix subspace not found

* fix unused todo var

* fix param subspace for testutil

* fix unused import for module without params

* fix condition with wrong syntax

* fix integration test collision

* fix dummy value index

* fix dummy ValueInvalidIndex

* value index should be a string not a number

* prevent unused import error cor strconv

* avoid use strconv for string params types

* fix param index for the genesis state and some comments

* add bool param into the integration test

* improve todo comment for default value

Co-authored-by: İlker G. Öztürk <[email protected]>
Co-authored-by: Lucas Bertrand <[email protected]>
  • Loading branch information
3 people authored Oct 30, 2021
1 parent 23be58f commit 25dbd8b
Show file tree
Hide file tree
Showing 40 changed files with 364 additions and 50 deletions.
18 changes: 17 additions & 1 deletion integration/app/cmd_ibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,22 @@ func TestCreateIBCOracle(t *testing.T) {
)),
))

env.Must(env.Exec("create an IBC module with params",
step.NewSteps(step.New(
step.Exec(
"starport",
"s",
"module",
"paramsFoo",
"--ibc",
"--params",
"defaultName,isLaunched:bool,minLaunch:uint,maxLaunch:int",
"--require-registration",
),
step.Workdir(path),
)),
))

env.Must(env.Exec("create the first BandChain oracle integration",
step.NewSteps(step.New(
step.Exec("starport", "s", "band", "oracleone", "--module", "foo"),
Expand Down Expand Up @@ -151,7 +167,7 @@ func TestCreateIBCOracle(t *testing.T) {

env.Must(env.Exec("create a non-IBC module",
step.NewSteps(step.New(
step.Exec("starport", "s", "module", "bar", "--require-registration"),
step.Exec("starport", "s", "module", "bar", "--params", "name,minLaunch:uint,maxLaunch:int", "--require-registration"),
step.Workdir(path),
)),
))
Expand Down
13 changes: 11 additions & 2 deletions starport/cmd/scaffold_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
const (
flagDep = "dep"
flagIBC = "ibc"
flagParams = "params"
flagIBCOrdering = "ordering"
flagRequireRegistration = "require-registration"
)
Expand All @@ -37,14 +38,13 @@ func NewScaffoldModule() *cobra.Command {
c.Flags().Bool(flagIBC, false, "scaffold an IBC module")
c.Flags().String(flagIBCOrdering, "none", "channel ordering of the IBC module [none|ordered|unordered]")
c.Flags().Bool(flagRequireRegistration, false, "if true command will fail if module can't be registered")
c.Flags().StringSlice(flagParams, []string{}, "scaffold module params")

return c
}

func scaffoldModuleHandler(cmd *cobra.Command, args []string) error {
var (
options []scaffolder.ModuleCreationOption

name = args[0]
appPath = flagGetPath(cmd)
)
Expand All @@ -65,6 +65,15 @@ func scaffoldModuleHandler(cmd *cobra.Command, args []string) error {
return err
}

params, err := cmd.Flags().GetStringSlice(flagParams)
if err != nil {
return err
}

options := []scaffolder.ModuleCreationOption{
scaffolder.WithParams(params),
}

// Check if the module must be an IBC module
if ibcModule {
options = append(options, scaffolder.WithIBCChannelOrdering(ibcOrdering), scaffolder.WithIBC())
Expand Down
24 changes: 21 additions & 3 deletions starport/services/scaffolder/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/tendermint/starport/starport/pkg/placeholder"
"github.com/tendermint/starport/starport/pkg/validation"
"github.com/tendermint/starport/starport/pkg/xgenny"
"github.com/tendermint/starport/starport/templates/field"
"github.com/tendermint/starport/starport/templates/module"
modulecreate "github.com/tendermint/starport/starport/templates/module/create"
moduleimport "github.com/tendermint/starport/starport/templates/module/import"
Expand Down Expand Up @@ -89,13 +90,16 @@ var (

// moduleCreationOptions holds options for creating a new module
type moduleCreationOptions struct {
// chainID is the chain's id.
// ibc true if the module is an ibc module
ibc bool

// homePath of the chain's config dir.
// params list of parameters
params []string

// ibcChannelOrdering ibc channel ordering
ibcChannelOrdering string

// list of module depencies
// dependencies list of module dependencies
dependencies []modulecreate.Dependency
}

Expand All @@ -109,6 +113,13 @@ func WithIBC() ModuleCreationOption {
}
}

// WithParams scaffolds a module with params
func WithParams(params []string) ModuleCreationOption {
return func(m *moduleCreationOptions) {
m.params = params
}
}

// WithIBCChannelOrdering configures channel ordering of the IBC module
func WithIBCChannelOrdering(ordering string) ModuleCreationOption {
return func(m *moduleCreationOptions) {
Expand Down Expand Up @@ -162,6 +173,12 @@ func (s Scaffolder) CreateModule(
apply(&creationOpts)
}

// Parse params with the associated type
params, err := field.ParseFields(creationOpts.params, checkForbiddenTypeIndex)
if err != nil {
return sm, err
}

// Check dependencies
if err := checkDependencies(creationOpts.dependencies, s.path); err != nil {
return sm, err
Expand All @@ -170,6 +187,7 @@ func (s Scaffolder) CreateModule(
opts := &modulecreate.CreateOptions{
ModuleName: moduleName,
ModulePath: s.modpath.RawPath,
Params: params,
AppName: s.modpath.Package,
AppPath: s.path,
OwnerName: owner(s.modpath.RawPath),
Expand Down
1 change: 1 addition & 0 deletions starport/services/scaffolder/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ func checkForbiddenTypeField(name string) error {
case
"id",
"creator",
"params",
"appendedvalue",
datatype.TypeCustom:
return fmt.Errorf("%s is used by type scaffolder", name)
Expand Down
2 changes: 1 addition & 1 deletion starport/templates/field/datatype/bool.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var (
ValueIndex: "false",
ValueInvalidIndex: "false",
ProtoType: func(_, name string, index int) string {
return fmt.Sprintf("bool %s = %d;", name, index)
return fmt.Sprintf("bool %s = %d", name, index)
},
GenesisArgs: func(name multiformatname.Name, value int) string {
return fmt.Sprintf("%s: %t,\n", name.UpperCamel, value%2 == 0)
Expand Down
4 changes: 2 additions & 2 deletions starport/templates/field/datatype/coin.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var (
DataType: func(string) string { return "sdk.Coin" },
DefaultTestValue: "10token",
ProtoType: func(_, name string, index int) string {
return fmt.Sprintf("cosmos.base.v1beta1.Coin %s = %d [(gogoproto.nullable) = false];",
return fmt.Sprintf("cosmos.base.v1beta1.Coin %s = %d [(gogoproto.nullable) = false]",
name, index)
},
GenesisArgs: func(multiformatname.Name, int) string { return "" },
Expand All @@ -32,7 +32,7 @@ var (
DataType: func(string) string { return "sdk.Coins" },
DefaultTestValue: "10token,20stake",
ProtoType: func(_, name string, index int) string {
return fmt.Sprintf("repeated cosmos.base.v1beta1.Coin %s = %d [(gogoproto.nullable) = false];",
return fmt.Sprintf("repeated cosmos.base.v1beta1.Coin %s = %d [(gogoproto.nullable) = false]",
name, index)
},
GenesisArgs: func(multiformatname.Name, int) string { return "" },
Expand Down
2 changes: 1 addition & 1 deletion starport/templates/field/datatype/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var (
DataType: func(datatype string) string { return fmt.Sprintf("*%s", datatype) },
DefaultTestValue: "null",
ProtoType: func(datatype, name string, index int) string {
return fmt.Sprintf("%s %s = %d;", datatype, name, index)
return fmt.Sprintf("%s %s = %d", datatype, name, index)
},
GenesisArgs: func(name multiformatname.Name, value int) string {
return fmt.Sprintf("%s: new(types.%s),\n", name.UpperCamel, name.UpperCamel)
Expand Down
4 changes: 2 additions & 2 deletions starport/templates/field/datatype/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var (
ValueIndex: "0",
ValueInvalidIndex: "100000",
ProtoType: func(_, name string, index int) string {
return fmt.Sprintf("int32 %s = %d;", name, index)
return fmt.Sprintf("int32 %s = %d", name, index)
},
GenesisArgs: func(name multiformatname.Name, value int) string {
return fmt.Sprintf("%s: %d,\n", name.UpperCamel, value)
Expand All @@ -42,7 +42,7 @@ var (
DataType: func(string) string { return "[]int32" },
DefaultTestValue: "1,2,3,4,5",
ProtoType: func(_, name string, index int) string {
return fmt.Sprintf("repeated int32 %s = %d;", name, index)
return fmt.Sprintf("repeated int32 %s = %d", name, index)
},
GenesisArgs: func(name multiformatname.Name, value int) string {
return fmt.Sprintf("%s: []int32{%d},\n", name.UpperCamel, value)
Expand Down
4 changes: 2 additions & 2 deletions starport/templates/field/datatype/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var (
ValueIndex: "strconv.Itoa(0)",
ValueInvalidIndex: "strconv.Itoa(100000)",
ProtoType: func(_, name string, index int) string {
return fmt.Sprintf("string %s = %d;", name, index)
return fmt.Sprintf("string %s = %d", name, index)
},
GenesisArgs: func(name multiformatname.Name, value int) string {
return fmt.Sprintf("%s: \"%d\",\n", name.UpperCamel, value)
Expand All @@ -36,7 +36,7 @@ var (
DataType: func(string) string { return "[]string" },
DefaultTestValue: "abc,xyz",
ProtoType: func(_, name string, index int) string {
return fmt.Sprintf("repeated string %s = %d;", name, index)
return fmt.Sprintf("repeated string %s = %d", name, index)
},
GenesisArgs: func(name multiformatname.Name, value int) string {
return fmt.Sprintf("%s: []string{\"%d\"},\n", name.UpperCamel, value)
Expand Down
4 changes: 2 additions & 2 deletions starport/templates/field/datatype/uint.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var (
ValueIndex: "0",
ValueInvalidIndex: "100000",
ProtoType: func(_, name string, index int) string {
return fmt.Sprintf("uint64 %s = %d;", name, index)
return fmt.Sprintf("uint64 %s = %d", name, index)
},
GenesisArgs: func(name multiformatname.Name, value int) string {
return fmt.Sprintf("%s: %d,\n", name.UpperCamel, value)
Expand All @@ -42,7 +42,7 @@ var (
DataType: func(string) string { return "[]uint64" },
DefaultTestValue: "1,2,3,4,5",
ProtoType: func(_, name string, index int) string {
return fmt.Sprintf("repeated uint64 %s = %d;", name, index)
return fmt.Sprintf("repeated uint64 %s = %d", name, index)
},
GenesisArgs: func(name multiformatname.Name, value int) string {
return fmt.Sprintf("%s: []uint64{%d},\n", name.UpperCamel, value)
Expand Down
6 changes: 3 additions & 3 deletions starport/templates/ibc/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,12 @@ func protoModify(replacer placeholder.Replacer, opts *PacketOptions) genny.RunFn
// Add the message definition for packet and acknowledgment
var packetFields string
for i, field := range opts.Fields {
packetFields += fmt.Sprintf(" %s\n", field.ProtoType(i+1))
packetFields += fmt.Sprintf(" %s;\n", field.ProtoType(i+1))
}

var ackFields string
for i, field := range opts.AckFields {
ackFields += fmt.Sprintf(" %s\n", field.ProtoType(i+1))
ackFields += fmt.Sprintf(" %s;\n", field.ProtoType(i+1))
}

// Ensure custom types are imported
Expand Down Expand Up @@ -289,7 +289,7 @@ func protoTxModify(replacer placeholder.Replacer, opts *PacketOptions) genny.Run

var sendFields string
for i, field := range opts.Fields {
sendFields += fmt.Sprintf(" %s\n", field.ProtoType(i+5))
sendFields += fmt.Sprintf(" %s;\n", field.ProtoType(i+5))
}

// Ensure custom types are imported
Expand Down
4 changes: 2 additions & 2 deletions starport/templates/message/stargate.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ func protoTxMessageModify(replacer placeholder.Replacer, opts *Options) genny.Ru

var msgFields string
for i, field := range opts.Fields {
msgFields += fmt.Sprintf(" %s\n", field.ProtoType(i+2))
msgFields += fmt.Sprintf(" %s;\n", field.ProtoType(i+2))
}
var resFields string
for i, field := range opts.ResFields {
resFields += fmt.Sprintf(" %s\n", field.ProtoType(i+1))
resFields += fmt.Sprintf(" %s;\n", field.ProtoType(i+1))
}

template := `message Msg%[2]v {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

func TestGenesis(t *testing.T) {
genesisState := types.GenesisState{
Params: types.DefaultParams(),
<%= if (isIBC) { %>PortId: types.PortID,<% } %>
// this line is used by starport scaffolding # genesis/test/state
}
Expand Down
2 changes: 1 addition & 1 deletion starport/templates/module/create/ibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func genesisProtoModify(replacer placeholder.Replacer, opts *CreateOptions) genn
// Determine the new field number
content := f.String()

template := `string port_id = 1;
template := `string port_id = 2;
%s`
replacement := fmt.Sprintf(template, typed.PlaceholderGenesisProtoState)
content = replacer.Replace(content, typed.PlaceholderGenesisProtoState, replacement)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,8 @@ func <%= title(moduleName) %>Keeper(t testing.TB) (*keeper.Keeper, sdk.Context)
appCodec := codec.NewProtoCodec(registry)
capabilityKeeper := capabilitykeeper.NewKeeper(appCodec, storeKey, memStoreKey)

amino := codec.NewLegacyAmino()
ss := typesparams.NewSubspace(appCodec,
amino,
types.Amino,
storeKey,
memStoreKey,
"<%= title(moduleName) %>SubSpace",
Expand All @@ -51,16 +50,27 @@ func <%= title(moduleName) %>Keeper(t testing.TB) (*keeper.Keeper, sdk.Context)
capabilityKeeper.ScopeToModule("<%= title(moduleName) %>IBCKeeper"),
)

paramsSubspace := typesparams.NewSubspace(appCodec,
types.Amino,
storeKey,
memStoreKey,
"<%= title(moduleName) %>Params",
)
k := keeper.NewKeeper(
codec.NewProtoCodec(registry),
appCodec,
storeKey,
memStoreKey,
paramsSubspace,
IBCKeeper.ChannelKeeper,
&IBCKeeper.PortKeeper,
capabilityKeeper.ScopeToModule("<%= title(moduleName) %>ScopedKeeper"),<%= for (dependency) in dependencies { %>
nil,<% } %>
)

ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, logger)

// Initialize params
k.SetParams(ctx, types.DefaultParams())

return k, ctx
}
3 changes: 3 additions & 0 deletions starport/templates/module/create/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package modulecreate
import (
"fmt"
"strings"

"github.com/tendermint/starport/starport/templates/field"
)

// CreateOptions represents the options to scaffold a Cosmos SDK module
Expand All @@ -12,6 +14,7 @@ type CreateOptions struct {
AppName string
AppPath string
OwnerName string
Params field.Fields

// True if the module should implement the IBC module interface
IsIBC bool
Expand Down
2 changes: 2 additions & 0 deletions starport/templates/module/create/stargate.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func NewStargate(opts *CreateOptions) (*genny.Generator, error) {
ctx.Set("appName", opts.AppName)
ctx.Set("ownerName", opts.OwnerName)
ctx.Set("dependencies", opts.Dependencies)
ctx.Set("params", opts.Params)
ctx.Set("isIBC", opts.IsIBC)

// Used for proto package name
Expand Down Expand Up @@ -153,6 +154,7 @@ func appModifyStargate(replacer placeholder.Replacer, opts *CreateOptions) genny
appCodec,
keys[%[2]vmoduletypes.StoreKey],
keys[%[2]vmoduletypes.MemStoreKey],
app.GetSubspace(%[2]vmoduletypes.ModuleName),
%[4]v
%[6]v)
%[2]vModule := %[2]vmodule.NewAppModule(appCodec, app.%[5]vKeeper)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
syntax = "proto3";
package <%= formatOwnerName(ownerName) %>.<%= appName %>.<%= moduleName %>;

import "gogoproto/gogo.proto";
import "<%= moduleName %>/params.proto";
// this line is used by starport scaffolding # genesis/proto/import

option go_package = "<%= modulePath %>/x/<%= moduleName %>/types";

// GenesisState defines the <%= moduleName %> module's genesis state.
message GenesisState {
// this line is used by starport scaffolding # genesis/proto/state
Params params = 1 [(gogoproto.nullable) = false];
// this line is used by starport scaffolding # genesis/proto/state
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
syntax = "proto3";
package <%= formatOwnerName(ownerName) %>.<%= appName %>.<%= moduleName %>;

import "gogoproto/gogo.proto";

option go_package = "<%= modulePath %>/x/<%= moduleName %>/types";

// Params defines the parameters for the module.
message Params {
option (gogoproto.goproto_stringer) = false;
<%= for (i, param) in params { %>
<%= param.ProtoType(i+1) %> [(gogoproto.moretags) = "yaml:\"<%= param.Name.Snake %>\""];<% } %>
}
Loading

0 comments on commit 25dbd8b

Please sign in to comment.