From 44189d905509c8b88b46b4f1a8951c3c34fe4ec9 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 13 Mar 2017 17:23:05 -0400 Subject: [PATCH 01/19] basecoin init, default to in-proc, fix up guide --- README.md | 28 ++------ cmd/basecoin/main.go | 1 + cmd/commands/flags.go | 12 +--- cmd/commands/init.go | 116 ++++++++++++++++++++++++++++++++++ cmd/commands/key.go | 6 +- cmd/commands/log.go | 7 ++ cmd/commands/start.go | 29 ++++----- cmd/commands/tx.go | 3 +- cmd/commands/utils.go | 11 ++++ docs/guide/basecoin-basics.md | 68 ++++---------------- 10 files changed, 173 insertions(+), 108 deletions(-) create mode 100644 cmd/commands/init.go create mode 100644 cmd/commands/log.go diff --git a/README.md b/README.md index 6b4b0c34e4..22b29bcb1a 100644 --- a/README.md +++ b/README.md @@ -15,45 +15,25 @@ WARNING: Currently uses plain-text private keys for transactions and is otherwis ## Prerequisites -* Go to https://golang.org/doc/install to install Golang. -* You will also need to set the $GOPATH environment variable as per the instructions [here](https://golang.org/doc/code.html#GOPATH). +[Install and setup Golang](https://tendermint.com/docs/guides/install-go). ## Installation -On a good day, basecoin can be installed like a normal Go program: - ``` go get -u github.com/tendermint/basecoin/cmd/basecoin ``` - -If that fails, or if another branch is required, you may have to compile from source. -You will first need to install the Golang package manager [`glide`](https://github.com/Masterminds/glide). - -``` -cd $GOPATH/src/github.com/tendermint/basecoin -git checkout develop # (until we release tendermint v0.9) -make get_vendor_deps -make install -``` - -This will create the `basecoin` binary in `$GOPATH/bin`. +See the [install guide](/docs/guide/install.md) for more details. -## Command Line Interface - -The basecoin CLI can be used to start a stand-alone basecoin instance (`basecoin start`), -or to start basecoin with Tendermint in the same process (`basecoin start --in-proc`). -It can also be used to send transactions, eg. `basecoin tx send --to 0x4793A333846E5104C46DD9AB9A00E31821B2F301 --amount 100btc,10gold` -See `basecoin --help` and `basecoin [cmd] --help` for more details`. - -## Learn more +## Guide 1. Getting started with the [Basecoin tool](/docs/guide/basecoin-basics.md) 1. Learn more about [Basecoin's design](/docs/guide/basecoin-design.md) 1. Extend Basecoin [using the plugin system](/docs/guide/example-plugin.md) 1. Learn more about [plugin design](/docs/guide/plugin-design.md) 1. See some [more example applications](/docs/guide/more-examples.md) +1. More features of the [Basecoin tool](/docs/guide/basecoin-tool.md) 1. Learn how to use [InterBlockchain Communication (IBC)](/docs/guide/ibc.md) 1. [Deploy testnets](deployment.md) running your basecoin application. diff --git a/cmd/basecoin/main.go b/cmd/basecoin/main.go index d16d001f0e..cab2213684 100644 --- a/cmd/basecoin/main.go +++ b/cmd/basecoin/main.go @@ -14,6 +14,7 @@ func main() { app.Usage = "basecoin [command] [args...]" app.Version = version.Version app.Commands = []cli.Command{ + commands.InitCmd, commands.StartCmd, commands.TxCmd, commands.QueryCmd, diff --git a/cmd/commands/flags.go b/cmd/commands/flags.go index 0c4c477707..06f0ce4233 100644 --- a/cmd/commands/flags.go +++ b/cmd/commands/flags.go @@ -21,15 +21,9 @@ var ( // TODO: move to config file // eyesCacheSizePtr := flag.Int("eyes-cache-size", 10000, "MerkleEyes db cache size, for embedded") - DirFlag = cli.StringFlag{ - Name: "dir", - Value: ".", - Usage: "Root directory", - } - - InProcTMFlag = cli.BoolFlag{ - Name: "in-proc", - Usage: "Run Tendermint in-process with the App", + ABCIServerFlag = cli.BoolFlag{ + Name: "abci-server", + Usage: "Run the Basecoin app and ABCI server, but not Tendermint (run Tendermint in another process)", } ) diff --git a/cmd/commands/init.go b/cmd/commands/init.go new file mode 100644 index 0000000000..9d44167e46 --- /dev/null +++ b/cmd/commands/init.go @@ -0,0 +1,116 @@ +package commands + +import ( + "io/ioutil" + "os" + "path" + + "github.com/urfave/cli" + + cmn "github.com/tendermint/go-common" + tmcfg "github.com/tendermint/tendermint/config/tendermint" + types "github.com/tendermint/tendermint/types" +) + +var InitCmd = cli.Command{ + Name: "init", + Usage: "Initialize a basecoin blockchain", + ArgsUsage: "", + Action: func(c *cli.Context) error { + return cmdInit(c) + }, + Flags: []cli.Flag{ + ChainIDFlag, + }, +} + +func cmdInit(c *cli.Context) error { + basecoinDir := BasecoinRoot("") + tmDir := path.Join(basecoinDir, "tendermint") + + // initalize tendermint + tmConfig := tmcfg.GetConfig(tmDir) + + privValFile := tmConfig.GetString("priv_validator_file") + if _, err := os.Stat(privValFile); os.IsNotExist(err) { + privValidator := types.GenPrivValidator() + privValidator.SetFile(privValFile) + privValidator.Save() + + genFile := tmConfig.GetString("genesis_file") + + if _, err := os.Stat(genFile); os.IsNotExist(err) { + genDoc := types.GenesisDoc{ + ChainID: cmn.Fmt("test-chain-%v", cmn.RandStr(6)), + } + genDoc.Validators = []types.GenesisValidator{types.GenesisValidator{ + PubKey: privValidator.PubKey, + Amount: 10, + }} + + genDoc.SaveAs(genFile) + } + log.Notice("Initialized Tendermint", "genesis", tmConfig.GetString("genesis_file"), "priv_validator", tmConfig.GetString("priv_validator_file")) + } else { + log.Notice("Already initialized Tendermint", "priv_validator", tmConfig.GetString("priv_validator_file")) + } + + // initalize basecoin + genesisFile := path.Join(basecoinDir, "genesis.json") + key1File := path.Join(basecoinDir, "key.json") + key2File := path.Join(basecoinDir, "key2.json") + + if err := ioutil.WriteFile(genesisFile, []byte(genesisJSON), 0644); err != nil { + return err + } + if err := ioutil.WriteFile(key1File, []byte(key1JSON), 0400); err != nil { + return err + } + if err := ioutil.WriteFile(key2File, []byte(key2JSON), 0400); err != nil { + return err + } + + log.Notice("Initialized Basecoin", "genesis", genesisFile, "key", key1File) + + return nil +} + +const genesisJSON = `[ + "base/chainID", "test_chain_id", + "base/account", { + "pub_key": { + "type": "ed25519", + "data": "619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279" + }, + "coins": [ + { + "denom": "mycoin", + "amount": 9007199254740992 + } + ] + } +]` + +const key1JSON = `{ + "address": "1B1BE55F969F54064628A63B9559E7C21C925165", + "priv_key": [ + 1, + "C70D6934B4F55F1B7BC33B56B9CA8A2061384AFC19E91E44B40C4BBA182953D1619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279" + ], + "pub_key": [ + 1, + "619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279" + ] +}` + +const key2JSON = `{ + "address": "1DA7C74F9C219229FD54CC9F7386D5A3839F0090", + "priv_key": [ + 1, + "34BAE9E65CE8245FAD035A0E3EED9401BDE8785FFB3199ACCF8F5B5DDF7486A8352195DA90CB0B90C24295B90AEBA25A5A71BC61BAB2FE2387241D439698B7B8" + ], + "pub_key": [ + 1, + "352195DA90CB0B90C24295B90AEBA25A5A71BC61BAB2FE2387241D439698B7B8" + ] +}` diff --git a/cmd/commands/key.go b/cmd/commands/key.go index 2ebd74afd4..714958a07d 100644 --- a/cmd/commands/key.go +++ b/cmd/commands/key.go @@ -3,6 +3,7 @@ package commands import ( "fmt" "io/ioutil" + "path" "github.com/urfave/cli" @@ -60,14 +61,15 @@ func genKey() *Key { } } -func LoadKey(filePath string) *Key { +func LoadKey(keyFile string) *Key { + filePath := path.Join(BasecoinRoot(""), keyFile) keyJSONBytes, err := ioutil.ReadFile(filePath) if err != nil { cmn.Exit(err.Error()) } key := wire.ReadJSON(&Key{}, keyJSONBytes, &err).(*Key) if err != nil { - cmn.Exit(cmn.Fmt("Error reading PrivValidator from %v: %v\n", filePath, err)) + cmn.Exit(cmn.Fmt("Error reading key from %v: %v\n", filePath, err)) } return key } diff --git a/cmd/commands/log.go b/cmd/commands/log.go new file mode 100644 index 0000000000..720e168b57 --- /dev/null +++ b/cmd/commands/log.go @@ -0,0 +1,7 @@ +package commands + +import ( + "github.com/tendermint/go-logger" +) + +var log = logger.New("module", "commands") diff --git a/cmd/commands/start.go b/cmd/commands/start.go index 72a13107df..4c4afd199d 100644 --- a/cmd/commands/start.go +++ b/cmd/commands/start.go @@ -10,8 +10,6 @@ import ( "github.com/tendermint/abci/server" cmn "github.com/tendermint/go-common" - cfg "github.com/tendermint/go-config" - //logger "github.com/tendermint/go-logger" eyes "github.com/tendermint/merkleeyes/client" tmcfg "github.com/tendermint/tendermint/config/tendermint" @@ -23,8 +21,6 @@ import ( "github.com/tendermint/basecoin/types" ) -var config cfg.Config - const EyesCacheSize = 10000 var StartCmd = cli.Command{ @@ -37,8 +33,7 @@ var StartCmd = cli.Command{ Flags: []cli.Flag{ AddrFlag, EyesFlag, - DirFlag, - InProcTMFlag, + ABCIServerFlag, ChainIDFlag, }, } @@ -56,11 +51,12 @@ func RegisterStartPlugin(name string, newPlugin func() types.Plugin) { } func cmdStart(c *cli.Context) error { + basecoinDir := BasecoinRoot("") // Connect to MerkleEyes var eyesCli *eyes.Client if c.String("eyes") == "local" { - eyesCli = eyes.NewLocalClient(path.Join(c.String("dir"), "merkleeyes.db"), EyesCacheSize) + eyesCli = eyes.NewLocalClient(path.Join(basecoinDir, "merkleeyes.db"), EyesCacheSize) } else { var err error eyesCli, err = eyes.NewClient(c.String("eyes")) @@ -81,7 +77,7 @@ func cmdStart(c *cli.Context) error { } // If genesis file exists, set key-value options - genesisFile := path.Join(c.String("dir"), "genesis.json") + genesisFile := path.Join(basecoinDir, "genesis.json") if _, err := os.Stat(genesisFile); err == nil { err := basecoinApp.LoadGenesis(genesisFile) if err != nil { @@ -91,12 +87,14 @@ func cmdStart(c *cli.Context) error { fmt.Printf("No genesis file at %s, skipping...\n", genesisFile) } - if c.Bool("in-proc") { - startTendermint(c, basecoinApp) - } else { + if c.Bool("abci-server") { + // run just the abci app/server if err := startBasecoinABCI(c, basecoinApp); err != nil { return err } + } else { + // start the app with tendermint in-process + startTendermint(basecoinDir, basecoinApp) } return nil @@ -117,17 +115,18 @@ func startBasecoinABCI(c *cli.Context, basecoinApp *app.Basecoin) error { } -func startTendermint(c *cli.Context, basecoinApp *app.Basecoin) { +func startTendermint(dir string, basecoinApp *app.Basecoin) { // Get configuration - config = tmcfg.GetConfig("") + tmConfig := tmcfg.GetConfig(path.Join(dir, "tendermint")) + // logger.SetLogLevel("notice") //config.GetString("log_level")) // parseFlags(config, args[1:]) // Command line overrides // Create & start tendermint node - privValidatorFile := config.GetString("priv_validator_file") + privValidatorFile := tmConfig.GetString("priv_validator_file") privValidator := tmtypes.LoadOrGenPrivValidator(privValidatorFile) - n := node.NewNode(config, privValidator, proxy.NewLocalClientCreator(basecoinApp)) + n := node.NewNode(tmConfig, privValidator, proxy.NewLocalClientCreator(basecoinApp)) n.Start() diff --git a/cmd/commands/tx.go b/cmd/commands/tx.go index de1a923277..b4a900832e 100644 --- a/cmd/commands/tx.go +++ b/cmd/commands/tx.go @@ -14,7 +14,6 @@ import ( client "github.com/tendermint/go-rpc/client" "github.com/tendermint/go-wire" ctypes "github.com/tendermint/tendermint/rpc/core/types" - tmtypes "github.com/tendermint/tendermint/types" ) var TxFlags = []cli.Flag{ @@ -144,7 +143,7 @@ func AppTx(c *cli.Context, name string, data []byte) error { gas := int64(c.Int("gas")) chainID := c.String("chain_id") - privKey := tmtypes.LoadPrivValidator(fromFile) + privKey := LoadKey(fromFile) sequence, err := getSeq(c, privKey.Address) if err != nil { diff --git a/cmd/commands/utils.go b/cmd/commands/utils.go index bfd3d8564b..35af75baae 100644 --- a/cmd/commands/utils.go +++ b/cmd/commands/utils.go @@ -3,6 +3,7 @@ package commands import ( "encoding/hex" "errors" + "os" "regexp" "strconv" "strings" @@ -20,6 +21,16 @@ import ( tmtypes "github.com/tendermint/tendermint/types" ) +func BasecoinRoot(rootDir string) string { + if rootDir == "" { + rootDir = os.Getenv("BASECOIN_ROOT") + } + if rootDir == "" { + rootDir = os.Getenv("HOME") + "/.basecoin" + } + return rootDir +} + // Returns true for non-empty hex-string prefixed with "0x" func isHex(s string) bool { if len(s) > 2 && s[:2] == "0x" { diff --git a/docs/guide/basecoin-basics.md b/docs/guide/basecoin-basics.md index 0dccb32622..9ecb08c447 100644 --- a/docs/guide/basecoin-basics.md +++ b/docs/guide/basecoin-basics.md @@ -5,77 +5,34 @@ and how to send transactions between accounts using the `basecoin` tool. ## Install -Make sure you have [basecoin installed](install.md). -You will also need to [install Tendermint](https://tendermint.com/intro/getting-started/download). +Installing basecoin is simple: -**Note** All code is on the 0.9 pre-release branch, you may have to -[install Tendermint from source](https://tendermint.com/docs/guides/install) -until 0.9 is released. (Make sure to add `git checkout develop` to the linked install instructions) +``` +go get -u github.com/tendermint/basecoin/cmd/basecoin +``` + +If you have trouble, see the [installation guide](install.md). ## Initialization -Basecoin is an ABCI application that runs on Tendermint, so we first need to initialize Tendermint: +To initialize a new Basecoin blockchain, run: ``` -tendermint init +basecoin init ``` -This will create the necessary files for a single Tendermint node in `~/.tendermint`. -If you had previously run Tendermint, make sure you reset the chain -(note this will delete all chain data, so back it up if you need it): - -``` -tendermint unsafe_reset_all -``` - -Now we need some initialization files for basecoin. -We have included some defaults in the basecoin directory, under `data`. -For purposes of convenience, change to that directory: - -``` -cd $GOPATH/src/github.com/tendermint/basecoin/data -``` - -The directory contains a genesis file and two private keys. - -You can generate your own private keys with `tendermint gen_validator`, -and construct the `genesis.json` as you like. -Note, however, that you must be careful with the `chain_id` field, -as every transaction must contain the correct `chain_id` -(default is `test_chain_id`). +This will create the necessary files for a Basecoin blockchain with one validator and one account in `~/.basecoin`. +For more options on setup, see the [guide to using the Basecoin tool](/docs/guide/basecoin-tool.md). ## Start Now we can start basecoin: -``` -basecoin start --in-proc -``` - -This will initialize the chain with the `genesis.json` file from the current directory. -If you want to specify another location, you can run: - -``` -basecoin start --in-proc --dir PATH/TO/CUSTOM/DATA -``` - -Note that `--in-proc` stands for "in process", which means -basecoin will be started with the Tendermint node running in the same process. -To start Tendermint in a separate process instead, use: - ``` basecoin start ``` -and in another window: - -``` -tendermint node -``` - -In either case, you should see blocks start streaming in! -Note, however, that currently basecoin currently requires the -`develop` branch of Tendermint for this to work. +You should see blocks start streaming in! ## Send transactions @@ -98,8 +55,7 @@ Let's send funds from the first account to the second: basecoin tx send --to 0x1DA7C74F9C219229FD54CC9F7386D5A3839F0090 --amount 10mycoin ``` -By default, the CLI looks for a `priv_validator.json` to sign the transaction with, -so this will only work if you are in the `$GOPATH/src/github.com/tendermint/basecoin/data`. +By default, the CLI looks for a `key.json` to sign the transaction with. To specify a different key, we can use the `--from` flag. Now if we check the second account, it should have `10` 'mycoin' coins! From 2eee3567bd30a144bb59b102a188df72730f40b0 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 13 Mar 2017 19:36:40 -0400 Subject: [PATCH 02/19] docs/guide: update example-plugin --- docs/guide/example-plugin.md | 80 +++++++----------------------------- 1 file changed, 15 insertions(+), 65 deletions(-) diff --git a/docs/guide/example-plugin.md b/docs/guide/example-plugin.md index 73a6b4e854..94cfc56c57 100644 --- a/docs/guide/example-plugin.md +++ b/docs/guide/example-plugin.md @@ -19,6 +19,8 @@ main.go plugin.go ``` +### main.go + The `main.go` is very simple and does not need to be changed: ```golang @@ -45,7 +47,7 @@ In addition, if we want to send transactions to our plugin, we need to add a new command to the CLI. This is where the `cmd.go` comes in. -## Commands +### cmd.go First, we register the plugin: @@ -157,7 +159,7 @@ All plugin data must be serialized (ie. encoded as a byte-array) and sent as data in an `AppTx`. The `commands.AppTx` function does this for us - it creates an `AppTx` with the corresponding data, signs it, and sends it on to the blockchain. -## RunTx +### plugin.go Ok, now we're ready to actually look at the implementation of the plugin in `plugin.go`. Note I'll leave out some of the methods as they don't serve any purpose for this example, @@ -296,94 +298,42 @@ And that's it! Now that we have a simple plugin, let's see how to run it. ## Running your plugin -In the [previous tutorial](basecoin-basics.md), -we used a pre-generated `genesis.json` and `priv_validator.json` for the application. -This time, let's make our own. - -First, let's create a new directory and change into it: +First, initialize the new blockchain with ``` -mkdir example-data -cd example-data +basecoin init ``` -Now, let's create a new private key: +If you've already run a basecoin blockchain, reset the data with ``` -example-plugin key new > key.json +basecoin unsafe_reset_all ``` -Here's what my `key.json looks like: - -```json -{ - "address": "15F591CA434CFCCBDEC1D206F3ED3EBA207BFE7D", - "priv_key": [ - 1, - "737C629667A9EAADBB8E7CF792D5A8F63AA4BB51E06457DDD7FDCC6D7412AAAD43AA6C88034F9EB8D2717CA4BBFCBA745EFF19B13EFCD6F339EDBAAAFCD2F7B3" - ], - "pub_key": [ - 1, - "43AA6C88034F9EB8D2717CA4BBFCBA745EFF19B13EFCD6F339EDBAAAFCD2F7B3" - ] -} -``` - -Now we can make a `genesis.json` file and add an account with out public key: - -```json -[ - "base/chainID", "example-chain", - "base/account", { - "pub_key": [1, "43AA6C88034F9EB8D2717CA4BBFCBA745EFF19B13EFCD6F339EDBAAAFCD2F7B3"], - "coins": [ - { - "denom": "gold", - "amount": 1000000000, - } - ] - } -] -``` - -Here we've granted ourselves `1000000000` units of the `gold` token. - -Before we can start the blockchain, we must initialize and/or reset the Tendermint state for a new blockchain: - -``` -tendermint init -tendermint unsafe_reset_all -``` - -Great, now we're ready to go. To start the blockchain, simply run ``` -example-plugin start --in-proc +example-plugin start ``` In another window, we can try sending some transactions: ``` -example-plugin tx send --to 0x1B1BE55F969F54064628A63B9559E7C21C925165 --amount 100gold --chain_id example-chain +example-plugin tx send --to 0x1B1BE55F969F54064628A63B9559E7C21C925165 --amount 100gold ``` -Note the `--chain_id` flag. In the [previous tutorial](basecoin-basics.md), -we didn't include it because we were using the default chain ID ("test_chain_id"). -Now that we're using a custom chain, we need to specify the chain explicitly on the command line. - Ok, so that's how we can send a `SendTx` transaction using our `example-plugin` CLI, but we were already able to do that with the `basecoin` CLI. With our new CLI, however, we can also send an `ExamplePluginTx`: ``` -example-plugin tx example --amount 1gold --chain_id example-chain +example-plugin tx example --amount 1gold ``` The transaction is invalid! That's because we didn't specify the `--valid` flag: ``` -example-plugin tx example --valid --amount 1gold --chain_id example-chain +example-plugin tx example --valid --amount 1gold ``` Tada! We successfuly created, signed, broadcast, and processed our custom transaction type. @@ -403,13 +353,13 @@ which contains only an integer. If we send another transaction, and then query again, we'll see the value increment: ``` -example-plugin tx example --valid --amount 1gold --chain_id example-chain +example-plugin tx example --valid --amount 1gold example-plugin query ExamplePlugin.State ``` Neat, right? Notice how the result of the query comes with a proof. This is a Merkle proof that the state is what we say it is. -In a latter [tutorial on Interblockchain Communication](ibc.md), +In a latter [tutorial on InterBlockchain Communication](ibc.md), we'll put this proof to work! ## Next Steps @@ -419,5 +369,5 @@ basecoin CLI to activate the plugin on the blockchain and to send transactions t Hopefully by now you have some ideas for your own plugin, and feel comfortable implementing them. In the [next tutorial](more-examples.md), we tour through some other plugin examples, -adding features for minting new coins, voting, and changin the Tendermint validator set. +adding features for minting new coins, voting, and changing the Tendermint validator set. But first, you may want to learn a bit more about [the design of the plugin system](plugin-design.md) From 75da135755a01c5b6f7dbd3528fcdb6e9d425aca Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 13 Mar 2017 20:20:07 -0400 Subject: [PATCH 03/19] basecoin unsafe_reset_all --- cmd/basecoin/main.go | 1 + cmd/commands/reset.go | 52 +++++++++++++++++ docs/guide/basecoin-tool.md | 110 ++++++++++++++++++++++++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 cmd/commands/reset.go create mode 100644 docs/guide/basecoin-tool.md diff --git a/cmd/basecoin/main.go b/cmd/basecoin/main.go index cab2213684..d452aeb6f8 100644 --- a/cmd/basecoin/main.go +++ b/cmd/basecoin/main.go @@ -22,6 +22,7 @@ func main() { commands.VerifyCmd, commands.BlockCmd, commands.AccountCmd, + commands.UnsafeResetAllCmd, } app.Run(os.Args) } diff --git a/cmd/commands/reset.go b/cmd/commands/reset.go new file mode 100644 index 0000000000..693e6107ee --- /dev/null +++ b/cmd/commands/reset.go @@ -0,0 +1,52 @@ +package commands + +import ( + "os" + "path" + + "github.com/urfave/cli" + + tmcfg "github.com/tendermint/tendermint/config/tendermint" + types "github.com/tendermint/tendermint/types" +) + +var UnsafeResetAllCmd = cli.Command{ + Name: "unsafe_reset_all", + Usage: "Reset all blockchain data", + ArgsUsage: "", + Action: func(c *cli.Context) error { + return cmdUnsafeResetAll(c) + }, +} + +func cmdUnsafeResetAll(c *cli.Context) error { + basecoinDir := BasecoinRoot("") + tmDir := path.Join(basecoinDir, "tendermint") + tmConfig := tmcfg.GetConfig(tmDir) + + // Get and Reset PrivValidator + var privValidator *types.PrivValidator + privValidatorFile := tmConfig.GetString("priv_validator_file") + if _, err := os.Stat(privValidatorFile); err == nil { + privValidator = types.LoadPrivValidator(privValidatorFile) + privValidator.Reset() + log.Notice("Reset PrivValidator", "file", privValidatorFile) + } else { + privValidator = types.GenPrivValidator() + privValidator.SetFile(privValidatorFile) + privValidator.Save() + log.Notice("Generated PrivValidator", "file", privValidatorFile) + } + + // Remove all tendermint data + tmDataDir := tmConfig.GetString("db_dir") + os.RemoveAll(tmDataDir) + log.Notice("Removed Tendermint data", "dir", tmDataDir) + + // Remove all basecoin data + basecoinDataDir := path.Join(basecoinDir, "merkleeyes.db") + os.RemoveAll(basecoinDataDir) + log.Notice("Removed Basecoin data", "dir", basecoinDataDir) + + return nil +} diff --git a/docs/guide/basecoin-tool.md b/docs/guide/basecoin-tool.md new file mode 100644 index 0000000000..a55570a0a9 --- /dev/null +++ b/docs/guide/basecoin-tool.md @@ -0,0 +1,110 @@ +# The Basecoin Tool + +In previous tutorials we learned the [basics of the `basecoin` CLI](/docs/guides/basecoin-basics) +and [how to implement a plugin](/docs/guides/example-plugin). +In this tutorial, we provide more details on using the `basecoin` tool. + +# ABCI Server + +So far we have run Basecoin and Tendermint in a single process. +However, since we use ABCI, we can actually run them in different processes. +First, initialize both Basecoin and Tendermint: + +``` +basecoin init +tendermint init +``` + +In one window, run + +``` +basecoin start --abci-server +``` + +and in another, + +``` +tendermint node +``` + +You should see Tendermint start making blocks! + + +# Keys and Genesis + +In previous tutorials we used `basecoin init` to initialize `~/.basecoin` with the default configuration. +This command creates files both for Tendermint and for Basecoin. +The Tendermint files are stored in `~/.basecoin/tendermint`, and are the same type of files that would exist in `~/.tendermint` after running `tendermint init`. +For more information on these files, see the [guide to using tendermint](https://tendermint.com/docs/guides/using-tendermint). + +Now let's make our own custom Basecoin data. + +First, create a new directory: + +``` +mkdir example-data +``` + +We can tell `basecoin` to use this directory by exporting the `BASECOIN_ROOT` environment variable: + +``` +export BASECOIN_ROOT=$(pwd)/example-data +``` + +If you're going to be using multiple terminal windows, make sure to add this variable to your shell startup scripts (eg. `~/.bashrc`). + +Now, let's create a new private key: + +``` +basecoin key new > $BASECOIN_ROOT/key.json +``` + +Here's what my `key.json looks like: + +```json +{ + "address": "15F591CA434CFCCBDEC1D206F3ED3EBA207BFE7D", + "priv_key": [ + 1, + "737C629667A9EAADBB8E7CF792D5A8F63AA4BB51E06457DDD7FDCC6D7412AAAD43AA6C88034F9EB8D2717CA4BBFCBA745EFF19B13EFCD6F339EDBAAAFCD2F7B3" + ], + "pub_key": [ + 1, + "43AA6C88034F9EB8D2717CA4BBFCBA745EFF19B13EFCD6F339EDBAAAFCD2F7B3" + ] +} +``` + +Yours will look different - each key is randomly derrived. + +Now we can make a `genesis.json` file and add an account with our public key: + +```json +[ + "base/chainID", "example-chain", + "base/account", { + "pub_key": [1, "43AA6C88034F9EB8D2717CA4BBFCBA745EFF19B13EFCD6F339EDBAAAFCD2F7B3"], + "coins": [ + { + "denom": "gold", + "amount": 1000000000, + } + ] + } +] +``` + +Here we've granted ourselves `1000000000` units of the `gold` token. +Note that we've also set the `base/chainID` to be `example-chain`. +All transactions must therefore include the `--chain_id example-chain` in order to make sure they are valid for this chain. +Previously, we didn't need this flag because we were using the default chain ID ("test_chain_id"). +Now that we're using a custom chain, we need to specify the chain explicitly on the command line. + + +# Reset + +You can reset all blockchain data by running: + +``` +basecoin unsafe_reset_all +``` From fd6c20739d40225536b5bd7ec749c7fc02633c77 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 13 Mar 2017 20:24:23 -0400 Subject: [PATCH 04/19] docs/guide: update install --- docs/guide/install.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/guide/install.md b/docs/guide/install.md index 2a04abe73b..ef0ef28a61 100644 --- a/docs/guide/install.md +++ b/docs/guide/install.md @@ -8,16 +8,17 @@ go get -u github.com/tendermint/basecoin/cmd/basecoin In some cases, if that fails, or if another branch is required, we use `glide` for dependency management. - -The correct way of compiling from source, assuming you've already -run `go get` or otherwise cloned the repo, is: +Thus, assuming you've already run `go get` or otherwise cloned the repo, +the correct way to install is: ``` cd $GOPATH/src/github.com/tendermint/basecoin -git checkout develop # (until we release v0.9) make get_vendor_deps make install ``` This will create the `basecoin` binary in `$GOPATH/bin`. +Note the `make get_vendor_deps` command will install `glide` and the correct version of all dependencies. + +If you need another branch, make sure to run `git checkout ` before the `make` commands. From f1ce14c2846ced16e64e6c9c05dd64ce061f7eca Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 13 Mar 2017 20:46:40 -0400 Subject: [PATCH 05/19] update demo and ibc guide --- README.md | 2 +- demo/start.sh | 17 +++++++++++------ docs/guide/deployment.md | 7 +++---- docs/guide/example-plugin.md | 2 +- docs/guide/ibc.md | 12 +++++++----- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 22b29bcb1a..55f46c0b95 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,6 @@ See the [install guide](/docs/guide/install.md) for more details. 1. See some [more example applications](/docs/guide/more-examples.md) 1. More features of the [Basecoin tool](/docs/guide/basecoin-tool.md) 1. Learn how to use [InterBlockchain Communication (IBC)](/docs/guide/ibc.md) -1. [Deploy testnets](deployment.md) running your basecoin application. +1. [Deploy testnets](/docs/guide/deployment.md) running your basecoin application. diff --git a/demo/start.sh b/demo/start.sh index d4891ecdd7..d1d7d97382 100644 --- a/demo/start.sh +++ b/demo/start.sh @@ -60,29 +60,34 @@ function waitForBlock() { done } +# make basecoin root vars +export BASECOIN_ROOT="." +BCROOT1="./data/chain1/basecoin" +BCROOT2="./data/chain2/basecoin" # grab the chain ids -CHAIN_ID1=$(cat ./data/chain1/basecoin/genesis.json | jq .[1]) +CHAIN_ID1=$(cat $BCROOT1/genesis.json | jq .[1]) CHAIN_ID1=$(removeQuotes $CHAIN_ID1) -CHAIN_ID2=$(cat ./data/chain2/basecoin/genesis.json | jq .[1]) +CHAIN_ID2=$(cat $BCROOT2/genesis.json | jq .[1]) CHAIN_ID2=$(removeQuotes $CHAIN_ID2) echo "CHAIN_ID1: $CHAIN_ID1" echo "CHAIN_ID2: $CHAIN_ID2" # make reusable chain flags -CHAIN_FLAGS1="--chain_id $CHAIN_ID1 --from ./data/chain1/basecoin/key.json" -CHAIN_FLAGS2="--chain_id $CHAIN_ID2 --from ./data/chain2/basecoin/key.json --node tcp://localhost:36657" +CHAIN_FLAGS1="--chain_id $CHAIN_ID1 --from $BCROOT1/key.json" +CHAIN_FLAGS2="--chain_id $CHAIN_ID2 --from $BCROOT2/key.json --node tcp://localhost:36657" + echo "" echo "... starting chains" echo "" # start the first node TMROOT=./data/chain1/tendermint tendermint node --skip_upnp --log_level=info &> $LOG_DIR/chain1_tendermint.log & -basecoin start --dir ./data/chain1/basecoin &> $LOG_DIR/chain1_basecoin.log & +BASECOIN_ROOT=$BCROOT1 basecoin start --abci-server &> $LOG_DIR/chain1_basecoin.log & # start the second node TMROOT=./data/chain2/tendermint tendermint node --skip_upnp --log_level=info --node_laddr tcp://localhost:36656 --rpc_laddr tcp://localhost:36657 --proxy_app tcp://localhost:36658 &> $LOG_DIR/chain2_tendermint.log & -basecoin start --address tcp://localhost:36658 --dir ./data/chain2/basecoin &> $LOG_DIR/chain2_basecoin.log & +BASECOIN_ROOT=$BCROOT2 basecoin start --address tcp://localhost:36658 --abci-server &> $LOG_DIR/chain2_basecoin.log & echo "" echo "... waiting for chains to start" diff --git a/docs/guide/deployment.md b/docs/guide/deployment.md index e6a7845fc9..74e954a25a 100644 --- a/docs/guide/deployment.md +++ b/docs/guide/deployment.md @@ -1,9 +1,8 @@ ## Deployment -Up until this point, we have only been testing the code as a stand-alone abci app, -which is nice for developing, but it is no blockchain. Just a blockchain-ready application. +Up until this point, we have only been testing the code as a blockchain with a single validator node running locally. +This is nice for developing, but it's not a real distributed application yet. This section will demonstrate how to launch your basecoin-based application along with a tendermint testnet and initialize the genesis block for fun and profit. - -**TODO** Maybe we link to a blog post for this??? +We do this using the [mintnet-kubernetes tool](https://github.com/tendermint/mintnet-kubernetes). diff --git a/docs/guide/example-plugin.md b/docs/guide/example-plugin.md index 94cfc56c57..48da0da730 100644 --- a/docs/guide/example-plugin.md +++ b/docs/guide/example-plugin.md @@ -310,7 +310,7 @@ If you've already run a basecoin blockchain, reset the data with basecoin unsafe_reset_all ``` -To start the blockchain, simply run +To start the blockchain with your new plugin, simply run ``` example-plugin start diff --git a/docs/guide/ibc.md b/docs/guide/ibc.md index f933c22ea7..165b962e44 100644 --- a/docs/guide/ibc.md +++ b/docs/guide/ibc.md @@ -195,14 +195,14 @@ We can start the two chains as follows: ``` TMROOT=./data/chain1/tendermint tendermint node &> chain1_tendermint.log & -basecoin start --dir ./data/chain1/basecoin &> chain1_basecoin.log & +BASECOIN_ROOT=./data/chain1/basecoin basecoin start --abci-server &> chain1_basecoin.log & ``` and ``` TMROOT=./data/chain2/tendermint tendermint node --node_laddr tcp://localhost:36656 --rpc_laddr tcp://localhost:36657 --proxy_app tcp://localhost:36658 &> chain2_tendermint.log & -basecoin start --address tcp://localhost:36658 --dir ./data/chain2/basecoin &> chain2_basecoin.log & +BASECOIN_ROOT=./data/chain2/basecoin basecoin start --abci-server --address tcp://localhost:36658 &> chain2_basecoin.log & ``` Note how we refer to the relevant data directories. Also note how we have to set the various addresses for the second node so as not to conflict with the first. @@ -226,6 +226,8 @@ export CHAIN_ID2=test_chain_2 export CHAIN_FLAGS1="--chain_id $CHAIN_ID1 --from ./data/chain1/basecoin/key.json" export CHAIN_FLAGS2="--chain_id $CHAIN_ID2 --from ./data/chain2/basecoin/key.json --node tcp://localhost:36657" + +export BASECOIN_ROOT="." ``` Let's start by registering `test_chain_1` on `test_chain_2`: @@ -265,7 +267,7 @@ The former is used as input for later commands; the latter is human-readable, so Let's send this updated information about `test_chain_1` to `test_chain_2`: ``` -basecoin tx ibc --amount 10mycoin $CHAIN_FLAGS2 update --header 0x
--commit 0x +basecoin tx ibc --amount 10mycoin $CHAIN_FLAGS2 update --header 0x
--commit 0x ``` where `
` and `` are the hex-encoded header and commit returned by the previous `block` command. @@ -275,10 +277,10 @@ along with proof the packet was committed on `test_chain_1`. Since `test_chain_2 of `test_chain_1`, it will be able to verify the proof! ``` -basecoin tx ibc --amount 10mycoin $CHAIN_FLAGS2 packet post --from $CHAIN_ID1 --height --packet 0x --proof 0x +basecoin tx ibc --amount 10mycoin $CHAIN_FLAGS2 packet post --from $CHAIN_ID1 --height --packet 0x --proof 0x ``` -Here, `` is one greater than the height retuned by the previous `query` command, and `` and `` are the +Here, `` is the height retuned by the previous `query` command, and `` and `` are the `value` and `proof` returned in that same query. Tada! From 39311620c74ad6651a25be3cfe4d609845f107a6 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 13 Mar 2017 20:57:28 -0400 Subject: [PATCH 06/19] changelog --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dfdd0dd68..d268bfe496 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 0.3.0 (March 13, 2017) + +BREAKING CHANGES: + +- Remove `--data` flag and use `BASECOIN_ROOT` to set the home directory (defaults to `~/.basecoin`) +- Remove `--in-proc` flag and start Tendermint in-process by default (expect Tendermint files in $BASECOIN_ROOT/tendermint). +To start just the ABCI app/server, use `basecoin start --abci-server`. + +FEATURES: + +- Introduce `basecoin init` and `basecoin unsafe_reset_all` + ## 0.2.0 (March 6, 2017) BREAKING CHANGES: From 4ec594947122faf423886ed98f67e0230766dcaf Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 13 Mar 2017 21:02:28 -0400 Subject: [PATCH 07/19] remove data dir --- data/genesis.json | 15 --------------- data/key.json | 11 ----------- data/key2.json | 11 ----------- 3 files changed, 37 deletions(-) delete mode 100644 data/genesis.json delete mode 100644 data/key.json delete mode 100644 data/key2.json diff --git a/data/genesis.json b/data/genesis.json deleted file mode 100644 index 66d96300cd..0000000000 --- a/data/genesis.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - "base/chainID", "test_chain_id", - "base/account", { - "pub_key": { - "type": "ed25519", - "data": "619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279" - }, - "coins": [ - { - "denom": "mycoin", - "amount": 9007199254740992 - } - ] - } -] diff --git a/data/key.json b/data/key.json deleted file mode 100644 index 34ea194386..0000000000 --- a/data/key.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "address": "1B1BE55F969F54064628A63B9559E7C21C925165", - "priv_key": [ - 1, - "C70D6934B4F55F1B7BC33B56B9CA8A2061384AFC19E91E44B40C4BBA182953D1619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279" - ], - "pub_key": [ - 1, - "619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279" - ] -} diff --git a/data/key2.json b/data/key2.json deleted file mode 100644 index 38af8af74b..0000000000 --- a/data/key2.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "address": "1DA7C74F9C219229FD54CC9F7386D5A3839F0090", - "priv_key": [ - 1, - "34BAE9E65CE8245FAD035A0E3EED9401BDE8785FFB3199ACCF8F5B5DDF7486A8352195DA90CB0B90C24295B90AEBA25A5A71BC61BAB2FE2387241D439698B7B8" - ], - "pub_key": [ - 1, - "352195DA90CB0B90C24295B90AEBA25A5A71BC61BAB2FE2387241D439698B7B8" - ] -} From e0df8da40a0b5ba209dd07f5a9ae2a0bff8d62b1 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 14 Mar 2017 01:47:10 -0400 Subject: [PATCH 08/19] --abci-server -> --without-tendermint --- CHANGELOG.md | 2 +- cmd/commands/flags.go | 6 +++--- cmd/commands/start.go | 4 ++-- demo/start.sh | 4 ++-- docs/guide/basecoin-tool.md | 2 +- docs/guide/ibc.md | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d268bfe496..5da333362a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ BREAKING CHANGES: - Remove `--data` flag and use `BASECOIN_ROOT` to set the home directory (defaults to `~/.basecoin`) - Remove `--in-proc` flag and start Tendermint in-process by default (expect Tendermint files in $BASECOIN_ROOT/tendermint). -To start just the ABCI app/server, use `basecoin start --abci-server`. +To start just the ABCI app/server, use `basecoin start --without-tendermint`. FEATURES: diff --git a/cmd/commands/flags.go b/cmd/commands/flags.go index 06f0ce4233..ccf95769d3 100644 --- a/cmd/commands/flags.go +++ b/cmd/commands/flags.go @@ -21,9 +21,9 @@ var ( // TODO: move to config file // eyesCacheSizePtr := flag.Int("eyes-cache-size", 10000, "MerkleEyes db cache size, for embedded") - ABCIServerFlag = cli.BoolFlag{ - Name: "abci-server", - Usage: "Run the Basecoin app and ABCI server, but not Tendermint (run Tendermint in another process)", + WithoutTendermintFlag = cli.BoolFlag{ + Name: "without-tendermint", + Usage: "Run the Basecoin app without Tendermint", } ) diff --git a/cmd/commands/start.go b/cmd/commands/start.go index 4c4afd199d..f9867e86c6 100644 --- a/cmd/commands/start.go +++ b/cmd/commands/start.go @@ -33,7 +33,7 @@ var StartCmd = cli.Command{ Flags: []cli.Flag{ AddrFlag, EyesFlag, - ABCIServerFlag, + WithoutTendermintFlag, ChainIDFlag, }, } @@ -87,7 +87,7 @@ func cmdStart(c *cli.Context) error { fmt.Printf("No genesis file at %s, skipping...\n", genesisFile) } - if c.Bool("abci-server") { + if c.Bool("without-tendermint") { // run just the abci app/server if err := startBasecoinABCI(c, basecoinApp); err != nil { return err diff --git a/demo/start.sh b/demo/start.sh index d1d7d97382..f227653047 100644 --- a/demo/start.sh +++ b/demo/start.sh @@ -83,11 +83,11 @@ echo "... starting chains" echo "" # start the first node TMROOT=./data/chain1/tendermint tendermint node --skip_upnp --log_level=info &> $LOG_DIR/chain1_tendermint.log & -BASECOIN_ROOT=$BCROOT1 basecoin start --abci-server &> $LOG_DIR/chain1_basecoin.log & +BASECOIN_ROOT=$BCROOT1 basecoin start --without-tendermint &> $LOG_DIR/chain1_basecoin.log & # start the second node TMROOT=./data/chain2/tendermint tendermint node --skip_upnp --log_level=info --node_laddr tcp://localhost:36656 --rpc_laddr tcp://localhost:36657 --proxy_app tcp://localhost:36658 &> $LOG_DIR/chain2_tendermint.log & -BASECOIN_ROOT=$BCROOT2 basecoin start --address tcp://localhost:36658 --abci-server &> $LOG_DIR/chain2_basecoin.log & +BASECOIN_ROOT=$BCROOT2 basecoin start --address tcp://localhost:36658 --without-tendermint &> $LOG_DIR/chain2_basecoin.log & echo "" echo "... waiting for chains to start" diff --git a/docs/guide/basecoin-tool.md b/docs/guide/basecoin-tool.md index a55570a0a9..49bca18584 100644 --- a/docs/guide/basecoin-tool.md +++ b/docs/guide/basecoin-tool.md @@ -18,7 +18,7 @@ tendermint init In one window, run ``` -basecoin start --abci-server +basecoin start --without-tendermint ``` and in another, diff --git a/docs/guide/ibc.md b/docs/guide/ibc.md index 165b962e44..0de9fb375b 100644 --- a/docs/guide/ibc.md +++ b/docs/guide/ibc.md @@ -195,14 +195,14 @@ We can start the two chains as follows: ``` TMROOT=./data/chain1/tendermint tendermint node &> chain1_tendermint.log & -BASECOIN_ROOT=./data/chain1/basecoin basecoin start --abci-server &> chain1_basecoin.log & +BASECOIN_ROOT=./data/chain1/basecoin basecoin start --without-tendermint &> chain1_basecoin.log & ``` and ``` TMROOT=./data/chain2/tendermint tendermint node --node_laddr tcp://localhost:36656 --rpc_laddr tcp://localhost:36657 --proxy_app tcp://localhost:36658 &> chain2_tendermint.log & -BASECOIN_ROOT=./data/chain2/basecoin basecoin start --abci-server --address tcp://localhost:36658 &> chain2_basecoin.log & +BASECOIN_ROOT=./data/chain2/basecoin basecoin start --without-tendermint --address tcp://localhost:36658 &> chain2_basecoin.log & ``` Note how we refer to the relevant data directories. Also note how we have to set the various addresses for the second node so as not to conflict with the first. From 4a6b7131e4ce1212858e01503248572a2c333aa2 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 14 Mar 2017 01:50:10 -0400 Subject: [PATCH 09/19] BASECOIN_ROOT -> BCHOME --- CHANGELOG.md | 4 ++-- cmd/commands/utils.go | 2 +- demo/start.sh | 18 +++++++++--------- docs/guide/basecoin-tool.md | 6 +++--- docs/guide/ibc.md | 6 +++--- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5da333362a..0fc71fdea9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,8 @@ BREAKING CHANGES: -- Remove `--data` flag and use `BASECOIN_ROOT` to set the home directory (defaults to `~/.basecoin`) -- Remove `--in-proc` flag and start Tendermint in-process by default (expect Tendermint files in $BASECOIN_ROOT/tendermint). +- Remove `--data` flag and use `BCHOME` to set the home directory (defaults to `~/.basecoin`) +- Remove `--in-proc` flag and start Tendermint in-process by default (expect Tendermint files in $BCHOME/tendermint). To start just the ABCI app/server, use `basecoin start --without-tendermint`. FEATURES: diff --git a/cmd/commands/utils.go b/cmd/commands/utils.go index 35af75baae..56c1480780 100644 --- a/cmd/commands/utils.go +++ b/cmd/commands/utils.go @@ -23,7 +23,7 @@ import ( func BasecoinRoot(rootDir string) string { if rootDir == "" { - rootDir = os.Getenv("BASECOIN_ROOT") + rootDir = os.Getenv("BCHOME") } if rootDir == "" { rootDir = os.Getenv("HOME") + "/.basecoin" diff --git a/demo/start.sh b/demo/start.sh index f227653047..412f23d8b4 100644 --- a/demo/start.sh +++ b/demo/start.sh @@ -61,21 +61,21 @@ function waitForBlock() { } # make basecoin root vars -export BASECOIN_ROOT="." -BCROOT1="./data/chain1/basecoin" -BCROOT2="./data/chain2/basecoin" +export BCHOME="." +BCHOME1="./data/chain1/basecoin" +BCHOME2="./data/chain2/basecoin" # grab the chain ids -CHAIN_ID1=$(cat $BCROOT1/genesis.json | jq .[1]) +CHAIN_ID1=$(cat $BCHOME1/genesis.json | jq .[1]) CHAIN_ID1=$(removeQuotes $CHAIN_ID1) -CHAIN_ID2=$(cat $BCROOT2/genesis.json | jq .[1]) +CHAIN_ID2=$(cat $BCHOME2/genesis.json | jq .[1]) CHAIN_ID2=$(removeQuotes $CHAIN_ID2) echo "CHAIN_ID1: $CHAIN_ID1" echo "CHAIN_ID2: $CHAIN_ID2" # make reusable chain flags -CHAIN_FLAGS1="--chain_id $CHAIN_ID1 --from $BCROOT1/key.json" -CHAIN_FLAGS2="--chain_id $CHAIN_ID2 --from $BCROOT2/key.json --node tcp://localhost:36657" +CHAIN_FLAGS1="--chain_id $CHAIN_ID1 --from $BCHOME1/key.json" +CHAIN_FLAGS2="--chain_id $CHAIN_ID2 --from $BCHOME2/key.json --node tcp://localhost:36657" echo "" @@ -83,11 +83,11 @@ echo "... starting chains" echo "" # start the first node TMROOT=./data/chain1/tendermint tendermint node --skip_upnp --log_level=info &> $LOG_DIR/chain1_tendermint.log & -BASECOIN_ROOT=$BCROOT1 basecoin start --without-tendermint &> $LOG_DIR/chain1_basecoin.log & +BCHOME=$BCHOME1 basecoin start --without-tendermint &> $LOG_DIR/chain1_basecoin.log & # start the second node TMROOT=./data/chain2/tendermint tendermint node --skip_upnp --log_level=info --node_laddr tcp://localhost:36656 --rpc_laddr tcp://localhost:36657 --proxy_app tcp://localhost:36658 &> $LOG_DIR/chain2_tendermint.log & -BASECOIN_ROOT=$BCROOT2 basecoin start --address tcp://localhost:36658 --without-tendermint &> $LOG_DIR/chain2_basecoin.log & +BCHOME=$BCHOME2 basecoin start --address tcp://localhost:36658 --without-tendermint &> $LOG_DIR/chain2_basecoin.log & echo "" echo "... waiting for chains to start" diff --git a/docs/guide/basecoin-tool.md b/docs/guide/basecoin-tool.md index 49bca18584..7046093d9c 100644 --- a/docs/guide/basecoin-tool.md +++ b/docs/guide/basecoin-tool.md @@ -45,10 +45,10 @@ First, create a new directory: mkdir example-data ``` -We can tell `basecoin` to use this directory by exporting the `BASECOIN_ROOT` environment variable: +We can tell `basecoin` to use this directory by exporting the `BCHOME` environment variable: ``` -export BASECOIN_ROOT=$(pwd)/example-data +export BCHOME=$(pwd)/example-data ``` If you're going to be using multiple terminal windows, make sure to add this variable to your shell startup scripts (eg. `~/.bashrc`). @@ -56,7 +56,7 @@ If you're going to be using multiple terminal windows, make sure to add this var Now, let's create a new private key: ``` -basecoin key new > $BASECOIN_ROOT/key.json +basecoin key new > $BCHOME/key.json ``` Here's what my `key.json looks like: diff --git a/docs/guide/ibc.md b/docs/guide/ibc.md index 0de9fb375b..e67dcda1cf 100644 --- a/docs/guide/ibc.md +++ b/docs/guide/ibc.md @@ -195,14 +195,14 @@ We can start the two chains as follows: ``` TMROOT=./data/chain1/tendermint tendermint node &> chain1_tendermint.log & -BASECOIN_ROOT=./data/chain1/basecoin basecoin start --without-tendermint &> chain1_basecoin.log & +BCHOME=./data/chain1/basecoin basecoin start --without-tendermint &> chain1_basecoin.log & ``` and ``` TMROOT=./data/chain2/tendermint tendermint node --node_laddr tcp://localhost:36656 --rpc_laddr tcp://localhost:36657 --proxy_app tcp://localhost:36658 &> chain2_tendermint.log & -BASECOIN_ROOT=./data/chain2/basecoin basecoin start --without-tendermint --address tcp://localhost:36658 &> chain2_basecoin.log & +BCHOME=./data/chain2/basecoin basecoin start --without-tendermint --address tcp://localhost:36658 &> chain2_basecoin.log & ``` Note how we refer to the relevant data directories. Also note how we have to set the various addresses for the second node so as not to conflict with the first. @@ -227,7 +227,7 @@ export CHAIN_ID2=test_chain_2 export CHAIN_FLAGS1="--chain_id $CHAIN_ID1 --from ./data/chain1/basecoin/key.json" export CHAIN_FLAGS2="--chain_id $CHAIN_ID2 --from ./data/chain2/basecoin/key.json --node tcp://localhost:36657" -export BASECOIN_ROOT="." +export BCHOME="." ``` Let's start by registering `test_chain_1` on `test_chain_2`: From 0e730e67f8379bcde04b5fbd0ab307a38b7669fb Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Tue, 14 Mar 2017 11:25:42 +0400 Subject: [PATCH 10/19] Dockerfile and Dockerfile.dev for development --- Dockerfile | 28 ++++++++++++++++++++++++++++ Dockerfile.dev | 12 ++++++++++++ Makefile | 10 ++++++++-- 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 Dockerfile create mode 100644 Dockerfile.dev diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..79b078d91c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,28 @@ +FROM alpine:3.5 + +# BCHOME is where your genesis.json, key.json and other files including state are stored. +ENV BCHOME /basecoin + +# Create a basecoin user and group first so the IDs get set the same way, even +# as the rest of this may change over time. +RUN addgroup basecoin && \ + adduser -S -G basecoin basecoin + +RUN mkdir -p $BCHOME && \ + chown -R basecoin:basecoin $BCHOME +WORKDIR $BCHOME + +# Expose the basecoin home directory as a volume since there's mutable state in there. +VOLUME $BCHOME + +# jq and curl used for extracting `pub_key` from private validator while +# deploying tendermint with Kubernetes. It is nice to have bash so the users +# could execute bash commands. +RUN apk add --no-cache bash curl jq + +COPY basecoin /usr/bin/basecoin + +ENTRYPOINT ["basecoin"] + +# By default you will get the basecoin with local MerkleEyes and in-proc Tendermint. +CMD ["start", "--dir=${BCHOME}"] diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 0000000000..ee6cdc6e21 --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,12 @@ +FROM golang:latest + +RUN mkdir -p /go/src/github.com/tendermint/basecoin +WORKDIR /go/src/github.com/tendermint/basecoin + +COPY Makefile /go/src/github.com/tendermint/basecoin/ +COPY glide.yaml /go/src/github.com/tendermint/basecoin/ +COPY glide.lock /go/src/github.com/tendermint/basecoin/ + +RUN make get_vendor_deps + +COPY . /go/src/github.com/tendermint/basecoin diff --git a/Makefile b/Makefile index 89f9af72b5..32ec678624 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,3 @@ -.PHONY: all test get_deps - all: test install NOVENDOR = go list github.com/tendermint/basecoin/... | grep -v /vendor/ @@ -24,3 +22,11 @@ get_vendor_deps: go get github.com/Masterminds/glide glide install +build-docker: + docker run -it --rm -v "$(PWD):/go/src/github.com/tendermint/basecoin" -w "/go/src/github.com/tendermint/basecoin" -e "CGO_ENABLED=0" golang:alpine go build ./cmd/basecoin + docker build -t "tendermint/basecoin" . + +clean: + @rm -f ./basecoin + +.PHONY: all build install test get_deps update_deps get_vendor_deps build-docker clean From 03ea00f1e63601eb74119722d595c0b0dbe50870 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 14 Mar 2017 03:11:49 -0400 Subject: [PATCH 11/19] consolidate genesis files --- app/app.go | 5 +- app/genesis.go | 51 +++++++-- cmd/commands/init.go | 103 ++++++++++-------- cmd/commands/reset.go | 9 +- cmd/commands/start.go | 4 +- demo/clean.sh | 11 +- demo/data/chain1/basecoin/genesis.json | 15 --- demo/data/chain1/{tendermint => }/config.toml | 0 demo/data/chain1/genesis.json | 32 ++++++ demo/data/chain1/{basecoin => }/key.json | 0 .../{tendermint => }/priv_validator.json | 0 demo/data/chain1/tendermint/genesis.json | 15 --- demo/data/chain2/basecoin/genesis.json | 15 --- demo/data/chain2/{tendermint => }/config.toml | 0 demo/data/chain2/genesis.json | 32 ++++++ demo/data/chain2/{basecoin => }/key.json | 0 .../{tendermint => }/priv_validator.json | 0 demo/data/chain2/tendermint/genesis.json | 15 --- demo/start.sh | 14 +-- 19 files changed, 180 insertions(+), 141 deletions(-) delete mode 100644 demo/data/chain1/basecoin/genesis.json rename demo/data/chain1/{tendermint => }/config.toml (100%) create mode 100644 demo/data/chain1/genesis.json rename demo/data/chain1/{basecoin => }/key.json (100%) rename demo/data/chain1/{tendermint => }/priv_validator.json (100%) delete mode 100644 demo/data/chain1/tendermint/genesis.json delete mode 100644 demo/data/chain2/basecoin/genesis.json rename demo/data/chain2/{tendermint => }/config.toml (100%) create mode 100644 demo/data/chain2/genesis.json rename demo/data/chain2/{basecoin => }/key.json (100%) rename demo/data/chain2/{tendermint => }/priv_validator.json (100%) delete mode 100644 demo/data/chain2/tendermint/genesis.json diff --git a/app/app.go b/app/app.go index 0b8fb6d2e3..b783ea5c6c 100644 --- a/app/app.go +++ b/app/app.go @@ -65,7 +65,7 @@ func (app *Basecoin) SetOption(key string, value string) string { } else { // Set option on basecoin switch key { - case "chainID": + case "chain_id": app.state.SetChainID(value) return "Success" case "account": @@ -75,7 +75,8 @@ func (app *Basecoin) SetOption(key string, value string) string { return "Error decoding acc message: " + err.Error() } app.state.SetAccount(acc.PubKey.Address(), &acc) - log.Info("SetAccount", "addr", acc.PubKey.Address(), "acc", acc) + log.Notice("SetAccount", "addr", acc.PubKey.Address(), "acc", acc) + return "Success" } return "Unrecognized option key " + key diff --git a/app/genesis.go b/app/genesis.go index afa94ecab3..8f96aa8bc9 100644 --- a/app/genesis.go +++ b/app/genesis.go @@ -2,18 +2,32 @@ package app import ( "encoding/json" + "fmt" "github.com/pkg/errors" + "github.com/tendermint/basecoin/types" cmn "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" + tmtypes "github.com/tendermint/tendermint/types" ) func (app *Basecoin) LoadGenesis(path string) error { - kvz, err := loadGenesis(path) + tmDoc, appDoc, err := loadGenesis(path) if err != nil { return err } - for _, kv := range kvz { - app.SetOption(kv.Key, kv.Value) + fmt.Println("TMGendoc", tmDoc) + fmt.Println("AppGendoc", appDoc) + + app.SetOption("base/chain_id", appDoc.ChainID) + for _, acc := range appDoc.Accounts { + accBytes, err := json.Marshal(acc) + if err != nil { + return err + } + r := app.SetOption("base/account", string(accBytes)) + // TODO: SetOption returns an error + log.Notice("SetOption", "result", r) } return nil } @@ -23,16 +37,37 @@ type keyValue struct { Value string `json:"value"` } -func loadGenesis(filePath string) (kvz []keyValue, err error) { - kvz_ := []json.RawMessage{} +// includes tendermint (in the json, we ignore here) +type FullGenesisDoc struct { + AppOptions *GenesisDoc `json:"app_options"` +} + +type GenesisDoc struct { + ChainID string `json:"chain_id"` + Accounts []types.Account `json:"accounts"` +} + +func loadGenesis(filePath string) (*tmtypes.GenesisDoc, *GenesisDoc, error) { bytes, err := cmn.ReadFile(filePath) if err != nil { - return nil, errors.Wrap(err, "loading genesis file") + return nil, nil, errors.Wrap(err, "loading genesis file") } - err = json.Unmarshal(bytes, &kvz_) + + tmGenesis := new(tmtypes.GenesisDoc) + appGenesis := new(FullGenesisDoc) + + // the tendermint genesis is go-wire + err = wire.ReadJSONBytes(bytes, tmGenesis) + + // the basecoin genesis go-data :) + err = json.Unmarshal(bytes, appGenesis) if err != nil { - return nil, errors.Wrap(err, "parsing genesis file") + return nil, nil, errors.Wrap(err, "unmarshaling genesis file") } + return tmGenesis, appGenesis.AppOptions, nil +} + +func parseGenesisList(kvz_ []json.RawMessage) (kvz []keyValue, err error) { if len(kvz_)%2 != 0 { return nil, errors.New("genesis cannot have an odd number of items. Format = [key1, value1, key2, value2, ...]") } diff --git a/cmd/commands/init.go b/cmd/commands/init.go index 9d44167e46..695220445c 100644 --- a/cmd/commands/init.go +++ b/cmd/commands/init.go @@ -2,14 +2,11 @@ package commands import ( "io/ioutil" - "os" "path" "github.com/urfave/cli" cmn "github.com/tendermint/go-common" - tmcfg "github.com/tendermint/tendermint/config/tendermint" - types "github.com/tendermint/tendermint/types" ) var InitCmd = cli.Command{ @@ -25,44 +22,22 @@ var InitCmd = cli.Command{ } func cmdInit(c *cli.Context) error { - basecoinDir := BasecoinRoot("") - tmDir := path.Join(basecoinDir, "tendermint") + rootDir := BasecoinRoot("") - // initalize tendermint - tmConfig := tmcfg.GetConfig(tmDir) - - privValFile := tmConfig.GetString("priv_validator_file") - if _, err := os.Stat(privValFile); os.IsNotExist(err) { - privValidator := types.GenPrivValidator() - privValidator.SetFile(privValFile) - privValidator.Save() - - genFile := tmConfig.GetString("genesis_file") - - if _, err := os.Stat(genFile); os.IsNotExist(err) { - genDoc := types.GenesisDoc{ - ChainID: cmn.Fmt("test-chain-%v", cmn.RandStr(6)), - } - genDoc.Validators = []types.GenesisValidator{types.GenesisValidator{ - PubKey: privValidator.PubKey, - Amount: 10, - }} - - genDoc.SaveAs(genFile) - } - log.Notice("Initialized Tendermint", "genesis", tmConfig.GetString("genesis_file"), "priv_validator", tmConfig.GetString("priv_validator_file")) - } else { - log.Notice("Already initialized Tendermint", "priv_validator", tmConfig.GetString("priv_validator_file")) - } + cmn.EnsureDir(rootDir, 0777) // initalize basecoin - genesisFile := path.Join(basecoinDir, "genesis.json") - key1File := path.Join(basecoinDir, "key.json") - key2File := path.Join(basecoinDir, "key2.json") + genesisFile := path.Join(rootDir, "genesis.json") + privValFile := path.Join(rootDir, "priv_validator.json") + key1File := path.Join(rootDir, "key.json") + key2File := path.Join(rootDir, "key2.json") if err := ioutil.WriteFile(genesisFile, []byte(genesisJSON), 0644); err != nil { return err } + if err := ioutil.WriteFile(privValFile, []byte(privValJSON), 0400); err != nil { + return err + } if err := ioutil.WriteFile(key1File, []byte(key1JSON), 0400); err != nil { return err } @@ -75,21 +50,53 @@ func cmdInit(c *cli.Context) error { return nil } -const genesisJSON = `[ - "base/chainID", "test_chain_id", - "base/account", { - "pub_key": { - "type": "ed25519", - "data": "619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279" - }, - "coins": [ - { - "denom": "mycoin", - "amount": 9007199254740992 - } - ] +const privValJSON = `{ + "address": "7A956FADD20D3A5B2375042B2959F8AB172A058F", + "last_height": 0, + "last_round": 0, + "last_signature": null, + "last_signbytes": "", + "last_step": 0, + "priv_key": [ + 1, + "D07ABE82A8B15559A983B2DB5D4842B2B6E4D6AF58B080005662F424F17D68C17B90EA87E7DC0C7145C8C48C08992BE271C7234134343E8A8E8008E617DE7B30" + ], + "pub_key": [ + 1, + "7B90EA87E7DC0C7145C8C48C08992BE271C7234134343E8A8E8008E617DE7B30" + ] +}` + +const genesisJSON = `{ + "app_hash": "", + "chain_id": "test-chain-Ppk1h3", + "genesis_time": "0001-01-01T00:00:00.000Z", + "validators": [ + { + "amount": 10, + "name": "", + "pub_key": [ + 1, + "7B90EA87E7DC0C7145C8C48C08992BE271C7234134343E8A8E8008E617DE7B30" + ] + } + ], + "app_options": { + "chain_id": "test_chain_id", + "accounts": [{ + "pub_key": { + "type": "ed25519", + "data": "619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279" + }, + "coins": [ + { + "denom": "mycoin", + "amount": 9007199254740992 + } + ] + }] } -]` +}` const key1JSON = `{ "address": "1B1BE55F969F54064628A63B9559E7C21C925165", diff --git a/cmd/commands/reset.go b/cmd/commands/reset.go index 693e6107ee..d9688fd859 100644 --- a/cmd/commands/reset.go +++ b/cmd/commands/reset.go @@ -21,7 +21,7 @@ var UnsafeResetAllCmd = cli.Command{ func cmdUnsafeResetAll(c *cli.Context) error { basecoinDir := BasecoinRoot("") - tmDir := path.Join(basecoinDir, "tendermint") + tmDir := path.Join(basecoinDir) tmConfig := tmcfg.GetConfig(tmDir) // Get and Reset PrivValidator @@ -41,12 +41,7 @@ func cmdUnsafeResetAll(c *cli.Context) error { // Remove all tendermint data tmDataDir := tmConfig.GetString("db_dir") os.RemoveAll(tmDataDir) - log.Notice("Removed Tendermint data", "dir", tmDataDir) - - // Remove all basecoin data - basecoinDataDir := path.Join(basecoinDir, "merkleeyes.db") - os.RemoveAll(basecoinDataDir) - log.Notice("Removed Basecoin data", "dir", basecoinDataDir) + log.Notice("Removed all data", "dir", tmDataDir) return nil } diff --git a/cmd/commands/start.go b/cmd/commands/start.go index f9867e86c6..97946384a3 100644 --- a/cmd/commands/start.go +++ b/cmd/commands/start.go @@ -56,7 +56,7 @@ func cmdStart(c *cli.Context) error { // Connect to MerkleEyes var eyesCli *eyes.Client if c.String("eyes") == "local" { - eyesCli = eyes.NewLocalClient(path.Join(basecoinDir, "merkleeyes.db"), EyesCacheSize) + eyesCli = eyes.NewLocalClient(path.Join(basecoinDir, "data", "merkleeyes.db"), EyesCacheSize) } else { var err error eyesCli, err = eyes.NewClient(c.String("eyes")) @@ -117,7 +117,7 @@ func startBasecoinABCI(c *cli.Context, basecoinApp *app.Basecoin) error { func startTendermint(dir string, basecoinApp *app.Basecoin) { // Get configuration - tmConfig := tmcfg.GetConfig(path.Join(dir, "tendermint")) + tmConfig := tmcfg.GetConfig(dir) // logger.SetLogLevel("notice") //config.GetString("log_level")) diff --git a/demo/clean.sh b/demo/clean.sh index e2d519337d..e39f090eec 100644 --- a/demo/clean.sh +++ b/demo/clean.sh @@ -1,13 +1,10 @@ #! /bin/bash killall -9 basecoin tendermint -TMROOT=./data/chain1/tendermint tendermint unsafe_reset_all -TMROOT=./data/chain2/tendermint tendermint unsafe_reset_all - -rm -rf ./data/chain1/basecoin/merkleeyes.db -rm -rf ./data/chain2/basecoin/merkleeyes.db +TMROOT=./data/chain1 tendermint unsafe_reset_all +TMROOT=./data/chain2 tendermint unsafe_reset_all rm ./*.log -rm ./data/chain1/tendermint/*.bak -rm ./data/chain2/tendermint/*.bak +rm ./data/chain1/*.bak +rm ./data/chain2/*.bak diff --git a/demo/data/chain1/basecoin/genesis.json b/demo/data/chain1/basecoin/genesis.json deleted file mode 100644 index 588fc86f4f..0000000000 --- a/demo/data/chain1/basecoin/genesis.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - "base/chainID", "test_chain_1", - "base/account", { - "pub_key": { - "type": "ed25519", - "data": "B3588BDC92015ED3CDB6F57A86379E8C79A7111063610B7E625487C76496F4DF" - }, - "coins": [ - { - "denom": "mycoin", - "amount": 9007199254740992 - } - ] - } -] diff --git a/demo/data/chain1/tendermint/config.toml b/demo/data/chain1/config.toml similarity index 100% rename from demo/data/chain1/tendermint/config.toml rename to demo/data/chain1/config.toml diff --git a/demo/data/chain1/genesis.json b/demo/data/chain1/genesis.json new file mode 100644 index 0000000000..4b9ab3079a --- /dev/null +++ b/demo/data/chain1/genesis.json @@ -0,0 +1,32 @@ +{ + "app_hash": "", + "chain_id": "test_chain_1", + "genesis_time": "0001-01-01T00:00:00.000Z", + "validators": [ + { + "amount": 10, + "name": "", + "pub_key": [ + 1, + "D6EBB92440CF375054AA59BCF0C99D596DEEDFFB2543CAE1BA1908B72CF9676A" + ] + } + ], + "app_options": { + "chain_id": "test_chain_1", + "accounts": [ + { + "pub_key": { + "type": "ed25519", + "data": "B3588BDC92015ED3CDB6F57A86379E8C79A7111063610B7E625487C76496F4DF" + }, + "coins": [ + { + "denom": "mycoin", + "amount": 9007199254740992 + } + ] + } + ] + } +} diff --git a/demo/data/chain1/basecoin/key.json b/demo/data/chain1/key.json similarity index 100% rename from demo/data/chain1/basecoin/key.json rename to demo/data/chain1/key.json diff --git a/demo/data/chain1/tendermint/priv_validator.json b/demo/data/chain1/priv_validator.json similarity index 100% rename from demo/data/chain1/tendermint/priv_validator.json rename to demo/data/chain1/priv_validator.json diff --git a/demo/data/chain1/tendermint/genesis.json b/demo/data/chain1/tendermint/genesis.json deleted file mode 100644 index 91830dd23f..0000000000 --- a/demo/data/chain1/tendermint/genesis.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "app_hash": "", - "chain_id": "test_chain_1", - "genesis_time": "0001-01-01T00:00:00.000Z", - "validators": [ - { - "amount": 10, - "name": "", - "pub_key": [ - 1, - "D6EBB92440CF375054AA59BCF0C99D596DEEDFFB2543CAE1BA1908B72CF9676A" - ] - } - ] -} diff --git a/demo/data/chain2/basecoin/genesis.json b/demo/data/chain2/basecoin/genesis.json deleted file mode 100644 index 05df04be5a..0000000000 --- a/demo/data/chain2/basecoin/genesis.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - "base/chainID", "test_chain_2", - "base/account", { - "pub_key": { - "type": "ed25519", - "data": "0628C8E6C2D50B15764B443394E06C6A64F3082CE966A2A8C1A55A4D63D0FC5D" - }, - "coins": [ - { - "denom": "mycoin", - "amount": 9007199254740992 - } - ] - } -] diff --git a/demo/data/chain2/tendermint/config.toml b/demo/data/chain2/config.toml similarity index 100% rename from demo/data/chain2/tendermint/config.toml rename to demo/data/chain2/config.toml diff --git a/demo/data/chain2/genesis.json b/demo/data/chain2/genesis.json new file mode 100644 index 0000000000..2079970346 --- /dev/null +++ b/demo/data/chain2/genesis.json @@ -0,0 +1,32 @@ +{ + "app_hash": "", + "chain_id": "test_chain_2", + "genesis_time": "0001-01-01T00:00:00.000Z", + "validators": [ + { + "amount": 10, + "name": "", + "pub_key": [ + 1, + "9A76DDE4CA4EE660C073D288DBE4F8A128F23857881A95F18167682D47E7058F" + ] + } + ], + "app_options": { + "chain_id": "test_chain_2", + "accounts": [ + { + "pub_key": { + "type": "ed25519", + "data": "0628C8E6C2D50B15764B443394E06C6A64F3082CE966A2A8C1A55A4D63D0FC5D" + }, + "coins": [ + { + "denom": "mycoin", + "amount": 9007199254740992 + } + ] + } + ] + } +} diff --git a/demo/data/chain2/basecoin/key.json b/demo/data/chain2/key.json similarity index 100% rename from demo/data/chain2/basecoin/key.json rename to demo/data/chain2/key.json diff --git a/demo/data/chain2/tendermint/priv_validator.json b/demo/data/chain2/priv_validator.json similarity index 100% rename from demo/data/chain2/tendermint/priv_validator.json rename to demo/data/chain2/priv_validator.json diff --git a/demo/data/chain2/tendermint/genesis.json b/demo/data/chain2/tendermint/genesis.json deleted file mode 100644 index 6c9f17c952..0000000000 --- a/demo/data/chain2/tendermint/genesis.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "app_hash": "", - "chain_id": "test_chain_2", - "genesis_time": "0001-01-01T00:00:00.000Z", - "validators": [ - { - "amount": 10, - "name": "", - "pub_key": [ - 1, - "9A76DDE4CA4EE660C073D288DBE4F8A128F23857881A95F18167682D47E7058F" - ] - } - ] -} diff --git a/demo/start.sh b/demo/start.sh index 412f23d8b4..bfc6872350 100644 --- a/demo/start.sh +++ b/demo/start.sh @@ -62,13 +62,13 @@ function waitForBlock() { # make basecoin root vars export BCHOME="." -BCHOME1="./data/chain1/basecoin" -BCHOME2="./data/chain2/basecoin" +BCHOME1="./data/chain1" +BCHOME2="./data/chain2" # grab the chain ids -CHAIN_ID1=$(cat $BCHOME1/genesis.json | jq .[1]) +CHAIN_ID1=$(cat $BCHOME1/genesis.json | jq .chain_id) CHAIN_ID1=$(removeQuotes $CHAIN_ID1) -CHAIN_ID2=$(cat $BCHOME2/genesis.json | jq .[1]) +CHAIN_ID2=$(cat $BCHOME2/genesis.json | jq .chain_id) CHAIN_ID2=$(removeQuotes $CHAIN_ID2) echo "CHAIN_ID1: $CHAIN_ID1" echo "CHAIN_ID2: $CHAIN_ID2" @@ -82,11 +82,11 @@ echo "" echo "... starting chains" echo "" # start the first node -TMROOT=./data/chain1/tendermint tendermint node --skip_upnp --log_level=info &> $LOG_DIR/chain1_tendermint.log & +TMROOT=./data/chain1 tendermint node --skip_upnp --log_level=info &> $LOG_DIR/chain1_tendermint.log & BCHOME=$BCHOME1 basecoin start --without-tendermint &> $LOG_DIR/chain1_basecoin.log & # start the second node -TMROOT=./data/chain2/tendermint tendermint node --skip_upnp --log_level=info --node_laddr tcp://localhost:36656 --rpc_laddr tcp://localhost:36657 --proxy_app tcp://localhost:36658 &> $LOG_DIR/chain2_tendermint.log & +TMROOT=./data/chain2 tendermint node --skip_upnp --log_level=info --node_laddr tcp://localhost:36656 --rpc_laddr tcp://localhost:36657 --proxy_app tcp://localhost:36658 &> $LOG_DIR/chain2_tendermint.log & BCHOME=$BCHOME2 basecoin start --address tcp://localhost:36658 --without-tendermint &> $LOG_DIR/chain2_basecoin.log & echo "" @@ -103,7 +103,7 @@ sleep 3 echo "... registering chain1 on chain2" echo "" # register chain1 on chain2 -basecoin tx ibc --amount 10mycoin $CHAIN_FLAGS2 register --chain_id $CHAIN_ID1 --genesis ./data/chain1/tendermint/genesis.json +basecoin tx ibc --amount 10mycoin $CHAIN_FLAGS2 register --chain_id $CHAIN_ID1 --genesis ./data/chain1/genesis.json echo "" echo "... creating egress packet on chain1" From 09433299caab79ab80bccfbfb4ad17700ca822e5 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 14 Mar 2017 13:55:46 -0400 Subject: [PATCH 12/19] add plugin_options and fix tests --- CHANGELOG.md | 42 +++++++++++++++++++++++++- app/app.go | 2 +- app/genesis.go | 53 ++++++++++++++++++++------------- app/testdata/genesis.json | 37 ++++++++++++----------- cmd/commands/init.go | 3 +- demo/data/chain1/genesis.json | 1 - demo/data/chain2/genesis.json | 1 - docs/guide/basecoin-tool.md | 4 +-- plugins/counter/counter_test.go | 2 +- tests/tmsp/tmsp_test.go | 4 +-- 10 files changed, 101 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fc71fdea9..df585e79fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,52 @@ # Changelog -## 0.3.0 (March 13, 2017) +## 0.3.0 (March 14, 2017) BREAKING CHANGES: - Remove `--data` flag and use `BCHOME` to set the home directory (defaults to `~/.basecoin`) - Remove `--in-proc` flag and start Tendermint in-process by default (expect Tendermint files in $BCHOME/tendermint). To start just the ABCI app/server, use `basecoin start --without-tendermint`. +- Consolidate genesis files so the Basecoin genesis is an object under `app_options` in Tendermint genesis. For instance: + +``` +{ + "app_hash": "", + "chain_id": "foo_bar_chain", + "genesis_time": "0001-01-01T00:00:00.000Z", + "validators": [ + { + "amount": 10, + "name": "", + "pub_key": [ + 1, + "7B90EA87E7DC0C7145C8C48C08992BE271C7234134343E8A8E8008E617DE7B30" + ] + } + ], + "app_options": { + "accounts": [{ + "pub_key": { + "type": "ed25519", + "data": "6880db93598e283a67c4d88fc67a8858aa2de70f713fe94a5109e29c137100c2" + }, + "coins": [ + { + "denom": "blank", + "amount": 12345 + }, + { + "denom": "ETH", + "amount": 654321 + } + ] + }], + "plugin_options": ["plugin1/key1", "value1", "plugin1/key2", "value2"] + } +} +``` + +Note the array of key-value pairs is now under `app_options.plugin_options` while the `app_options` themselves are well formed. FEATURES: diff --git a/app/app.go b/app/app.go index b783ea5c6c..5aafff04ce 100644 --- a/app/app.go +++ b/app/app.go @@ -60,7 +60,7 @@ func (app *Basecoin) SetOption(key string, value string) string { if plugin == nil { return "Invalid plugin name: " + pluginName } - log.Info("SetOption on plugin", "plugin", pluginName, "key", key, "value", value) + log.Notice("SetOption on plugin", "plugin", pluginName, "key", key, "value", value) return plugin.SetOption(app.state, key, value) } else { // Set option on basecoin diff --git a/app/genesis.go b/app/genesis.go index 8f96aa8bc9..ad8b2b6c9e 100644 --- a/app/genesis.go +++ b/app/genesis.go @@ -2,32 +2,37 @@ package app import ( "encoding/json" - "fmt" "github.com/pkg/errors" "github.com/tendermint/basecoin/types" cmn "github.com/tendermint/go-common" - "github.com/tendermint/go-wire" - tmtypes "github.com/tendermint/tendermint/types" + //tmtypes "github.com/tendermint/tendermint/types" ) func (app *Basecoin) LoadGenesis(path string) error { - tmDoc, appDoc, err := loadGenesis(path) + genDoc, err := loadGenesis(path) if err != nil { return err } - fmt.Println("TMGendoc", tmDoc) - fmt.Println("AppGendoc", appDoc) - app.SetOption("base/chain_id", appDoc.ChainID) - for _, acc := range appDoc.Accounts { + // set chain_id + app.SetOption("base/chain_id", genDoc.ChainID) + + // set accounts + for _, acc := range genDoc.AppOptions.Accounts { accBytes, err := json.Marshal(acc) if err != nil { return err } r := app.SetOption("base/account", string(accBytes)) // TODO: SetOption returns an error - log.Notice("SetOption", "result", r) + log.Notice("Done setting Account via SetOption", "result", r) + } + + // set plugin options + for _, kv := range genDoc.AppOptions.pluginOptions { + r := app.SetOption(kv.Key, kv.Value) + log.Notice("Done setting Plugin key-value pair via SetOption", "result", r, "k", kv.Key, "v", kv.Value) } return nil } @@ -39,32 +44,40 @@ type keyValue struct { // includes tendermint (in the json, we ignore here) type FullGenesisDoc struct { + ChainID string `json:"chain_id"` AppOptions *GenesisDoc `json:"app_options"` } type GenesisDoc struct { - ChainID string `json:"chain_id"` - Accounts []types.Account `json:"accounts"` + Accounts []types.Account `json:"accounts"` + PluginOptions []json.RawMessage `json:"plugin_options"` + + pluginOptions []keyValue // unmarshaled rawmessages } -func loadGenesis(filePath string) (*tmtypes.GenesisDoc, *GenesisDoc, error) { +func loadGenesis(filePath string) (*FullGenesisDoc, error) { bytes, err := cmn.ReadFile(filePath) if err != nil { - return nil, nil, errors.Wrap(err, "loading genesis file") + return nil, errors.Wrap(err, "loading genesis file") } - tmGenesis := new(tmtypes.GenesisDoc) - appGenesis := new(FullGenesisDoc) - // the tendermint genesis is go-wire - err = wire.ReadJSONBytes(bytes, tmGenesis) + // tmGenesis := new(tmtypes.GenesisDoc) + // err = wire.ReadJSONBytes(bytes, tmGenesis) // the basecoin genesis go-data :) - err = json.Unmarshal(bytes, appGenesis) + genDoc := new(FullGenesisDoc) + err = json.Unmarshal(bytes, genDoc) if err != nil { - return nil, nil, errors.Wrap(err, "unmarshaling genesis file") + return nil, errors.Wrap(err, "unmarshaling genesis file") } - return tmGenesis, appGenesis.AppOptions, nil + + pluginOpts, err := parseGenesisList(genDoc.AppOptions.PluginOptions) + if err != nil { + return nil, err + } + genDoc.AppOptions.pluginOptions = pluginOpts + return genDoc, nil } func parseGenesisList(kvz_ []json.RawMessage) (kvz []keyValue, err error) { diff --git a/app/testdata/genesis.json b/app/testdata/genesis.json index 0308716c9c..ee8879fd28 100644 --- a/app/testdata/genesis.json +++ b/app/testdata/genesis.json @@ -1,19 +1,22 @@ -[ - "base/chainID", "foo_bar_chain", - "base/account", { - "pub_key": { - "type": "ed25519", - "data": "6880db93598e283a67c4d88fc67a8858aa2de70f713fe94a5109e29c137100c2" - }, - "coins": [ - { - "denom": "blank", - "amount": 12345 +{ + "chain_id": "foo_bar_chain", + "app_options": { + "accounts": [{ + "pub_key": { + "type": "ed25519", + "data": "6880db93598e283a67c4d88fc67a8858aa2de70f713fe94a5109e29c137100c2" }, - { - "denom": "ETH", - "amount": 654321 - } - ] + "coins": [ + { + "denom": "blank", + "amount": 12345 + }, + { + "denom": "ETH", + "amount": 654321 + } + ] + }], + "plugin_options": ["plugin1/key1", "value1", "plugin1/key2", "value2"] } -] +} diff --git a/cmd/commands/init.go b/cmd/commands/init.go index 695220445c..de60b0b5b8 100644 --- a/cmd/commands/init.go +++ b/cmd/commands/init.go @@ -69,7 +69,7 @@ const privValJSON = `{ const genesisJSON = `{ "app_hash": "", - "chain_id": "test-chain-Ppk1h3", + "chain_id": "test_chain_id", "genesis_time": "0001-01-01T00:00:00.000Z", "validators": [ { @@ -82,7 +82,6 @@ const genesisJSON = `{ } ], "app_options": { - "chain_id": "test_chain_id", "accounts": [{ "pub_key": { "type": "ed25519", diff --git a/demo/data/chain1/genesis.json b/demo/data/chain1/genesis.json index 4b9ab3079a..d50161a5aa 100644 --- a/demo/data/chain1/genesis.json +++ b/demo/data/chain1/genesis.json @@ -13,7 +13,6 @@ } ], "app_options": { - "chain_id": "test_chain_1", "accounts": [ { "pub_key": { diff --git a/demo/data/chain2/genesis.json b/demo/data/chain2/genesis.json index 2079970346..c534617562 100644 --- a/demo/data/chain2/genesis.json +++ b/demo/data/chain2/genesis.json @@ -13,7 +13,6 @@ } ], "app_options": { - "chain_id": "test_chain_2", "accounts": [ { "pub_key": { diff --git a/docs/guide/basecoin-tool.md b/docs/guide/basecoin-tool.md index 7046093d9c..8d87e43f98 100644 --- a/docs/guide/basecoin-tool.md +++ b/docs/guide/basecoin-tool.md @@ -81,7 +81,7 @@ Now we can make a `genesis.json` file and add an account with our public key: ```json [ - "base/chainID", "example-chain", + "base/chain_id", "example-chain", "base/account", { "pub_key": [1, "43AA6C88034F9EB8D2717CA4BBFCBA745EFF19B13EFCD6F339EDBAAAFCD2F7B3"], "coins": [ @@ -95,7 +95,7 @@ Now we can make a `genesis.json` file and add an account with our public key: ``` Here we've granted ourselves `1000000000` units of the `gold` token. -Note that we've also set the `base/chainID` to be `example-chain`. +Note that we've also set the `base/chain_id` to be `example-chain`. All transactions must therefore include the `--chain_id example-chain` in order to make sure they are valid for this chain. Previously, we didn't need this flag because we were using the default chain ID ("test_chain_id"). Now that we're using a custom chain, we need to specify the chain explicitly on the command line. diff --git a/plugins/counter/counter_test.go b/plugins/counter/counter_test.go index 833b18f86d..9c76544bc5 100644 --- a/plugins/counter/counter_test.go +++ b/plugins/counter/counter_test.go @@ -20,7 +20,7 @@ func TestCounterPlugin(t *testing.T) { eyesCli := eyescli.NewLocalClient("", 0) chainID := "test_chain_id" bcApp := app.NewBasecoin(eyesCli) - bcApp.SetOption("base/chainID", chainID) + bcApp.SetOption("base/chain_id", chainID) // t.Log(bcApp.Info()) // Add Counter plugin diff --git a/tests/tmsp/tmsp_test.go b/tests/tmsp/tmsp_test.go index 309af1a697..eec105deda 100644 --- a/tests/tmsp/tmsp_test.go +++ b/tests/tmsp/tmsp_test.go @@ -18,7 +18,7 @@ func TestSendTx(t *testing.T) { eyesCli := eyescli.NewLocalClient("", 0) chainID := "test_chain_id" bcApp := app.NewBasecoin(eyesCli) - bcApp.SetOption("base/chainID", chainID) + bcApp.SetOption("base/chain_id", chainID) // t.Log(bcApp.Info()) test1PrivAcc := types.PrivAccountFromSecret("test1") @@ -64,7 +64,7 @@ func TestSequence(t *testing.T) { eyesCli := eyescli.NewLocalClient("", 0) chainID := "test_chain_id" bcApp := app.NewBasecoin(eyesCli) - bcApp.SetOption("base/chainID", chainID) + bcApp.SetOption("base/chain_id", chainID) // t.Log(bcApp.Info()) // Get the test account From fa5d7b30f24adbe756b3fa9a0939662fba042bdf Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 14 Mar 2017 14:29:12 -0400 Subject: [PATCH 13/19] update docs --- docs/guide/basecoin-tool.md | 88 ++++++++++++++++++++++++------------ docs/guide/example-plugin.md | 8 ++-- docs/guide/ibc.md | 14 +++--- docs/guide/more-examples.md | 19 +++----- 4 files changed, 78 insertions(+), 51 deletions(-) diff --git a/docs/guide/basecoin-tool.md b/docs/guide/basecoin-tool.md index 8d87e43f98..5d4f93a94a 100644 --- a/docs/guide/basecoin-tool.md +++ b/docs/guide/basecoin-tool.md @@ -4,18 +4,36 @@ In previous tutorials we learned the [basics of the `basecoin` CLI](/docs/guides and [how to implement a plugin](/docs/guides/example-plugin). In this tutorial, we provide more details on using the `basecoin` tool. +# Data Directory + +By default, `basecoin` works out of `~/.basecoin`. To change this, set the `BCHOME` environment variable: + +``` +export BCHOME=~/.my_basecoin_data +basecoin init +basecoin start +``` + +or + +``` +BCHOME=~/.my_basecoin_data basecoin init +BCHOME=~/.my_basecoin_data basecoin start +``` + # ABCI Server So far we have run Basecoin and Tendermint in a single process. However, since we use ABCI, we can actually run them in different processes. -First, initialize both Basecoin and Tendermint: +First, initialize them: ``` basecoin init -tendermint init ``` -In one window, run +This will create a single `genesis.json` file in `~/.basecoin` with the information for both Basecoin and Tendermint. + +Now, In one window, run ``` basecoin start --without-tendermint @@ -24,17 +42,24 @@ basecoin start --without-tendermint and in another, ``` -tendermint node +TMROOT=~/.basecoin tendermint node ``` You should see Tendermint start making blocks! +Alternatively, you could ignore the Tendermint details in `~/.basecoin/genesis.json` and use a separate directory by running: + +``` +tendermint init +tendermint node +``` + +For more details on using `tendermint`, see [the guide](https://tendermint.com/docs/guides/using-tendermint). # Keys and Genesis In previous tutorials we used `basecoin init` to initialize `~/.basecoin` with the default configuration. -This command creates files both for Tendermint and for Basecoin. -The Tendermint files are stored in `~/.basecoin/tendermint`, and are the same type of files that would exist in `~/.tendermint` after running `tendermint init`. +This command creates files both for Tendermint and for Basecoin, and a single `genesis.json` file for both of them. For more information on these files, see the [guide to using tendermint](https://tendermint.com/docs/guides/using-tendermint). Now let's make our own custom Basecoin data. @@ -59,19 +84,19 @@ Now, let's create a new private key: basecoin key new > $BCHOME/key.json ``` -Here's what my `key.json looks like: +Here's what my `key.json looks like (TODO: change `keys` so it looks like this ...): ```json { - "address": "15F591CA434CFCCBDEC1D206F3ED3EBA207BFE7D", - "priv_key": [ - 1, - "737C629667A9EAADBB8E7CF792D5A8F63AA4BB51E06457DDD7FDCC6D7412AAAD43AA6C88034F9EB8D2717CA4BBFCBA745EFF19B13EFCD6F339EDBAAAFCD2F7B3" - ], - "pub_key": [ - 1, - "43AA6C88034F9EB8D2717CA4BBFCBA745EFF19B13EFCD6F339EDBAAAFCD2F7B3" - ] + "address": "4EGEhnqOw/gX326c7KARUkY1kic=", + "pub_key": { + "type": "ed25519", + "data": "a20d48b5caff42892d0ac67ccdeee38c1dcbbe42b15b486057d16244541e8141" + }, + "priv_key": { + "type": "ed25519", + "data": "654c845f4b36d1a881deb0ff09381165d3ccd156b4aabb5b51267e91f1d024a5a20d48b5caff42892d0ac67ccdeee38c1dcbbe42b15b486057d16244541e8141" + } } ``` @@ -80,26 +105,33 @@ Yours will look different - each key is randomly derrived. Now we can make a `genesis.json` file and add an account with our public key: ```json -[ - "base/chain_id", "example-chain", - "base/account", { - "pub_key": [1, "43AA6C88034F9EB8D2717CA4BBFCBA745EFF19B13EFCD6F339EDBAAAFCD2F7B3"], - "coins": [ - { - "denom": "gold", - "amount": 1000000000, - } - ] +{ + "chain_id": "example-chain", + "app_options": { + "accounts": [{ + "pub_key": { + "type": "ed25519", + "data": "a20d48b5caff42892d0ac67ccdeee38c1dcbbe42b15b486057d16244541e8141" + }, + "coins": [ + { + "denom": "gold", + "amount": 1000000000 + } + ] + }] } -] +} ``` Here we've granted ourselves `1000000000` units of the `gold` token. -Note that we've also set the `base/chain_id` to be `example-chain`. +Note that we've also set the `chain_id` to be `example-chain`. All transactions must therefore include the `--chain_id example-chain` in order to make sure they are valid for this chain. Previously, we didn't need this flag because we were using the default chain ID ("test_chain_id"). Now that we're using a custom chain, we need to specify the chain explicitly on the command line. +Note we have also left out the details of the tendermint genesis. These are documented in the [tendermint guide](https://tendermint.com/docs/guides/using-tendermint). + # Reset diff --git a/docs/guide/example-plugin.md b/docs/guide/example-plugin.md index 48da0da730..31aa3479c2 100644 --- a/docs/guide/example-plugin.md +++ b/docs/guide/example-plugin.md @@ -319,7 +319,7 @@ example-plugin start In another window, we can try sending some transactions: ``` -example-plugin tx send --to 0x1B1BE55F969F54064628A63B9559E7C21C925165 --amount 100gold +example-plugin tx send --to 0x1DA7C74F9C219229FD54CC9F7386D5A3839F0090 --amount 100mycoin ``` Ok, so that's how we can send a `SendTx` transaction using our `example-plugin` CLI, @@ -327,13 +327,13 @@ but we were already able to do that with the `basecoin` CLI. With our new CLI, however, we can also send an `ExamplePluginTx`: ``` -example-plugin tx example --amount 1gold +example-plugin tx example --amount 1mycoin ``` The transaction is invalid! That's because we didn't specify the `--valid` flag: ``` -example-plugin tx example --valid --amount 1gold +example-plugin tx example --valid --amount 1mycoin ``` Tada! We successfuly created, signed, broadcast, and processed our custom transaction type. @@ -353,7 +353,7 @@ which contains only an integer. If we send another transaction, and then query again, we'll see the value increment: ``` -example-plugin tx example --valid --amount 1gold +example-plugin tx example --valid --amount 1mycoin example-plugin query ExamplePlugin.State ``` diff --git a/docs/guide/ibc.md b/docs/guide/ibc.md index e67dcda1cf..9b88c416ba 100644 --- a/docs/guide/ibc.md +++ b/docs/guide/ibc.md @@ -194,15 +194,15 @@ The relevant data is now in the `data` directory. We can start the two chains as follows: ``` -TMROOT=./data/chain1/tendermint tendermint node &> chain1_tendermint.log & -BCHOME=./data/chain1/basecoin basecoin start --without-tendermint &> chain1_basecoin.log & +TMROOT=./data/chain1 tendermint node &> chain1_tendermint.log & +BCHOME=./data/chain1 basecoin start --without-tendermint &> chain1_basecoin.log & ``` and ``` -TMROOT=./data/chain2/tendermint tendermint node --node_laddr tcp://localhost:36656 --rpc_laddr tcp://localhost:36657 --proxy_app tcp://localhost:36658 &> chain2_tendermint.log & -BCHOME=./data/chain2/basecoin basecoin start --without-tendermint --address tcp://localhost:36658 &> chain2_basecoin.log & +TMROOT=./data/chain2 tendermint node --node_laddr tcp://localhost:36656 --rpc_laddr tcp://localhost:36657 --proxy_app tcp://localhost:36658 &> chain2_tendermint.log & +BCHOME=./data/chain2 basecoin start --without-tendermint --address tcp://localhost:36658 &> chain2_basecoin.log & ``` Note how we refer to the relevant data directories. Also note how we have to set the various addresses for the second node so as not to conflict with the first. @@ -224,8 +224,8 @@ For the sake of convenience, let's first set some environment variables: export CHAIN_ID1=test_chain_1 export CHAIN_ID2=test_chain_2 -export CHAIN_FLAGS1="--chain_id $CHAIN_ID1 --from ./data/chain1/basecoin/key.json" -export CHAIN_FLAGS2="--chain_id $CHAIN_ID2 --from ./data/chain2/basecoin/key.json --node tcp://localhost:36657" +export CHAIN_FLAGS1="--chain_id $CHAIN_ID1 --from ./data/chain1/key.json" +export CHAIN_FLAGS2="--chain_id $CHAIN_ID2 --from ./data/chain2/key.json --node tcp://localhost:36657" export BCHOME="." ``` @@ -233,7 +233,7 @@ export BCHOME="." Let's start by registering `test_chain_1` on `test_chain_2`: ``` -basecoin tx ibc --amount 10mycoin $CHAIN_FLAGS2 register --chain_id $CHAIN_ID1 --genesis ./data/chain1/tendermint/genesis.json +basecoin tx ibc --amount 10mycoin $CHAIN_FLAGS2 register --chain_id $CHAIN_ID1 --genesis ./data/chain1/genesis.json ``` Now we can create the outgoing packet on `test_chain_1`: diff --git a/docs/guide/more-examples.md b/docs/guide/more-examples.md index 7df37ca0be..1fc1b545c4 100644 --- a/docs/guide/more-examples.md +++ b/docs/guide/more-examples.md @@ -1,19 +1,14 @@ # Plugin Examples -Now that we've seen [how to write a simple plugin](example-plugin.md) -and taken a look at [how the plugin system is designed](plugin-design.md), +Now that we've seen [how to write a simple plugin](/docs/guide/example-plugin.md) +and taken a look at [how the plugin system is designed](/docs/guide/plugin-design.md), it's time for some more advanced examples. For now, most examples are contained in the `github.com/tendermint/basecoin-examples` repository. In particular, we have the following: -1. [Mintcoin][0] - a plugin for issuing new Basecoin tokens -2. [Trader][1] - a plugin for adding escrow and options features to Basecoin -3. [Stakecoin][2] - a plugin for bonding and unbonding Tendermint validators and updating the validator set accordingly -4. [PayToVote][3] - a plugin for creating issues and voting on them -5. [IBC][4] - a plugin for facilitating InterBlockchain Communication -[0]: https://github.com/tendermint/basecoin-examples/tree/develop/mintcoin -[1]: https://github.com/tendermint/basecoin-examples/tree/develop/trader -[2]: https://github.com/tendermint/basecoin-examples/tree/develop/stake -[3]: https://github.com/tendermint/basecoin-examples/tree/develop/paytovote -[4]: ibc.md +1. [Mintcoin](https://github.com/tendermint/basecoin-examples/tree/develop/mintcoin) - a plugin for issuing new Basecoin tokens +2. [Trader](https://github.com/tendermint/basecoin-examples/tree/develop/trader) - a plugin for adding escrow and options features to Basecoin +3. [Stakecoin](https://github.com/tendermint/basecoin-examples/tree/develop/stake) - a plugin for bonding and unbonding Tendermint validators and updating the validator set accordingly +4. [PayToVote](https://github.com/tendermint/basecoin-examples/tree/develop/paytovote) - a plugin for creating issues and voting on them +5. [IBC](/docs/guide/ibc.md) - a plugin for facilitating InterBlockchain Communication From de5506dd8f982c1f3cf88bc9fcc4aea57504e944 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 14 Mar 2017 17:28:49 -0400 Subject: [PATCH 14/19] fix keys and glide --- cmd/commands/init.go | 32 ++++++++++++------------- cmd/commands/key.go | 47 +++++++++++++++++++++++++++++-------- cmd/commands/start.go | 24 ++++++++++++------- cmd/commands/tx.go | 4 ++-- demo/data/chain1/key.json | 16 ++++++------- demo/data/chain2/key.json | 16 ++++++------- docs/guide/basecoin-tool.md | 2 +- glide.lock | 33 +++++++++++++------------- glide.yaml | 18 +++++++------- state/state.go | 6 +++-- 10 files changed, 118 insertions(+), 80 deletions(-) diff --git a/cmd/commands/init.go b/cmd/commands/init.go index de60b0b5b8..e60e7d1306 100644 --- a/cmd/commands/init.go +++ b/cmd/commands/init.go @@ -99,24 +99,24 @@ const genesisJSON = `{ const key1JSON = `{ "address": "1B1BE55F969F54064628A63B9559E7C21C925165", - "priv_key": [ - 1, - "C70D6934B4F55F1B7BC33B56B9CA8A2061384AFC19E91E44B40C4BBA182953D1619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279" - ], - "pub_key": [ - 1, - "619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279" - ] + "priv_key": { + "type": "ed25519", + "data": "C70D6934B4F55F1B7BC33B56B9CA8A2061384AFC19E91E44B40C4BBA182953D1619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279" + }, + "pub_key": { + "type": "ed25519", + "data": "619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279" + } }` const key2JSON = `{ "address": "1DA7C74F9C219229FD54CC9F7386D5A3839F0090", - "priv_key": [ - 1, - "34BAE9E65CE8245FAD035A0E3EED9401BDE8785FFB3199ACCF8F5B5DDF7486A8352195DA90CB0B90C24295B90AEBA25A5A71BC61BAB2FE2387241D439698B7B8" - ], - "pub_key": [ - 1, - "352195DA90CB0B90C24295B90AEBA25A5A71BC61BAB2FE2387241D439698B7B8" - ] + "priv_key": { + "type": "ed25519", + "data": "34BAE9E65CE8245FAD035A0E3EED9401BDE8785FFB3199ACCF8F5B5DDF7486A8352195DA90CB0B90C24295B90AEBA25A5A71BC61BAB2FE2387241D439698B7B8" + }, + "pub_key": { + "type": "ed25519", + "data": "352195DA90CB0B90C24295B90AEBA25A5A71BC61BAB2FE2387241D439698B7B8" + } }` diff --git a/cmd/commands/key.go b/cmd/commands/key.go index 714958a07d..801cefef16 100644 --- a/cmd/commands/key.go +++ b/cmd/commands/key.go @@ -1,15 +1,18 @@ package commands import ( + "encoding/hex" + "encoding/json" "fmt" "io/ioutil" "path" + "strings" "github.com/urfave/cli" cmn "github.com/tendermint/go-common" "github.com/tendermint/go-crypto" - "github.com/tendermint/go-wire" + // "github.com/tendermint/go-wire" ) var ( @@ -32,18 +35,37 @@ var ( func cmdNewKey(c *cli.Context) error { key := genKey() - keyJSON := wire.JSONBytesPretty(key) - fmt.Println(string(keyJSON)) + // keyJSON := wire.JSONBytesPretty(key) + keyJSON, err := json.MarshalIndent(key, "", "\t") + if err != nil { + return err + } + fmt.Println(keyJSON) return nil } //--------------------------------------------- // simple implementation of a key +type Address [20]byte + +func (a Address) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%x"`, a[:])), nil +} + +func (a *Address) UnmarshalJSON(addrHex []byte) error { + addr, err := hex.DecodeString(strings.Trim(string(addrHex), `"`)) + if err != nil { + return err + } + copy(a[:], addr) + return nil +} + type Key struct { - Address []byte `json:"address"` - PubKey crypto.PubKey `json:"pub_key"` - PrivKey crypto.PrivKey `json:"priv_key"` + Address Address `json:"address"` + PubKey crypto.PubKeyS `json:"pub_key"` + PrivKey crypto.PrivKeyS `json:"priv_key"` } // Implements Signer @@ -54,10 +76,13 @@ func (k *Key) Sign(msg []byte) crypto.Signature { // Generates a new validator with private key. func genKey() *Key { privKey := crypto.GenPrivKeyEd25519() + addrBytes := privKey.PubKey().Address() + var addr Address + copy(addr[:], addrBytes) return &Key{ - Address: privKey.PubKey().Address(), - PubKey: privKey.PubKey(), - PrivKey: privKey, + Address: addr, + PubKey: crypto.PubKeyS{privKey.PubKey()}, + PrivKey: crypto.PrivKeyS{privKey}, } } @@ -67,7 +92,9 @@ func LoadKey(keyFile string) *Key { if err != nil { cmn.Exit(err.Error()) } - key := wire.ReadJSON(&Key{}, keyJSONBytes, &err).(*Key) + key := new(Key) + err = json.Unmarshal(keyJSONBytes, key) + // key := wire.ReadJSON(&Key{}, keyJSONBytes, &err).(*Key) if err != nil { cmn.Exit(cmn.Fmt("Error reading key from %v: %v\n", filePath, err)) } diff --git a/cmd/commands/start.go b/cmd/commands/start.go index 97946384a3..ba9194ee17 100644 --- a/cmd/commands/start.go +++ b/cmd/commands/start.go @@ -76,17 +76,25 @@ func cmdStart(c *cli.Context) error { basecoinApp.RegisterPlugin(p.newPlugin()) } - // If genesis file exists, set key-value options - genesisFile := path.Join(basecoinDir, "genesis.json") - if _, err := os.Stat(genesisFile); err == nil { - err := basecoinApp.LoadGenesis(genesisFile) - if err != nil { - return errors.New(cmn.Fmt("%+v", err)) + fmt.Println("CHAIN ID", basecoinApp.GetState().GetChainID()) + + // if chain_id has not been set yet, load the genesis. + // else, assume it's been loaded + if basecoinApp.GetState().GetChainID() == "" { + // If genesis file exists, set key-value options + genesisFile := path.Join(basecoinDir, "genesis.json") + if _, err := os.Stat(genesisFile); err == nil { + err := basecoinApp.LoadGenesis(genesisFile) + if err != nil { + return errors.New(cmn.Fmt("%+v", err)) + } + } else { + fmt.Printf("No genesis file at %s, skipping...\n", genesisFile) } - } else { - fmt.Printf("No genesis file at %s, skipping...\n", genesisFile) } + fmt.Println("CHAIN ID", basecoinApp.GetState().GetChainID()) + if c.Bool("without-tendermint") { // run just the abci app/server if err := startBasecoinABCI(c, basecoinApp); err != nil { diff --git a/cmd/commands/tx.go b/cmd/commands/tx.go index b4a900832e..3c5cebd837 100644 --- a/cmd/commands/tx.go +++ b/cmd/commands/tx.go @@ -86,7 +86,7 @@ func cmdSendTx(c *cli.Context) error { privKey := LoadKey(fromFile) // get the sequence number for the tx - sequence, err := getSeq(c, privKey.Address) + sequence, err := getSeq(c, privKey.Address[:]) if err != nil { return err } @@ -145,7 +145,7 @@ func AppTx(c *cli.Context, name string, data []byte) error { privKey := LoadKey(fromFile) - sequence, err := getSeq(c, privKey.Address) + sequence, err := getSeq(c, privKey.Address[:]) if err != nil { return err } diff --git a/demo/data/chain1/key.json b/demo/data/chain1/key.json index e610ba89d2..751dc858f0 100644 --- a/demo/data/chain1/key.json +++ b/demo/data/chain1/key.json @@ -1,12 +1,12 @@ { "address": "D397BC62B435F3CF50570FBAB4340FE52C60858F", - "priv_key": [ - 1, - "39E75AA1CF7BC710585977EFC375CD1730519186BD231478C339F2819C3C26E7B3588BDC92015ED3CDB6F57A86379E8C79A7111063610B7E625487C76496F4DF" - ], - "pub_key": [ - 1, - "B3588BDC92015ED3CDB6F57A86379E8C79A7111063610B7E625487C76496F4DF" - ] + "priv_key": { + "type": "ed25519", + "data": "39E75AA1CF7BC710585977EFC375CD1730519186BD231478C339F2819C3C26E7B3588BDC92015ED3CDB6F57A86379E8C79A7111063610B7E625487C76496F4DF" + }, + "pub_key": { + "type": "ed25519", + "data": "B3588BDC92015ED3CDB6F57A86379E8C79A7111063610B7E625487C76496F4DF" + } } diff --git a/demo/data/chain2/key.json b/demo/data/chain2/key.json index 90761696de..6aa8b7965f 100644 --- a/demo/data/chain2/key.json +++ b/demo/data/chain2/key.json @@ -1,11 +1,11 @@ { "address": "053BA0F19616AFF975C8756A2CBFF04F408B4D47", - "priv_key": [ - 1, - "22920C428043D869987F253D7C9B2305E7010642C40CE88A52C9F6CE5ACC42080628C8E6C2D50B15764B443394E06C6A64F3082CE966A2A8C1A55A4D63D0FC5D" - ], - "pub_key": [ - 1, - "0628C8E6C2D50B15764B443394E06C6A64F3082CE966A2A8C1A55A4D63D0FC5D" - ] + "priv_key": { + "type": "ed25519", + "data": "22920C428043D869987F253D7C9B2305E7010642C40CE88A52C9F6CE5ACC42080628C8E6C2D50B15764B443394E06C6A64F3082CE966A2A8C1A55A4D63D0FC5D" + }, + "pub_key": { + "type": "ed25519", + "data": "0628C8E6C2D50B15764B443394E06C6A64F3082CE966A2A8C1A55A4D63D0FC5D" + } } diff --git a/docs/guide/basecoin-tool.md b/docs/guide/basecoin-tool.md index 5d4f93a94a..8af94cdee0 100644 --- a/docs/guide/basecoin-tool.md +++ b/docs/guide/basecoin-tool.md @@ -84,7 +84,7 @@ Now, let's create a new private key: basecoin key new > $BCHOME/key.json ``` -Here's what my `key.json looks like (TODO: change `keys` so it looks like this ...): +Here's what my `key.json looks like: ```json { diff --git a/glide.lock b/glide.lock index 2d3ddd34e4..d53e80837b 100644 --- a/glide.lock +++ b/glide.lock @@ -1,34 +1,34 @@ -hash: 3869944d14a8df914ffcad02c2ef3548173daba51c5ea697767f8af77c07b348 -updated: 2017-03-06T05:37:03.828355251-05:00 +hash: c71c0d6c409bfddb4c4b471d8445f59cebd2cd41e1635a90d6facd81bd09a5e0 +updated: 2017-03-14T17:02:44.512359631-04:00 imports: - name: github.com/btcsuite/btcd - version: d06c0bb181529331be8f8d9350288c420d9e60e4 + version: 583684b21bfbde9b5fc4403916fd7c807feb0289 subpackages: - btcec - name: github.com/BurntSushi/toml - version: 99064174e013895bbd9b025c31100bd1d9b590ca + version: e643e9ef00b049d75de26e61109c5ea01885cd21 - name: github.com/ebuchman/fail-test - version: 13f91f14c826314205cdbed1ec8ac8bf08e03381 + version: 95f809107225be108efcf10a3509e4ea6ceef3c4 - name: github.com/go-stack/stack version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82 - name: github.com/golang/protobuf - version: 8ee79997227bf9b34611aee7946ae64735e6fd93 + version: c9c7427a2a70d2eb3bafa0ab2dc163e45f143317 subpackages: - proto - name: github.com/golang/snappy - version: d9eb7a3d35ec988b8585d4a0068e462c27d28380 + version: 553a641470496b2327abcac10b36396bd98e45c9 - name: github.com/gorilla/websocket version: 3ab3a8b8831546bd18fd182c20687ca853b2bb13 - name: github.com/jmhodges/levigo version: c42d9e0ca023e2198120196f842701bb4c55d7b9 - name: github.com/mattn/go-colorable - version: d228849504861217f796da67fae4f6e347643f15 + version: a392f450ea64cee2b268dfaacdc2502b50a22b18 - name: github.com/mattn/go-isatty - version: 30a891c33c7cde7b02a981314b4228ec99380cca + version: 57fdcb988a5c543893cc61bce354a6e24ab70022 - name: github.com/pkg/errors - version: 645ef00459ed84a119197bfb8d8205042c6df63d + version: bfd5150e4e41705ded2129ec33379de1cb90b513 - name: github.com/syndtr/goleveldb - version: 23851d93a2292dcc56e71a18ec9e0624d84a0f65 + version: 3c5717caf1475fd25964109a0fc640bd150fce43 subpackages: - leveldb - leveldb/cache @@ -43,7 +43,7 @@ imports: - leveldb/table - leveldb/util - name: github.com/tendermint/abci - version: 1236e8fb6eee3a63909f4014a8e84385ead7933d + version: af792eac777de757cd496349a5f6b5313738fcbc subpackages: - client - example/dummy @@ -117,7 +117,7 @@ imports: - name: github.com/urfave/cli version: 0bdeddeeb0f650497d603c4ad7b20cfe685682f6 - name: golang.org/x/crypto - version: 7c6cc321c680f03b9ef0764448e780704f486b51 + version: 728b753d0135da6801d45a38e6f43ff55779c5c2 subpackages: - curve25519 - nacl/box @@ -128,7 +128,7 @@ imports: - ripemd160 - salsa20/salsa - name: golang.org/x/net - version: 61557ac0112b576429a0df080e1c2cef5dfbb642 + version: a6577fac2d73be281a500b310739095313165611 subpackages: - context - http2 @@ -138,16 +138,17 @@ imports: - lex/httplex - trace - name: golang.org/x/sys - version: d75a52659825e75fff6158388dddc6a5b04f9ba5 + version: 99f16d856c9836c42d24e7ab64ea72916925fa97 subpackages: - unix - name: google.golang.org/grpc - version: cbcceb2942a489498cf22b2f918536e819d33f0a + version: 0713829b980f4ddd276689a36235c5fcc82a21bf subpackages: - codes - credentials - grpclog - internal + - keepalive - metadata - naming - peer diff --git a/glide.yaml b/glide.yaml index ecf4f151b4..d607c41cb4 100644 --- a/glide.yaml +++ b/glide.yaml @@ -1,22 +1,22 @@ package: github.com/tendermint/basecoin import: - package: github.com/tendermint/go-common - version: develop + version: master - package: github.com/tendermint/go-crypto - version: develop + version: master - package: github.com/tendermint/go-events - version: develop + version: master - package: github.com/tendermint/go-logger - version: develop + version: master - package: github.com/tendermint/go-rpc - version: develop + version: master - package: github.com/tendermint/go-wire - version: develop + version: master - package: github.com/tendermint/merkleeyes - version: develop + version: master - package: github.com/tendermint/tendermint - version: develop + version: master - package: github.com/tendermint/abci - version: develop + version: master - package: github.com/gorilla/websocket version: v1.1.0 diff --git a/state/state.go b/state/state.go index 7fb6c48bac..68a7c36243 100644 --- a/state/state.go +++ b/state/state.go @@ -28,12 +28,14 @@ func NewState(store types.KVStore) *State { func (s *State) SetChainID(chainID string) { s.chainID = chainID + s.store.Set([]byte("base/chain_id"), []byte(chainID)) } func (s *State) GetChainID() string { - if s.chainID == "" { - PanicSanity("Expected to have set SetChainID") + if s.chainID != "" { + return s.chainID } + s.chainID = string(s.store.Get([]byte("base/chain_id"))) return s.chainID } From 43beb174d68f5088582fc7491c4af19b31ae021b Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 15 Mar 2017 01:17:12 -0400 Subject: [PATCH 15/19] README: tool -> basics --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55f46c0b95..0c15ed0576 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ See the [install guide](/docs/guide/install.md) for more details. ## Guide -1. Getting started with the [Basecoin tool](/docs/guide/basecoin-basics.md) +1. Getting started with the [Basecoin basics](/docs/guide/basecoin-basics.md) 1. Learn more about [Basecoin's design](/docs/guide/basecoin-design.md) 1. Extend Basecoin [using the plugin system](/docs/guide/example-plugin.md) 1. Learn more about [plugin design](/docs/guide/plugin-design.md) From c0f093551f5ea6bbb764e0815920ef0b1b453ef7 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 16 Mar 2017 23:09:49 -0400 Subject: [PATCH 16/19] sign bytes bug fix --- types/tx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/tx.go b/types/tx.go index 5dcec7dacc..285902db6f 100644 --- a/types/tx.go +++ b/types/tx.go @@ -152,7 +152,7 @@ func (tx *SendTx) SignBytes(chainID string) []byte { signBytes := wire.BinaryBytes(chainID) sigz := make([]crypto.Signature, len(tx.Inputs)) for i, input := range tx.Inputs { - sigz[i] = input.Signature + sigz[i] = input.Signature.Signature tx.Inputs[i].Signature.Signature = nil } signBytes = append(signBytes, wire.BinaryBytes(tx)...) From 9fc2668c37e7e6e68d2abcd1f050440d0731713a Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 18 Mar 2017 20:48:48 -0400 Subject: [PATCH 17/19] clean up some logging --- cmd/commands/start.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/cmd/commands/start.go b/cmd/commands/start.go index ba9194ee17..1e6861ac06 100644 --- a/cmd/commands/start.go +++ b/cmd/commands/start.go @@ -76,8 +76,6 @@ func cmdStart(c *cli.Context) error { basecoinApp.RegisterPlugin(p.newPlugin()) } - fmt.Println("CHAIN ID", basecoinApp.GetState().GetChainID()) - // if chain_id has not been set yet, load the genesis. // else, assume it's been loaded if basecoinApp.GetState().GetChainID() == "" { @@ -93,16 +91,15 @@ func cmdStart(c *cli.Context) error { } } - fmt.Println("CHAIN ID", basecoinApp.GetState().GetChainID()) - + chainID := basecoinApp.GetState().GetChainID() if c.Bool("without-tendermint") { + log.Notice("Starting Basecoin without Tendermint", "chain_id", chainID) // run just the abci app/server - if err := startBasecoinABCI(c, basecoinApp); err != nil { - return err - } + return startBasecoinABCI(c, basecoinApp) } else { + log.Notice("Starting Basecoin with Tendermint", "chain_id", chainID) // start the app with tendermint in-process - startTendermint(basecoinDir, basecoinApp) + return startTendermint(basecoinDir, basecoinApp) } return nil @@ -123,7 +120,7 @@ func startBasecoinABCI(c *cli.Context, basecoinApp *app.Basecoin) error { } -func startTendermint(dir string, basecoinApp *app.Basecoin) { +func startTendermint(dir string, basecoinApp *app.Basecoin) error { // Get configuration tmConfig := tmcfg.GetConfig(dir) @@ -136,11 +133,16 @@ func startTendermint(dir string, basecoinApp *app.Basecoin) { privValidator := tmtypes.LoadOrGenPrivValidator(privValidatorFile) n := node.NewNode(tmConfig, privValidator, proxy.NewLocalClientCreator(basecoinApp)) - n.Start() + _, err := n.Start() + if err != nil { + return err + } // Wait forever cmn.TrapSignal(func() { // Cleanup n.Stop() }) + + return nil } From 06a8478a7042fc1109db46753432510485c0c1fc Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Thu, 23 Mar 2017 18:07:31 -0400 Subject: [PATCH 18/19] update changelog and remove dead wire code --- CHANGELOG.md | 3 ++- cmd/commands/key.go | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df585e79fa..26d1c87aa4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 0.3.0 (March 14, 2017) +## 0.3.0 (March 23, 2017) BREAKING CHANGES: @@ -47,6 +47,7 @@ To start just the ABCI app/server, use `basecoin start --without-tendermint`. ``` Note the array of key-value pairs is now under `app_options.plugin_options` while the `app_options` themselves are well formed. +We also changed `chainID` to `chain_id` and consolidated to have just one of them. FEATURES: diff --git a/cmd/commands/key.go b/cmd/commands/key.go index 801cefef16..b492eb94bc 100644 --- a/cmd/commands/key.go +++ b/cmd/commands/key.go @@ -12,7 +12,6 @@ import ( cmn "github.com/tendermint/go-common" "github.com/tendermint/go-crypto" - // "github.com/tendermint/go-wire" ) var ( @@ -35,7 +34,6 @@ var ( func cmdNewKey(c *cli.Context) error { key := genKey() - // keyJSON := wire.JSONBytesPretty(key) keyJSON, err := json.MarshalIndent(key, "", "\t") if err != nil { return err @@ -94,7 +92,6 @@ func LoadKey(keyFile string) *Key { } key := new(Key) err = json.Unmarshal(keyJSONBytes, key) - // key := wire.ReadJSON(&Key{}, keyJSONBytes, &err).(*Key) if err != nil { cmn.Exit(cmn.Fmt("Error reading key from %v: %v\n", filePath, err)) } From f156eb5bbd0b79446b6eb3cb5432ec753f0ad8aa Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Thu, 23 Mar 2017 18:15:00 -0400 Subject: [PATCH 19/19] v0.3.0 --- version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version/version.go b/version/version.go index 0f685af284..3a114fc238 100644 --- a/version/version.go +++ b/version/version.go @@ -1,7 +1,7 @@ package version const Maj = "0" -const Min = "2" +const Min = "3" const Fix = "0" const Version = Maj + "." + Min + "." + Fix