From 9b7ba69a87e116905d2fcabc3c9a6b28933bc507 Mon Sep 17 00:00:00 2001 From: Peter Bourgon Date: Mon, 22 Oct 2018 15:03:55 -0700 Subject: [PATCH] Building and running --- .gitignore | 1 + Makefile | 33 +++++++++++++ README.md | 74 +++++++++++++++++++++++++++--- bootstrap_1.fish => bootstrap_1.sh | 38 ++++++--------- bootstrap_3.fish | 73 ----------------------------- bootstrap_3.sh | 68 +++++++++++++++++++++++++++ cmd/tendermint-cas-demo/main.go | 4 +- 7 files changed, 185 insertions(+), 106 deletions(-) create mode 100644 Makefile rename bootstrap_1.fish => bootstrap_1.sh (58%) delete mode 100755 bootstrap_3.fish create mode 100755 bootstrap_3.sh diff --git a/.gitignore b/.gitignore index c70dde3..2ee78ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +tendermint-cas-demo tendermint_* *.json diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fcc1c55 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +os = $(shell uname | tr '[A-Z]' '[a-z]') +arch = $(shell uname -m | sed 's/x86_64/amd64/') +tendermint_version = 0.25.0 +tendermint_binary = tendermint_${tendermint_version}_${os}_${arch} +tendermint_archive = ${tendermint_binary}.zip + +tendermint-cas-demo: + @go build ./cmd/tendermint-cas-demo + +${tendermint_binary}: ${tendermint_archive} + @unzip -o $< + @mv tendermint $@ + @touch $@ + +${tendermint_archive}: + @echo downloading ${tendermint_archive}... + @curl -o $@ -Ss -L https://github.com/tendermint/tendermint/releases/download/v${tendermint_version}/${tendermint_archive} + @touch $@ + +.PHONY: bootstrap_1 +bootstrap_1: ${tendermint_binary} tendermint-cas-demo + @./bootstrap_1.sh ./${tendermint_binary} + +.PHONY: bootstrap_3 +bootstrap_3: ${tendermint_binary} tendermint-cas-demo + @./bootstrap_3.sh ./${tendermint_binary} + +.PHONY: clean +clean: + @rm -rf tendermint-cas-demo + @rm -rf ${tendermint_binary} ${tendermint_archive} + @rm -rf tendermint_zero/ tendermint_{a,b,c}/ + @rm -rf zero.json {a,b,c}.json diff --git a/README.md b/README.md index 1bb7248..32ef5a8 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Tendermint ABCI, implementing a key-value store with a compare-and-swap API. 1. [The abci-cli](#the-abci-cli) 1. [System architecture](#system-architecture) 1. [Operations](#operations) -1. [Conclusion](#conclusion) +1. [Building and running](#building-and-running) ## The goal @@ -556,12 +556,72 @@ itself and its validators. The helper scripts [bootstrap_1][bootstrap1] and clusters on the local machine respectively. Studying them should give you a good start toward scripting your own deployment. -[bootstrap1]: https://github.com/6thc/tendermint-cas-demo/blob/master/bootstrap_1.fish -[bootstrap3]: https://github.com/6thc/tendermint-cas-demo/blob/master/bootstrap_3.fish +[bootstrap1]: https://github.com/6thc/tendermint-cas-demo/blob/master/bootstrap_1.sh +[bootstrap3]: https://github.com/6thc/tendermint-cas-demo/blob/master/bootstrap_3.sh -## Conclusion +## Building and running -Thanks for your time and attention; I hope it's been helpful. If you have any -further questions, or things in this repo don't work as expected, please file an -issue. +Building this repository requires [a working Go installation](https://golang.org). +Most operating system package managers ship a reasonably up-to-date version of the +Go development environment. If you're on a Mac and using Homebrew, I recommend + +``` +$ brew install go +``` + +Clone this repo into the correct location in your GOPATH. + +``` +$ mkdir -p $(go env GOPATH)/src/github.com/6thc +$ cd $(go env GOPATH)/src/github.com/6thc +$ git clone git@github.com:6thc/tendermint-cas-demo +$ cd tendermint-cas-demo +``` + +Then, build the binary. + +``` +$ make +$ ./tendermint-cas-demo -h +USAGE + tendermint-cas-demo [flags] + +FLAGS + -api-addr 127.0.0.1:8081 HTTP API address + -app-file db.json application persistence file + -app-verbose false verbose logging of application information + -tendermint-dir tendermint Tendermint directory (config, data, etc.) + -tendermint-verbose false verbose logging of Tendermint information +``` + +You can also use the Makefile to bootstrap a 1- or 3-node-cluster on your local +machine. Once everything is set up, it will print instructions on how to start +the cluster. + +``` +$ make bootstrap_3 +downloading tendermint_0.25.0_darwin_amd64.zip... +Archive: tendermint_0.25.0_darwin_amd64.zip +tendermint_0c9c3292c918617624f6f3fbcd95eceade18bcd5_darwin_amd64 + extracting: tendermint +clearing any old state... +initializing three nodes... +capturing validators... +capturing peer addresses... +building a common genesis file... +writing common genesis file... +producing config files... +now you can run three nodes + + ./tendermint-cas-demo -api-addr 127.0.0.1:8081 -app-file a.json -tendermint-dir tendermint_a + ./tendermint-cas-demo -api-addr 127.0.0.1:8082 -app-file b.json -tendermint-dir tendermint_b + ./tendermint-cas-demo -api-addr 127.0.0.1:8083 -app-file c.json -tendermint-dir tendermint_c + +other fun things to try + + watch -n1 -- cat ?.json # watch state being updated + curl -Ss -XPOST 'localhost:8081/x?new=one' # set x=one + curl -Ss -XPOST 'localhost:8082/x?old=one&new=two' # set x=two + curl -Ss -XGET 'localhost:8083/x' # get x +``` diff --git a/bootstrap_1.fish b/bootstrap_1.sh similarity index 58% rename from bootstrap_1.fish rename to bootstrap_1.sh index c81e71d..142c041 100755 --- a/bootstrap_1.fish +++ b/bootstrap_1.sh @@ -1,33 +1,23 @@ -#!/usr/bin/env fish +#!/usr/bin/env sh -function prereqs - echo - echo " Download Tendermint v0.25.0 for your system from" - echo " https://github.com/tendermint/tendermint/releases/tag/v0.25.0" - echo " and place the tendermint binary in your PATH." - echo -end +set -e -if test (type tendermint >/dev/null 2>&1) - echo tendermint binary is required in PATH - prereqs +if [ $# -ne 1 ] +then + echo "usage: $0 " exit -end +fi -if test ! (string match -r 0.25.0 (tendermint version)) - echo tendermint v0.25.0 is required - prereqs - exit -end +tendermint_binary=$1 -echo removing any old state -rm -rf tendermint_zero +echo clearing any old state... +rm -rf tendermint_zero/ rm -rf zero.json -echo initializing node -tendermint init --home tendermint_zero >/dev/null 2>&1 +echo initializing one node... +${tendermint_binary} init --home tendermint_zero >/dev/null -echo producing config files +echo producing config file... echo 'moniker = "zero"' > tendermint_zero/config/config.toml echo 'proxy_app = ""' >> tendermint_zero/config/config.toml echo '' >> tendermint_zero/config/config.toml @@ -39,10 +29,10 @@ echo 'laddr = "tcp://127.0.0.1:10000"' >> tendermint_zero/config/config.toml echo now you can run one node echo -echo " td -api-addr 127.0.0.1:8081 -app-file zero.json -tendermint-dir tendermint_zero" +echo " ./tendermint-cas-demo -api-addr 127.0.0.1:8081 -app-file zero.json -tendermint-dir tendermint_zero" echo echo other fun things to try -echo +echo echo " watch -n1 -- cat zero.json # watch state being updated" echo " curl -Ss -XPOST 'localhost:8081/x?new=one' # set x=one" echo " curl -Ss -XPOST 'localhost:8081/x?old=one&new=two' # set x=two" diff --git a/bootstrap_3.fish b/bootstrap_3.fish deleted file mode 100755 index 2078107..0000000 --- a/bootstrap_3.fish +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env fish - -function prereqs - echo - echo " Download Tendermint v0.25.0 for your system from" - echo " https://github.com/tendermint/tendermint/releases/tag/v0.25.0" - echo " and place the tendermint binary in your PATH." - echo -end - -if test (type tendermint >/dev/null 2>&1) - echo tendermint binary is required - prereqs - exit -end - -if test ! (string match -r 0.25.0 (tendermint version)) - echo tendermint v0.25.0 is required - prereqs - exit -end - -echo removing any old state -rm -rf tendermint_{a,b,c} -rm -rf {a,b,c}.json - -echo initializing 3 nodes -tendermint init --home tendermint_a >/dev/null 2>&1 -tendermint init --home tendermint_b >/dev/null 2>&1 -tendermint init --home tendermint_c >/dev/null 2>&1 - -echo producing common genesis file -set a (cat tendermint_a/config/genesis.json | jq .validators[0]) -set b (cat tendermint_b/config/genesis.json | jq .validators[0]) -set c (cat tendermint_c/config/genesis.json | jq .validators[0]) -set common_genesis (cat tendermint_a/config/genesis.json | jq "(.validators) = [$a, $b, $c]") -echo $common_genesis | jq . > tendermint_a/config/genesis.json -echo $common_genesis | jq . > tendermint_b/config/genesis.json -echo $common_genesis | jq . > tendermint_c/config/genesis.json - -echo producing config files -set a (cat tendermint_a/config/genesis.json | jq .validators[0].address | tr -d '"') -set b (cat tendermint_b/config/genesis.json | jq .validators[0].address | tr -d '"') -set c (cat tendermint_c/config/genesis.json | jq .validators[0].address | tr -d '"') -set persistent_peers "$a@127.0.0.1:10001, $b@127.0.0.1:10002, $c@127.0.0.1:10003" -echo 'moniker = "a"' | tee tendermint_a/config/config.toml >/dev/null -echo 'moniker = "b"' | tee tendermint_b/config/config.toml >/dev/null -echo 'moniker = "c"' | tee tendermint_c/config/config.toml >/dev/null -echo 'proxy_app = ""' | tee -a tendermint_?/config/config.toml >/dev/null -echo '' | tee -a tendermint_?/config/config.toml >/dev/null -echo '[rpc]' | tee -a tendermint_?/config/config.toml >/dev/null -echo 'laddr = ""' | tee -a tendermint_?/config/config.toml >/dev/null -echo '' | tee -a tendermint_?/config/config.toml >/dev/null -echo '[p2p]' | tee -a tendermint_?/config/config.toml >/dev/null -echo 'laddr = "tcp://127.0.0.1:10001"' | tee -a tendermint_a/config/config.toml >/dev/null -echo 'laddr = "tcp://127.0.0.1:10002"' | tee -a tendermint_b/config/config.toml >/dev/null -echo 'laddr = "tcp://127.0.0.1:10003"' | tee -a tendermint_c/config/config.toml >/dev/null -echo "persistent_peers = \"$persistent_peers\"" | tee -a tendermint_?/config/config.toml >/dev/null - -echo now you can run three nodes -echo -echo " td -api-addr 127.0.0.1:8081 -app-file a.json -tendermint-dir tendermint_a" -echo " td -api-addr 127.0.0.1:8082 -app-file b.json -tendermint-dir tendermint_b" -echo " td -api-addr 127.0.0.1:8083 -app-file c.json -tendermint-dir tendermint_c" -echo -echo other fun things to try -echo -echo " watch -n1 -- cat ?.json # watch state being updated" -echo " curl -Ss -XPOST 'localhost:8081/x?new=one' # set x=one on node a" -echo " curl -Ss -XPOST 'localhost:8082/x?old=one&new=two' # set x=two on node b" -echo " curl -Ss -XGET 'localhost:8083/x' # get x on node c" -echo - diff --git a/bootstrap_3.sh b/bootstrap_3.sh new file mode 100755 index 0000000..3612dd4 --- /dev/null +++ b/bootstrap_3.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env sh + +set -e + +if [ $# -ne 1 ] +then + echo "usage: $0 " + exit +fi + +tendermint_binary=$1 + +echo clearing any old state... +rm -rf tendermint_{a,b,c}/ +rm -rf {a,b,c}.json + +echo initializing three nodes... +${tendermint_binary} init --home tendermint_a >/dev/null +${tendermint_binary} init --home tendermint_b >/dev/null +${tendermint_binary} init --home tendermint_c >/dev/null + +echo capturing validators... +a_validator=$(cat tendermint_a/config/genesis.json | jq .validators[0]) +b_validator=$(cat tendermint_b/config/genesis.json | jq .validators[0]) +c_validator=$(cat tendermint_c/config/genesis.json | jq .validators[0]) + +echo capturing peer addresses... +a_address=$(echo $a_validator | jq .address | tr -d '"') +b_address=$(echo $b_validator | jq .address | tr -d '"') +c_address=$(echo $c_validator | jq .address | tr -d '"') +persistent_peers="${a_address}@127.0.0.1:10001, ${b_address}@127.0.0.1:10002, ${c_address}@127.0.0.1:10003" + +echo building a common genesis file... +common_genesis=$(cat tendermint_a/config/genesis.json | jq "(.validators) = [${a_validator}, ${b_validator}, ${c_validator}]") + +echo writing common genesis file... +echo $common_genesis | jq . > tendermint_a/config/genesis.json +echo $common_genesis | jq . > tendermint_b/config/genesis.json +echo $common_genesis | jq . > tendermint_c/config/genesis.json + +echo producing config files... +echo 'moniker = "a"' | tee tendermint_a/config/config.toml >/dev/null +echo 'moniker = "b"' | tee tendermint_b/config/config.toml >/dev/null +echo 'moniker = "c"' | tee tendermint_c/config/config.toml >/dev/null +echo 'proxy_app = ""' | tee -a tendermint_?/config/config.toml >/dev/null +echo '' | tee -a tendermint_?/config/config.toml >/dev/null +echo '[rpc]' | tee -a tendermint_?/config/config.toml >/dev/null +echo 'laddr = ""' | tee -a tendermint_?/config/config.toml >/dev/null +echo '' | tee -a tendermint_?/config/config.toml >/dev/null +echo '[p2p]' | tee -a tendermint_?/config/config.toml >/dev/null +echo 'laddr = "tcp://127.0.0.1:10001"' | tee -a tendermint_a/config/config.toml >/dev/null +echo 'laddr = "tcp://127.0.0.1:10002"' | tee -a tendermint_b/config/config.toml >/dev/null +echo 'laddr = "tcp://127.0.0.1:10003"' | tee -a tendermint_c/config/config.toml >/dev/null +echo "persistent_peers = \"${persistent_peers}\"" | tee -a tendermint_?/config/config.toml >/dev/null + +echo now you can run three nodes +echo +echo " ./tendermint-cas-demo -api-addr 127.0.0.1:8081 -app-file a.json -tendermint-dir tendermint_a" +echo " ./tendermint-cas-demo -api-addr 127.0.0.1:8082 -app-file b.json -tendermint-dir tendermint_b" +echo " ./tendermint-cas-demo -api-addr 127.0.0.1:8083 -app-file c.json -tendermint-dir tendermint_c" +echo +echo other fun things to try +echo +echo " watch -n1 -- cat ?.json # watch state being updated" +echo " curl -Ss -XPOST 'localhost:8081/x?new=one' # set x=one" +echo " curl -Ss -XPOST 'localhost:8082/x?old=one&new=two' # set x=two" +echo " curl -Ss -XGET 'localhost:8083/x' # get x" +echo diff --git a/cmd/tendermint-cas-demo/main.go b/cmd/tendermint-cas-demo/main.go index 73ef7c4..e089d84 100644 --- a/cmd/tendermint-cas-demo/main.go +++ b/cmd/tendermint-cas-demo/main.go @@ -31,7 +31,7 @@ import ( ) func main() { - fs := flag.NewFlagSet("td", flag.ExitOnError) + fs := flag.NewFlagSet("tendermint-cas-demo", flag.ExitOnError) var ( apiAddr = fs.String("api-addr", "127.0.0.1:8081", "HTTP API address") appFile = fs.String("app-file", "db.json", "application persistence file") @@ -39,7 +39,7 @@ func main() { tendermintDir = fs.String("tendermint-dir", "tendermint", "Tendermint directory (config, data, etc.)") tendermintVerbose = fs.Bool("tendermint-verbose", false, "verbose logging of Tendermint information") ) - fs.Usage = usage.For(fs, "td [flags]") + fs.Usage = usage.For(fs, "tendermint-cas-demo [flags]") fs.Parse(os.Args[1:]) var logger log.Logger