diff --git a/CODEOWNERS b/CODEOWNERS index 75b0327623..2992bcf66f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1,2 @@ * @jaekwon +* @ebuchman diff --git a/Makefile b/Makefile index 703a0803e3..a238e7e7c6 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,11 @@ ci: get_tools get_vendor_deps build test_cover ######################################## ### Build +# This can be unified later, here for easy demos +gaia: + go build $(BUILD_FLAGS) -o build/gaiad ./examples/gaia/gaiad + go build $(BUILD_FLAGS) -o build/gaiacli ./examples/gaia/gaiacli + build: @rm -rf examples/basecoin/vendor/ go build $(BUILD_FLAGS) -o build/basecoin ./examples/basecoin/cmd/... diff --git a/examples/gaia/gaiacli/client.go b/examples/gaia/gaiacli/client.go new file mode 100644 index 0000000000..682a571e6e --- /dev/null +++ b/examples/gaia/gaiacli/client.go @@ -0,0 +1,131 @@ +package main + +import "github.com/spf13/cobra" + +const ( + // these are needed for every init + flagChainID = "chain-id" + flagNode = "node" + + // one of the following should be provided to verify the connection + flagGenesis = "genesis" + flagCommit = "commit" + flagValHash = "validator-set" + + flagSelect = "select" + flagTags = "tag" + flagAny = "any" + + flagBind = "bind" + flagCORS = "cors" + flagTrustNode = "trust-node" + + // this is for signing + flagName = "name" +) + +var ( + statusCmd = &cobra.Command{ + Use: "status", + Short: "Query remote node for status", + RunE: todoNotImplemented, + } +) + +// AddClientCommands returns a sub-tree of all basic client commands +// +// Call AddGetCommand and AddPostCommand to add custom txs and queries +func AddClientCommands(cmd *cobra.Command) { + cmd.AddCommand( + initClientCommand(), + statusCmd, + blockCommand(), + validatorCommand(), + lineBreak, + txSearchCommand(), + txCommand(), + lineBreak, + ) +} + +// GetCommands adds common flags to query commands +func GetCommands(cmds ...*cobra.Command) []*cobra.Command { + for _, c := range cmds { + c.Flags().Bool(flagTrustNode, false, "Don't verify proofs for responses") + } + return cmds +} + +// PostCommands adds common flags for commands to post tx +func PostCommands(cmds ...*cobra.Command) []*cobra.Command { + for _, c := range cmds { + c.Flags().String(flagName, "", "Name of private key with which to sign") + c.Flags().String(flagPassword, "", "Password to use the named private key") + } + return cmds +} + +func initClientCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "init", + Short: "Initialize light client", + RunE: todoNotImplemented, + } + cmd.Flags().StringP(flagChainID, "c", "", "ID of chain we connect to") + cmd.Flags().StringP(flagNode, "n", "tcp://localhost:46657", "Node to connect to") + cmd.Flags().String(flagGenesis, "", "Genesis file to verify header validity") + cmd.Flags().String(flagCommit, "", "File with trusted and signed header") + cmd.Flags().String(flagValHash, "", "Hash of trusted validator set (hex-encoded)") + return cmd +} + +func blockCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "block ", + Short: "Get verified data for a the block at given height", + RunE: todoNotImplemented, + } + cmd.Flags().StringSlice(flagSelect, []string{"header", "tx"}, "Fields to return (header|txs|results)") + return cmd +} + +func validatorCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "validatorset ", + Short: "Get the full validator set at given height", + RunE: todoNotImplemented, + } + return cmd +} + +func serveCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "serve", + Short: "Start LCD (light-client daemon), a local REST server", + RunE: todoNotImplemented, + } + // TODO: handle unix sockets also? + cmd.Flags().StringP(flagBind, "b", "localhost:1317", "Interface and port that server binds to") + cmd.Flags().String(flagCORS, "", "Set to domains that can make CORS requests (* for all)") + return cmd +} + +func txSearchCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "txs", + Short: "Search for all transactions that match the given tags", + RunE: todoNotImplemented, + } + cmd.Flags().StringSlice(flagTags, nil, "Tags that must match (may provide multiple)") + cmd.Flags().Bool(flagAny, false, "Return transactions that match ANY tag, rather than ALL") + return cmd +} + +func txCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "tx ", + Short: "Matches this txhash over all committed blocks", + RunE: todoNotImplemented, + } + return cmd +} diff --git a/examples/gaia/gaiacli/key.go b/examples/gaia/gaiacli/key.go new file mode 100644 index 0000000000..b3ffa323ae --- /dev/null +++ b/examples/gaia/gaiacli/key.go @@ -0,0 +1,77 @@ +package main + +import "github.com/spf13/cobra" + +const ( + flagPassword = "password" + flagNewPassword = "new-password" + flagType = "type" + flagSeed = "seed" + flagDryRun = "dry-run" +) + +var ( + listKeysCmd = &cobra.Command{ + Use: "list", + Short: "List all locally availably keys", + RunE: todoNotImplemented, + } + + showKeysCmd = &cobra.Command{ + Use: "show ", + Short: "Show key info for the given name", + RunE: todoNotImplemented, + } +) + +// KeyCommands registers a sub-tree of commands to interact with +// local private key storage. +func KeyCommands() *cobra.Command { + cmd := &cobra.Command{ + Use: "keys", + Short: "Add or view local private keys", + } + cmd.AddCommand( + addKeyCommand(), + listKeysCmd, + showKeysCmd, + lineBreak, + deleteKeyCommand(), + updateKeyCommand(), + ) + return cmd +} + +func addKeyCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "add ", + Short: "Create a new key, or import from seed", + RunE: todoNotImplemented, + } + cmd.Flags().StringP(flagPassword, "p", "", "Password to encrypt private key") + cmd.Flags().StringP(flagType, "t", "ed25519", "Type of private key (ed25519|secp256k1|ledger)") + cmd.Flags().StringP(flagSeed, "s", "", "Provide seed phrase to recover existing key instead of creating") + cmd.Flags().Bool(flagDryRun, false, "Perform action, but don't add key to local keystore") + return cmd +} + +func updateKeyCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "update ", + Short: "Change the password used to protect private key", + RunE: todoNotImplemented, + } + cmd.Flags().StringP(flagPassword, "p", "", "Current password to decrypt key") + cmd.Flags().String(flagNewPassword, "", "New password to use to protect key") + return cmd +} + +func deleteKeyCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "delete ", + Short: "Delete the given key", + RunE: todoNotImplemented, + } + cmd.Flags().StringP(flagPassword, "p", "", "Password of existing key to delete") + return cmd +} diff --git a/examples/gaia/gaiacli/main.go b/examples/gaia/gaiacli/main.go new file mode 100644 index 0000000000..6321e25ee7 --- /dev/null +++ b/examples/gaia/gaiacli/main.go @@ -0,0 +1,75 @@ +package main + +import ( + "errors" + "os" + + "github.com/spf13/cobra" + + "github.com/tendermint/tmlibs/cli" +) + +const ( + flagTo = "to" + flagAmount = "amount" + flagFee = "fee" +) + +// gaiacliCmd is the entry point for this binary +var ( + gaiacliCmd = &cobra.Command{ + Use: "gaiacli", + Short: "Gaia light-client", + } + + lineBreak = &cobra.Command{Run: func(*cobra.Command, []string) {}} + + getAccountCmd = &cobra.Command{ + Use: "account
", + Short: "Query account balance", + RunE: todoNotImplemented, + } +) + +func todoNotImplemented(_ *cobra.Command, _ []string) error { + return errors.New("TODO: Command not yet implemented") +} + +func postSendCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "send", + Short: "Create and sign a send tx", + RunE: todoNotImplemented, + } + cmd.Flags().String(flagTo, "", "Address to send coins") + cmd.Flags().String(flagAmount, "", "Amount of coins to send") + cmd.Flags().String(flagFee, "", "Fee to pay along with transaction") + return cmd +} + +func main() { + // disable sorting + cobra.EnableCommandSorting = false + + // generic client commands + AddClientCommands(gaiacliCmd) + // query commands (custom to binary) + gaiacliCmd.AddCommand( + GetCommands(getAccountCmd)...) + // post tx commands (custom to binary) + gaiacliCmd.AddCommand( + PostCommands(postSendCommand())...) + + // add proxy, version and key info + gaiacliCmd.AddCommand( + lineBreak, + serveCommand(), + KeyCommands(), + lineBreak, + VersionCmd, + ) + + // prepare and add flags + executor := cli.PrepareBaseCmd(gaiacliCmd, "GA", os.ExpandEnv("$HOME/.gaiacli")) + executor.Execute() +} diff --git a/examples/gaia/gaiacli/version.go b/examples/gaia/gaiacli/version.go new file mode 100644 index 0000000000..59fd799c07 --- /dev/null +++ b/examples/gaia/gaiacli/version.go @@ -0,0 +1,26 @@ +package main + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/version" +) + +var ( + // VersionCmd prints out the current sdk version + VersionCmd = &cobra.Command{ + Use: "version", + Short: "Print the app version", + Run: doVersionCmd, + } +) + +func doVersionCmd(cmd *cobra.Command, args []string) { + v := version.Version + if version.GitCommit != "" { + v = v + " " + version.GitCommit + } + fmt.Println(v) +} diff --git a/examples/gaia/gaiad/main.go b/examples/gaia/gaiad/main.go new file mode 100644 index 0000000000..ca9bb20dba --- /dev/null +++ b/examples/gaia/gaiad/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "errors" + "os" + + "github.com/spf13/cobra" + + "github.com/tendermint/tmlibs/cli" + + "github.com/cosmos/cosmos-sdk/baseapp" +) + +const ( + flagTo = "to" + flagAmount = "amount" + flagFee = "fee" +) + +// gaiadCmd is the entry point for this binary +var ( + gaiadCmd = &cobra.Command{ + Use: "gaiad", + Short: "Gaia Daemon (server)", + } +) + +func todoNotImplemented(_ *cobra.Command, _ []string) error { + return errors.New("TODO: Command not yet implemented") +} + +func main() { + // TODO: set this to something real + var node baseapp.BaseApp + + AddNodeCommands(gaiadCmd, node) + gaiadCmd.AddCommand( + VersionCmd, + ) + + // prepare and add flags + executor := cli.PrepareBaseCmd(gaiadCmd, "GA", os.ExpandEnv("$HOME/.gaiad")) + executor.Execute() +} diff --git a/examples/gaia/gaiad/node.go b/examples/gaia/gaiad/node.go new file mode 100644 index 0000000000..8d362a6a78 --- /dev/null +++ b/examples/gaia/gaiad/node.go @@ -0,0 +1,47 @@ +package main + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/baseapp" +) + +const ( + flagWithTendermint = "with-tendermint" +) + +var ( + initNodeCmd = &cobra.Command{ + Use: "init ", + Short: "Initialize full node", + RunE: todoNotImplemented, + } + + resetNodeCmd = &cobra.Command{ + Use: "unsafe_reset_all", + Short: "Reset full node data (danger, must resync)", + RunE: todoNotImplemented, + } +) + +// AddNodeCommands registers all commands to interact +// with a local full-node as subcommands of the argument. +// +// Accept an application it should start +func AddNodeCommands(cmd *cobra.Command, node baseapp.BaseApp) { + cmd.AddCommand( + initNodeCmd, + startNodeCmd(node), + resetNodeCmd, + ) +} + +func startNodeCmd(node baseapp.BaseApp) *cobra.Command { + cmd := &cobra.Command{ + Use: "start", + Short: "Run the full node", + RunE: todoNotImplemented, + } + cmd.Flags().Bool(flagWithTendermint, true, "run abci app embedded in-process with tendermint") + return cmd +} diff --git a/examples/gaia/gaiad/version.go b/examples/gaia/gaiad/version.go new file mode 100644 index 0000000000..59fd799c07 --- /dev/null +++ b/examples/gaia/gaiad/version.go @@ -0,0 +1,26 @@ +package main + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/version" +) + +var ( + // VersionCmd prints out the current sdk version + VersionCmd = &cobra.Command{ + Use: "version", + Short: "Print the app version", + Run: doVersionCmd, + } +) + +func doVersionCmd(cmd *cobra.Command, args []string) { + v := version.Version + if version.GitCommit != "" { + v = v + " " + version.GitCommit + } + fmt.Println(v) +} diff --git a/glide.lock b/glide.lock index 2ce3afb93c..bb013ee718 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: b0d6b76ffe90ef74c9c9672f18eb9abb90c3e7636dbc0504e343d88c337b1ea0 -updated: 2018-02-03T12:28:51.055275+01:00 +hash: 2b4ad3bf1489a7cb5e62c6cb4c1fa976d4ae21993743e4968418c4e81925fb99 +updated: 2018-02-13T08:33:22.402132782-05:00 imports: - name: github.com/btcsuite/btcd version: 50de9da05b50eb15658bb350f6ea24368a111ab7 @@ -9,6 +9,8 @@ imports: version: 346938d642f2ec3594ed81d874461961cd0faa76 subpackages: - spew +- name: github.com/fsnotify/fsnotify + version: c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9 - name: github.com/go-kit/kit version: 4dc7be5d2d12881735283bcab7352178e190fc71 subpackages: @@ -38,14 +40,47 @@ imports: - ptypes/timestamp - name: github.com/golang/snappy version: 553a641470496b2327abcac10b36396bd98e45c9 +- name: github.com/hashicorp/hcl + version: 23c074d0eceb2b8a5bfdbb271ab780cde70f05a8 + subpackages: + - hcl/ast + - hcl/parser + - hcl/scanner + - hcl/strconv + - hcl/token + - json/parser + - json/scanner + - json/token +- name: github.com/inconshreveable/mousetrap + version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 - name: github.com/jmhodges/levigo version: c42d9e0ca023e2198120196f842701bb4c55d7b9 - name: github.com/kr/logfmt version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0 +- name: github.com/magiconair/properties + version: 49d762b9817ba1c2e9d0c69183c2b4a8b8f1d934 +- name: github.com/mitchellh/mapstructure + version: b4575eea38cca1123ec2dc90c26529b5c5acfcff +- name: github.com/pelletier/go-toml + version: acdc4509485b587f5e675510c4f2c63e90ff68a8 - name: github.com/pkg/errors version: 645ef00459ed84a119197bfb8d8205042c6df63d - name: github.com/rigelrozanski/common version: f691f115798593d783b9999b1263c2f4ffecc439 +- name: github.com/spf13/afero + version: bb8f1927f2a9d3ab41c9340aa034f6b803f4359c + subpackages: + - mem +- name: github.com/spf13/cast + version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4 +- name: github.com/spf13/cobra + version: 7b2c5ac9fc04fc5efafb60700713d4fa609b777b +- name: github.com/spf13/jwalterweatherman + version: 7c0cea34c8ece3fbeb2b27ab9b59511d360fb394 +- name: github.com/spf13/pflag + version: e57e3eeb33f795204c1ca35f56c44f83227c6e66 +- name: github.com/spf13/viper + version: 25b30aa063fc18e48662b86996252eabdcf2f0c7 - name: github.com/syndtr/goleveldb version: 211f780988068502fe874c44dae530528ebd840f subpackages: @@ -62,7 +97,7 @@ imports: - leveldb/table - leveldb/util - name: github.com/tendermint/abci - version: 5a4f56056e23cdfd5f3733db056968e016468508 + version: bf70f5e273bd7dd6e22e64186cd1ccc4e3a03df1 subpackages: - server - types @@ -78,8 +113,9 @@ imports: - name: github.com/tendermint/iavl version: 1a59ec0c82dc940c25339dd7c834df5cb76a95cb - name: github.com/tendermint/tmlibs - version: deaaf014d8b8d1095054380a38b1b00e293f725f + version: c858b3ba78316fdd9096a11409a7e7a493e7d974 subpackages: + - cli - common - db - log @@ -103,6 +139,10 @@ imports: - internal/timeseries - lex/httplex - trace +- name: golang.org/x/sys + version: 37707fdb30a5b38865cfb95e5aab41707daec7fd + subpackages: + - unix - name: golang.org/x/text version: e19ae1496984b1c655b8044a65c0300a3c878dd3 subpackages: @@ -133,6 +173,8 @@ imports: - status - tap - transport +- name: gopkg.in/yaml.v2 + version: d670f9405373e636a5a2765eea47fac0c9bc91a4 testImports: - name: github.com/pmezard/go-difflib version: 792786c7400a136282c1664665ae0a8db921c6c2 diff --git a/glide.yaml b/glide.yaml index ea7856ff2c..276513b2ce 100644 --- a/glide.yaml +++ b/glide.yaml @@ -28,6 +28,12 @@ import: - package: golang.org/x/crypto subpackages: - ripemd160 +- package: github.com/spf13/pflag + version: v1.0.0 +- package: github.com/spf13/cobra + version: v0.0.1 +- package: github.com/spf13/viper + version: ^1.0.0 testImport: - package: github.com/stretchr/testify version: ^1.2.1 diff --git a/version/version.go b/version/version.go index 14dd668d51..419e406adf 100644 --- a/version/version.go +++ b/version/version.go @@ -9,4 +9,7 @@ const Maj = "0" const Min = "9" const Fix = "0" -const Version = "0.9.0" +const Version = "0.9.0-dev" + +// GitCommit set by build flags +var GitCommit = ""