From c9cf9a8bbfec22e7b5d4463ecd268efc8da18750 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 27 Jul 2020 18:58:09 +0200 Subject: [PATCH 01/14] Add build-gaiaflex to Makefile --- Makefile | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Makefile b/Makefile index 0a03819e32..8218304721 100644 --- a/Makefile +++ b/Makefile @@ -73,8 +73,23 @@ coral_ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=coral \ coral_ldflags += $(LDFLAGS) coral_ldflags := $(strip $(coral_ldflags)) +flex_ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=gaiaflex \ + -X github.com/cosmos/cosmos-sdk/version.ServerName=gaiaflexd \ + -X github.com/cosmos/cosmos-sdk/version.ClientName=gaiaflex \ + -X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \ + -X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \ + -X github.com/CosmWasm/wasmd/app.CLIDir=.gaiaflex \ + -X github.com/CosmWasm/wasmd/app.NodeDir=.gaiaflexd \ + -X github.com/CosmWasm/wasmd/app.Bech32Prefix=cosmos \ + -X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" + +flex_ldflags += $(LDFLAGS) +flex_ldflags := $(strip $(flex_ldflags)) + + BUILD_FLAGS := -tags $(build_tags_comma_sep) -ldflags '$(ldflags)' -trimpath CORAL_BUILD_FLAGS := -tags $(build_tags_comma_sep) -ldflags '$(coral_ldflags)' -trimpath +FLEX_BUILD_FLAGS := -tags $(build_tags_comma_sep) -ldflags '$(flex_ldflags)' -trimpath all: install lint test @@ -97,6 +112,15 @@ else go build -mod=readonly $(CORAL_BUILD_FLAGS) -o build/coral ./cmd/wasmcli endif +build-gaiaflex: go.sum +ifeq ($(OS),Windows_NT) + # wasmd nodes not supported on windows, maybe the cli? + go build -mod=readonly $(FLEX_BUILD_FLAGS) -o build/gaiaflex.exe ./cmd/wasmcli +else + go build -mod=readonly $(FLEX_BUILD_FLAGS) -o build/gaiaflexd ./cmd/wasmd + go build -mod=readonly $(FLEX_BUILD_FLAGS) -o build/gaiaflex ./cmd/wasmcli +endif + build-linux: go.sum LEDGER_ENABLED=false GOOS=linux GOARCH=amd64 $(MAKE) build From 7b1a4de59dcbd62cd15b6c384a72f9eadf8ddef8 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 27 Jul 2020 19:20:25 +0200 Subject: [PATCH 02/14] Add logic to app.go to configure enabled proposals --- app/app.go | 26 ++++++++++++++++++++++++++ cmd/wasmd/main.go | 8 ++++---- cmd/wasmd/replay.go | 3 +-- x/wasm/alias.go | 1 + x/wasm/internal/types/proposal.go | 18 ++++++++++++++++++ 5 files changed, 50 insertions(+), 6 deletions(-) diff --git a/app/app.go b/app/app.go index 9126471dc9..cc45f80f9c 100644 --- a/app/app.go +++ b/app/app.go @@ -4,6 +4,7 @@ import ( "io" "os" "path/filepath" + "strings" "github.com/CosmWasm/wasmd/x/wasm" wasmclient "github.com/CosmWasm/wasmd/x/wasm/client" @@ -44,8 +45,33 @@ var ( CLIDir = ".wasmcli" NodeDir = ".wasmd" Bech32Prefix = sdk.Bech32MainPrefix + + // If EnabledSpecificProposals is "", then we check this to decide to enable all or disable all x/wasm proposals + ProposalsEnabled = false + // If set to non-empty string it must be comma-separated list of values that are all a subset + // of "EnableAllProposals" (takes precedence over ProposalsEnabled) + // https://github.com/CosmWasm/wasmd/blob/02a54d33ff2c064f3539ae12d75d027d9c665f05/x/wasm/internal/types/proposal.go#L28-L34 + EnableSpecificProposals = "" ) +// GetEnabledProposals parses the ProposalsEnabled / EnableSpecificProposals values to +// produce a list of enabled proposals to pass into wasmd app. +func GetEnabledProposals() []wasm.ProposalType { + if EnableSpecificProposals == "" { + if ProposalsEnabled { + return wasm.EnableAllProposals + } else { + return wasm.DisableAllProposals + } + } + chunks := strings.Split(EnableSpecificProposals, ",") + proposals, err := wasm.ConvertToProposals(chunks) + if err != nil { + panic(err) + } + return proposals +} + // These constants are derived from the above variables. // These are the ones we will want to use in the code, based on // any overrides above diff --git a/cmd/wasmd/main.go b/cmd/wasmd/main.go index 99b75db470..91493f542f 100644 --- a/cmd/wasmd/main.go +++ b/cmd/wasmd/main.go @@ -6,7 +6,6 @@ import ( "io" "github.com/CosmWasm/wasmd/app" - "github.com/CosmWasm/wasmd/x/wasm" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client/debug" "github.com/cosmos/cosmos-sdk/client/flags" @@ -90,7 +89,8 @@ func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer) abci.Application } return app.NewWasmApp(logger, db, traceStore, true, invCheckPeriod, - wasm.DisableAllProposals, skipUpgradeHeights, + app.GetEnabledProposals(), + skipUpgradeHeights, baseapp.SetPruning(pruningOpts), baseapp.SetMinGasPrices(viper.GetString(server.FlagMinGasPrices)), baseapp.SetHaltHeight(viper.GetUint64(server.FlagHaltHeight)), @@ -103,7 +103,7 @@ func exportAppStateAndTMValidators( ) (json.RawMessage, []tmtypes.GenesisValidator, error) { if height != -1 { - gapp := app.NewWasmApp(logger, db, traceStore, false, uint(1), wasm.DisableAllProposals, nil) + gapp := app.NewWasmApp(logger, db, traceStore, false, uint(1), app.GetEnabledProposals(), nil) err := gapp.LoadHeight(height) if err != nil { return nil, nil, err @@ -111,6 +111,6 @@ func exportAppStateAndTMValidators( return gapp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) } - gapp := app.NewWasmApp(logger, db, traceStore, true, uint(1), wasm.DisableAllProposals, nil) + gapp := app.NewWasmApp(logger, db, traceStore, true, uint(1), app.GetEnabledProposals(), nil) return gapp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) } diff --git a/cmd/wasmd/replay.go b/cmd/wasmd/replay.go index 3b7f25bc56..c877fcc96b 100644 --- a/cmd/wasmd/replay.go +++ b/cmd/wasmd/replay.go @@ -8,7 +8,6 @@ import ( "time" "github.com/CosmWasm/wasmd/app" - "github.com/CosmWasm/wasmd/x/wasm" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/server" storetypes "github.com/cosmos/cosmos-sdk/store/types" @@ -92,7 +91,7 @@ func replayTxs(rootDir string) error { fmt.Fprintln(os.Stderr, "Creating application") gapp := app.NewWasmApp( // TODO: do we want to set skipUpgradeHieghts here? - ctx.Logger, appDB, traceStoreWriter, true, uint(1), wasm.DisableAllProposals, nil, + ctx.Logger, appDB, traceStoreWriter, true, uint(1), app.GetEnabledProposals(), nil, baseapp.SetPruning(storetypes.PruneEverything)) // Genesis diff --git a/x/wasm/alias.go b/x/wasm/alias.go index e0755f2acf..edf77ee8c6 100644 --- a/x/wasm/alias.go +++ b/x/wasm/alias.go @@ -39,6 +39,7 @@ var ( // functions aliases RegisterCodec = types.RegisterCodec ValidateGenesis = types.ValidateGenesis + ConvertToProposals = types.ConvertToProposals GetCodeKey = types.GetCodeKey GetContractAddressKey = types.GetContractAddressKey GetContractStorePrefixKey = types.GetContractStorePrefixKey diff --git a/x/wasm/internal/types/proposal.go b/x/wasm/internal/types/proposal.go index 363effa20f..3db50c7adc 100644 --- a/x/wasm/internal/types/proposal.go +++ b/x/wasm/internal/types/proposal.go @@ -33,6 +33,24 @@ var EnableAllProposals = []ProposalType{ ProposalTypeClearAdmin, } +// ConvertToProposals maps each key to a ProposalType and returns a typed list. +// If any string is not a valid type (in this file), then return an error +func ConvertToProposals(keys []string) ([]ProposalType, error) { + valid := make(map[string]bool, len(EnableAllProposals)) + for _, key := range EnableAllProposals { + valid[string(key)] = true + } + + proposals := make([]ProposalType, len(keys)) + for i, key := range keys { + if _, ok := valid[key]; !ok { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "'%s' is not a valid ProposalType", key) + } + proposals[i] = ProposalType(key) + } + return proposals, nil +} + func init() { // register new content types with the sdk govtypes.RegisterProposalType(string(ProposalTypeStoreCode)) govtypes.RegisterProposalType(string(ProposalTypeStoreInstantiateContract)) From 9c6a5c46d051a7bed8f608c2ec11cacfb0ba92bd Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 27 Jul 2020 19:30:40 +0200 Subject: [PATCH 03/14] Update Makefile, update proposals via -X flags --- Makefile | 4 +++- app/app.go | 11 ++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 8218304721..f20f8b076a 100644 --- a/Makefile +++ b/Makefile @@ -69,6 +69,8 @@ coral_ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=coral \ -X github.com/CosmWasm/wasmd/app.NodeDir=.corald \ -X github.com/CosmWasm/wasmd/app.Bech32Prefix=coral \ -X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" +# we could consider enabling governance override? +# -X github.com/CosmWasm/wasmd/app.EnableSpecificProposals=MigrateContract,UpdateAdmin,ClearAdmin \ coral_ldflags += $(LDFLAGS) coral_ldflags := $(strip $(coral_ldflags)) @@ -78,6 +80,7 @@ flex_ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=gaiaflex \ -X github.com/cosmos/cosmos-sdk/version.ClientName=gaiaflex \ -X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \ -X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \ + -X github.com/CosmWasm/wasmd/app.ProposalsEnabled=true \ -X github.com/CosmWasm/wasmd/app.CLIDir=.gaiaflex \ -X github.com/CosmWasm/wasmd/app.NodeDir=.gaiaflexd \ -X github.com/CosmWasm/wasmd/app.Bech32Prefix=cosmos \ @@ -86,7 +89,6 @@ flex_ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=gaiaflex \ flex_ldflags += $(LDFLAGS) flex_ldflags := $(strip $(flex_ldflags)) - BUILD_FLAGS := -tags $(build_tags_comma_sep) -ldflags '$(ldflags)' -trimpath CORAL_BUILD_FLAGS := -tags $(build_tags_comma_sep) -ldflags '$(coral_ldflags)' -trimpath FLEX_BUILD_FLAGS := -tags $(build_tags_comma_sep) -ldflags '$(flex_ldflags)' -trimpath diff --git a/app/app.go b/app/app.go index cc45f80f9c..e0eb742c4e 100644 --- a/app/app.go +++ b/app/app.go @@ -1,6 +1,7 @@ package app import ( + "fmt" "io" "os" "path/filepath" @@ -46,8 +47,9 @@ var ( NodeDir = ".wasmd" Bech32Prefix = sdk.Bech32MainPrefix - // If EnabledSpecificProposals is "", then we check this to decide to enable all or disable all x/wasm proposals - ProposalsEnabled = false + // If EnabledSpecificProposals is "", and this is "true", then enable all x/wasm proposals. + // If EnabledSpecificProposals is "", and this is not "true", then disable all x/wasm proposals. + ProposalsEnabled = "false" // If set to non-empty string it must be comma-separated list of values that are all a subset // of "EnableAllProposals" (takes precedence over ProposalsEnabled) // https://github.com/CosmWasm/wasmd/blob/02a54d33ff2c064f3539ae12d75d027d9c665f05/x/wasm/internal/types/proposal.go#L28-L34 @@ -58,9 +60,11 @@ var ( // produce a list of enabled proposals to pass into wasmd app. func GetEnabledProposals() []wasm.ProposalType { if EnableSpecificProposals == "" { - if ProposalsEnabled { + if ProposalsEnabled == "true" { + fmt.Println("Enabled all proposals") return wasm.EnableAllProposals } else { + fmt.Println("Disabled all proposals") return wasm.DisableAllProposals } } @@ -69,6 +73,7 @@ func GetEnabledProposals() []wasm.ProposalType { if err != nil { panic(err) } + fmt.Printf("Enabled proposals: %s\n", proposals) return proposals } From 133ed4e75e2eec591f92d3c453ee9c15f8757036 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 27 Jul 2020 19:36:39 +0200 Subject: [PATCH 04/14] Add testcase for ConvertToProposals --- app/app.go | 7 +---- x/wasm/internal/types/proposal_test.go | 38 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/app/app.go b/app/app.go index e0eb742c4e..256d276e1e 100644 --- a/app/app.go +++ b/app/app.go @@ -1,7 +1,6 @@ package app import ( - "fmt" "io" "os" "path/filepath" @@ -61,19 +60,15 @@ var ( func GetEnabledProposals() []wasm.ProposalType { if EnableSpecificProposals == "" { if ProposalsEnabled == "true" { - fmt.Println("Enabled all proposals") return wasm.EnableAllProposals - } else { - fmt.Println("Disabled all proposals") - return wasm.DisableAllProposals } + return wasm.DisableAllProposals } chunks := strings.Split(EnableSpecificProposals, ",") proposals, err := wasm.ConvertToProposals(chunks) if err != nil { panic(err) } - fmt.Printf("Enabled proposals: %s\n", proposals) return proposals } diff --git a/x/wasm/internal/types/proposal_test.go b/x/wasm/internal/types/proposal_test.go index 3616287363..96f38f35b2 100644 --- a/x/wasm/internal/types/proposal_test.go +++ b/x/wasm/internal/types/proposal_test.go @@ -616,3 +616,41 @@ contract: cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5 }) } } + +func TestConvertToProposals(t *testing.T) { + cases := map[string]struct { + input string + isError bool + proposals []ProposalType + }{ + "one proper item": { + input: "UpdateAdmin", + proposals: []ProposalType{ProposalTypeUpdateAdmin}, + }, + "multiple proper items": { + input: "StoreCode,InstantiateContract,MigrateContract", + proposals: []ProposalType{ProposalTypeStoreCode, ProposalTypeStoreInstantiateContract, ProposalTypeMigrateContract}, + }, + "empty trailing item": { + input: "StoreCode,", + isError: true, + }, + "invalid item": { + input: "StoreCode,InstanceContract", + isError: true, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + chunks := strings.Split(tc.input, ",") + proposals, err := ConvertToProposals(chunks) + if tc.isError { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, proposals, tc.proposals) + } + }) + } +} From 21dd88137a550d572876efdacad294d6464cc234 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 27 Jul 2020 19:38:04 +0200 Subject: [PATCH 05/14] Rename type ProposalTypeStoreInstantiateContract --- x/wasm/internal/types/proposal.go | 16 ++++++++-------- x/wasm/internal/types/proposal_test.go | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/x/wasm/internal/types/proposal.go b/x/wasm/internal/types/proposal.go index 3db50c7adc..23a35ebb82 100644 --- a/x/wasm/internal/types/proposal.go +++ b/x/wasm/internal/types/proposal.go @@ -14,11 +14,11 @@ import ( type ProposalType string const ( - ProposalTypeStoreCode ProposalType = "StoreCode" - ProposalTypeStoreInstantiateContract ProposalType = "InstantiateContract" - ProposalTypeMigrateContract ProposalType = "MigrateContract" - ProposalTypeUpdateAdmin ProposalType = "UpdateAdmin" - ProposalTypeClearAdmin ProposalType = "ClearAdmin" + ProposalTypeStoreCode ProposalType = "StoreCode" + ProposalTypeInstantiateContract ProposalType = "InstantiateContract" + ProposalTypeMigrateContract ProposalType = "MigrateContract" + ProposalTypeUpdateAdmin ProposalType = "UpdateAdmin" + ProposalTypeClearAdmin ProposalType = "ClearAdmin" ) // DisableAllProposals contains no wasm gov types. @@ -27,7 +27,7 @@ var DisableAllProposals []ProposalType // EnableAllProposals contains all wasm gov types as keys. var EnableAllProposals = []ProposalType{ ProposalTypeStoreCode, - ProposalTypeStoreInstantiateContract, + ProposalTypeInstantiateContract, ProposalTypeMigrateContract, ProposalTypeUpdateAdmin, ProposalTypeClearAdmin, @@ -53,7 +53,7 @@ func ConvertToProposals(keys []string) ([]ProposalType, error) { func init() { // register new content types with the sdk govtypes.RegisterProposalType(string(ProposalTypeStoreCode)) - govtypes.RegisterProposalType(string(ProposalTypeStoreInstantiateContract)) + govtypes.RegisterProposalType(string(ProposalTypeInstantiateContract)) govtypes.RegisterProposalType(string(ProposalTypeMigrateContract)) govtypes.RegisterProposalType(string(ProposalTypeUpdateAdmin)) govtypes.RegisterProposalType(string(ProposalTypeClearAdmin)) @@ -193,7 +193,7 @@ type InstantiateContractProposal struct { // ProposalType returns the type func (p InstantiateContractProposal) ProposalType() string { - return string(ProposalTypeStoreInstantiateContract) + return string(ProposalTypeInstantiateContract) } // ValidateBasic validates the proposal diff --git a/x/wasm/internal/types/proposal_test.go b/x/wasm/internal/types/proposal_test.go index 96f38f35b2..1a4e44d4c1 100644 --- a/x/wasm/internal/types/proposal_test.go +++ b/x/wasm/internal/types/proposal_test.go @@ -629,7 +629,7 @@ func TestConvertToProposals(t *testing.T) { }, "multiple proper items": { input: "StoreCode,InstantiateContract,MigrateContract", - proposals: []ProposalType{ProposalTypeStoreCode, ProposalTypeStoreInstantiateContract, ProposalTypeMigrateContract}, + proposals: []ProposalType{ProposalTypeStoreCode, ProposalTypeInstantiateContract, ProposalTypeMigrateContract}, }, "empty trailing item": { input: "StoreCode,", From 2e5c6d1678cd0e903ecf32394c59e5e905b15d26 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 27 Jul 2020 19:43:30 +0200 Subject: [PATCH 06/14] Add gaiaflex to dockerfile --- Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 12e59569d8..6fe3c2d825 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,8 +34,9 @@ COPY --from=rust-builder /lib/libgo_cosmwasm_muslc.a /lib/libgo_cosmwasm_muslc.a # force it to use static lib (from above) not standard libgo_cosmwasm.so file RUN LEDGER_ENABLED=false BUILD_TAGS=muslc make build -# we also (temporarily) build the testnet binaries here +# we also (temporarily?) build the testnet binaries here RUN LEDGER_ENABLED=false BUILD_TAGS=muslc make build-coral +RUN LEDGER_ENABLED=false BUILD_TAGS=muslc make build-gaiaflex # -------------------------------------------------------- FROM alpine:3.12 @@ -47,6 +48,8 @@ COPY --from=go-builder /code/build/wasmcli /usr/bin/wasmcli # testnet COPY --from=go-builder /code/build/coral /usr/bin/coral COPY --from=go-builder /code/build/corald /usr/bin/corald +COPY --from=go-builder /code/build/gaiaflex /usr/bin/gaiaflex +COPY --from=go-builder /code/build/gaiaflexd /usr/bin/gaiaflexd COPY docker/* /opt/ RUN chmod +x /opt/*.sh From 67279c356de0dcc321e049aef7e977bb04cbc0ef Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 27 Jul 2020 20:09:43 +0200 Subject: [PATCH 07/14] Remove wasmgovd files and Makefile entry --- Makefile | 1 - cmd/wasmgovd/genaccounts.go | 153 --------------- cmd/wasmgovd/main.go | 117 ----------- cmd/wasmgovd/replay.go | 191 ------------------ cmd/wasmgovd/testnet.go | 374 ------------------------------------ 5 files changed, 836 deletions(-) delete mode 100644 cmd/wasmgovd/genaccounts.go delete mode 100644 cmd/wasmgovd/main.go delete mode 100644 cmd/wasmgovd/replay.go delete mode 100644 cmd/wasmgovd/testnet.go diff --git a/Makefile b/Makefile index f20f8b076a..0e7263d5c1 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,6 @@ ifeq ($(OS),Windows_NT) go build -mod=readonly $(BUILD_FLAGS) -o build/wasmcli.exe ./cmd/wasmcli else go build -mod=readonly $(BUILD_FLAGS) -o build/wasmd ./cmd/wasmd - go build -mod=readonly $(BUILD_FLAGS) -o build/wasmgovd ./cmd/wasmgovd go build -mod=readonly $(BUILD_FLAGS) -o build/wasmcli ./cmd/wasmcli endif diff --git a/cmd/wasmgovd/genaccounts.go b/cmd/wasmgovd/genaccounts.go deleted file mode 100644 index 031e6576de..0000000000 --- a/cmd/wasmgovd/genaccounts.go +++ /dev/null @@ -1,153 +0,0 @@ -package main - -import ( - "bufio" - "errors" - "fmt" - - "github.com/spf13/cobra" - "github.com/spf13/viper" - - "github.com/tendermint/tendermint/libs/cli" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/crypto/keys" - "github.com/cosmos/cosmos-sdk/server" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" - authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" - authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting" - "github.com/cosmos/cosmos-sdk/x/genutil" -) - -const ( - flagClientHome = "home-client" - flagVestingStart = "vesting-start-time" - flagVestingEnd = "vesting-end-time" - flagVestingAmt = "vesting-amount" -) - -// AddGenesisAccountCmd returns add-genesis-account cobra Command. -func AddGenesisAccountCmd( - ctx *server.Context, cdc *codec.Codec, defaultNodeHome, defaultClientHome string, -) *cobra.Command { - - cmd := &cobra.Command{ - Use: "add-genesis-account [address_or_key_name] [coin][,[coin]]", - Short: "Add a genesis account to genesis.json", - Long: `Add a genesis account to genesis.json. The provided account must specify -the account address or key name and a list of initial coins. If a key name is given, -the address will be looked up in the local Keybase. The list of initial tokens must -contain valid denominations. Accounts may optionally be supplied with vesting parameters. -`, - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - config := ctx.Config - config.SetRoot(viper.GetString(cli.HomeFlag)) - - addr, err := sdk.AccAddressFromBech32(args[0]) - inBuf := bufio.NewReader(cmd.InOrStdin()) - if err != nil { - // attempt to lookup address from Keybase if no address was provided - kb, err := keys.NewKeyring( - sdk.KeyringServiceName(), - viper.GetString(flags.FlagKeyringBackend), - viper.GetString(flagClientHome), - inBuf, - ) - if err != nil { - return err - } - - info, err := kb.Get(args[0]) - if err != nil { - return fmt.Errorf("failed to get address from Keybase: %w", err) - } - - addr = info.GetAddress() - } - - coins, err := sdk.ParseCoins(args[1]) - if err != nil { - return fmt.Errorf("failed to parse coins: %w", err) - } - - vestingStart := viper.GetInt64(flagVestingStart) - vestingEnd := viper.GetInt64(flagVestingEnd) - vestingAmt, err := sdk.ParseCoins(viper.GetString(flagVestingAmt)) - if err != nil { - return fmt.Errorf("failed to parse vesting amount: %w", err) - } - - // create concrete account type based on input parameters - var genAccount authexported.GenesisAccount - - baseAccount := auth.NewBaseAccount(addr, coins.Sort(), nil, 0, 0) - if !vestingAmt.IsZero() { - baseVestingAccount, err := authvesting.NewBaseVestingAccount(baseAccount, vestingAmt.Sort(), vestingEnd) - if err != nil { - return fmt.Errorf("failed to create base vesting account: %w", err) - } - - switch { - case vestingStart != 0 && vestingEnd != 0: - genAccount = authvesting.NewContinuousVestingAccountRaw(baseVestingAccount, vestingStart) - - case vestingEnd != 0: - genAccount = authvesting.NewDelayedVestingAccountRaw(baseVestingAccount) - - default: - return errors.New("invalid vesting parameters; must supply start and end time or end time") - } - } else { - genAccount = baseAccount - } - - if err := genAccount.Validate(); err != nil { - return fmt.Errorf("failed to validate new genesis account: %w", err) - } - - genFile := config.GenesisFile() - appState, genDoc, err := genutil.GenesisStateFromGenFile(cdc, genFile) - if err != nil { - return fmt.Errorf("failed to unmarshal genesis state: %w", err) - } - - authGenState := auth.GetGenesisStateFromAppState(cdc, appState) - - if authGenState.Accounts.Contains(addr) { - return fmt.Errorf("cannot add account at existing address %s", addr) - } - - // Add the new account to the set of genesis accounts and sanitize the - // accounts afterwards. - authGenState.Accounts = append(authGenState.Accounts, genAccount) - authGenState.Accounts = auth.SanitizeGenesisAccounts(authGenState.Accounts) - - authGenStateBz, err := cdc.MarshalJSON(authGenState) - if err != nil { - return fmt.Errorf("failed to marshal auth genesis state: %w", err) - } - - appState[auth.ModuleName] = authGenStateBz - - appStateJSON, err := cdc.MarshalJSON(appState) - if err != nil { - return fmt.Errorf("failed to marshal application genesis state: %w", err) - } - - genDoc.AppState = appStateJSON - return genutil.ExportGenesisFile(genDoc, genFile) - }, - } - - cmd.Flags().String(cli.HomeFlag, defaultNodeHome, "node's home directory") - cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") - cmd.Flags().String(flagClientHome, defaultClientHome, "client's home directory") - cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts") - cmd.Flags().Uint64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts") - cmd.Flags().Uint64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts") - - return cmd -} diff --git a/cmd/wasmgovd/main.go b/cmd/wasmgovd/main.go deleted file mode 100644 index f52ce1ac1f..0000000000 --- a/cmd/wasmgovd/main.go +++ /dev/null @@ -1,117 +0,0 @@ -package main - -import ( - "encoding/json" - "io" - "os" - - "github.com/CosmWasm/wasmd/app" - "github.com/CosmWasm/wasmd/x/wasm" - "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/client/debug" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/store" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" - genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" - "github.com/cosmos/cosmos-sdk/x/staking" - "github.com/spf13/cobra" - "github.com/spf13/viper" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/libs/cli" - "github.com/tendermint/tendermint/libs/log" - tmtypes "github.com/tendermint/tendermint/types" - dbm "github.com/tendermint/tm-db" -) - -const flagInvCheckPeriod = "inv-check-period" - -var invCheckPeriod uint - -func main() { - cdc := app.MakeCodec() - - config := sdk.GetConfig() - config.SetBech32PrefixForAccount(sdk.Bech32PrefixAccAddr, sdk.Bech32PrefixAccPub) - config.SetBech32PrefixForValidator(sdk.Bech32PrefixValAddr, sdk.Bech32PrefixValPub) - config.SetBech32PrefixForConsensusNode(sdk.Bech32PrefixConsAddr, sdk.Bech32PrefixConsPub) - config.Seal() - - homeDir := os.ExpandEnv("$HOME/.wasmgovd") - - ctx := server.NewDefaultContext() - cobra.EnableCommandSorting = false - rootCmd := &cobra.Command{ - Use: "wasmgovd", - Short: "Wasm Daemon (server) with wasm gov proposals enabled\",", - PersistentPreRunE: server.PersistentPreRunEFn(ctx), - } - rootCmd.AddCommand(genutilcli.InitCmd(ctx, cdc, app.ModuleBasics, homeDir)) - rootCmd.AddCommand(genutilcli.CollectGenTxsCmd(ctx, cdc, auth.GenesisAccountIterator{}, homeDir)) - rootCmd.AddCommand(genutilcli.MigrateGenesisCmd(ctx, cdc)) - rootCmd.AddCommand( - genutilcli.GenTxCmd( - ctx, cdc, app.ModuleBasics, staking.AppModuleBasic{}, - auth.GenesisAccountIterator{}, homeDir, app.DefaultCLIHome, - ), - ) - rootCmd.AddCommand(genutilcli.ValidateGenesisCmd(ctx, cdc, app.ModuleBasics)) - rootCmd.AddCommand(AddGenesisAccountCmd(ctx, cdc, homeDir, app.DefaultCLIHome)) - rootCmd.AddCommand(flags.NewCompletionCmd(rootCmd, true)) - // rootCmd.AddCommand(testnetCmd(ctx, cdc, app.ModuleBasics, auth.GenesisAccountIterator{})) - rootCmd.AddCommand(replayCmd()) - rootCmd.AddCommand(debug.Cmd(cdc)) - - server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators) - - // prepare and add flags - executor := cli.PrepareBaseCmd(rootCmd, "WM", homeDir) - rootCmd.PersistentFlags().UintVar(&invCheckPeriod, flagInvCheckPeriod, - 0, "Assert registered invariants every N blocks") - err := executor.Execute() - if err != nil { - panic(err) - } -} - -func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer) abci.Application { - var cache sdk.MultiStorePersistentCache - - if viper.GetBool(server.FlagInterBlockCache) { - cache = store.NewCommitKVStoreCacheManager() - } - pruningOpts, err := server.GetPruningOptionsFromFlags() - if err != nil { - panic(err) - } - skipUpgradeHeights := make(map[int64]bool) - for _, h := range viper.GetIntSlice(server.FlagUnsafeSkipUpgrades) { - skipUpgradeHeights[int64(h)] = true - } - - return app.NewWasmApp(logger, db, traceStore, true, invCheckPeriod, - wasm.EnableAllProposals, skipUpgradeHeights, - baseapp.SetPruning(pruningOpts), - baseapp.SetMinGasPrices(viper.GetString(server.FlagMinGasPrices)), - baseapp.SetHaltHeight(viper.GetUint64(server.FlagHaltHeight)), - baseapp.SetHaltTime(viper.GetUint64(server.FlagHaltTime)), - baseapp.SetInterBlockCache(cache)) -} - -func exportAppStateAndTMValidators( - logger log.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailWhiteList []string, -) (json.RawMessage, []tmtypes.GenesisValidator, error) { - - if height != -1 { - gapp := app.NewWasmApp(logger, db, traceStore, false, uint(1), wasm.EnableAllProposals, nil) - err := gapp.LoadHeight(height) - if err != nil { - return nil, nil, err - } - return gapp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) - } - - gapp := app.NewWasmApp(logger, db, traceStore, true, uint(1), wasm.EnableAllProposals, nil) - return gapp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) -} diff --git a/cmd/wasmgovd/replay.go b/cmd/wasmgovd/replay.go deleted file mode 100644 index ca0f3a32ce..0000000000 --- a/cmd/wasmgovd/replay.go +++ /dev/null @@ -1,191 +0,0 @@ -package main - -import ( - "fmt" - "io" - "os" - "path/filepath" - "time" - - "github.com/CosmWasm/wasmd/app" - "github.com/CosmWasm/wasmd/x/wasm" - "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/server" - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - cpm "github.com/otiai10/copy" - "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" - tmos "github.com/tendermint/tendermint/libs/os" - "github.com/tendermint/tendermint/proxy" - tmsm "github.com/tendermint/tendermint/state" - tmstore "github.com/tendermint/tendermint/store" - tm "github.com/tendermint/tendermint/types" -) - -func replayCmd() *cobra.Command { - return &cobra.Command{ - Use: "replay ", - Short: "Replay gaia transactions", - RunE: func(_ *cobra.Command, args []string) error { - return replayTxs(args[0]) - }, - Args: cobra.ExactArgs(1), - } -} - -func replayTxs(rootDir string) error { - - if false { - // Copy the rootDir to a new directory, to preserve the old one. - fmt.Fprintln(os.Stderr, "Copying rootdir over") - oldRootDir := rootDir - rootDir = oldRootDir + "_replay" - if tmos.FileExists(rootDir) { - tmos.Exit(fmt.Sprintf("temporary copy dir %v already exists", rootDir)) - } - if err := cpm.Copy(oldRootDir, rootDir); err != nil { - return err - } - } - - configDir := filepath.Join(rootDir, "config") - dataDir := filepath.Join(rootDir, "data") - ctx := server.NewDefaultContext() - - // App DB - // appDB := dbm.NewMemDB() - fmt.Fprintln(os.Stderr, "Opening app database") - appDB, err := sdk.NewLevelDB("application", dataDir) - if err != nil { - return err - } - - // TM DB - // tmDB := dbm.NewMemDB() - fmt.Fprintln(os.Stderr, "Opening tendermint state database") - tmDB, err := sdk.NewLevelDB("state", dataDir) - if err != nil { - return err - } - - // Blockchain DB - fmt.Fprintln(os.Stderr, "Opening blockstore database") - bcDB, err := sdk.NewLevelDB("blockstore", dataDir) - if err != nil { - return err - } - - // TraceStore - var traceStoreWriter io.Writer - var traceStoreDir = filepath.Join(dataDir, "trace.log") - traceStoreWriter, err = os.OpenFile( - traceStoreDir, - os.O_WRONLY|os.O_APPEND|os.O_CREATE, - 0666, - ) - if err != nil { - return err - } - - // Application - fmt.Fprintln(os.Stderr, "Creating application") - gapp := app.NewWasmApp( - // TODO: do we want to set skipUpgradeHieghts here? - ctx.Logger, appDB, traceStoreWriter, true, uint(1), wasm.EnableAllProposals, nil, - baseapp.SetPruning(storetypes.PruneEverything)) - - // Genesis - var genDocPath = filepath.Join(configDir, "genesis.json") - genDoc, err := tm.GenesisDocFromFile(genDocPath) - if err != nil { - return err - } - genState, err := tmsm.MakeGenesisState(genDoc) - if err != nil { - return err - } - // tmsm.SaveState(tmDB, genState) - - cc := proxy.NewLocalClientCreator(gapp) - proxyApp := proxy.NewAppConns(cc) - err = proxyApp.Start() - if err != nil { - return err - } - defer func() { - err = proxyApp.Stop() - if err != nil { - return - } - }() - - state := tmsm.LoadState(tmDB) - if state.LastBlockHeight == 0 { - // Send InitChain msg - fmt.Fprintln(os.Stderr, "Sending InitChain msg") - validators := tm.TM2PB.ValidatorUpdates(genState.Validators) - csParams := tm.TM2PB.ConsensusParams(genDoc.ConsensusParams) - req := abci.RequestInitChain{ - Time: genDoc.GenesisTime, - ChainId: genDoc.ChainID, - ConsensusParams: csParams, - Validators: validators, - AppStateBytes: genDoc.AppState, - } - res, err := proxyApp.Consensus().InitChainSync(req) - if err != nil { - return err - } - newValidatorz, err := tm.PB2TM.ValidatorUpdates(res.Validators) - if err != nil { - return err - } - newValidators := tm.NewValidatorSet(newValidatorz) - - // Take the genesis state. - state = genState - state.Validators = newValidators - state.NextValidators = newValidators - } - - // Create executor - fmt.Fprintln(os.Stderr, "Creating block executor") - blockExec := tmsm.NewBlockExecutor(tmDB, ctx.Logger, proxyApp.Consensus(), nil, tmsm.MockEvidencePool{}) - - // Create block store - fmt.Fprintln(os.Stderr, "Creating block store") - blockStore := tmstore.NewBlockStore(bcDB) - - tz := []time.Duration{0, 0, 0} - for i := int(state.LastBlockHeight) + 1; ; i++ { - fmt.Fprintln(os.Stderr, "Running block ", i) - t1 := time.Now() - - // Apply block - fmt.Printf("loading and applying block %d\n", i) - blockmeta := blockStore.LoadBlockMeta(int64(i)) - if blockmeta == nil { - fmt.Printf("Couldn't find block meta %d... done?\n", i) - return nil - } - block := blockStore.LoadBlock(int64(i)) - if block == nil { - return fmt.Errorf("couldn't find block %d", i) - } - - t2 := time.Now() - - state, _, err = blockExec.ApplyBlock(state, blockmeta.BlockID, block) - if err != nil { - return err - } - - t3 := time.Now() - tz[0] += t2.Sub(t1) - tz[1] += t3.Sub(t2) - - fmt.Fprintf(os.Stderr, "new app hash: %X\n", state.AppHash) - fmt.Fprintln(os.Stderr, tz) - } -} diff --git a/cmd/wasmgovd/testnet.go b/cmd/wasmgovd/testnet.go deleted file mode 100644 index 3409f74e60..0000000000 --- a/cmd/wasmgovd/testnet.go +++ /dev/null @@ -1,374 +0,0 @@ -package main - -// DONTCOVER - -import ( - "bufio" - "encoding/json" - "fmt" - "net" - "os" - "path/filepath" - - "github.com/spf13/cobra" - "github.com/spf13/viper" - tmconfig "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/crypto" - tmos "github.com/tendermint/tendermint/libs/os" - tmrand "github.com/tendermint/tendermint/libs/rand" - "github.com/tendermint/tendermint/types" - tmtime "github.com/tendermint/tendermint/types/time" - - "github.com/cosmos/cosmos-sdk/client/flags" - clientkeys "github.com/cosmos/cosmos-sdk/client/keys" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/crypto/keys" - "github.com/cosmos/cosmos-sdk/server" - srvconfig "github.com/cosmos/cosmos-sdk/server/config" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - "github.com/cosmos/cosmos-sdk/x/auth" - authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" - "github.com/cosmos/cosmos-sdk/x/genutil" - genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - "github.com/cosmos/cosmos-sdk/x/staking" -) - -var ( - flagNodeDirPrefix = "node-dir-prefix" - flagNumValidators = "v" - flagOutputDir = "output-dir" - flagNodeDaemonHome = "node-daemon-home" - flagNodeCLIHome = "node-cli-home" - flagStartingIPAddress = "starting-ip-address" -) - -// get cmd to initialize all files for tendermint testnet and application -func testnetCmd(ctx *server.Context, cdc *codec.Codec, - mbm module.BasicManager, genAccIterator genutiltypes.GenesisAccountsIterator, -) *cobra.Command { - - cmd := &cobra.Command{ - Use: "testnet", - Short: "Initialize files for a Wasmd testnet", - Long: `testnet will create "v" number of directories and populate each with -necessary files (private validator, genesis, config, etc.). - -Note, strict routability for addresses is turned off in the config file. - -Example: - wasmd testnet --v 4 --output-dir ./output --starting-ip-address 192.168.10.2 - `, - RunE: func(cmd *cobra.Command, _ []string) error { - config := ctx.Config - - outputDir := viper.GetString(flagOutputDir) - chainID := viper.GetString(flags.FlagChainID) - minGasPrices := viper.GetString(server.FlagMinGasPrices) - nodeDirPrefix := viper.GetString(flagNodeDirPrefix) - nodeDaemonHome := viper.GetString(flagNodeDaemonHome) - nodeCLIHome := viper.GetString(flagNodeCLIHome) - startingIPAddress := viper.GetString(flagStartingIPAddress) - numValidators := viper.GetInt(flagNumValidators) - - return InitTestnet(cmd, config, cdc, mbm, genAccIterator, outputDir, chainID, - minGasPrices, nodeDirPrefix, nodeDaemonHome, nodeCLIHome, startingIPAddress, numValidators) - }, - } - - cmd.Flags().Int(flagNumValidators, 4, - "Number of validators to initialize the testnet with") - cmd.Flags().StringP(flagOutputDir, "o", "./mytestnet", - "Directory to store initialization data for the testnet") - cmd.Flags().String(flagNodeDirPrefix, "node", - "Prefix the directory name for each node with (node results in node0, node1, ...)") - cmd.Flags().String(flagNodeDaemonHome, "wasmd", - "Home directory of the node's daemon configuration") - cmd.Flags().String(flagNodeCLIHome, "wasmcli", - "Home directory of the node's cli configuration") - cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", - "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)") - cmd.Flags().String( - flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created") - cmd.Flags().String( - server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom), - "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)") - cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") - return cmd -} - -const nodeDirPerm = 0755 - -// Initialize the testnet -func InitTestnet(cmd *cobra.Command, config *tmconfig.Config, cdc *codec.Codec, - mbm module.BasicManager, genAccIterator genutiltypes.GenesisAccountsIterator, - outputDir, chainID, minGasPrices, nodeDirPrefix, nodeDaemonHome, - nodeCLIHome, startingIPAddress string, numValidators int) error { - - if chainID == "" { - chainID = "chain-" + tmrand.Str(6) - } - - monikers := make([]string, numValidators) - nodeIDs := make([]string, numValidators) - valPubKeys := make([]crypto.PubKey, numValidators) - - wasmConfig := srvconfig.DefaultConfig() - wasmConfig.MinGasPrices = minGasPrices - - //nolint:prealloc - var ( - genAccounts []authexported.GenesisAccount - genFiles []string - ) - - inBuf := bufio.NewReader(cmd.InOrStdin()) - // generate private keys, node IDs, and initial transactions - for i := 0; i < numValidators; i++ { - nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) - nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome) - clientDir := filepath.Join(outputDir, nodeDirName, nodeCLIHome) - gentxsDir := filepath.Join(outputDir, "gentxs") - - config.SetRoot(nodeDir) - config.RPC.ListenAddress = "tcp://0.0.0.0:26657" - - if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - if err := os.MkdirAll(clientDir, nodeDirPerm); err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - monikers = append(monikers, nodeDirName) - config.Moniker = nodeDirName - - ip, err := getIP(i, startingIPAddress) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(config) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip) - genFiles = append(genFiles, config.GenesisFile()) - - kb, err := keys.NewKeyring( - sdk.KeyringServiceName(), - viper.GetString(flags.FlagKeyringBackend), - viper.GetString(flagClientHome), - inBuf, - ) - if err != nil { - return err - } - - keyPass := clientkeys.DefaultKeyPass - addr, secret, err := server.GenerateSaveCoinKey(kb, nodeDirName, keyPass, true) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - info := map[string]string{"secret": secret} - - cliPrint, err := json.Marshal(info) - if err != nil { - return err - } - - // save private key seed words - if err := writeFile(fmt.Sprintf("%v.json", "key_seed"), clientDir, cliPrint); err != nil { - return err - } - - accTokens := sdk.TokensFromConsensusPower(1000) - accStakingTokens := sdk.TokensFromConsensusPower(500) - coins := sdk.Coins{ - sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), accTokens), - sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens), - } - genAccounts = append(genAccounts, auth.NewBaseAccount(addr, coins.Sort(), nil, 0, 0)) - - valTokens := sdk.TokensFromConsensusPower(100) - msg := staking.NewMsgCreateValidator( - sdk.ValAddress(addr), - valPubKeys[i], - sdk.NewCoin(sdk.DefaultBondDenom, valTokens), - staking.NewDescription(nodeDirName, "", "", "", ""), - staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()), - sdk.OneInt(), - ) - - tx := auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, []auth.StdSignature{}, memo) - txBldr := auth.NewTxBuilderFromCLI(inBuf).WithChainID(chainID).WithMemo(memo).WithKeybase(kb) - - signedTx, err := txBldr.SignStdTx(nodeDirName, clientkeys.DefaultKeyPass, tx, false) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - txBytes, err := cdc.MarshalJSON(signedTx) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - // gather gentxs folder - if err := writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBytes); err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - // TODO: Rename config file to server.toml as it's not particular to Gaia - // (REF: https://github.com/cosmos/cosmos-sdk/issues/4125). - wasmConfigFilePath := filepath.Join(nodeDir, "config/wasmd.toml") - srvconfig.WriteConfigFile(wasmConfigFilePath, wasmConfig) - } - - if err := initGenFiles(cdc, mbm, chainID, genAccounts, genFiles, numValidators); err != nil { - return err - } - - err := collectGenFiles( - cdc, config, chainID, monikers, nodeIDs, valPubKeys, numValidators, - outputDir, nodeDirPrefix, nodeDaemonHome, genAccIterator, - ) - if err != nil { - return err - } - - cmd.PrintErrf("Successfully initialized %d node directories\n", numValidators) - return nil -} - -func initGenFiles( - cdc *codec.Codec, mbm module.BasicManager, chainID string, - genAccounts []authexported.GenesisAccount, genFiles []string, numValidators int, -) error { - - appGenState := mbm.DefaultGenesis() - - // set the accounts in the genesis state - authDataBz := appGenState[auth.ModuleName] - var authGenState auth.GenesisState - cdc.MustUnmarshalJSON(authDataBz, &authGenState) - authGenState.Accounts = genAccounts - appGenState[auth.ModuleName] = cdc.MustMarshalJSON(authGenState) - - appGenStateJSON, err := codec.MarshalJSONIndent(cdc, appGenState) - if err != nil { - return err - } - - genDoc := types.GenesisDoc{ - ChainID: chainID, - AppState: appGenStateJSON, - Validators: nil, - } - - // generate empty genesis files for each validator and save - for i := 0; i < numValidators; i++ { - if err := genDoc.SaveAs(genFiles[i]); err != nil { - return err - } - } - return nil -} - -func collectGenFiles( - cdc *codec.Codec, config *tmconfig.Config, chainID string, - monikers, nodeIDs []string, valPubKeys []crypto.PubKey, - numValidators int, outputDir, nodeDirPrefix, nodeDaemonHome string, - genAccIterator genutiltypes.GenesisAccountsIterator) error { - - var appState json.RawMessage - genTime := tmtime.Now() - - for i := 0; i < numValidators; i++ { - nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) - nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome) - gentxsDir := filepath.Join(outputDir, "gentxs") - moniker := monikers[i] - config.Moniker = nodeDirName - - config.SetRoot(nodeDir) - - nodeID, valPubKey := nodeIDs[i], valPubKeys[i] - initCfg := genutil.NewInitConfig(chainID, gentxsDir, moniker, nodeID, valPubKey) - - genDoc, err := types.GenesisDocFromFile(config.GenesisFile()) - if err != nil { - return err - } - - nodeAppState, err := genutil.GenAppStateFromConfig(cdc, config, initCfg, *genDoc, genAccIterator) - if err != nil { - return err - } - - if appState == nil { - // set the canonical application state (they should not differ) - appState = nodeAppState - } - - genFile := config.GenesisFile() - - // overwrite each validator's genesis file to have a canonical genesis time - if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil { - return err - } - } - - return nil -} - -func getIP(i int, startingIPAddr string) (ip string, err error) { - if len(startingIPAddr) == 0 { - ip, err = server.ExternalIP() - if err != nil { - return "", err - } - return ip, nil - } - return calculateIP(startingIPAddr, i) -} - -func calculateIP(ip string, i int) (string, error) { - ipv4 := net.ParseIP(ip).To4() - if ipv4 == nil { - return "", fmt.Errorf("%v: non ipv4 address", ip) - } - - for j := 0; j < i; j++ { - ipv4[3]++ - } - - return ipv4.String(), nil -} - -func writeFile(name string, dir string, contents []byte) error { - writePath := filepath.Join(dir) - file := filepath.Join(writePath, name) - - err := tmos.EnsureDir(writePath, 0700) - if err != nil { - return err - } - - err = tmos.WriteFile(file, contents, 0600) - if err != nil { - return err - } - - return nil -} From 37e67245e7464d4355e16365efeef9e3de91ef33 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 27 Jul 2020 20:09:58 +0200 Subject: [PATCH 08/14] Explain compile-time flags in the README --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 815c49eaaf..b95d5469b1 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,27 @@ docker run --rm -it \ cosmwasm/wasmd:latest ./logs.sh ``` +## Runtime flags + +We provide a number of variables in `app/app.go` that are intended to be set via `-ldflags -X ...` +compile-time flags. This enables us to avoid copying a new binary directory over for each small change +to the configuration. + +Available flags: + +* `-X github.com/CosmWasm/wasmd/app.CLIDir=.coral` - set the config directory for the cli (default `~/.wasmcli`) +* `-X github.com/CosmWasm/wasmd/app.NodeDir=.corald` - set the config/data directory for the node (default `~/.wasmd`) +* `-X github.com/CosmWasm/wasmd/app.Bech32Prefix=coral` - set the bech32 prefix for all accounts (default `cosmos`) +* `-X github.com/CosmWasm/wasmd/app.ProposalsEnabled=true` - enable all x/wasm governance proposals (default `false`) +* `-X github.com/CosmWasm/wasmd/app.EnableSpecificProposals=MigrateContract,UpdateAdmin,ClearAdmin` - + enable a subset of the x/wasm governance proposal types (overrides `ProposalsEnabled`) + +Examples: + +* [`wasmd`](./Makefile#L50-L55) is a generic, permissionless version using the `cosmos` bech32 prefix +* [`gaiaflex`](./Makefile#L78-L87) is a generic, *permissioned* version using the `cosmos` bech32 prefix +* [`coral`](./Makefile#L63-L71) is a permissionless version designed for a specific testnet, with a `coral` bech32 prefix + ## Contributors Much thanks to all who have contributed to this project, from this app, to the `cosmwasm` framework, to example contracts and documentation. From 6d2a01b4252f09410e84fc43832b4e389cf6e7f1 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 27 Jul 2020 20:10:24 +0200 Subject: [PATCH 09/14] Remove wasmgovd from Dockerfile --- Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 6fe3c2d825..bf5113ca14 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,7 +42,6 @@ RUN LEDGER_ENABLED=false BUILD_TAGS=muslc make build-gaiaflex FROM alpine:3.12 COPY --from=go-builder /code/build/wasmd /usr/bin/wasmd -COPY --from=go-builder /code/build/wasmgovd /usr/bin/wasmgovd COPY --from=go-builder /code/build/wasmcli /usr/bin/wasmcli # testnet From 08aef4a650afb94b4a80f64d80d185087629348e Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 27 Jul 2020 20:25:46 +0200 Subject: [PATCH 10/14] Remove unneeded libs from rust build --- Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6fe3c2d825..880f170d56 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,6 @@ FROM cosmwasm/go-ext-builder:0.8.2-alpine AS rust-builder RUN apk add git -# without this, build with LEDGER_ENABLED=false -RUN apk add libusb-dev linux-headers # copy all code into /code WORKDIR /code From ec3edaad2283fb37f4e123f1339fc9590069e813 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Jul 2020 09:28:59 +0200 Subject: [PATCH 11/14] Fix spaces for tabs in Makefile --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index f20f8b076a..b495e7440b 100644 --- a/Makefile +++ b/Makefile @@ -97,7 +97,7 @@ all: install lint test build: go.sum ifeq ($(OS),Windows_NT) - # wasmd nodes not supported on windows, maybe the cli? + # wasmd nodes not supported on windows, maybe the cli? go build -mod=readonly $(BUILD_FLAGS) -o build/wasmcli.exe ./cmd/wasmcli else go build -mod=readonly $(BUILD_FLAGS) -o build/wasmd ./cmd/wasmd @@ -107,7 +107,7 @@ endif build-coral: go.sum ifeq ($(OS),Windows_NT) - # wasmd nodes not supported on windows, maybe the cli? + # wasmd nodes not supported on windows, maybe the cli? go build -mod=readonly $(CORAL_BUILD_FLAGS) -o build/coral.exe ./cmd/wasmcli else go build -mod=readonly $(CORAL_BUILD_FLAGS) -o build/corald ./cmd/wasmd @@ -116,7 +116,7 @@ endif build-gaiaflex: go.sum ifeq ($(OS),Windows_NT) - # wasmd nodes not supported on windows, maybe the cli? + # wasmd nodes not supported on windows, maybe the cli? go build -mod=readonly $(FLEX_BUILD_FLAGS) -o build/gaiaflex.exe ./cmd/wasmcli else go build -mod=readonly $(FLEX_BUILD_FLAGS) -o build/gaiaflexd ./cmd/wasmd From 97c8574d9b4f53599b9cca734447c19811fe5e73 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Jul 2020 11:22:53 +0200 Subject: [PATCH 12/14] Remove wasmgovd scripts and add some to README --- README.md | 10 ++++++++++ docker/run_wasmgovd.sh | 10 ---------- docker/setup_wasmgovd.sh | 24 ------------------------ 3 files changed, 10 insertions(+), 34 deletions(-) delete mode 100755 docker/run_wasmgovd.sh delete mode 100755 docker/setup_wasmgovd.sh diff --git a/README.md b/README.md index b95d5469b1..4faa5a4b78 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,16 @@ Examples: * [`gaiaflex`](./Makefile#L78-L87) is a generic, *permissioned* version using the `cosmos` bech32 prefix * [`coral`](./Makefile#L63-L71) is a permissionless version designed for a specific testnet, with a `coral` bech32 prefix +## Genesis Configuration + +@alpe we should document all the genesis config for x/wasm even more. + +Tip: if you want to lock this down to a permisisoned network, the following script can edit the genesis file +to only allow permissioned use of code upload or instantiating. (Make sure you set `app.ProposalsEnabled=true` +in this binary): + +`sed -i 's/permission": "Everybody"/permission": "Nobody"/' .../config/genesis.json` + ## Contributors Much thanks to all who have contributed to this project, from this app, to the `cosmwasm` framework, to example contracts and documentation. diff --git a/docker/run_wasmgovd.sh b/docker/run_wasmgovd.sh deleted file mode 100755 index 7e5d12176f..0000000000 --- a/docker/run_wasmgovd.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -if test -n "$1"; then - # need -R not -r to copy hidden files - cp -R "$1/.wasmd" /root - cp -R "$1/.wasmcli" /root -fi - -mkdir -p /root/log -wasmgovd start --rpc.laddr tcp://0.0.0.0:26657 --trace diff --git a/docker/setup_wasmgovd.sh b/docker/setup_wasmgovd.sh deleted file mode 100755 index 40198c403c..0000000000 --- a/docker/setup_wasmgovd.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -#set -o errexit -o nounset -o pipefail - -PASSWORD=${PASSWORD:-1234567890} -STAKE=${STAKE_TOKEN:-ustake} -FEE=${FEE_TOKEN:-ucosm} - -wasmgovd init --chain-id=testing testing -sed -i 's/permission": "Everybody"/permission": "Nobody"/' "$HOME"/.wasmgovd/config/genesis.json -# staking/governance token is hardcoded in config, change this -sed -i "s/\"stake\"/\"$STAKE\"/" "$HOME"/.wasmgovd/config/genesis.json -if ! wasmcli keys show validator; then - (echo "$PASSWORD"; echo "$PASSWORD") | wasmcli keys add validator -fi -# hardcode the validator account for this instance -echo "$PASSWORD" | wasmgovd add-genesis-account validator "1000000000$STAKE,1000000000$FEE" -# (optionally) add a few more genesis accounts -for addr in "$@"; do - echo $addr - wasmgovd add-genesis-account "$addr" "1000000000$STAKE,1000000000$FEE" -done -# submit a genesis validator tx -(echo "$PASSWORD"; echo "$PASSWORD"; echo "$PASSWORD") | wasmgovd gentx --name validator --amount "250000000$STAKE" -wasmgovd collect-gentxs From 95d5646520ef1a4b678c23fa2d93d45b1b0e7b7e Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Jul 2020 11:33:15 +0200 Subject: [PATCH 13/14] Add more test cases --- app/app_test.go | 38 ++++++++++++++++++-- x/wasm/alias.go | 49 ++++++++++++++------------ x/wasm/internal/types/proposal_test.go | 2 +- 3 files changed, 63 insertions(+), 26 deletions(-) diff --git a/app/app_test.go b/app/app_test.go index 7939cbda0b..6acefa0992 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -1,18 +1,19 @@ package app import ( + "github.com/magiconair/properties/assert" "os" "testing" - "github.com/CosmWasm/wasmd/x/wasm" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/libs/log" - db "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" - abci "github.com/tendermint/tendermint/abci/types" + db "github.com/tendermint/tm-db" + + "github.com/CosmWasm/wasmd/x/wasm" ) func TestWasmdExport(t *testing.T) { @@ -37,6 +38,37 @@ func TestBlackListedAddrs(t *testing.T) { } } +func TestGetEnabledProposals(t *testing.T) { + cases := map[string]struct { + proposalsEnabled string + specificEnabled string + expected []wasm.ProposalType + }{ + "all disabled": { + proposalsEnabled: "false", + expected: wasm.DisableAllProposals, + }, + "all enabled": { + proposalsEnabled: "true", + expected: wasm.EnableAllProposals, + }, + "some enabled": { + proposalsEnabled: "okay", + specificEnabled: "StoreCode,InstantiateContract", + expected: []wasm.ProposalType{wasm.ProposalTypeStoreCode, wasm.ProposalTypeInstantiateContract}, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + ProposalsEnabled = tc.proposalsEnabled + EnableSpecificProposals = tc.specificEnabled + proposals := GetEnabledProposals() + assert.Equal(t, tc.expected, proposals) + }) + } +} + func setGenesis(gapp *WasmApp) error { genesisState := simapp.NewDefaultGenesisState() genesisState[wasm.ModuleName] = wasm.AppModuleBasic{}.DefaultGenesis() diff --git a/x/wasm/alias.go b/x/wasm/alias.go index edf77ee8c6..022c945503 100644 --- a/x/wasm/alias.go +++ b/x/wasm/alias.go @@ -11,28 +11,33 @@ import ( ) const ( - DefaultParamspace = types.DefaultParamspace - ModuleName = types.ModuleName - StoreKey = types.StoreKey - TStoreKey = types.TStoreKey - QuerierRoute = types.QuerierRoute - RouterKey = types.RouterKey - MaxWasmSize = types.MaxWasmSize - MaxLabelSize = types.MaxLabelSize - BuildTagRegexp = types.BuildTagRegexp - MaxBuildTagSize = types.MaxBuildTagSize - CustomEventType = types.CustomEventType - AttributeKeyContractAddr = types.AttributeKeyContractAddr - GasMultiplier = keeper.GasMultiplier - MaxGas = keeper.MaxGas - QueryListContractByCode = keeper.QueryListContractByCode - QueryGetContract = keeper.QueryGetContract - QueryGetContractState = keeper.QueryGetContractState - QueryGetCode = keeper.QueryGetCode - QueryListCode = keeper.QueryListCode - QueryMethodContractStateSmart = keeper.QueryMethodContractStateSmart - QueryMethodContractStateAll = keeper.QueryMethodContractStateAll - QueryMethodContractStateRaw = keeper.QueryMethodContractStateRaw + DefaultParamspace = types.DefaultParamspace + ModuleName = types.ModuleName + StoreKey = types.StoreKey + TStoreKey = types.TStoreKey + QuerierRoute = types.QuerierRoute + RouterKey = types.RouterKey + MaxWasmSize = types.MaxWasmSize + MaxLabelSize = types.MaxLabelSize + BuildTagRegexp = types.BuildTagRegexp + MaxBuildTagSize = types.MaxBuildTagSize + CustomEventType = types.CustomEventType + AttributeKeyContractAddr = types.AttributeKeyContractAddr + ProposalTypeStoreCode = types.ProposalTypeStoreCode + ProposalTypeInstantiateContract = types.ProposalTypeInstantiateContract + ProposalTypeMigrateContract = types.ProposalTypeMigrateContract + ProposalTypeUpdateAdmin = types.ProposalTypeUpdateAdmin + ProposalTypeClearAdmin = types.ProposalTypeClearAdmin + GasMultiplier = keeper.GasMultiplier + MaxGas = keeper.MaxGas + QueryListContractByCode = keeper.QueryListContractByCode + QueryGetContract = keeper.QueryGetContract + QueryGetContractState = keeper.QueryGetContractState + QueryGetCode = keeper.QueryGetCode + QueryListCode = keeper.QueryListCode + QueryMethodContractStateSmart = keeper.QueryMethodContractStateSmart + QueryMethodContractStateAll = keeper.QueryMethodContractStateAll + QueryMethodContractStateRaw = keeper.QueryMethodContractStateRaw ) var ( diff --git a/x/wasm/internal/types/proposal_test.go b/x/wasm/internal/types/proposal_test.go index 1a4e44d4c1..5f2a57bbab 100644 --- a/x/wasm/internal/types/proposal_test.go +++ b/x/wasm/internal/types/proposal_test.go @@ -636,7 +636,7 @@ func TestConvertToProposals(t *testing.T) { isError: true, }, "invalid item": { - input: "StoreCode,InstanceContract", + input: "StoreCode,InvalidProposalType", isError: true, }, } From f3cf3737713f6aeb9366b32d952d437d8b09684e Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 28 Jul 2020 11:39:54 +0200 Subject: [PATCH 14/14] Update go.mod --- go.mod | 1 + 1 file changed, 1 insertion(+) diff --git a/go.mod b/go.mod index 92b829fc7c..83d772a744 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/golang/mock v1.4.3 // indirect github.com/google/gofuzz v1.0.0 github.com/gorilla/mux v1.7.4 + github.com/magiconair/properties v1.8.1 github.com/onsi/ginkgo v1.8.0 // indirect github.com/onsi/gomega v1.5.0 // indirect github.com/otiai10/copy v1.0.2