diff --git a/CHANGELOG.md b/CHANGELOG.md index 3690f5b7475f..538d30c6ea1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,34 @@ # Changelog +## 0.23.1 + +*July 27th, 2018* + +BUG FIXES + * [tendermint] Update to v0.22.8 + - [consensus, blockchain] Register the Evidence interface so it can be + marshalled/unmarshalled by the blockchain and consensus reactors + +## 0.23.0 + +*July 25th, 2018* + +BREAKING CHANGES +* [x/stake] Fixed the period check for the inflation calculation + +IMPROVEMENTS +* [cli] Improve error messages for all txs when the account doesn't exist +* [tendermint] Update to v0.22.6 + - Updates the crypto imports/API (#1966) +* [x/stake] Add revoked to human-readable validator + +BUG FIXES +* [tendermint] Update to v0.22.6 + - Fixes some security vulnerabilities reported in the [Bug Bounty](https://hackerone.com/tendermint) +* \#1797 Fix off-by-one error in slashing for downtime +* \#1787 Fixed bug where Tally fails due to revoked/unbonding validator +* \#1666 Add intra-tx counter to the genesis validators + ## 0.22.0 *July 16th, 2018* diff --git a/Gopkg.lock b/Gopkg.lock index a1372b1fa81c..849bf143d70e 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -3,78 +3,57 @@ [[projects]] branch = "master" - digest = "1:09a7f74eb6bb3c0f14d8926610c87f569c5cff68e978d30e9a3540aeb626fdf0" name = "github.com/bartekn/go-bip39" packages = ["."] - pruneopts = "UT" revision = "a05967ea095d81c8fe4833776774cfaff8e5036c" [[projects]] branch = "master" - digest = "1:d6afaeed1502aa28e80a4ed0981d570ad91b2579193404256ce672ed0a609e0d" name = "github.com/beorn7/perks" packages = ["quantile"] - pruneopts = "UT" revision = "3a771d992973f24aa725d07868b467d1ddfceafb" [[projects]] - digest = "1:1343a2963481a305ca4d051e84bc2abd16b601ee22ed324f8d605de1adb291b0" name = "github.com/bgentry/speakeasy" packages = ["."] - pruneopts = "UT" revision = "4aabc24848ce5fd31929f7d1e4ea74d3709c14cd" version = "v0.1.0" [[projects]] branch = "master" - digest = "1:70f6b224a59b2fa453debffa85c77f71063d8754b90c8c4fbad5794e2c382b0f" name = "github.com/brejski/hid" packages = ["."] - pruneopts = "UT" revision = "06112dcfcc50a7e0e4fd06e17f9791e788fdaafc" [[projects]] branch = "master" - digest = "1:6aabc1566d6351115d561d038da82a4c19b46c3b6e17f4a0a2fa60260663dc79" name = "github.com/btcsuite/btcd" packages = ["btcec"] - pruneopts = "UT" - revision = "fdfc19097e7ac6b57035062056f5b7b4638b8898" + revision = "9a2f9524024889e129a5422aca2cff73cb3eabf6" [[projects]] - branch = "master" - digest = "1:386de157f7d19259a7f9c81f26ce011223ce0f090353c1152ffdf730d7d10ac2" name = "github.com/btcsuite/btcutil" packages = ["bech32"] - pruneopts = "UT" - revision = "ab6388e0c60ae4834a1f57511e20c17b5f78be4b" + revision = "d4cc87b860166d00d6b5b9e0d3b3d71d6088d4d4" [[projects]] - digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39" name = "github.com/davecgh/go-spew" packages = ["spew"] - pruneopts = "UT" revision = "346938d642f2ec3594ed81d874461961cd0faa76" version = "v1.1.0" [[projects]] - branch = "master" - digest = "1:c7644c73a3d23741fdba8a99b1464e021a224b7e205be497271a8003a15ca41b" name = "github.com/ebuchman/fail-test" packages = ["."] - pruneopts = "UT" revision = "95f809107225be108efcf10a3509e4ea6ceef3c4" [[projects]] - digest = "1:abeb38ade3f32a92943e5be54f55ed6d6e3b6602761d74b4aab4c9dd45c18abd" name = "github.com/fsnotify/fsnotify" packages = ["."] - pruneopts = "UT" revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" version = "v1.4.7" [[projects]] - digest = "1:fa30c0652956e159cdb97dcb2ef8b8db63ed668c02a5c3a40961c8f0641252fe" name = "github.com/go-kit/kit" packages = [ "log", @@ -83,30 +62,24 @@ "metrics", "metrics/discard", "metrics/internal/lv", - "metrics/prometheus", + "metrics/prometheus" ] - pruneopts = "UT" revision = "4dc7be5d2d12881735283bcab7352178e190fc71" version = "v0.6.0" [[projects]] - digest = "1:31a18dae27a29aa074515e43a443abfd2ba6deb6d69309d8d7ce789c45f34659" name = "github.com/go-logfmt/logfmt" packages = ["."] - pruneopts = "UT" revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5" version = "v0.3.0" [[projects]] - digest = "1:c4a2528ccbcabf90f9f3c464a5fc9e302d592861bbfd0b7135a7de8a943d0406" name = "github.com/go-stack/stack" packages = ["."] - pruneopts = "UT" revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc" version = "v1.7.0" [[projects]] - digest = "1:af1306bff89268721ea2550d504413c9487ebfca11e2ff8f39ae79b99a720ff5" name = "github.com/gogo/protobuf" packages = [ "gogoproto", @@ -114,61 +87,49 @@ "proto", "protoc-gen-gogo/descriptor", "sortkeys", - "types", + "types" ] - pruneopts = "UT" - revision = "1adfc126b41513cc696b209667c8656ea7aac67c" - version = "v1.0.0" + revision = "636bf0302bc95575d69441b25a2603156ffdddf1" + version = "v1.1.1" [[projects]] - digest = "1:cb22af0ed7c72d495d8be1106233ee553898950f15fd3f5404406d44c2e86888" name = "github.com/golang/protobuf" packages = [ "proto", "ptypes", "ptypes/any", "ptypes/duration", - "ptypes/timestamp", + "ptypes/timestamp" ] - pruneopts = "UT" revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265" version = "v1.1.0" [[projects]] branch = "master" - digest = "1:4a0c6bb4805508a6287675fac876be2ac1182539ca8a32468d8128882e9d5009" name = "github.com/golang/snappy" packages = ["."] - pruneopts = "UT" revision = "2e65f85255dbc3072edf28d6b5b8efc472979f5a" [[projects]] - digest = "1:c79fb010be38a59d657c48c6ba1d003a8aa651fa56b579d959d74573b7dff8e1" name = "github.com/gorilla/context" packages = ["."] - pruneopts = "UT" revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42" version = "v1.1.1" [[projects]] - digest = "1:e73f5b0152105f18bc131fba127d9949305c8693f8a762588a82a48f61756f5f" name = "github.com/gorilla/mux" packages = ["."] - pruneopts = "UT" revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf" version = "v1.6.2" [[projects]] - digest = "1:43dd08a10854b2056e615d1b1d22ac94559d822e1f8b6fcc92c1a1057e85188e" name = "github.com/gorilla/websocket" packages = ["."] - pruneopts = "UT" revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b" version = "v1.2.0" [[projects]] branch = "master" - digest = "1:8951fe6e358876736d8fa1f3992624fdbb2dec6bc49401c1381d1ef8abbb544f" name = "github.com/hashicorp/hcl" packages = [ ".", @@ -179,208 +140,160 @@ "hcl/token", "json/parser", "json/scanner", - "json/token", + "json/token" ] - pruneopts = "UT" revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168" [[projects]] - digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be" name = "github.com/inconshreveable/mousetrap" packages = ["."] - pruneopts = "UT" revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" version = "v1.0" [[projects]] branch = "master" - digest = "1:39b27d1381a30421f9813967a5866fba35dc1d4df43a6eefe3b7a5444cb07214" name = "github.com/jmhodges/levigo" packages = ["."] - pruneopts = "UT" revision = "c42d9e0ca023e2198120196f842701bb4c55d7b9" [[projects]] branch = "master" - digest = "1:a64e323dc06b73892e5bb5d040ced475c4645d456038333883f58934abbf6f72" name = "github.com/kr/logfmt" packages = ["."] - pruneopts = "UT" revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0" [[projects]] - digest = "1:c568d7727aa262c32bdf8a3f7db83614f7af0ed661474b24588de635c20024c7" name = "github.com/magiconair/properties" packages = ["."] - pruneopts = "UT" revision = "c2353362d570a7bfa228149c62842019201cfb71" version = "v1.8.0" [[projects]] - digest = "1:d4d17353dbd05cb52a2a52b7fe1771883b682806f68db442b436294926bbfafb" name = "github.com/mattn/go-isatty" packages = ["."] - pruneopts = "UT" revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" version = "v0.0.3" [[projects]] - digest = "1:ff5ebae34cfbf047d505ee150de27e60570e8c394b3b8fdbb720ff6ac71985fc" name = "github.com/matttproud/golang_protobuf_extensions" packages = ["pbutil"] - pruneopts = "UT" revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c" version = "v1.0.1" [[projects]] branch = "master" - digest = "1:e730597b38a4d56e2361e0b6236cb800e52c73cace2ff91396f4ff35792ddfa7" name = "github.com/mitchellh/mapstructure" packages = ["."] - pruneopts = "UT" - revision = "bb74f1db0675b241733089d5a1faa5dd8b0ef57b" + revision = "f15292f7a699fcc1a38a80977f80a046874ba8ac" [[projects]] - digest = "1:95741de3af260a92cc5c7f3f3061e85273f5a81b5db20d4bd68da74bd521675e" name = "github.com/pelletier/go-toml" packages = ["."] - pruneopts = "UT" revision = "c01d1270ff3e442a8a57cddc1c92dc1138598194" version = "v1.2.0" [[projects]] - digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747" name = "github.com/pkg/errors" packages = ["."] - pruneopts = "UT" revision = "645ef00459ed84a119197bfb8d8205042c6df63d" version = "v0.8.0" [[projects]] - digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" name = "github.com/pmezard/go-difflib" packages = ["difflib"] - pruneopts = "UT" revision = "792786c7400a136282c1664665ae0a8db921c6c2" version = "v1.0.0" [[projects]] - branch = "master" - digest = "1:98225904b7abff96c052b669b25788f18225a36673fba022fb93514bb9a2a64e" name = "github.com/prometheus/client_golang" packages = [ "prometheus", - "prometheus/promhttp", + "prometheus/promhttp" ] - pruneopts = "UT" revision = "ae27198cdd90bf12cd134ad79d1366a6cf49f632" [[projects]] branch = "master" - digest = "1:53a76eb11bdc815fcf0c757a9648fda0ab6887da13f07587181ff2223b67956c" name = "github.com/prometheus/client_model" packages = ["go"] - pruneopts = "UT" revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c" [[projects]] branch = "master" - digest = "1:4d291d51042ed9de40eef61a3c1b56e969d6e0f8aa5fd3da5e958ec66bee68e4" name = "github.com/prometheus/common" packages = [ "expfmt", "internal/bitbucket.org/ww/goautoneg", - "model", + "model" ] - pruneopts = "UT" revision = "7600349dcfe1abd18d72d3a1770870d9800a7801" [[projects]] branch = "master" - digest = "1:55d7449d6987dabf272b4e81b2f9c449f05b17415c939b68d1e82f57e3374b7f" name = "github.com/prometheus/procfs" packages = [ ".", "internal/util", "nfs", - "xfs", + "xfs" ] - pruneopts = "UT" revision = "ae68e2d4c00fed4943b5f6698d504a5fe083da8a" [[projects]] - branch = "master" - digest = "1:c4556a44e350b50a490544d9b06e9fba9c286c21d6c0e47f54f3a9214597298c" name = "github.com/rcrowley/go-metrics" packages = ["."] - pruneopts = "UT" revision = "e2704e165165ec55d062f5919b4b29494e9fa790" [[projects]] - digest = "1:37ace7f35375adec11634126944bdc45a673415e2fcc07382d03b75ec76ea94c" name = "github.com/spf13/afero" packages = [ ".", - "mem", + "mem" ] - pruneopts = "UT" revision = "787d034dfe70e44075ccc060d346146ef53270ad" version = "v1.1.1" [[projects]] - digest = "1:516e71bed754268937f57d4ecb190e01958452336fa73dbac880894164e91c1f" name = "github.com/spf13/cast" packages = ["."] - pruneopts = "UT" revision = "8965335b8c7107321228e3e3702cab9832751bac" version = "v1.2.0" [[projects]] - digest = "1:627ab2f549a6a55c44f46fa24a4307f4d0da81bfc7934ed0473bf38b24051d26" name = "github.com/spf13/cobra" packages = ["."] - pruneopts = "UT" revision = "7b2c5ac9fc04fc5efafb60700713d4fa609b777b" version = "v0.0.1" [[projects]] branch = "master" - digest = "1:080e5f630945ad754f4b920e60b4d3095ba0237ebf88dc462eb28002932e3805" name = "github.com/spf13/jwalterweatherman" packages = ["."] - pruneopts = "UT" revision = "7c0cea34c8ece3fbeb2b27ab9b59511d360fb394" [[projects]] - digest = "1:9424f440bba8f7508b69414634aef3b2b3a877e522d8a4624692412805407bb7" name = "github.com/spf13/pflag" packages = ["."] - pruneopts = "UT" revision = "583c0c0531f06d5278b7d917446061adc344b5cd" version = "v1.0.1" [[projects]] - digest = "1:f8e1a678a2571e265f4bf91a3e5e32aa6b1474a55cb0ea849750cc177b664d96" name = "github.com/spf13/viper" packages = ["."] - pruneopts = "UT" revision = "25b30aa063fc18e48662b86996252eabdcf2f0c7" version = "v1.0.0" [[projects]] - digest = "1:73697231b93fb74a73ebd8384b68b9a60c57ea6b13c56d2425414566a72c8e6d" name = "github.com/stretchr/testify" packages = [ "assert", - "require", + "require" ] - pruneopts = "UT" revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" version = "v1.2.1" [[projects]] branch = "master" - digest = "1:922191411ad8f61bcd8018ac127589bb489712c1d1a0ab2497aca4b16de417d2" name = "github.com/syndtr/goleveldb" packages = [ "leveldb", @@ -394,41 +307,33 @@ "leveldb/opt", "leveldb/storage", "leveldb/table", - "leveldb/util", + "leveldb/util" ] - pruneopts = "UT" revision = "c4c61651e9e37fa117f53c5a906d3b63090d8445" [[projects]] branch = "master" - digest = "1:203b409c21115233a576f99e8f13d8e07ad82b25500491f7e1cca12588fb3232" name = "github.com/tendermint/ed25519" packages = [ ".", "edwards25519", - "extra25519", + "extra25519" ] - pruneopts = "UT" revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" [[projects]] - digest = "1:e9113641c839c21d8eaeb2c907c7276af1eddeed988df8322168c56b7e06e0e1" name = "github.com/tendermint/go-amino" packages = ["."] - pruneopts = "UT" revision = "2106ca61d91029c931fd54968c2bb02dc96b1412" version = "0.10.1" [[projects]] - digest = "1:d4a15d404afbf591e8be16fcda7f5ac87948d5c7531f9d909fd84cc730ab16e2" name = "github.com/tendermint/iavl" packages = ["."] - pruneopts = "UT" revision = "35f66e53d9b01e83b30de68b931f54b2477a94c9" version = "v0.9.2" [[projects]] - digest = "1:2511fa7bc2725251a1a48a923c8f01cd41de29b00a21224092d448a9e4627c21" name = "github.com/tendermint/tendermint" packages = [ "abci/client", @@ -442,8 +347,13 @@ "consensus", "consensus/types", "crypto", + "crypto/armor", + "crypto/ed25519", + "crypto/encoding/amino", "crypto/merkle", + "crypto/secp256k1", "crypto/tmhash", + "crypto/xsalsa20symmetric", "evidence", "libs/autofile", "libs/bech32", @@ -483,22 +393,18 @@ "state/txindex/kv", "state/txindex/null", "types", - "version", + "version" ] - pruneopts = "UT" - revision = "5ff65274b84ea905787a48512cc3124385bddf2f" - version = "v0.22.2" + revision = "d542d2c3945116697f60451e6a407082c41c3cc9" + version = "v0.22.8-rc0" [[projects]] - digest = "1:5bd938386bd1f61a581bf8cd6ff2b7b2f79c542929176db4ceb44965440dae07" name = "github.com/zondax/ledger-goclient" packages = ["."] - pruneopts = "UT" revision = "39ba4728c137c75718a21f9b4b3280fa31b9139b" [[projects]] branch = "master" - digest = "1:e8206c1653e050116ec8c9a823a86413fc9f9ee3c2f3ae977c96d6a1747f7325" name = "golang.org/x/crypto" packages = [ "blowfish", @@ -511,14 +417,11 @@ "pbkdf2", "poly1305", "ripemd160", - "salsa20/salsa", + "salsa20/salsa" ] - pruneopts = "UT" - revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602" + revision = "c126467f60eb25f8f27e5a981f32a87e3965053f" [[projects]] - branch = "master" - digest = "1:04dda8391c3e2397daf254ac68003f30141c069b228d06baec8324a5f81dc1e9" name = "golang.org/x/net" packages = [ "context", @@ -528,21 +431,17 @@ "idna", "internal/timeseries", "netutil", - "trace", + "trace" ] - pruneopts = "UT" revision = "292b43bbf7cb8d35ddf40f8d5100ef3837cced3f" [[projects]] branch = "master" - digest = "1:d773e525476aefa22ea944a5425a9bfb99819b2e67eeb9b1966454fd57522bbf" name = "golang.org/x/sys" packages = ["unix"] - pruneopts = "UT" - revision = "1b2967e3c290b7c545b3db0deeda16e9be4f98a2" + revision = "ac767d655b305d4e9612f5f6e33120b9176c4ad4" [[projects]] - digest = "1:7509ba4347d1f8de6ae9be8818b0cd1abc3deeffe28aeaf4be6d4b6b5178d9ca" name = "golang.org/x/text" packages = [ "collate", @@ -558,22 +457,18 @@ "unicode/bidi", "unicode/cldr", "unicode/norm", - "unicode/rangetable", + "unicode/rangetable" ] - pruneopts = "UT" revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" version = "v0.3.0" [[projects]] branch = "master" - digest = "1:601e63e7d4577f907118bec825902505291918859d223bce015539e79f1160e3" name = "google.golang.org/genproto" packages = ["googleapis/rpc/status"] - pruneopts = "UT" - revision = "e92b116572682a5b432ddd840aeaba2a559eeff1" + revision = "02b4e95473316948020af0b7a4f0f22c73929b0e" [[projects]] - digest = "1:4d7b5d9746840266938cdb21a40f8eba7137d9153c4ed404d6bb2a450d06f690" name = "google.golang.org/grpc" packages = [ ".", @@ -585,9 +480,11 @@ "credentials", "encoding", "encoding/proto", - "grpclb/grpc_lb_v1/messages", "grpclog", "internal", + "internal/backoff", + "internal/channelz", + "internal/grpcrand", "keepalive", "metadata", "naming", @@ -598,63 +495,20 @@ "stats", "status", "tap", - "transport", + "transport" ] - pruneopts = "UT" - revision = "d11072e7ca9811b1100b80ca0269ac831f06d024" - version = "v1.11.3" + revision = "168a6198bcb0ef175f7dacec0b8691fc141dc9b8" + version = "v1.13.0" [[projects]] - digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202" name = "gopkg.in/yaml.v2" packages = ["."] - pruneopts = "UT" revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" version = "v2.2.1" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - input-imports = [ - "github.com/bartekn/go-bip39", - "github.com/bgentry/speakeasy", - "github.com/btcsuite/btcd/btcec", - "github.com/golang/protobuf/proto", - "github.com/gorilla/mux", - "github.com/mattn/go-isatty", - "github.com/pkg/errors", - "github.com/spf13/cobra", - "github.com/spf13/pflag", - "github.com/spf13/viper", - "github.com/stretchr/testify/assert", - "github.com/stretchr/testify/require", - "github.com/tendermint/go-amino", - "github.com/tendermint/iavl", - "github.com/tendermint/tendermint/abci/server", - "github.com/tendermint/tendermint/abci/types", - "github.com/tendermint/tendermint/cmd/tendermint/commands", - "github.com/tendermint/tendermint/config", - "github.com/tendermint/tendermint/crypto", - "github.com/tendermint/tendermint/crypto/merkle", - "github.com/tendermint/tendermint/crypto/tmhash", - "github.com/tendermint/tendermint/libs/bech32", - "github.com/tendermint/tendermint/libs/cli", - "github.com/tendermint/tendermint/libs/cli/flags", - "github.com/tendermint/tendermint/libs/common", - "github.com/tendermint/tendermint/libs/db", - "github.com/tendermint/tendermint/libs/log", - "github.com/tendermint/tendermint/node", - "github.com/tendermint/tendermint/p2p", - "github.com/tendermint/tendermint/privval", - "github.com/tendermint/tendermint/proxy", - "github.com/tendermint/tendermint/rpc/client", - "github.com/tendermint/tendermint/rpc/core/types", - "github.com/tendermint/tendermint/rpc/lib/client", - "github.com/tendermint/tendermint/rpc/lib/server", - "github.com/tendermint/tendermint/types", - "github.com/zondax/ledger-goclient", - "golang.org/x/crypto/blowfish", - "golang.org/x/crypto/ripemd160", - ] + inputs-digest = "93154e6c678a7bfa273eccf7222531922d644999974efe347893bdd8ba24b14b" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index da2c8e29ce0e..d5d461ff6003 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -62,7 +62,7 @@ [[override]] name = "github.com/tendermint/tendermint" - version = "=0.22.2" + version = "=v0.22.8" [[constraint]] name = "github.com/bartekn/go-bip39" diff --git a/PENDING.md b/PENDING.md new file mode 100644 index 000000000000..a8824c98d037 --- /dev/null +++ b/PENDING.md @@ -0,0 +1,41 @@ +## PENDING + +BREAKING CHANGES +* [baseapp] Msgs are no longer run on CheckTx, removed `ctx.IsCheckTx()` +* [x/gov] CLI flag changed from `proposalID` to `proposal-id` +* [x/stake] Inflation doesn't use rationals in calculation (performance boost) +* [baseapp] NewBaseApp constructor now takes sdk.TxDecoder as argument instead of wire.Codec +* [x/auth] Default TxDecoder can be found in `x/auth` rather than baseapp +* \#1606 The following CLI commands have been switched to use `--from` + * `gaiacli stake create-validator --address-validator` + * `gaiacli stake edit-validator --address-validator` + * `gaiacli stake delegate --address-delegator` + * `gaiacli stake unbond begin --address-delegator` + * `gaiacli stake unbond complete --address-delegator` + * `gaiacli stake redelegate begin --address-delegator` + * `gaiacli stake redelegate complete --address-delegator` + * `gaiacli stake unrevoke [validator-address]` + * `gaiacli gov submit-proposal --proposer` + * `gaiacli gov deposit --depositer` + * `gaiacli gov vote --voter` +* [x/gov] Added tags sub-package, changed tags to use dash-case + +FEATURES +* [lcd] Can now query governance proposals by ProposalStatus +* [x/mock/simulation] Randomized simulation framework + * Modules specify invariants and operations, preferably in an x/[module]/simulation package + * Modules can test random combinations of their own operations + * Applications can integrate operations and invariants from modules together for an integrated simulation +* [baseapp] Initialize validator set on ResponseInitChain +* [cosmos-sdk-cli] Added support for cosmos-sdk-cli tool under cosmos-sdk/cmd + * This allows SDK users to initialize a new project repository. +* [tests] Remotenet commands for AWS (awsnet) + +IMPROVEMENTS +* [baseapp] Allow any alphanumeric character in route +* [tools] Remove `rm -rf vendor/` from `make get_vendor_deps` +* [x/auth] Recover ErrorOutOfGas panic in order to set sdk.Result attributes correctly +* [tests] Add tests to example apps in docs +* [x/gov] Votes on a proposal can now be queried +* [x/bank] Unit tests are now table-driven +* [tests] Fixes ansible scripts to work with AWS too diff --git a/README.md b/README.md index e865a2c55b8d..6dfbf01d9919 100644 --- a/README.md +++ b/README.md @@ -12,32 +12,35 @@ [![riot.im](https://img.shields.io/badge/riot.im-JOIN%20CHAT-green.svg)](https://riot.im/app/#/room/#cosmos-sdk:matrix.org) The Cosmos-SDK is a framework for building blockchain applications in Golang. -It is being used to build `Gaia`, the first implementation of the [Cosmos Hub](https://cosmos.network), +It is being used to build `Gaia`, the first implementation of the [Cosmos Hub](https://cosmos.network/docs/), **WARNING**: The SDK has mostly stabilized, but we are still making some breaking changes. -**Note**: The `master` branch is an active development branch. For the latest -release, see the [release page](https://github.com/cosmos/cosmos-sdk/releases). - **Note**: Requires [Go 1.10+](https://golang.org/dl/) ## Gaia Testnet -For more information on connecting to the testnet, see -[cmd/gaia/testnets](/cmd/gaia/testnets) +To join the latest testnet, follow +[the guide](https://cosmos.network/docs/getting-started/full-node.html#setting-up-a-new-node). -For the latest status of the testnet, see the [status -file](/cmd/gaia/testnets/STATUS.md). +For status updates and genesis files, see the +[testnets repo](https://github.com/cosmos/testnets). ## Install -See the [install instructions](/docs/install.md) +See the +[install instructions](https://cosmos.network/docs/getting-started/installation.html). ## Quick Start -- [Documentation](/docs) -- [Examples](/examples) +See the [Cosmos Docs](https://cosmos.network/docs/) + +- [Getting started with the + SDK](https://cosmos.network/docs/sdk/core/intro.html) +- [SDK Examples](/examples) +- [Join the + testnet](https://cosmos.network/docs/getting-started/full-node.html#run-a-full-node) ## Disambiguation diff --git a/client/context/helpers.go b/client/context/helpers.go index 00ff8a81c79b..7742dfe03a01 100644 --- a/client/context/helpers.go +++ b/client/context/helpers.go @@ -186,6 +186,11 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msgs []sdk.Msg, cdc // sign and build the transaction from the msg func (ctx CoreContext) ensureSignBuild(name string, msgs []sdk.Msg, cdc *wire.Codec) (tyBytes []byte, err error) { + err = EnsureAccountExists(ctx, name) + if err != nil { + return nil, err + } + ctx, err = EnsureAccountNumber(ctx) if err != nil { return nil, err diff --git a/client/context/viper.go b/client/context/viper.go index 611ad1b92f0a..6c7646079e43 100644 --- a/client/context/viper.go +++ b/client/context/viper.go @@ -3,6 +3,7 @@ package context import ( "fmt" + "github.com/pkg/errors" "github.com/spf13/viper" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" @@ -10,6 +11,9 @@ import ( tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/keys" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) // NewCoreContextFromViper - return a new context with parameters from the command line @@ -68,6 +72,36 @@ func defaultChainID() (string, error) { return doc.ChainID, nil } +// EnsureAccountExists - Make sure account exists +func EnsureAccountExists(ctx CoreContext, name string) error { + keybase, err := keys.GetKeyBase() + if err != nil { + return err + } + + if name == "" { + return errors.Errorf("must provide a from address name") + } + + info, err := keybase.Get(name) + if err != nil { + return errors.Errorf("no key for: %s", name) + } + + accAddr := sdk.AccAddress(info.GetPubKey().Address()) + + Acc, err := ctx.QueryStore(auth.AddressStoreKey(accAddr), ctx.AccountStore) + if err != nil { + return err + } + + // Check if account was found + if Acc == nil { + return errors.Errorf("No account with address %s was found in the state.\nAre you sure there has been a transaction involving it?", accAddr) + } + return nil +} + // EnsureAccount - automatically set account number if none provided func EnsureAccountNumber(ctx CoreContext) (CoreContext, error) { // Should be viper.IsSet, but this does not work - https://github.com/spf13/viper/pull/331 diff --git a/client/lcd/test_helpers.go b/client/lcd/test_helpers.go index 0dfab1a506d2..49ffc441b33a 100644 --- a/client/lcd/test_helpers.go +++ b/client/lcd/test_helpers.go @@ -19,6 +19,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" tmcfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/cli" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" @@ -119,7 +120,7 @@ func InitializeTestLCD(t *testing.T, nValidators int, initAddrs []sdk.AccAddress for i := 1; i < nValidators; i++ { genDoc.Validators = append(genDoc.Validators, tmtypes.GenesisValidator{ - PubKey: crypto.GenPrivKeyEd25519().PubKey(), + PubKey: ed25519.GenPrivKey().PubKey(), Power: 1, Name: "val", }, @@ -151,7 +152,7 @@ func InitializeTestLCD(t *testing.T, nValidators int, initAddrs []sdk.AccAddress appState, err := wire.MarshalJSONIndent(cdc, genesisState) require.NoError(t, err) - genDoc.AppStateJSON = appState + genDoc.AppState = appState // LCD listen address var listenAddr string diff --git a/cmd/gaia/app/genesis_test.go b/cmd/gaia/app/genesis_test.go index d0e080376bcd..85b5b0d9b46d 100644 --- a/cmd/gaia/app/genesis_test.go +++ b/cmd/gaia/app/genesis_test.go @@ -6,11 +6,11 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" ) func TestToAccount(t *testing.T) { - priv := crypto.GenPrivKeyEd25519() + priv := ed25519.GenPrivKey() addr := sdk.AccAddress(priv.PubKey().Address()) authAcc := auth.NewBaseAccountWithAddress(addr) genAcc := NewGenesisAccount(&authAcc) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 650021d315ab..fa2d459e2dae 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -201,6 +201,11 @@ func TestGaiaCLISubmitProposal(t *testing.T) { vote := executeGetVote(t, fmt.Sprintf("gaiacli gov query-vote --proposalID=1 --voter=%s --output=json %v", fooAddr, flags)) require.Equal(t, int64(1), vote.ProposalID) require.Equal(t, gov.OptionYes, vote.Option) + + votes := executeGetVotes(t, fmt.Sprintf("gaiacli gov query-votes --proposalID=1 --output=json %v", flags)) + require.Len(t, votes, 1) + require.Equal(t, int64(1), votes[0].ProposalID) + require.Equal(t, gov.OptionYes, votes[0].Option) } //___________________________________________________________________________________ @@ -305,3 +310,12 @@ func executeGetVote(t *testing.T, cmdStr string) gov.Vote { require.NoError(t, err, "out %v\n, err %v", out, err) return vote } + +func executeGetVotes(t *testing.T, cmdStr string) []gov.Vote { + out := tests.ExecuteT(t, cmdStr) + var votes []gov.Vote + cdc := app.MakeCodec() + err := cdc.UnmarshalJSON([]byte(out), &votes) + require.NoError(t, err, "out %v\n, err %v", out, err) + return votes +} diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go index 4ab5d02b98cf..7c66cb9ef7bf 100644 --- a/cmd/gaia/cmd/gaiacli/main.go +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -112,6 +112,7 @@ func main() { client.GetCommands( govcmd.GetCmdQueryProposal("gov", cdc), govcmd.GetCmdQueryVote("gov", cdc), + govcmd.GetCmdQueryVotes("gov", cdc), )...) govCmd.AddCommand( client.PostCommands( diff --git a/cmd/gaia/cmd/gaiadebug/hack.go b/cmd/gaia/cmd/gaiadebug/hack.go index 0d8af92eeeb1..2e2b96205210 100644 --- a/cmd/gaia/cmd/gaiadebug/hack.go +++ b/cmd/gaia/cmd/gaiadebug/hack.go @@ -12,7 +12,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" + cmn "github.com/tendermint/tendermint/libs/common" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" @@ -94,9 +95,9 @@ func runHackCmd(cmd *cobra.Command, args []string) error { } } -func base64ToPub(b64 string) crypto.PubKeyEd25519 { +func base64ToPub(b64 string) ed25519.PubKeyEd25519 { data, _ := base64.StdEncoding.DecodeString(b64) - var pubKey crypto.PubKeyEd25519 + var pubKey ed25519.PubKeyEd25519 copy(pubKey[:], data) return pubKey diff --git a/cmd/gaia/cmd/gaiadebug/main.go b/cmd/gaia/cmd/gaiadebug/main.go index bff79870b1c4..a6db38a2120c 100644 --- a/cmd/gaia/cmd/gaiadebug/main.go +++ b/cmd/gaia/cmd/gaiadebug/main.go @@ -15,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" "github.com/spf13/cobra" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" ) func init() { @@ -116,11 +117,11 @@ func runPubKeyCmd(cmd *cobra.Command, args []string) error { } } - var pubKey crypto.PubKeyEd25519 + var pubKey ed25519.PubKeyEd25519 if pubKeyI == nil { copy(pubKey[:], pubkeyBytes) } else { - pubKey = pubKeyI.(crypto.PubKeyEd25519) + pubKey = pubKeyI.(ed25519.PubKeyEd25519) pubkeyBytes = pubKey[:] } diff --git a/cmd/gaia/testnets/README.md b/cmd/gaia/testnets/README.md index a76d01921b4a..7f9707e90892 100644 --- a/cmd/gaia/testnets/README.md +++ b/cmd/gaia/testnets/README.md @@ -1,475 +1,9 @@ -# Connect to the `gaia-7001` Testnet +# DEPRECATED -_**NOTE:**_ We are aware this documentation is a work in progress. We are actively -working to improve the tooling and the documentation to make this process as painless as -possible. In the meantime, join the [Validator Chat](https://riot.im/app/#/room/#cosmos_validators:matrix.org) -for technical support, and [open issues](https://github.com/cosmos/cosmos-sdk) if you run into any! Thanks very much for your patience and support. :) +The content of this file was moved to the `/docs` folder and is hosted on the +[website](https://cosmos.network/docs/getting-started/full-node.html#run-a-full-node). -## Setting Up a New Node +The rest of this folder was moved to the [testnets +repo](https://github.com/cosmos/testnets). -These instructions are for setting up a brand new full node from scratch. If you ran a full node on a previous testnet you will need to start from scratch due to some breaking changes in key format. -### Install Go - -Install `go` by following the [official docs](https://golang.org/doc/install). -**Go 1.10+** is required for the Cosmos SDK. Remember to properly setup your `$GOPATH`, `$GOBIN`, and `$PATH` variables, for example: - -```bash -mkdir -p $HOME/go/bin -echo "export GOPATH=$HOME/go" >> ~/.bash_profile -echo "export GOBIN=$GOPATH/bin" >> ~/.bash_profile -echo "export PATH=$PATH:$GOBIN" >> ~/.bash_profile -``` - -### Install Cosmos SDK - -Next, let's install the testnet's version of the Cosmos SDK. - -```bash -mkdir -p $GOPATH/src/github.com/cosmos -cd $GOPATH/src/github.com/cosmos -git clone https://github.com/cosmos/cosmos-sdk -cd cosmos-sdk && git checkout v0.22.0 -make get_tools && make get_vendor_deps && make install -``` - -That will install the `gaiad` and `gaiacli` binaries. Verify that everything is OK: - -```bash -$ gaiad version -0.22.0 - -$ gaiacli version -0.22.0 -``` - -### Node Setup - -Create the required configuration files, and initialize the node: - -```bash -gaiad init --name -``` - -> *NOTE:* Note that only ASCII characters are supported for the `--name`. Using Unicode renders your node unreachable. - -You can also edit this `moniker` in the `~/.gaiad/config/config.toml` file: - -```toml -# A custom human readable name for this node -moniker = "" -``` - -Your full node has been initialized! - -## Upgrading From Previous Testnet - -These instructions are for full nodes that have ran on previous testnets and -would like to upgrade to the latest testnet. - -### Reset Data - -First, remove the outdated files and reset the data. - -```bash -rm $HOME/.gaiad/config/addrbook.json $HOME/.gaiad/config/genesis.json -gaiad unsafe_reset_all -``` - -Your node is now in a pristine state while keeping the original `priv_validator.json` and `config.toml`. -If you had any sentry nodes or full nodes setup before, your node will still try to connect to them, -but may fail if they haven't also been upgraded. - -**WARNING:** Make sure that every node has a unique `priv_validator.json`. -Do not copy the `priv_validator.json` from an old node to multiple new nodes. -Running two nodes with the same `priv_validator.json` will cause you to double sign. - -NOTE: key formats changed between gaia-6002 and gaia-7000. If you're trying to upgrade from gaia-6002, -you will also need to delete your `priv_validator.json`: - -``` -rm $HOME/.gaiad/config/priv_validator.json -``` - -### Software Upgrade - -Now it is time to upgrade the software: - -```bash -cd $GOPATH/src/github.com/cosmos/cosmos-sdk -git fetch --all && git checkout v0.22.0 -make update_tools && make get_vendor_deps && make install -``` - -Your full node has been cleanly upgraded! - -## Genesis & Seeds - -### Copy the Genesis File - -Fetch the testnet's `genesis.json` file and place it in `gaiad`'s config directory. - -```bash -mkdir -p $HOME/.gaiad/config -curl https://gist.githubusercontent.com/cwgoes/311da6ba05be6e113185a716538a44c3/raw/7b6e784cf29761b5781488006313bd69d164aa6c/chris-final.json > $HOME/.gaiad/config/genesis.json -``` - -### Add Seed Nodes - -Your node needs to know how to find peers. You'll need to add healthy seed nodes to `$HOME/.gaiad/config/config.toml`. Here are some seed nodes you can use: - -```toml -# Comma separated list of seed nodes to connect to -seeds = "718145d422a823fd2a4e1e36e91b92bb0c4ddf8e@gaia-7000.coinculture.net:26656,5922bf29b48a18c2300b85cc53f424fce23927ab@67.207.73.206:26656,7c8b8fd03577cd4817f5be1f03d506f879df98d8@gaia-7000-seed1.interblock.io:26656,a28737ff02391a6e00a1d3b79befd57e68e8264c@gaia-7000-seed2.interblock.io:26656,987ffd26640cd03d08ed7e53b24dfaa7956e612d@gaia-7000-seed3.interblock.io:26656" -``` - -If those seeds aren't working, you can find more seeds and persistent peers on the [Cosmos Explorer](https://explorecosmos.network/nodes). Open the the `Full Nodes` pane and select nodes that do not have private (`10.x.x.x`) or [local IP addresses](https://en.wikipedia.org/wiki/Private_network). The `Persistent Peer` field contains the connection string. For best results use 4-6. - -For more information on seeds and peers, [read this](https://github.com/tendermint/tendermint/blob/develop/docs/using-tendermint.md#peers). - -## Run a Full Node - -Start the full node with this command: - -```bash -gaiad start -``` - -Check that everything is running smoothly: - -```bash -gaiacli status -``` - -View the status of the network with the [Cosmos Explorer](https://explorecosmos.network). Once your full node syncs up to the current block height, you should see it appear on the [list of full nodes](https://explorecosmos.network/validators). If it doesn't show up, that's ok--the Explorer does not connect to every node. - -## Generating Keys - -### A Note on Keys in Cosmos: - -There are three types of key representations that are used in this tutorial: - -- `cosmosaccaddr` - * Derived from account keys generated by `gaiacli keys add` - * Used to receive funds - * e.g. `cosmosaccaddr15h6vd5f0wqps26zjlwrc6chah08ryu4hzzdwhc` - -- `cosmosaccpub` - * Derived from account keys generated by `gaiacli keys add` - * e.g. `cosmosaccpub1zcjduc3q7fu03jnlu2xpl75s2nkt7krm6grh4cc5aqth73v0zwmea25wj2hsqhlqzm` - -- `cosmosvalpub` - * Generated when the node is created with `gaiad init`. - * Get this value with `gaiad tendermint show_validator` - * e.g. `cosmosvalpub1zcjduc3qcyj09qc03elte23zwshdx92jm6ce88fgc90rtqhjx8v0608qh5ssp0w94c` - -### Key Generation - -You'll need an account private and public key pair \(a.k.a. `sk, pk` respectively\) to be able to receive funds, send txs, bond tx, etc. - -To generate a new key \(default _ed25519_ elliptic curve\): - -```bash -gaiacli keys add -``` - -Next, you will have to create a passphrase to protect the key on disk. The output of the above command will contain a _seed phrase_. Save the _seed phrase_ in a safe place in case you forget the password! - -If you check your private keys, you'll now see ``: - -```bash -gaiacli keys show -``` - -You can see all your available keys by typing: - -```bash -gaiacli keys list -``` - -View the validator pubkey for your node by typing: - -```bash -gaiad tendermint show_validator -``` - -**WARNING:** We strongly recommend NOT using the same passphrase for multiple keys. The Tendermint team and the Interchain Foundation will not be responsible for the loss of funds. This is not as important on the testnets, but is good security practice and should be followed. - -## Fund your account - -The best way to get tokens is from the [Cosmos Testnet Faucet](https://faucetcosmos.network). If the faucet is not working for you, try asking [#cosmos-validators](https://riot.im/app/#/room/#cosmos-validators:matrix.org). The faucet needs the `cosmosaccaddr` from the account you wish to use for staking. - -After receiving tokens to your address, you can view your account's balance by typing: - -```bash -gaiacli account -``` - -> _*Note:*_ When you query an account balance with zero tokens, you will get this error: `No account with address was found in the state.` This can also happen if you fund the account before your node has fully synced with the chain. These are both normal. Also, we're working on improving our error messages! - -## Run a Validator Node - -[Validators](https://cosmos.network/validators) are responsible for committing new blocks to the blockchain through voting. A validator's stake is slashed if they become unavailable, double sign a transaction, or don't cast their votes. If you only want to run a full node, a VM in the cloud is fine. However, if you are want to become a validator for the Hub's `mainnet`, you should research hardened setups. Please read [Sentry Node Architecture](https://forum.cosmos.network/t/sentry-node-architecture-overview/454) to protect your node from DDOS and ensure high-availability. Also see the [technical requirements](https://github.com/cosmos/cosmos/blob/master/VALIDATORS_FAQ.md#technical-requirements)). There's also more info on our [website](https://cosmos.network/validators). - -### Create Your Validator - -Your `cosmosvalpub` can be used to create a new validator by staking tokens. You can find your validator pubkey by running: - -```bash -gaiad tendermint show_validator -``` - -Next, craft your `gaiacli stake create-validator` command: - -> _*NOTE:*_ Don't use more `steak` thank you have! You can always get more by using the [Faucet](https://faucetcosmos.network/)! - -```bash -gaiacli stake create-validator \ - --amount=5steak \ - --pubkey=$(gaiad tendermint show_validator) \ - --address-validator= - --moniker="choose a moniker" \ - --chain-id=gaia-7001 \ - --from= -``` - -### Edit Validator Description - -You can edit your validator's public description. This info is to identify your validator, and will be relied on by delegators to decide which validators to stake to. Make sure to provide input for every flag below, otherwise the field will default to empty (`--moniker` defaults to the machine name). - -The `--keybase-sig` is a 16-digit string that is generated with a [keybase.io](https://keybase.io) account. It's a cryptographically secure method of verifying your identity across multiple online networks. The Keybase API allows us to retrieve your Keybase avatar. This is how you can add a logo to your validator profile. - -```bash -gaiacli stake edit-validator - --address-validator= - --moniker="choose a moniker" \ - --website="https://cosmos.network" \ - --keybase-sig="6A0D65E29A4CBC8E" - --details="To infinity and beyond!" - --chain-id=gaia-7001 \ - --from= -``` - -### View Validator Description -View the validator's information with this command: - -```bash -gaiacli stake validator \ - --address-validator= \ - --chain-id=gaia-7001 -``` - -Your validator is active if the following command returns anything: - -```bash -gaiacli advanced tendermint validator-set | grep "$(gaiad tendermint show_validator)" -``` - -You should also be able to see your validator on the [Explorer](https://explorecosmos.network/validators). You are looking for the `bech32` encoded `address` in the `~/.gaiad/config/priv_validator.json` file. - -> _*Note:*_ To be in the validator set, you need to have more total voting power than the 100th validator. This is not normally an issue. - -### Problem #1: My validator has `voting_power: 0` - -Your validator has become auto-unbonded. In `gaia-7001`, we unbond validators if they do not vote on `50` of the last `100` blocks. Since blocks are proposed every ~2 seconds, a validator unresponsive for ~100 seconds will become unbonded. This usually happens when your `gaiad` process crashes. - -Here's how you can return the voting power back to your validator. First, if `gaiad` is not running, start it up again: - -```bash -gaiad start -``` - -Wait for your full node to catch up to the latest block. Next, run the following command. Note that `` is the address of your validator account, and `` is the name of the validator account. You can find this info by running `gaiacli keys list`. - -```bash -gaiacli stake unrevoke --chain-id=gaia-7001 --from= -``` - -**WARNING:** If you don't wait for `gaiad` to sync before running `unrevoke`, you will receive an error message telling you your validator is still jailed. - -Lastly, check your validator again to see if your voting power is back. - -```bash -gaiacli status -``` - -You may notice that your voting power is less than it used to be. That's because you got slashed for downtime! - -### Problem #2: My `gaiad` crashes because of `too many open files` - -The default number of files Linux can open (per-process) is `1024`. `gaiad` is known to open more than `1024` files. This causes the process to crash. A quick fix is to run `ulimit -n 4096` (increase the number of open files allowed) and then restart the process with `gaiad start`. If you are using `systemd` or another process manager to launch `gaiad` this may require some configuration at that level. A sample `systemd` file to fix this issue is below: - -```toml -# /etc/systemd/system/gaiad.service -[Unit] -Description=Cosmos Gaia Node -After=network.target - -[Service] -Type=simple -User=ubuntu -WorkingDirectory=/home/ubuntu -ExecStart=/home/ubuntu/go/bin/gaiad start -Restart=on-failure -RestartSec=3 -LimitNOFILE=4096 - -[Install] -WantedBy=multi-user.target -``` - -## Delegating to a Validator - -On the upcoming mainnet, you can delegate `Atom` to a validator. These [delegators](https://cosmos.network/resources/delegators) can receive part of the validator's fee revenue. Read more about the [Cosmos Token Model](https://github.com/cosmos/cosmos/raw/master/Cosmos_Token_Model.pdf). - -### Bond Tokens - -On the testnet, we delegate `steak` instead of `Atom`. Here's how you can bond tokens to a testnet validator: - -```bash -gaiacli stake delegate \ - --amount=10steak \ - --address-delegator= \ - --address-validator= \ - --from= \ - --chain-id=gaia-7001 -``` - -While tokens are bonded, they are pooled with all the other bonded tokens in the network. Validators and delegators obtain a percentage of shares that equal their stake in this pool. - -> _*NOTE:*_ Don't use more `steak` thank you have! You can always get more by using the [Faucet](https://faucetcosmos.network/)! - -### Unbond Tokens - -If for any reason the validator misbehaves, or you want to unbond a certain amount of tokens, use this following command. You can unbond a specific amount of`shares`\(eg:`12.1`\) or all of them \(`MAX`\). - -```bash -gaiacli stake unbond \ - --address-delegator= \ - --address-validator= \ - --shares=MAX \ - --from= \ - --chain-id=gaia-7001 -``` - -You can check your balance and your stake delegation to see that the unbonding went through successfully. - -```bash -gaiacli account - -gaiacli stake delegation \ - --address-delegator= \ - --address-validator= \ - --chain-id=gaia-7001 -``` - -## Governance - -Governance is the process from which users in the Cosmos Hub can come to consensus on software upgrades, parameters of the mainnet or on custom text proposals. This is done through voting on proposals, which will be submitted by `Atom` holders on the mainnet. - -Some considerations about the voting process: - -- Voting is done by bonded `Atom` holders on a 1 bonded `Atom` 1 vote basis -- Delegators inherit the vote of their validator if they don't vote -- **Validators MUST vote on every proposal**. If a validator does not vote on a proposal, they will be **partially slashed** -- Votes are tallied at the end of the voting period (2 weeks on mainnet). Each address can vote multiple times to update its `Option` value (paying the transaction fee each time), only the last casted vote will count as valid -- Voters can choose between options `Yes`, `No`, `NoWithVeto` and `Abstain` -At the end of the voting period, a proposal is accepted if `(YesVotes/(YesVotes+NoVotes+NoWithVetoVotes))>1/2` and `(NoWithVetoVotes/(YesVotes+NoVotes+NoWithVetoVotes))<1/3`. It is rejected otherwise - -For more information about the governance process and how it works, please check out the Governance module [specification](https://github.com/cosmos/cosmos-sdk/tree/develop/docs/spec/governance). - -### Create a Governance proposal - -In order to create a governance proposal, you must submit an initial deposit along with the proposal details: - -- `title`: Title of the proposal -- `description`: Description of the proposal -- `type`: Type of proposal. Must be of value _Text_ (types _SoftwareUpgrade_ and _ParameterChange_ not supported yet). - -```bash -gaiacli gov submit-proposal \ - --title= \ - --description=<description> \ - --type=<Text/ParameterChange/SoftwareUpgrade> \ - --proposer=<account_cosmosaccaddr> \ - --deposit=<40steak> \ - --from=<name> \ - --chain-id=gaia-7001 -``` - - -### Increase deposit - -In order for a proposal to be broadcasted to the network, the amount deposited must be above a `minDeposit` value (default: `10 steak`). If the proposal you previously created didn't meet this requirement, you can still increase the total amount deposited to activate it. Once the minimum deposit is reached, the proposal enters voting period: - -```bash -gaiacli gov deposit \ - --proposalID=<proposal_id> \ - --depositer=<account_cosmosaccaddr> \ - --deposit=<200steak> \ - --from=<name> \ - --chain-id=gaia-7001 -``` - -> _NOTE_: Proposals that don't meet this requirement will be deleted after `MaxDepositPeriod` is reached. - -#### Query proposal - -Once created, you can now query information of the proposal: - -```bash -gaiacli gov query-proposal \ - --proposalID=<proposal_id> \ - --chain-id=gaia-7001 -``` - -### Vote on a proposal - -After a proposal's deposit reaches the `MinDeposit` value, the voting period opens. Bonded `Atom` holders can then cast vote on it: - -```bash -gaiacli gov vote \ - --proposalID=<proposal_id> \ - --voter=<account_cosmosaccaddr> \ - --option=<Yes/No/NoWithVeto/Abstain> \ - --from=<name> \ - --chain-id=gaia-7001 -``` - -#### Query vote - -Check the vote with the option you just submitted: - -```bash -gaiacli gov query-vote \ - --proposalID=<proposal_id> \ - --voter=<account_cosmosaccaddr> \ - --chain-id=gaia-7001 -``` - -## Other Operations - -### Send Tokens - -```bash -gaiacli send \ - --amount=10faucetToken \ - --chain-id=gaia-7001 \ - --from=<key_name> \ - --to=<destination_cosmosaccaddr> -``` - -> _*NOTE:*_ The `--amount` flag accepts the format `--amount=<value|coin_name>`. - -Now, view the updated balances of the origin and destination accounts: - -```bash -gaiacli account <account_cosmosaccaddr> -gaiacli account <destination_cosmosaccaddr> -``` - -You can also check your balance at a given block by using the `--block` flag: - -```bash -gaiacli account <account_cosmosaccaddr> --block=<block_height> -``` diff --git a/cmd/gaia/testnets/STATUS.md b/cmd/gaia/testnets/STATUS.md index 185df94c600f..0b4e9421bf5a 100644 --- a/cmd/gaia/testnets/STATUS.md +++ b/cmd/gaia/testnets/STATUS.md @@ -1,4 +1,6 @@ -# TESTNET STATUS +# DEPRECATED + +See [testnets repo](https://github.com/cosmos/testnets). ## *July 17, 2018, 4:00 EST* - New Testnet Gaia-7001 diff --git a/crypto/amino.go b/crypto/amino.go index 18d67e3d6a32..3a12c96815d6 100644 --- a/crypto/amino.go +++ b/crypto/amino.go @@ -2,14 +2,14 @@ package crypto import ( "github.com/tendermint/go-amino" - tcrypto "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/encoding/amino" ) var cdc = amino.NewCodec() func init() { RegisterAmino(cdc) - tcrypto.RegisterAmino(cdc) + cryptoAmino.RegisterAmino(cdc) } // RegisterAmino registers all go-crypto related types in the given (amino) codec. diff --git a/crypto/encode_test.go b/crypto/encode_test.go index 99dd727cf736..a2b5b1aea67b 100644 --- a/crypto/encode_test.go +++ b/crypto/encode_test.go @@ -1,11 +1,14 @@ package crypto import ( - "github.com/stretchr/testify/require" "os" "testing" + "github.com/stretchr/testify/require" + tcrypto "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/secp256k1" ) type byter interface { @@ -62,12 +65,12 @@ func TestKeyEncodings(t *testing.T) { privSize, pubSize int // binary sizes with the amino overhead }{ { - privKey: tcrypto.GenPrivKeyEd25519(), + privKey: ed25519.GenPrivKey(), privSize: 69, pubSize: 37, }, { - privKey: tcrypto.GenPrivKeySecp256k1(), + privKey: secp256k1.GenPrivKey(), privSize: 37, pubSize: 38, }, diff --git a/crypto/keys/hd/fundraiser_test.go b/crypto/keys/hd/fundraiser_test.go index f4112d958bc4..84de09758d59 100644 --- a/crypto/keys/hd/fundraiser_test.go +++ b/crypto/keys/hd/fundraiser_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/secp256k1" ) type addrData struct { @@ -57,7 +58,7 @@ func TestFundraiserCompatibility(t *testing.T) { master, ch := ComputeMastersFromSeed(seed) priv, err := DerivePrivateKeyForPath(master, ch, "44'/118'/0'/0/0") require.NoError(t, err) - pub := crypto.PrivKeySecp256k1(priv).PubKey() + pub := secp256k1.PrivKeySecp256k1(priv).PubKey() t.Log("\tNODEJS GOLANG\n") t.Logf("SEED \t%X %X\n", seedB, seed) @@ -70,7 +71,7 @@ func TestFundraiserCompatibility(t *testing.T) { require.Equal(t, priv[:], privB, "Expected priv keys to match") var pubBFixed [33]byte copy(pubBFixed[:], pubB) - require.Equal(t, pub, crypto.PubKeySecp256k1(pubBFixed), fmt.Sprintf("Expected pub keys to match for %d", i)) + require.Equal(t, pub, secp256k1.PubKeySecp256k1(pubBFixed), fmt.Sprintf("Expected pub keys to match for %d", i)) addr := pub.Address() t.Logf("ADDR \t%X %X\n", addrB, addr) diff --git a/crypto/keys/hd/hdpath.go b/crypto/keys/hd/hdpath.go index 1427752b4f09..ef2e6f783a2a 100644 --- a/crypto/keys/hd/hdpath.go +++ b/crypto/keys/hd/hdpath.go @@ -22,7 +22,7 @@ import ( "strings" "github.com/btcsuite/btcd/btcec" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/secp256k1" ) // BIP44Prefix is the parts of the BIP32 HD path that are fixed by what we used during the fundraiser. @@ -128,9 +128,9 @@ func derivePrivateKey(privKeyBytes [32]byte, chainCode [32]byte, index uint32, h data = append([]byte{byte(0)}, privKeyBytes[:]...) } else { // this can't return an error: - pubkey := crypto.PrivKeySecp256k1(privKeyBytes).PubKey() + pubkey := secp256k1.PrivKeySecp256k1(privKeyBytes).PubKey() - public := pubkey.(crypto.PubKeySecp256k1) + public := pubkey.(secp256k1.PubKeySecp256k1) data = public[:] } data = append(data, uint32ToBytes(index)...) diff --git a/crypto/keys/keybase.go b/crypto/keys/keybase.go index d9c1b5f57f90..aa1c0cdeb9f1 100644 --- a/crypto/keys/keybase.go +++ b/crypto/keys/keybase.go @@ -11,6 +11,8 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/hd" "github.com/pkg/errors" tmcrypto "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/encoding/amino" + "github.com/tendermint/tendermint/crypto/secp256k1" dbm "github.com/tendermint/tendermint/libs/db" ) @@ -163,9 +165,9 @@ func (kb *dbKeybase) persistDerivedKey(seed []byte, passwd, name, fullHdPath str // if we have a password, use it to encrypt the private key and store it // else store the public key only if passwd != "" { - info = kb.writeLocalKey(tmcrypto.PrivKeySecp256k1(derivedPriv), name, passwd) + info = kb.writeLocalKey(secp256k1.PrivKeySecp256k1(derivedPriv), name, passwd) } else { - pubk := tmcrypto.PrivKeySecp256k1(derivedPriv).PubKey() + pubk := secp256k1.PrivKeySecp256k1(derivedPriv).PubKey() info = kb.writeOfflineKey(pubk, name) } return @@ -314,7 +316,7 @@ func (kb dbKeybase) ImportPubKey(name string, armor string) (err error) { if err != nil { return } - pubKey, err := tmcrypto.PubKeyFromBytes(pubBytes) + pubKey, err := cryptoAmino.PubKeyFromBytes(pubBytes) if err != nil { return } diff --git a/crypto/keys/keybase_test.go b/crypto/keys/keybase_test.go index 1ca43179223d..7053896c67fc 100644 --- a/crypto/keys/keybase_test.go +++ b/crypto/keys/keybase_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" dbm "github.com/tendermint/tendermint/libs/db" ) @@ -69,7 +70,7 @@ func TestKeyManagement(t *testing.T) { // create an offline key o1 := "offline" - priv1 := crypto.GenPrivKeyEd25519() + priv1 := ed25519.GenPrivKey() pub1 := priv1.PubKey() i, err = cstore.CreateOffline(o1, pub1) require.Nil(t, err) diff --git a/crypto/keys/mintkey.go b/crypto/keys/mintkey.go index cfba18e092be..70e1bc44e259 100644 --- a/crypto/keys/mintkey.go +++ b/crypto/keys/mintkey.go @@ -8,6 +8,9 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/bcrypt" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/armor" + "github.com/tendermint/tendermint/crypto/encoding/amino" + "github.com/tendermint/tendermint/crypto/xsalsa20symmetric" ) const ( @@ -44,7 +47,7 @@ func armorBytes(bz []byte, blockType string) string { "type": "Info", "version": "0.0.0", } - return crypto.EncodeArmor(blockType, header, bz) + return armor.EncodeArmor(blockType, header, bz) } func unarmorInfoBytes(armorStr string) (bz []byte, err error) { @@ -56,7 +59,7 @@ func unarmorPubKeyBytes(armorStr string) (bz []byte, err error) { } func unarmorBytes(armorStr, blockType string) (bz []byte, err error) { - bType, header, bz, err := crypto.DecodeArmor(armorStr) + bType, header, bz, err := armor.DecodeArmor(armorStr) if err != nil { return } @@ -77,13 +80,13 @@ func encryptArmorPrivKey(privKey crypto.PrivKey, passphrase string) string { "kdf": "bcrypt", "salt": fmt.Sprintf("%X", saltBytes), } - armorStr := crypto.EncodeArmor(blockTypePrivKey, header, encBytes) + armorStr := armor.EncodeArmor(blockTypePrivKey, header, encBytes) return armorStr } func unarmorDecryptPrivKey(armorStr string, passphrase string) (crypto.PrivKey, error) { var privKey crypto.PrivKey - blockType, header, encBytes, err := crypto.DecodeArmor(armorStr) + blockType, header, encBytes, err := armor.DecodeArmor(armorStr) if err != nil { return privKey, err } @@ -112,7 +115,7 @@ func encryptPrivKey(privKey crypto.PrivKey, passphrase string) (saltBytes []byte } key = crypto.Sha256(key) // Get 32 bytes privKeyBytes := privKey.Bytes() - return saltBytes, crypto.EncryptSymmetric(privKeyBytes, key) + return saltBytes, xsalsa20symmetric.EncryptSymmetric(privKeyBytes, key) } func decryptPrivKey(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) { @@ -121,10 +124,10 @@ func decryptPrivKey(saltBytes []byte, encBytes []byte, passphrase string) (privK cmn.Exit("Error generating bcrypt key from passphrase: " + err.Error()) } key = crypto.Sha256(key) // Get 32 bytes - privKeyBytes, err := crypto.DecryptSymmetric(encBytes, key) + privKeyBytes, err := xsalsa20symmetric.DecryptSymmetric(encBytes, key) if err != nil { return privKey, err } - privKey, err = crypto.PrivKeyFromBytes(privKeyBytes) + privKey, err = cryptoAmino.PrivKeyFromBytes(privKeyBytes) return privKey, err } diff --git a/crypto/keys/wire.go b/crypto/keys/wire.go index 18e8e0f17f72..80a13539ae25 100644 --- a/crypto/keys/wire.go +++ b/crypto/keys/wire.go @@ -3,13 +3,13 @@ package keys import ( ccrypto "github.com/cosmos/cosmos-sdk/crypto" amino "github.com/tendermint/go-amino" - tcrypto "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/encoding/amino" ) var cdc = amino.NewCodec() func init() { - tcrypto.RegisterAmino(cdc) + cryptoAmino.RegisterAmino(cdc) cdc.RegisterInterface((*Info)(nil), nil) cdc.RegisterConcrete(ccrypto.PrivKeyLedgerSecp256k1{}, "tendermint/PrivKeyLedgerSecp256k1", nil) diff --git a/crypto/ledger_secp256k1.go b/crypto/ledger_secp256k1.go index 7a9f10c0dde9..4a9a435d6274 100644 --- a/crypto/ledger_secp256k1.go +++ b/crypto/ledger_secp256k1.go @@ -6,6 +6,7 @@ import ( secp256k1 "github.com/btcsuite/btcd/btcec" tmcrypto "github.com/tendermint/tendermint/crypto" + tmsecp256k1 "github.com/tendermint/tendermint/crypto/secp256k1" ) var ( @@ -140,7 +141,7 @@ func (pkl PrivKeyLedgerSecp256k1) signLedgerSecp256k1(msg []byte) (tmcrypto.Sign return nil, err } - return tmcrypto.SignatureSecp256k1FromBytes(sigBytes), nil + return tmsecp256k1.SignatureSecp256k1FromBytes(sigBytes), nil } func (pkl PrivKeyLedgerSecp256k1) pubkeyLedgerSecp256k1() (pub tmcrypto.PubKey, err error) { @@ -149,7 +150,7 @@ func (pkl PrivKeyLedgerSecp256k1) pubkeyLedgerSecp256k1() (pub tmcrypto.PubKey, return nil, fmt.Errorf("error fetching public key: %v", err) } - var pk tmcrypto.PubKeySecp256k1 + var pk tmsecp256k1.PubKeySecp256k1 // re-serialize in the 33-byte compressed format cmp, err := secp256k1.ParsePubKey(key[:], secp256k1.S256()) diff --git a/crypto/ledger_test.go b/crypto/ledger_test.go index 8e1a2ed65401..1aae158eff95 100644 --- a/crypto/ledger_test.go +++ b/crypto/ledger_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/stretchr/testify/require" - tmcrypto "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/encoding/amino" ) var ledgerEnabledEnv = "TEST_WITH_LEDGER" @@ -30,7 +30,7 @@ func TestRealLedgerSecp256k1(t *testing.T) { // now, let's serialize the public key and make sure it still works bs := priv.PubKey().Bytes() - pub2, err := tmcrypto.PubKeyFromBytes(bs) + pub2, err := cryptoAmino.PubKeyFromBytes(bs) require.Nil(t, err, "%+v", err) // make sure we get the same pubkey when we load from disk @@ -44,7 +44,7 @@ func TestRealLedgerSecp256k1(t *testing.T) { // make sure pubkeys serialize properly as well bs = pub.Bytes() - bpub, err := tmcrypto.PubKeyFromBytes(bs) + bpub, err := cryptoAmino.PubKeyFromBytes(bs) require.NoError(t, err) require.Equal(t, pub, bpub) } diff --git a/docs/getting-started/full-node.md b/docs/getting-started/full-node.md index 82583a3c9afc..1add3f8c0b19 100644 --- a/docs/getting-started/full-node.md +++ b/docs/getting-started/full-node.md @@ -1,5 +1,11 @@ # Join the Testnet +::: tip Current Testnet +See the [testnet repo](https://github.com/cosmos/testnets) for +information on the latest testnet, including the correct version +of the Cosmos-SDK to use and details about the genesis file. +::: + Please ensure you have the [Cosmos SDK](/getting-started/installation.md) installed. If you ran a full node on a previous testnet, please skip to [Upgrading From Previous Testnet](#upgrading-from-previous-testnet). ## Setting Up a New Node @@ -52,30 +58,40 @@ Now it is time to upgrade the software: ```bash cd $GOPATH/src/github.com/cosmos/cosmos-sdk -git fetch --all && git checkout v0.19.0 +git fetch --all && git checkout master make update_tools && make get_vendor_deps && make install ``` +Note we use `master` here since it contains the latest stable release. +See the [testnet repo](https://github.com/cosmos/testnets) +for details on which version is needed for which testnet, +and the [SDK release page](https://github.com/cosmos/cosmos-sdk/releases) +for details on each release. + Your full node has been cleanly upgraded! ## Genesis & Seeds ### Copy the Genesis File -Copy the testnet's `genesis.json` file and place it in `gaiad`'s config directory. +Fetch the testnet's `genesis.json` file into `gaiad`'s config directory. ```bash mkdir -p $HOME/.gaiad/config -cp -a $GOPATH/src/github.com/cosmos/cosmos-sdk/cmd/gaia/testnets/gaia-6002/genesis.json $HOME/.gaiad/config/genesis.json +curl https://raw.githubusercontent.com/cosmos/testnets/master/latest/genesis.json > $HOME/.gaiad/config/genesis.json ``` +Note we use the `latest` directory in the [testnets repo](https://github.com/cosmos/testnets) +which contains details for the latest testnet. If you are connecting to a different testnet, ensure you +get the right files. + ### Add Seed Nodes Your node needs to know how to find peers. You'll need to add healthy seed nodes to `$HOME/.gaiad/config/config.toml`. Here are some seed nodes you can use: ```toml # Comma separated list of seed nodes to connect to -seeds = "38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6002.coinculture.net:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@seed.cosmos.cryptium.ch:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656,032fa56301de335d835057fb6ad9f7ce2242a66d@165.227.236.213:46656" +seeds = "718145d422a823fd2a4e1e36e91b92bb0c4ddf8e@gaia-testnet.coinculture.net:26656,5922bf29b48a18c2300b85cc53f424fce23927ab@67.207.73.206:26656,7c8b8fd03577cd4817f5be1f03d506f879df98d8@gaia-7000-seed1.interblock.io:26656,a28737ff02391a6e00a1d3b79befd57e68e8264c@gaia-7000-seed2.interblock.io:26656,987ffd26640cd03d08ed7e53b24dfaa7956e612d@gaia-7000-seed3.interblock.io:26656" ``` If those seeds aren't working, you can find more seeds and persistent peers on the [Cosmos Explorer](https://explorecosmos.network/nodes). Open the the `Full Nodes` pane and select nodes that do not have private (`10.x.x.x`) or [local IP addresses](https://en.wikipedia.org/wiki/Private_network). The `Persistent Peer` field contains the connection string. For best results use 4-6. diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index 70922dc2054c..c23f3b02cdf6 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -20,12 +20,18 @@ echo "export PATH=$PATH:$GOBIN" >> ~/.bash_profile ## Install Cosmos SDK Next, let's install the testnet's version of the Cosmos SDK. +You can find information about the latest testnet and the right +version of the Cosmos-SDK for it in the [testnets +repo](https://github.com/cosmos/testnets#testnet-status). +Here we'll use the `master` branch, which contains the latest stable release. +If necessary, make sure you `git checkout` the correct +[released version](https://github.com/cosmos/cosmos-sdk/releases). ```bash mkdir -p $GOPATH/src/github.com/cosmos cd $GOPATH/src/github.com/cosmos git clone https://github.com/cosmos/cosmos-sdk -cd cosmos-sdk && git checkout v0.19.0 +cd cosmos-sdk && git checkout master make get_tools && make get_vendor_deps && make install ``` @@ -33,10 +39,7 @@ That will install the `gaiad` and `gaiacli` binaries. Verify that everything is ```bash $ gaiad version -0.19.0-c6711810 - $ gaiacli version -0.19.0-c6711810 ``` ## Run a Full Node diff --git a/docs/sdk/clients.md b/docs/sdk/clients.md index 9fa015908d7b..46a4756f1820 100644 --- a/docs/sdk/clients.md +++ b/docs/sdk/clients.md @@ -10,7 +10,6 @@ 🚧 We are actively working on improving documentation for Gaiacli and Gaiad. ::: - `gaiacli` is the command line interface to manage accounts and transactions on Cosmos testnets. Here is a list of useful `gaiacli` commands, including usage examples. ### Key Types @@ -18,18 +17,20 @@ There are three types of key representations that are used: - `cosmosaccaddr` - * Derived from account keys generated by `gaiacli keys add` - * Used to receive funds - * e.g. `cosmosaccaddr15h6vd5f0wqps26zjlwrc6chah08ryu4hzzdwhc` + + - Derived from account keys generated by `gaiacli keys add` + - Used to receive funds + - e.g. `cosmosaccaddr15h6vd5f0wqps26zjlwrc6chah08ryu4hzzdwhc` - `cosmosaccpub` - * Derived from account keys generated by `gaiacli keys add` - * e.g. `cosmosaccpub1zcjduc3q7fu03jnlu2xpl75s2nkt7krm6grh4cc5aqth73v0zwmea25wj2hsqhlqzm` + + - Derived from account keys generated by `gaiacli keys add` + - e.g. `cosmosaccpub1zcjduc3q7fu03jnlu2xpl75s2nkt7krm6grh4cc5aqth73v0zwmea25wj2hsqhlqzm` - `cosmosvalpub` - * Generated when the node is created with `gaiad init`. - * Get this value with `gaiad tendermint show_validator` - * e.g. `cosmosvalpub1zcjduc3qcyj09qc03elte23zwshdx92jm6ce88fgc90rtqhjx8v0608qh5ssp0w94c` + - Generated when the node is created with `gaiad init`. + - Get this value with `gaiad tendermint show_validator` + - e.g. `cosmosvalpub1zcjduc3qcyj09qc03elte23zwshdx92jm6ce88fgc90rtqhjx8v0608qh5ssp0w94c` ### Generate Keys @@ -62,7 +63,7 @@ gaiad tendermint show_validator ``` ::: danger Warning -We strongly recommend *NOT* using the same passphrase for multiple keys. The Tendermint team and the Interchain Foundation will not be responsible for the loss of funds. +We strongly recommend _NOT_ using the same passphrase for multiple keys. The Tendermint team and the Interchain Foundation will not be responsible for the loss of funds. ::: ### Get Tokens @@ -86,7 +87,7 @@ We're working on improving our error messages! ```bash gaiacli send \ --amount=10faucetToken \ - --chain-id=gaia-6002 \ + --chain-id=gaia-7005 \ --name=<key_name> \ --to=<destination_cosmosaccaddr> ``` @@ -122,13 +123,13 @@ gaiacli stake delegate \ --address-delegator=<account_cosmosaccaddr> \ --address-validator=$(gaiad tendermint show_validator) \ --name=<key_name> \ - --chain-id=gaia-6002 + --chain-id=gaia-7005 ``` While tokens are bonded, they are pooled with all the other bonded tokens in the network. Validators and delegators obtain a percentage of shares that equal their stake in this pool. ::: tip Note - Don't use more `steak` thank you have! You can always get more by using the [Faucet](https://faucetcosmos.network/)! +Don't use more `steak` thank you have! You can always get more by using the [Faucet](https://faucetcosmos.network/)! ::: ### Unbond Tokens @@ -141,7 +142,7 @@ gaiacli stake unbond \ --address-validator=$(gaiad tendermint show_validator) \ --shares=MAX \ --name=<key_name> \ - --chain-id=gaia-6002 + --chain-id=gaia-7005 ``` You can check your balance and your stake delegation to see that the unbonding went through successfully. @@ -152,7 +153,7 @@ gaiacli account <account_cosmosaccaddr> gaiacli stake delegation \ --address-delegator=<account_cosmosaccaddr> \ --address-validator=$(gaiad tendermint show_validator) \ - --chain-id=gaia-6002 + --chain-id=gaia-7005 ``` ## Light Client Daemon diff --git a/docs/sdk/core/examples/app2.go b/docs/sdk/core/examples/app2.go index 4c20c17c3a9c..12eab1c510b1 100644 --- a/docs/sdk/core/examples/app2.go +++ b/docs/sdk/core/examples/app2.go @@ -5,7 +5,7 @@ import ( "encoding/json" "fmt" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" cmn "github.com/tendermint/tendermint/libs/common" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" @@ -21,7 +21,7 @@ const ( ) var ( - issuer = crypto.GenPrivKeyEd25519().PubKey().Address() + issuer = ed25519.GenPrivKey().PubKey().Address() ) func NewCodec() *wire.Codec { diff --git a/docs/sdk/gaiacli.md b/docs/sdk/gaiacli.md index f42bfd14535f..d1b0261a09fe 100644 --- a/docs/sdk/gaiacli.md +++ b/docs/sdk/gaiacli.md @@ -7,18 +7,20 @@ There are three types of key representations that are used: - `cosmosaccaddr` - * Derived from account keys generated by `gaiacli keys add` - * Used to receive funds - * e.g. `cosmosaccaddr15h6vd5f0wqps26zjlwrc6chah08ryu4hzzdwhc` + + - Derived from account keys generated by `gaiacli keys add` + - Used to receive funds + - e.g. `cosmosaccaddr15h6vd5f0wqps26zjlwrc6chah08ryu4hzzdwhc` - `cosmosaccpub` - * Derived from account keys generated by `gaiacli keys add` - * e.g. `cosmosaccpub1zcjduc3q7fu03jnlu2xpl75s2nkt7krm6grh4cc5aqth73v0zwmea25wj2hsqhlqzm` + + - Derived from account keys generated by `gaiacli keys add` + - e.g. `cosmosaccpub1zcjduc3q7fu03jnlu2xpl75s2nkt7krm6grh4cc5aqth73v0zwmea25wj2hsqhlqzm` - `cosmosvalpub` - * Generated when the node is created with `gaiad init`. - * Get this value with `gaiad tendermint show_validator` - * e.g. `cosmosvalpub1zcjduc3qcyj09qc03elte23zwshdx92jm6ce88fgc90rtqhjx8v0608qh5ssp0w94c` + - Generated when the node is created with `gaiad init`. + - Get this value with `gaiad tendermint show_validator` + - e.g. `cosmosvalpub1zcjduc3qcyj09qc03elte23zwshdx92jm6ce88fgc90rtqhjx8v0608qh5ssp0w94c` ## Generate Keys @@ -51,7 +53,7 @@ gaiad tendermint show_validator ``` ::: danger Warning -We strongly recommend *NOT* using the same passphrase for multiple keys. The Tendermint team and the Interchain Foundation will not be responsible for the loss of funds. +We strongly recommend _NOT_ using the same passphrase for multiple keys. The Tendermint team and the Interchain Foundation will not be responsible for the loss of funds. ::: ## Get Tokens @@ -75,7 +77,7 @@ We're working on improving our error messages! ```bash gaiacli send \ --amount=10faucetToken \ - --chain-id=gaia-6002 \ + --chain-id=gaia-7005 \ --name=<key_name> \ --to=<destination_cosmosaccaddr> ``` @@ -111,13 +113,13 @@ gaiacli stake delegate \ --address-delegator=<account_cosmosaccaddr> \ --address-validator=$(gaiad tendermint show_validator) \ --name=<key_name> \ - --chain-id=gaia-6002 + --chain-id=gaia-7005 ``` While tokens are bonded, they are pooled with all the other bonded tokens in the network. Validators and delegators obtain a percentage of shares that equal their stake in this pool. ::: tip Note - Don't use more `steak` thank you have! You can always get more by using the [Faucet](https://faucetcosmos.network/)! +Don't use more `steak` thank you have! You can always get more by using the [Faucet](https://faucetcosmos.network/)! ::: ### Unbond Tokens @@ -130,7 +132,7 @@ gaiacli stake unbond \ --address-validator=$(gaiad tendermint show_validator) \ --shares=MAX \ --name=<key_name> \ - --chain-id=gaia-6002 + --chain-id=gaia-7005 ``` You can check your balance and your stake delegation to see that the unbonding went through successfully. @@ -141,5 +143,5 @@ gaiacli account <account_cosmosaccaddr> gaiacli stake delegation \ --address-delegator=<account_cosmosaccaddr> \ --address-validator=$(gaiad tendermint show_validator) \ - --chain-id=gaia-6002 + --chain-id=gaia-7005 ``` diff --git a/docs/validators/validator-setup.md b/docs/validators/validator-setup.md index f05aa6274723..8d5d045ef5f6 100644 --- a/docs/validators/validator-setup.md +++ b/docs/validators/validator-setup.md @@ -1,5 +1,9 @@ # Validator Setup +::: warning Current Testnet +The current testnet is `gaia-7005`. +::: + Before setting up your validator node, make sure you've already gone through the [Full Node Setup](/getting-started/full-node.md) guide. ## Running a Validator Node @@ -30,7 +34,7 @@ gaiacli stake create-validator \ --pubkey=$(gaiad tendermint show_validator) \ --address-validator=<account_cosmosaccaddr> --moniker="choose a moniker" \ - --chain-id=gaia-6002 \ + --chain-id=gaia-7005 \ --name=<key_name> ``` @@ -47,17 +51,18 @@ gaiacli stake edit-validator --website="https://cosmos.network" \ --keybase-sig="6A0D65E29A4CBC8E" --details="To infinity and beyond!" - --chain-id=gaia-6002 \ + --chain-id=gaia-7005 \ --name=<key_name> ``` ### View Validator Description + View the validator's information with this command: ```bash gaiacli stake validator \ --address-validator=<account_cosmosaccaddr> \ - --chain-id=gaia-6002 + --chain-id=gaia-7005 ``` ### Confirm Your Validator is Running @@ -79,7 +84,7 @@ To be in the validator set, you need to have more total voting power than the 10 ### Problem #1: My validator has `voting_power: 0` -Your validator has become auto-unbonded. In `gaia-6002`, we unbond validators if they do not vote on `50` of the last `100` blocks. Since blocks are proposed every ~2 seconds, a validator unresponsive for ~100 seconds will become unbonded. This usually happens when your `gaiad` process crashes. +Your validator has become auto-unbonded. In `gaia-7005`, we unbond validators if they do not vote on `50` of the last `100` blocks. Since blocks are proposed every ~2 seconds, a validator unresponsive for ~100 seconds will become unbonded. This usually happens when your `gaiad` process crashes. Here's how you can return the voting power back to your validator. First, if `gaiad` is not running, start it up again: @@ -90,7 +95,7 @@ gaiad start Wait for your full node to catch up to the latest block. Next, run the following command. Note that `<cosmosaccaddr>` is the address of your validator account, and `<name>` is the name of the validator account. You can find this info by running `gaiacli keys list`. ```bash -gaiacli stake unrevoke <cosmosaccaddr> --chain-id=gaia-6002 --name=<name> +gaiacli stake unrevoke <cosmosaccaddr> --chain-id=gaia-7005 --name=<name> ``` ::: danger Warning diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index 78f9e35a83bf..dad8191b356c 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -10,7 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" ) @@ -42,7 +42,7 @@ func TestGenesis(t *testing.T) { baseApp := NewBasecoinApp(logger, db) // construct a pubkey and an address for the test account - pubkey := crypto.GenPrivKeyEd25519().PubKey() + pubkey := ed25519.GenPrivKey().PubKey() addr := sdk.AccAddress(pubkey.Address()) // construct some test coins diff --git a/examples/democoin/app/app_test.go b/examples/democoin/app/app_test.go index b786af816e82..e964dbad2541 100644 --- a/examples/democoin/app/app_test.go +++ b/examples/democoin/app/app_test.go @@ -11,7 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" ) @@ -46,7 +46,7 @@ func TestGenesis(t *testing.T) { bapp := NewDemocoinApp(logger, db) // Construct some genesis bytes to reflect democoin/types/AppAccount - pk := crypto.GenPrivKeyEd25519().PubKey() + pk := ed25519.GenPrivKey().PubKey() addr := sdk.AccAddress(pk.Address()) coins, err := sdk.ParseCoins("77foocoin,99barcoin") require.Nil(t, err) diff --git a/examples/democoin/mock/validator.go b/examples/democoin/mock/validator.go index 84d41d4880f2..208636de98e8 100644 --- a/examples/democoin/mock/validator.go +++ b/examples/democoin/mock/validator.go @@ -82,6 +82,11 @@ func (vs *ValidatorSet) Validator(ctx sdk.Context, addr sdk.AccAddress) sdk.Vali return nil } +// ValidatorByPubKey implements sdk.ValidatorSet +func (vs *ValidatorSet) ValidatorByPubKey(ctx sdk.Context, pubkey crypto.PubKey) sdk.Validator { + panic("not implemented") +} + // TotalPower implements sdk.ValidatorSet func (vs *ValidatorSet) TotalPower(ctx sdk.Context) sdk.Rat { res := sdk.ZeroRat() diff --git a/examples/democoin/x/cool/app_test.go b/examples/democoin/x/cool/app_test.go index 269f0ae49c9a..71b4202bc332 100644 --- a/examples/democoin/x/cool/app_test.go +++ b/examples/democoin/x/cool/app_test.go @@ -9,11 +9,11 @@ import ( "github.com/cosmos/cosmos-sdk/x/mock" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" ) var ( - priv1 = crypto.GenPrivKeyEd25519() + priv1 = ed25519.GenPrivKey() pubKey = priv1.PubKey() addr1 = sdk.AccAddress(pubKey.Address()) diff --git a/examples/democoin/x/pow/app_test.go b/examples/democoin/x/pow/app_test.go index 32f57b8cb355..783f13d57bb6 100644 --- a/examples/democoin/x/pow/app_test.go +++ b/examples/democoin/x/pow/app_test.go @@ -11,11 +11,11 @@ import ( "github.com/cosmos/cosmos-sdk/x/mock" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" ) var ( - priv1 = crypto.GenPrivKeyEd25519() + priv1 = ed25519.GenPrivKey() addr1 = sdk.AccAddress(priv1.PubKey().Address()) ) diff --git a/examples/democoin/x/simplestake/client/cli/commands.go b/examples/democoin/x/simplestake/client/cli/commands.go index 20b5d9522122..20dc6fe97815 100644 --- a/examples/democoin/x/simplestake/client/cli/commands.go +++ b/examples/democoin/x/simplestake/client/cli/commands.go @@ -5,9 +5,9 @@ import ( "fmt" "github.com/spf13/cobra" - "github.com/spf13/viper" + "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto" + "github.com/spf13/viper" "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" @@ -55,7 +55,7 @@ func BondTxCmd(cdc *wire.Codec) *cobra.Command { if err != nil { return err } - var pubKeyEd crypto.PubKeyEd25519 + var pubKeyEd ed25519.PubKeyEd25519 copy(pubKeyEd[:], rawPubKey) msg := simplestake.NewMsgBond(from, stake, pubKeyEd) diff --git a/examples/democoin/x/simplestake/keeper_test.go b/examples/democoin/x/simplestake/keeper_test.go index 026f343465c2..91e60c50dcd6 100644 --- a/examples/democoin/x/simplestake/keeper_test.go +++ b/examples/democoin/x/simplestake/keeper_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" @@ -43,7 +43,7 @@ func TestKeeperGetSet(t *testing.T) { bi := stakeKeeper.getBondInfo(ctx, addr) require.Equal(t, bi, bondInfo{}) - privKey := crypto.GenPrivKeyEd25519() + privKey := ed25519.GenPrivKey() bi = bondInfo{ PubKey: privKey.PubKey(), @@ -69,7 +69,7 @@ func TestBonding(t *testing.T) { coinKeeper := bank.NewKeeper(accountMapper) stakeKeeper := NewKeeper(capKey, coinKeeper, DefaultCodespace) addr := sdk.AccAddress([]byte("some-address")) - privKey := crypto.GenPrivKeyEd25519() + privKey := ed25519.GenPrivKey() pubKey := privKey.PubKey() _, _, err := stakeKeeper.unbondWithoutCoins(ctx, addr) diff --git a/examples/democoin/x/simplestake/msgs_test.go b/examples/democoin/x/simplestake/msgs_test.go index fd6f3612a194..21f4e4abd5fc 100644 --- a/examples/democoin/x/simplestake/msgs_test.go +++ b/examples/democoin/x/simplestake/msgs_test.go @@ -4,14 +4,13 @@ import ( "testing" "github.com/stretchr/testify/require" - - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" ) func TestBondMsgValidation(t *testing.T) { - privKey := crypto.GenPrivKeyEd25519() + privKey := ed25519.GenPrivKey() cases := []struct { valid bool msgBond MsgBond diff --git a/server/export.go b/server/export.go index 5982e7b473d8..fa1c1907a1c3 100644 --- a/server/export.go +++ b/server/export.go @@ -30,7 +30,7 @@ func ExportCmd(ctx *Context, cdc *wire.Codec, appExporter AppExporter) *cobra.Co return err } - doc.AppStateJSON = appState + doc.AppState = appState doc.Validators = validators encoded, err := wire.MarshalJSONIndent(cdc, doc) diff --git a/server/init.go b/server/init.go index 7cf857c208c4..39f3d0b7f89a 100644 --- a/server/init.go +++ b/server/init.go @@ -346,9 +346,9 @@ func readOrCreatePrivValidator(tmConfig *cfg.Config) crypto.PubKey { // error is returned if building or writing the configuration to file fails. func writeGenesisFile(cdc *wire.Codec, genesisFile, chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage) error { genDoc := tmtypes.GenesisDoc{ - ChainID: chainID, - Validators: validators, - AppStateJSON: appState, + ChainID: chainID, + Validators: validators, + AppState: appState, } if err := genDoc.ValidateAndComplete(); err != nil { diff --git a/types/account.go b/types/account.go index daa3b614e8d7..92e2988f2470 100644 --- a/types/account.go +++ b/types/account.go @@ -7,6 +7,8 @@ import ( "fmt" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/encoding/amino" + "github.com/tendermint/tendermint/libs/bech32" ) @@ -225,7 +227,7 @@ func GetAccPubKeyBech32(address string) (pk crypto.PubKey, err error) { return nil, err } - pk, err = crypto.PubKeyFromBytes(bz) + pk, err = cryptoAmino.PubKeyFromBytes(bz) if err != nil { return nil, err } @@ -249,7 +251,7 @@ func GetValPubKeyBech32(pubkey string) (pk crypto.PubKey, err error) { return nil, err } - pk, err = crypto.PubKeyFromBytes(bz) + pk, err = cryptoAmino.PubKeyFromBytes(bz) if err != nil { return nil, err } diff --git a/types/stake.go b/types/stake.go index eb3f660820f3..c5e03e0d77a4 100644 --- a/types/stake.go +++ b/types/stake.go @@ -65,8 +65,9 @@ type ValidatorSet interface { IterateValidatorsBonded(Context, func(index int64, validator Validator) (stop bool)) - Validator(Context, AccAddress) Validator // get a particular validator by owner AccAddress - TotalPower(Context) Rat // total power of the validator set + Validator(Context, AccAddress) Validator // get a particular validator by owner AccAddress + ValidatorByPubKey(Context, crypto.PubKey) Validator // get a particular validator by signing PubKey + TotalPower(Context) Rat // total power of the validator set // slash the validator and delegators of the validator, specifying offence height, offence power, and slash fraction Slash(Context, crypto.PubKey, int64, int64, Rat) diff --git a/version/version.go b/version/version.go index c6361dd506a9..9b332353bc2c 100644 --- a/version/version.go +++ b/version/version.go @@ -2,10 +2,10 @@ package version const Maj = "0" -const Min = "22" -const Fix = "0" +const Min = "23" +const Fix = "1" -const Version = "0.22.0" +const Version = "0.23.1" // GitCommit set by build flags var GitCommit = "" diff --git a/wire/wire.go b/wire/wire.go index 679bf7c28a15..683149c99c59 100644 --- a/wire/wire.go +++ b/wire/wire.go @@ -5,7 +5,7 @@ import ( "encoding/json" amino "github.com/tendermint/go-amino" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/encoding/amino" ) // amino codec to marshal/unmarshal @@ -18,7 +18,7 @@ func NewCodec() *Codec { // Register the go-crypto to the codec func RegisterCrypto(cdc *Codec) { - crypto.RegisterAmino(cdc) + cryptoAmino.RegisterAmino(cdc) } // attempt to make some pretty json diff --git a/x/auth/account_test.go b/x/auth/account_test.go index 871f7f1c24b0..e6d669ba6986 100644 --- a/x/auth/account_test.go +++ b/x/auth/account_test.go @@ -6,13 +6,14 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" ) func keyPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.AccAddress) { - key := crypto.GenPrivKeyEd25519() + key := ed25519.GenPrivKey() pub := key.PubKey() addr := sdk.AccAddress(pub.Address()) return key, pub, addr diff --git a/x/auth/ante_test.go b/x/auth/ante_test.go index c30013d32fac..01fcab012f28 100644 --- a/x/auth/ante_test.go +++ b/x/auth/ante_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/log" sdk "github.com/cosmos/cosmos-sdk/types" @@ -32,7 +33,7 @@ func newCoins() sdk.Coins { // generate a priv key and return it with its address func privAndAddr() (crypto.PrivKey, sdk.AccAddress) { - priv := crypto.GenPrivKeyEd25519() + priv := ed25519.GenPrivKey() addr := sdk.AccAddress(priv.PubKey().Address()) return priv, addr } diff --git a/x/auth/stdtx_test.go b/x/auth/stdtx_test.go index bc9439663712..f6e3f8fc21e8 100644 --- a/x/auth/stdtx_test.go +++ b/x/auth/stdtx_test.go @@ -5,14 +5,13 @@ import ( "testing" "github.com/stretchr/testify/require" - - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" ) func TestStdTx(t *testing.T) { - priv := crypto.GenPrivKeyEd25519() + priv := ed25519.GenPrivKey() addr := sdk.AccAddress(priv.PubKey().Address()) msgs := []sdk.Msg{sdk.NewTestMsg(addr)} fee := newStdFee() @@ -27,7 +26,7 @@ func TestStdTx(t *testing.T) { } func TestStdSignBytes(t *testing.T) { - priv := crypto.GenPrivKeyEd25519() + priv := ed25519.GenPrivKey() addr := sdk.AccAddress(priv.PubKey().Address()) msgs := []sdk.Msg{sdk.NewTestMsg(addr)} fee := newStdFee() diff --git a/x/bank/app_test.go b/x/bank/app_test.go index 74a421bd7edf..4de8c8416944 100644 --- a/x/bank/app_test.go +++ b/x/bank/app_test.go @@ -13,17 +13,19 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" ) // test bank module in a mock application var ( - priv1 = crypto.GenPrivKeyEd25519() - addr1 = sdk.AccAddress(priv1.PubKey().Address()) - priv2 = crypto.GenPrivKeyEd25519() - addr2 = sdk.AccAddress(priv2.PubKey().Address()) - addr3 = sdk.AccAddress(crypto.GenPrivKeyEd25519().PubKey().Address()) - priv4 = crypto.GenPrivKeyEd25519() - addr4 = sdk.AccAddress(priv4.PubKey().Address()) + priv1 = ed25519.GenPrivKey() + addr1 = sdk.AccAddress(priv1.PubKey().Address()) + priv2 = ed25519.GenPrivKey() + addr2 = sdk.AccAddress(priv2.PubKey().Address()) + addr3 = sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()) + priv4 = ed25519.GenPrivKey() + addr4 = sdk.AccAddress(priv4.PubKey().Address()) + coins = sdk.Coins{sdk.NewCoin("foocoin", 10)} halfCoins = sdk.Coins{sdk.NewCoin("foocoin", 5)} manyCoins = sdk.Coins{sdk.NewCoin("foocoin", 1), sdk.NewCoin("barcoin", 1)} diff --git a/x/gov/client/cli/tx.go b/x/gov/client/cli/tx.go index 8369c9927394..8f30aefc10ea 100644 --- a/x/gov/client/cli/tx.go +++ b/x/gov/client/cli/tx.go @@ -245,3 +245,54 @@ func GetCmdQueryVote(storeName string, cdc *wire.Codec) *cobra.Command { return cmd } + +// Command to Get a Proposal Information +func GetCmdQueryVotes(storeName string, cdc *wire.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "query-votes", + Short: "query votes on a proposal", + RunE: func(cmd *cobra.Command, args []string) error { + proposalID := viper.GetInt64(flagProposalID) + + ctx := context.NewCoreContextFromViper() + + res, err := ctx.QueryStore(gov.KeyProposal(proposalID), storeName) + if len(res) == 0 || err != nil { + return errors.Errorf("proposalID [%d] does not exist", proposalID) + } + + var proposal gov.Proposal + cdc.MustUnmarshalBinary(res, &proposal) + + if proposal.GetStatus() != gov.StatusVotingPeriod { + fmt.Println("Proposal not in voting period.") + return nil + } + + res2, err := ctx.QuerySubspace(cdc, gov.KeyVotesSubspace(proposalID), storeName) + if err != nil { + return err + } + + var votes []gov.Vote + for i := 0; i < len(res2); i++ { + var vote gov.Vote + cdc.MustUnmarshalBinary(res2[i].Value, &vote) + votes = append(votes, vote) + } + + output, err := wire.MarshalJSONIndent(cdc, votes) + if err != nil { + return err + } + + fmt.Println(string(output)) + + return nil + }, + } + + cmd.Flags().String(flagProposalID, "", "proposalID of which proposal's votes are being queried") + + return cmd +} diff --git a/x/gov/client/rest/rest.go b/x/gov/client/rest/rest.go index 147304587126..b8fc781c086c 100644 --- a/x/gov/client/rest/rest.go +++ b/x/gov/client/rest/rest.go @@ -32,6 +32,8 @@ func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec) { r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/deposits/{%s}", RestProposalID, RestDepositer), queryDepositHandlerFn(cdc)).Methods("GET") r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/votes/{%s}", RestProposalID, RestVoter), queryVoteHandlerFn(cdc)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/votes", RestProposalID), queryVotesOnProposalHandlerFn(cdc)).Methods("GET") + r.HandleFunc("/gov/proposals", queryProposalsWithParameterFn(cdc)).Methods("GET") } @@ -334,6 +336,71 @@ func queryVoteHandlerFn(cdc *wire.Codec) http.HandlerFunc { } } +// nolint: gocyclo +// todo: Split this functionality into helper functions to remove the above +func queryVotesOnProposalHandlerFn(cdc *wire.Codec) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + strProposalID := vars[RestProposalID] + + if len(strProposalID) == 0 { + w.WriteHeader(http.StatusBadRequest) + err := errors.New("proposalId required but not specified") + w.Write([]byte(err.Error())) + return + } + + proposalID, err := strconv.ParseInt(strProposalID, 10, 64) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + err := errors.Errorf("proposalID [%s] is not positive", proposalID) + w.Write([]byte(err.Error())) + return + } + + ctx := context.NewCoreContextFromViper() + + res, err := ctx.QueryStore(gov.KeyProposal(proposalID), storeName) + if err != nil || len(res) == 0 { + err := errors.Errorf("proposalID [%d] does not exist", proposalID) + w.Write([]byte(err.Error())) + return + } + + var proposal gov.Proposal + cdc.MustUnmarshalBinary(res, &proposal) + + if proposal.GetStatus() != gov.StatusVotingPeriod { + err := errors.Errorf("proposal is not in Voting Period", proposalID) + w.Write([]byte(err.Error())) + return + } + + res2, err := ctx.QuerySubspace(cdc, gov.KeyVotesSubspace(proposalID), storeName) + if err != nil { + err = errors.New("ProposalID doesn't exist") + w.Write([]byte(err.Error())) + return + } + + var votes []gov.Vote + + for i := 0; i < len(res2); i++ { + var vote gov.Vote + cdc.MustUnmarshalBinary(res2[i].Value, &vote) + votes = append(votes, vote) + } + + output, err := wire.MarshalJSONIndent(cdc, votes) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return + } + w.Write(output) + } +} + // nolint: gocyclo // todo: Split this functionality into helper functions to remove the above func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc { diff --git a/x/gov/proposals.go b/x/gov/proposals.go index bb6b0aed4c71..61aafe577c73 100644 --- a/x/gov/proposals.go +++ b/x/gov/proposals.go @@ -167,11 +167,11 @@ func (pt *ProposalKind) UnmarshalJSON(data []byte) error { // Turns VoteOption byte to String func (pt ProposalKind) String() string { switch pt { - case 0x00: + case ProposalTypeText: return "Text" - case 0x01: + case ProposalTypeParameterChange: return "ParameterChange" - case 0x02: + case ProposalTypeSoftwareUpgrade: return "SoftwareUpgrade" default: return "" diff --git a/x/gov/tally.go b/x/gov/tally.go index 38462e72d0ff..2d8e85f7b2c6 100644 --- a/x/gov/tally.go +++ b/x/gov/tally.go @@ -48,16 +48,16 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, nonV } else { keeper.ds.IterateDelegations(ctx, vote.Voter, func(index int64, delegation sdk.Delegation) (stop bool) { - val := currValidators[delegation.GetValidator().String()] - val.Minus = val.Minus.Add(delegation.GetBondShares()) - currValidators[delegation.GetValidator().String()] = val + if val, ok := currValidators[delegation.GetValidator().String()]; ok { + val.Minus = val.Minus.Add(delegation.GetBondShares()) + currValidators[delegation.GetValidator().String()] = val - delegatorShare := delegation.GetBondShares().Quo(val.DelegatorShares) - votingPower := val.Power.Mul(delegatorShare) - - results[vote.Option] = results[vote.Option].Add(votingPower) - totalVotingPower = totalVotingPower.Add(votingPower) + delegatorShare := delegation.GetBondShares().Quo(val.DelegatorShares) + votingPower := val.Power.Mul(delegatorShare) + results[vote.Option] = results[vote.Option].Add(votingPower) + totalVotingPower = totalVotingPower.Add(votingPower) + } return false }) } diff --git a/x/gov/tally_test.go b/x/gov/tally_test.go index bcc3f2eb013e..545912a8198c 100644 --- a/x/gov/tally_test.go +++ b/x/gov/tally_test.go @@ -7,7 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/cosmos/cosmos-sdk/x/stake" ) @@ -19,9 +19,9 @@ func TestTallyNoOneVotes(t *testing.T) { stakeHandler := stake.NewHandler(sk) dummyDescription := stake.NewDescription("T", "E", "S", "T") - val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) + val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) stakeHandler(ctx, val1CreateMsg) - val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) + val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) stakeHandler(ctx, val2CreateMsg) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) @@ -41,10 +41,10 @@ func TestTallyOnlyValidatorsAllYes(t *testing.T) { stakeHandler := stake.NewHandler(sk) dummyDescription := stake.NewDescription("T", "E", "S", "T") - val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) + val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) res := stakeHandler(ctx, val1CreateMsg) require.True(t, res.IsOK()) - val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) + val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) res = stakeHandler(ctx, val2CreateMsg) require.True(t, res.IsOK()) @@ -70,9 +70,9 @@ func TestTallyOnlyValidators51No(t *testing.T) { stakeHandler := stake.NewHandler(sk) dummyDescription := stake.NewDescription("T", "E", "S", "T") - val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) + val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) stakeHandler(ctx, val1CreateMsg) - val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val2CreateMsg) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) @@ -97,11 +97,11 @@ func TestTallyOnlyValidators51Yes(t *testing.T) { stakeHandler := stake.NewHandler(sk) dummyDescription := stake.NewDescription("T", "E", "S", "T") - val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val1CreateMsg) - val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val2CreateMsg) - val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) + val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) stakeHandler(ctx, val3CreateMsg) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) @@ -128,11 +128,11 @@ func TestTallyOnlyValidatorsVetoed(t *testing.T) { stakeHandler := stake.NewHandler(sk) dummyDescription := stake.NewDescription("T", "E", "S", "T") - val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val1CreateMsg) - val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val2CreateMsg) - val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) + val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) stakeHandler(ctx, val3CreateMsg) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) @@ -159,11 +159,11 @@ func TestTallyOnlyValidatorsAbstainPasses(t *testing.T) { stakeHandler := stake.NewHandler(sk) dummyDescription := stake.NewDescription("T", "E", "S", "T") - val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val1CreateMsg) - val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val2CreateMsg) - val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) + val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) stakeHandler(ctx, val3CreateMsg) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) @@ -190,11 +190,11 @@ func TestTallyOnlyValidatorsAbstainFails(t *testing.T) { stakeHandler := stake.NewHandler(sk) dummyDescription := stake.NewDescription("T", "E", "S", "T") - val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val1CreateMsg) - val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val2CreateMsg) - val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) + val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) stakeHandler(ctx, val3CreateMsg) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) @@ -221,11 +221,11 @@ func TestTallyOnlyValidatorsNonVoter(t *testing.T) { stakeHandler := stake.NewHandler(sk) dummyDescription := stake.NewDescription("T", "E", "S", "T") - val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val1CreateMsg) - val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val2CreateMsg) - val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) + val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) stakeHandler(ctx, val3CreateMsg) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) @@ -252,11 +252,11 @@ func TestTallyDelgatorOverride(t *testing.T) { stakeHandler := stake.NewHandler(sk) dummyDescription := stake.NewDescription("T", "E", "S", "T") - val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) + val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) stakeHandler(ctx, val1CreateMsg) - val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val2CreateMsg) - val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) + val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) stakeHandler(ctx, val3CreateMsg) delegator1Msg := stake.NewMsgDelegate(addrs[3], addrs[2], sdk.NewCoin("steak", 30)) @@ -288,11 +288,11 @@ func TestTallyDelgatorInherit(t *testing.T) { stakeHandler := stake.NewHandler(sk) dummyDescription := stake.NewDescription("T", "E", "S", "T") - val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) + val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) stakeHandler(ctx, val1CreateMsg) - val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val2CreateMsg) - val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) + val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) stakeHandler(ctx, val3CreateMsg) delegator1Msg := stake.NewMsgDelegate(addrs[3], addrs[2], sdk.NewCoin("steak", 30)) @@ -323,11 +323,11 @@ func TestTallyDelgatorMultipleOverride(t *testing.T) { stakeHandler := stake.NewHandler(sk) dummyDescription := stake.NewDescription("T", "E", "S", "T") - val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) + val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 5), dummyDescription) stakeHandler(ctx, val1CreateMsg) - val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val2CreateMsg) - val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) + val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) stakeHandler(ctx, val3CreateMsg) delegator1Msg := stake.NewMsgDelegate(addrs[3], addrs[2], sdk.NewCoin("steak", 10)) @@ -361,11 +361,11 @@ func TestTallyDelgatorMultipleInherit(t *testing.T) { stakeHandler := stake.NewHandler(sk) dummyDescription := stake.NewDescription("T", "E", "S", "T") - val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 25), dummyDescription) + val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 25), dummyDescription) stakeHandler(ctx, val1CreateMsg) - val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) stakeHandler(ctx, val2CreateMsg) - val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], crypto.GenPrivKeyEd25519().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) + val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) stakeHandler(ctx, val3CreateMsg) delegator1Msg := stake.NewMsgDelegate(addrs[3], addrs[2], sdk.NewCoin("steak", 10)) @@ -389,3 +389,43 @@ func TestTallyDelgatorMultipleInherit(t *testing.T) { require.False(t, passes) } + +func TestTallyRevokedValidator(t *testing.T) { + mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) + mapp.BeginBlock(abci.RequestBeginBlock{}) + ctx := mapp.BaseApp.NewContext(false, abci.Header{}) + stakeHandler := stake.NewHandler(sk) + + dummyDescription := stake.NewDescription("T", "E", "S", "T") + val1CreateMsg := stake.NewMsgCreateValidator(addrs[0], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 25), dummyDescription) + stakeHandler(ctx, val1CreateMsg) + val2CreateMsg := stake.NewMsgCreateValidator(addrs[1], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 6), dummyDescription) + stakeHandler(ctx, val2CreateMsg) + val3CreateMsg := stake.NewMsgCreateValidator(addrs[2], ed25519.GenPrivKey().PubKey(), sdk.NewCoin("steak", 7), dummyDescription) + stakeHandler(ctx, val3CreateMsg) + + delegator1Msg := stake.NewMsgDelegate(addrs[3], addrs[2], sdk.NewCoin("steak", 10)) + stakeHandler(ctx, delegator1Msg) + delegator1Msg2 := stake.NewMsgDelegate(addrs[3], addrs[1], sdk.NewCoin("steak", 10)) + stakeHandler(ctx, delegator1Msg2) + + val2, found := sk.GetValidator(ctx, addrs[1]) + require.True(t, found) + sk.Revoke(ctx, val2.PubKey) + + proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) + proposalID := proposal.GetProposalID() + proposal.SetStatus(StatusVotingPeriod) + keeper.SetProposal(ctx, proposal) + + err := keeper.AddVote(ctx, proposalID, addrs[0], OptionYes) + require.Nil(t, err) + err = keeper.AddVote(ctx, proposalID, addrs[1], OptionNo) + require.Nil(t, err) + err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo) + require.Nil(t, err) + + passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID)) + + require.True(t, passes) +} diff --git a/x/ibc/app_test.go b/x/ibc/app_test.go index 4c559cb35036..d853c798700a 100644 --- a/x/ibc/app_test.go +++ b/x/ibc/app_test.go @@ -11,7 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/mock" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" ) // initialize the mock application for this module @@ -34,7 +34,7 @@ func TestIBCMsgs(t *testing.T) { sourceChain := "source-chain" destChain := "dest-chain" - priv1 := crypto.GenPrivKeyEd25519() + priv1 := ed25519.GenPrivKey() addr1 := sdk.AccAddress(priv1.PubKey().Address()) coins := sdk.Coins{sdk.NewCoin("foocoin", 10)} var emptyCoins sdk.Coins diff --git a/x/ibc/ibc_test.go b/x/ibc/ibc_test.go index 06e2bd167adb..d88204c7030c 100644 --- a/x/ibc/ibc_test.go +++ b/x/ibc/ibc_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" @@ -29,7 +29,7 @@ func defaultContext(key sdk.StoreKey) sdk.Context { } func newAddress() sdk.AccAddress { - return sdk.AccAddress(crypto.GenPrivKeyEd25519().PubKey().Address()) + return sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()) } func getCoins(ck bank.Keeper, ctx sdk.Context, addr sdk.AccAddress) (sdk.Coins, sdk.Error) { diff --git a/x/mock/app.go b/x/mock/app.go index 27f3b9d46e72..cb013f972516 100644 --- a/x/mock/app.go +++ b/x/mock/app.go @@ -10,6 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" ) @@ -97,7 +98,7 @@ func (app *App) InitChainer(ctx sdk.Context, _ abci.RequestInitChain) abci.Respo // their addresses, pubkeys, and privkeys. func CreateGenAccounts(numAccs int, genCoins sdk.Coins) (genAccs []auth.Account, addrs []sdk.AccAddress, pubKeys []crypto.PubKey, privKeys []crypto.PrivKey) { for i := 0; i < numAccs; i++ { - privKey := crypto.GenPrivKeyEd25519() + privKey := ed25519.GenPrivKey() pubKey := privKey.PubKey() addr := sdk.AccAddress(pubKey.Address()) @@ -158,7 +159,7 @@ func GeneratePrivKeys(n int) (keys []crypto.PrivKey) { // TODO: Randomize this between ed25519 and secp256k1 keys = make([]crypto.PrivKey, n, n) for i := 0; i < n; i++ { - keys[i] = crypto.GenPrivKeyEd25519() + keys[i] = ed25519.GenPrivKey() } return @@ -170,7 +171,7 @@ func GeneratePrivKeyAddressPairs(n int) (keys []crypto.PrivKey, addrs []sdk.AccA keys = make([]crypto.PrivKey, n, n) addrs = make([]sdk.AccAddress, n, n) for i := 0; i < n; i++ { - keys[i] = crypto.GenPrivKeyEd25519() + keys[i] = ed25519.GenPrivKey() addrs[i] = sdk.AccAddress(keys[i].PubKey().Address()) } return diff --git a/x/slashing/app_test.go b/x/slashing/app_test.go index c249134ac12d..e7b660d15e08 100644 --- a/x/slashing/app_test.go +++ b/x/slashing/app_test.go @@ -10,11 +10,11 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" ) var ( - priv1 = crypto.GenPrivKeyEd25519() + priv1 = ed25519.GenPrivKey() addr1 = sdk.AccAddress(priv1.PubKey().Address()) coins = sdk.Coins{sdk.NewCoin("foocoin", 10)} ) diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index 9f1ff205b5a1..648f9eaf969c 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -61,6 +61,7 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, pubkey crypto.PubKey, infracti } // handle a validator signature, must be called once per validator per block +// nolint gocyclo func (k Keeper) handleValidatorSignature(ctx sdk.Context, pubkey crypto.PubKey, power int64, signed bool) { logger := ctx.Logger().With("module", "x/slashing") height := ctx.BlockHeight() @@ -97,11 +98,19 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, pubkey crypto.PubKey, } minHeight := signInfo.StartHeight + SignedBlocksWindow if height > minHeight && signInfo.SignedBlocksCounter < MinSignedPerWindow { - // Downtime confirmed, slash, revoke, and jail the validator - logger.Info(fmt.Sprintf("Validator %s past min height of %d and below signed blocks threshold of %d", pubkey.Address(), minHeight, MinSignedPerWindow)) - k.validatorSet.Slash(ctx, pubkey, height, power, SlashFractionDowntime) - k.validatorSet.Revoke(ctx, pubkey) - signInfo.JailedUntil = ctx.BlockHeader().Time + DowntimeUnbondDuration + validator := k.validatorSet.ValidatorByPubKey(ctx, pubkey) + if validator != nil && !validator.GetRevoked() { + // Downtime confirmed, slash, revoke, and jail the validator + logger.Info(fmt.Sprintf("Validator %s past min height of %d and below signed blocks threshold of %d", + pubkey.Address(), minHeight, MinSignedPerWindow)) + k.validatorSet.Slash(ctx, pubkey, height, power, SlashFractionDowntime) + k.validatorSet.Revoke(ctx, pubkey) + signInfo.JailedUntil = ctx.BlockHeader().Time + DowntimeUnbondDuration + } else { + // Validator was (a) not found or (b) already revoked, don't slash + logger.Info(fmt.Sprintf("Validator %s would have been slashed for downtime, but was either not found in store or already revoked", + pubkey.Address())) + } } // Set the updated signing info diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index 794bc2c92c70..d85db77c0850 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -129,7 +129,8 @@ func TestHandleAbsentValidator(t *testing.T) { // validator should have been slashed pool = sk.GetPool(ctx) - require.Equal(t, int64(amtInt-1), pool.BondedTokens.RoundInt64()) + slashAmt := sdk.NewRat(amtInt).Mul(SlashFractionDowntime).RoundInt64() + require.Equal(t, int64(amtInt)-slashAmt, pool.BondedTokens.RoundInt64()) // validator start height should have been changed info, found = keeper.getValidatorSigningInfo(ctx, sdk.ValAddress(val.Address())) @@ -196,3 +197,47 @@ func TestHandleNewValidator(t *testing.T) { pool := sk.GetPool(ctx) require.Equal(t, int64(100), pool.BondedTokens.RoundInt64()) } + +// Test a revoked validator being "down" twice +// Ensure that they're only slashed once +func TestHandleAlreadyRevoked(t *testing.T) { + + // initial setup + ctx, _, sk, keeper := createTestInput(t) + amtInt := int64(100) + addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt) + sh := stake.NewHandler(sk) + got := sh(ctx, newTestMsgCreateValidator(addr, val, amt)) + require.True(t, got.IsOK()) + stake.EndBlocker(ctx, sk) + + // 1000 first blocks OK + height := int64(0) + for ; height < SignedBlocksWindow; height++ { + ctx = ctx.WithBlockHeight(height) + keeper.handleValidatorSignature(ctx, val, amtInt, true) + } + + // 501 blocks missed + for ; height < SignedBlocksWindow+(SignedBlocksWindow-MinSignedPerWindow)+1; height++ { + ctx = ctx.WithBlockHeight(height) + keeper.handleValidatorSignature(ctx, val, amtInt, false) + } + + // validator should have been revoked and slashed + validator, _ := sk.GetValidatorByPubKey(ctx, val) + require.Equal(t, sdk.Unbonded, validator.GetStatus()) + + // validator should have been slashed + slashAmt := sdk.NewRat(amtInt).Mul(SlashFractionDowntime).RoundInt64() + require.Equal(t, int64(amtInt)-slashAmt, validator.Tokens.RoundInt64()) // TODO replace w/ .GetTokens() + + // another block missed + ctx = ctx.WithBlockHeight(height) + keeper.handleValidatorSignature(ctx, val, amtInt, false) + + // validator should not have been slashed twice + validator, _ = sk.GetValidatorByPubKey(ctx, val) + require.Equal(t, int64(amtInt)-slashAmt, validator.Tokens.RoundInt64()) // TODO replace w/ .GetTokens() + +} diff --git a/x/slashing/params.go b/x/slashing/params.go index ebf14f283d4f..7a11737f95be 100644 --- a/x/slashing/params.go +++ b/x/slashing/params.go @@ -14,7 +14,7 @@ var ( // SignedBlocksWindow - sliding window for downtime slashing // TODO Governance parameter? // TODO Temporarily set to 40000 blocks for testnets - SignedBlocksWindow int64 = 40000 + SignedBlocksWindow int64 = 10000 // Downtime slashing threshold - 50% // TODO Governance parameter? @@ -38,5 +38,5 @@ var ( // SlashFractionDowntime - currently 1% // TODO Governance parameter? - SlashFractionDowntime = sdk.NewRat(1).Quo(sdk.NewRat(100)) + SlashFractionDowntime = sdk.NewRat(10).Quo(sdk.NewRat(100)) ) diff --git a/x/slashing/test_common.go b/x/slashing/test_common.go index 464796192279..89dabbd43ef9 100644 --- a/x/slashing/test_common.go +++ b/x/slashing/test_common.go @@ -9,6 +9,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" @@ -84,7 +85,7 @@ func newPubKey(pk string) (res crypto.PubKey) { if err != nil { panic(err) } - var pkEd crypto.PubKeyEd25519 + var pkEd ed25519.PubKeyEd25519 copy(pkEd[:], pkBytes[:]) return pkEd } diff --git a/x/stake/app_test.go b/x/stake/app_test.go index 606369cd65bb..d1183e6c922b 100644 --- a/x/stake/app_test.go +++ b/x/stake/app_test.go @@ -9,16 +9,16 @@ import ( "github.com/cosmos/cosmos-sdk/x/mock" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" ) var ( - priv1 = crypto.GenPrivKeyEd25519() + priv1 = ed25519.GenPrivKey() addr1 = sdk.AccAddress(priv1.PubKey().Address()) - priv2 = crypto.GenPrivKeyEd25519() + priv2 = ed25519.GenPrivKey() addr2 = sdk.AccAddress(priv2.PubKey().Address()) - addr3 = sdk.AccAddress(crypto.GenPrivKeyEd25519().PubKey().Address()) - priv4 = crypto.GenPrivKeyEd25519() + addr3 = sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()) + priv4 = ed25519.GenPrivKey() addr4 = sdk.AccAddress(priv4.PubKey().Address()) coins = sdk.Coins{{"foocoin", sdk.NewInt(10)}} fee = auth.StdFee{ diff --git a/x/stake/genesis.go b/x/stake/genesis.go index e54517fa5fd4..b4ed80e51482 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -17,7 +17,7 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) error keeper.SetNewParams(ctx, data.Params) keeper.InitIntraTxCounter(ctx) - for _, validator := range data.Validators { + for i, validator := range data.Validators { keeper.SetValidator(ctx, validator) if validator.Tokens.IsZero() { @@ -29,6 +29,8 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) error // Manually set indexes for the first time keeper.SetValidatorByPubKeyIndex(ctx, validator) + + validator.BondIntraTxCounter = int16(i) // set the intra-tx counter to the order the validators are presented keeper.SetValidatorByPowerIndex(ctx, validator, data.Pool) if validator.Status == sdk.Bonded { diff --git a/x/stake/genesis_test.go b/x/stake/genesis_test.go index 2faff5bc02d6..e27c7fed2c2c 100644 --- a/x/stake/genesis_test.go +++ b/x/stake/genesis_test.go @@ -14,23 +14,35 @@ func TestInitGenesis(t *testing.T) { ctx, _, keeper := keep.CreateTestInput(t, false, 1000) pool := keeper.GetPool(ctx) - pool.LooseTokens = sdk.OneRat() + pool.LooseTokens = sdk.NewRat(2) params := keeper.GetParams(ctx) var delegations []Delegation validators := []Validator{ NewValidator(keep.Addrs[0], keep.PKs[0], Description{Moniker: "hoop"}), + NewValidator(keep.Addrs[1], keep.PKs[1], Description{Moniker: "bloop"}), } - genesisState := types.NewGenesisState(pool, params, validators, delegations) err := InitGenesis(ctx, keeper, genesisState) require.Error(t, err) + // initialize the validators validators[0].Tokens = sdk.OneRat() validators[0].DelegatorShares = sdk.OneRat() + validators[1].Tokens = sdk.OneRat() + validators[1].DelegatorShares = sdk.OneRat() genesisState = types.NewGenesisState(pool, params, validators, delegations) err = InitGenesis(ctx, keeper, genesisState) require.NoError(t, err) + + // now make sure the validators are bonded + resVal, found := keeper.GetValidator(ctx, keep.Addrs[0]) + require.True(t, found) + require.Equal(t, sdk.Bonded, resVal.Status) + + resVal, found = keeper.GetValidator(ctx, keep.Addrs[1]) + require.True(t, found) + require.Equal(t, sdk.Bonded, resVal.Status) } diff --git a/x/stake/handler.go b/x/stake/handler.go index b39298edebc1..14fb4f7bfffe 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -39,7 +39,7 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) (ValidatorUpdates []abci.Valid // Process types.Validator Provisions blockTime := ctx.BlockHeader().Time - if pool.InflationLastTime+blockTime >= 3600 { + if blockTime-pool.InflationLastTime >= 3600 { pool.InflationLastTime = blockTime pool = pool.ProcessProvisions(params) } diff --git a/x/stake/keeper/sdk_types.go b/x/stake/keeper/sdk_types.go index 280320649601..9c331147447e 100644 --- a/x/stake/keeper/sdk_types.go +++ b/x/stake/keeper/sdk_types.go @@ -3,6 +3,8 @@ package keeper import ( "fmt" + "github.com/tendermint/tendermint/crypto" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake/types" ) @@ -57,6 +59,15 @@ func (k Keeper) Validator(ctx sdk.Context, address sdk.AccAddress) sdk.Validator return val } +// get the sdk.validator for a particular pubkey +func (k Keeper) ValidatorByPubKey(ctx sdk.Context, pubkey crypto.PubKey) sdk.Validator { + val, found := k.GetValidatorByPubKey(ctx, pubkey) + if !found { + return nil + } + return val +} + // total power from the bond func (k Keeper) TotalPower(ctx sdk.Context) sdk.Rat { pool := k.GetPool(ctx) diff --git a/x/stake/keeper/test_common.go b/x/stake/keeper/test_common.go index db7e382d5485..250a453b374a 100644 --- a/x/stake/keeper/test_common.go +++ b/x/stake/keeper/test_common.go @@ -10,6 +10,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" @@ -131,7 +132,7 @@ func NewPubKey(pk string) (res crypto.PubKey) { panic(err) } //res, err = crypto.PubKeyFromBytes(pkBytes) - var pkEd crypto.PubKeyEd25519 + var pkEd ed25519.PubKeyEd25519 copy(pkEd[:], pkBytes[:]) return pkEd } diff --git a/x/stake/types/test_utils.go b/x/stake/types/test_utils.go index 104eae3d315f..8a7f4a56e5b6 100644 --- a/x/stake/types/test_utils.go +++ b/x/stake/types/test_utils.go @@ -8,12 +8,13 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" ) var ( - pk1 = crypto.GenPrivKeyEd25519().PubKey() - pk2 = crypto.GenPrivKeyEd25519().PubKey() - pk3 = crypto.GenPrivKeyEd25519().PubKey() + pk1 = ed25519.GenPrivKey().PubKey() + pk2 = ed25519.GenPrivKey().PubKey() + pk3 = ed25519.GenPrivKey().PubKey() addr1 = sdk.AccAddress(pk1.Address()) addr2 = sdk.AccAddress(pk2.Address()) addr3 = sdk.AccAddress(pk3.Address()) diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index ed109830f035..f177c123d07e 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -147,6 +147,34 @@ func UnmarshalValidator(cdc *wire.Codec, ownerAddr, value []byte) (validator Val }, nil } +// HumanReadableString returns a human readable string representation of a +// validator. An error is returned if the owner or the owner's public key +// cannot be converted to Bech32 format. +func (v Validator) HumanReadableString() (string, error) { + bechVal, err := sdk.Bech32ifyValPub(v.PubKey) + if err != nil { + return "", err + } + + resp := "Validator \n" + resp += fmt.Sprintf("Owner: %s\n", v.Owner) + resp += fmt.Sprintf("Validator: %s\n", bechVal) + resp += fmt.Sprintf("Revoked: %v\n", v.Revoked) + resp += fmt.Sprintf("Status: %s\n", sdk.BondStatusToString(v.Status)) + resp += fmt.Sprintf("Tokens: %s\n", v.Tokens.FloatString()) + resp += fmt.Sprintf("Delegator Shares: %s\n", v.DelegatorShares.FloatString()) + resp += fmt.Sprintf("Description: %s\n", v.Description) + resp += fmt.Sprintf("Bond Height: %d\n", v.BondHeight) + resp += fmt.Sprintf("Proposer Reward Pool: %s\n", v.ProposerRewardPool.String()) + resp += fmt.Sprintf("Commission: %s\n", v.Commission.String()) + resp += fmt.Sprintf("Max Commission Rate: %s\n", v.CommissionMax.String()) + resp += fmt.Sprintf("Commission Change Rate: %s\n", v.CommissionChangeRate.String()) + resp += fmt.Sprintf("Commission Change Today: %s\n", v.CommissionChangeToday.String()) + resp += fmt.Sprintf("Previous Bonded Tokens: %s\n", v.LastBondedTokens.String()) + + return resp, nil +} + //___________________________________________________________________ // validator struct for bech output @@ -408,30 +436,3 @@ func (v Validator) GetPubKey() crypto.PubKey { return v.PubKey } func (v Validator) GetPower() sdk.Rat { return v.BondedTokens() } func (v Validator) GetDelegatorShares() sdk.Rat { return v.DelegatorShares } func (v Validator) GetBondHeight() int64 { return v.BondHeight } - -// HumanReadableString returns a human readable string representation of a -// validator. An error is returned if the owner or the owner's public key -// cannot be converted to Bech32 format. -func (v Validator) HumanReadableString() (string, error) { - bechVal, err := sdk.Bech32ifyValPub(v.PubKey) - if err != nil { - return "", err - } - - resp := "Validator \n" - resp += fmt.Sprintf("Owner: %s\n", v.Owner) - resp += fmt.Sprintf("Validator: %s\n", bechVal) - resp += fmt.Sprintf("Status: %s\n", sdk.BondStatusToString(v.Status)) - resp += fmt.Sprintf("Tokens: %s\n", v.Tokens.FloatString()) - resp += fmt.Sprintf("Delegator Shares: %s\n", v.DelegatorShares.FloatString()) - resp += fmt.Sprintf("Description: %s\n", v.Description) - resp += fmt.Sprintf("Bond Height: %d\n", v.BondHeight) - resp += fmt.Sprintf("Proposer Reward Pool: %s\n", v.ProposerRewardPool.String()) - resp += fmt.Sprintf("Commission: %s\n", v.Commission.String()) - resp += fmt.Sprintf("Max Commission Rate: %s\n", v.CommissionMax.String()) - resp += fmt.Sprintf("Commission Change Rate: %s\n", v.CommissionChangeRate.String()) - resp += fmt.Sprintf("Commission Change Today: %s\n", v.CommissionChangeToday.String()) - resp += fmt.Sprintf("Previous Bonded Tokens: %s\n", v.LastBondedTokens.String()) - - return resp, nil -}