diff --git a/.circleci/config.yml b/.circleci/config.yml index bf7892a8c2..90a8393c1a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -39,14 +39,6 @@ jobs: paths: - bin - profiles - - save_cache: - key: v1-pkg-cache - paths: - - /go/pkg - - save_cache: - key: v1-tree-{{ .Environment.CIRCLE_SHA1 }} - paths: - - /go/src/github.com/cosmos/cosmos-sdk lint: <<: *defaults @@ -54,10 +46,12 @@ jobs: steps: - attach_workspace: at: /tmp/workspace - - restore_cache: - key: v1-pkg-cache - - restore_cache: - key: v1-tree-{{ .Environment.CIRCLE_SHA1 }} + - checkout + - run: + name: dependencies + command: | + export PATH="$GOBIN:$PATH" + make get_vendor_deps - run: name: Get metalinter command: | @@ -75,32 +69,71 @@ jobs: steps: - attach_workspace: at: /tmp/workspace - - restore_cache: - key: v1-pkg-cache - - restore_cache: - key: v1-tree-{{ .Environment.CIRCLE_SHA1 }} + - checkout + - run: + name: dependencies + command: | + export PATH="$GOBIN:$PATH" + make get_vendor_deps - run: name: Test cli command: | export PATH="$GOBIN:$PATH" make test_cli - test_sim: + test_sim_modules: <<: *defaults parallelism: 1 steps: - attach_workspace: at: /tmp/workspace - - restore_cache: - key: v1-pkg-cache - - restore_cache: - key: v1-tree-{{ .Environment.CIRCLE_SHA1 }} + - checkout - run: - name: Test simulation + name: dependencies command: | export PATH="$GOBIN:$PATH" - export GAIA_SIMULATION_SEED=1531897442166404087 - make test_sim + make get_vendor_deps + - run: + name: Test individual module simulations + command: | + export PATH="$GOBIN:$PATH" + make test_sim_modules + + test_sim_gaia_nondeterminism: + <<: *defaults + parallelism: 1 + steps: + - attach_workspace: + at: /tmp/workspace + - checkout + - run: + name: dependencies + command: | + export PATH="$GOBIN:$PATH" + make get_vendor_deps + - run: + name: Test individual module simulations + command: | + export PATH="$GOBIN:$PATH" + make test_sim_gaia_nondeterminism + + test_sim_gaia_fast: + <<: *defaults + parallelism: 1 + steps: + - attach_workspace: + at: /tmp/workspace + - checkout + - run: + name: dependencies + command: | + export PATH="$GOBIN:$PATH" + make get_vendor_deps + - run: + name: Test full Gaia simulation + command: | + export PATH="$GOBIN:$PATH" + make test_sim_gaia_fast test_cover: <<: *defaults @@ -108,17 +141,19 @@ jobs: steps: - attach_workspace: at: /tmp/workspace - - restore_cache: - key: v1-pkg-cache - - restore_cache: - key: v1-tree-{{ .Environment.CIRCLE_SHA1 }} + - checkout + - run: + name: dependencies + command: | + export PATH="$GOBIN:$PATH" + make get_vendor_deps - run: mkdir -p /tmp/logs - run: name: Run tests command: | export PATH="$GOBIN:$PATH" make install - for pkg in $(go list github.com/cosmos/cosmos-sdk/... | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test | circleci tests split --split-by=timings); do + for pkg in $(go list github.com/cosmos/cosmos-sdk/... | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test | grep -v '/simulation' | circleci tests split --split-by=timings); do id=$(basename "$pkg") GOCACHE=off go test -timeout 8m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic "$pkg" | tee "/tmp/logs/$id-$RANDOM.log" done @@ -135,8 +170,12 @@ jobs: steps: - attach_workspace: at: /tmp/workspace - - restore_cache: - key: v1-tree-{{ .Environment.CIRCLE_SHA1 }} + - checkout + - run: + name: dependencies + command: | + export PATH="$GOBIN:$PATH" + make get_vendor_deps - run: name: gather command: | @@ -150,6 +189,29 @@ jobs: name: upload command: bash <(curl -s https://codecov.io/bash) -f coverage.txt + localnet: + working_directory: /home/circleci/.go_workspace/src/github.com/cosmos/cosmos-sdk + machine: + image: circleci/classic:latest + environment: + GOBIN: /home/circleci/.go_workspace/bin + GOPATH: /home/circleci/.go_workspace/ + GOOS: linux + GOARCH: amd64 + parallelism: 1 + steps: + - checkout + - run: + name: run localnet and exit on failure + command: | + set -x + make get_tools + make get_vendor_deps + make build-linux + make localnet-start + ./scripts/localnet-blocks-test.sh 40 5 10 localhost + + workflows: version: 2 test-suite: @@ -161,12 +223,21 @@ workflows: - test_cli: requires: - setup_dependencies - - test_sim: + - test_sim_modules: + requires: + - setup_dependencies + - test_sim_gaia_nondeterminism: + requires: + - setup_dependencies + - test_sim_gaia_fast: requires: - setup_dependencies - test_cover: requires: - setup_dependencies + - localnet: + requires: + - setup_dependencies - upload_coverage: requires: - test_cover diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f7e2d0fd6f..36b9f97f20 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -5,13 +5,14 @@ v If a checkbox is n/a - please still include it but + a little note why ☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --> - [ ] Linked to github-issue with discussion and accepted design OR link to spec that describes this work. -- [ ] Updated all relevant documentation (`docs/`) -- [ ] Updated all relevant code comments - [ ] Wrote tests -- [ ] Added entries in `PENDING.md` that include links to the relevant issue or PR that most accurately describes the change. -- [ ] Updated `cmd/gaia` and `examples/` -___________________________________ +- [ ] Updated relevant documentation (`docs/`) +- [ ] Added entries in `PENDING.md` with issue # +- [ ] rereviewed `Files changed` in the github PR explorer + +______ + For Admin Use: -- [ ] Added appropriate labels to PR (ex. wip, ready-for-review, docs) -- [ ] Reviewers Assigned -- [ ] Squashed all commits, uses message "Merge pull request #XYZ: [title]" ([coding standards](https://github.com/tendermint/coding/blob/master/README.md#merging-a-pr)) +- Added appropriate labels to PR (ex. wip, ready-for-review, docs) +- Reviewers Assigned +- Squashed all commits, uses message "Merge pull request #XYZ: [title]" ([coding standards](https://github.com/tendermint/coding/blob/master/README.md#merging-a-pr)) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d88642015..18b9d53486 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,128 @@ # Changelog +## 0.24.1 + +*August 21st, 2018* + +BUG FIXES + +* Gaia + - [x/slashing] Evidence tracking now uses validator address instead of validator pubkey + +## 0.24.0 + +*August 13th, 2018* + +BREAKING CHANGES + +* Gaia REST API (`gaiacli advanced rest-server`) + - [x/stake] \#1880 More REST-ful endpoints (large refactor) + - [x/slashing] \#1866 `/slashing/signing_info` takes cosmosvalpub instead of cosmosvaladdr + - use time.Time instead of int64 for time. See Tendermint v0.23.0 + - Signatures are no longer Amino encoded with prefixes (just encoded as raw + bytes) - see Tendermint v0.23.0 + +* Gaia CLI (`gaiacli`) + - [x/stake] change `--keybase-sig` to `--identity` + - [x/stake] \#1828 Force user to specify amount on create-validator command by removing default + - [x/gov] Change `--proposalID` to `--proposal-id` + - [x/stake, x/gov] \#1606 Use `--from` instead of adhoc flags like `--address-validator` + and `--proposer` to indicate the sender address. + - \#1551 Remove `--name` completely + - Genesis/key creation (`gaiad init`) now supports user-provided key passwords + +* Gaia + - [x/stake] Inflation doesn't use rationals in calculation (performance boost) + - [x/stake] Persist a map from `addr->pubkey` in the state since BeginBlock + doesn't provide pubkeys. + - [x/gov] \#1781 Added tags sub-package, changed tags to use dash-case + - [x/gov] \#1688 Governance parameters are now stored in globalparams store + - [x/gov] \#1859 Slash validators who do not vote on a proposal + - [x/gov] \#1914 added TallyResult type that gets stored in Proposal after tallying is finished + +* SDK + - [baseapp] Msgs are no longer run on CheckTx, removed `ctx.IsCheckTx()` + - [baseapp] NewBaseApp constructor takes sdk.TxDecoder as argument instead of wire.Codec + - [types] sdk.NewCoin takes sdk.Int, sdk.NewInt64Coin takes int64 + - [x/auth] Default TxDecoder can be found in `x/auth` rather than baseapp + - [client] \#1551: Refactored `CoreContext` to `TxContext` and `QueryContext` + - Removed all tx related fields and logic (building & signing) to separate + structure `TxContext` in `x/auth/client/context` + +* Tendermint + - v0.22.5 -> See [Tendermint PR](https://github.com/tendermint/tendermint/pull/1966) + - change all the cryptography imports. + - v0.23.0 -> See + [Changelog](https://github.com/tendermint/tendermint/blob/v0.23.0/CHANGELOG.md#0230) + and [SDK PR](https://github.com/cosmos/cosmos-sdk/pull/1927) + - BeginBlock no longer includes crypto.Pubkey + - use time.Time instead of int64 for time. + +FEATURES + +* Gaia REST API (`gaiacli advanced rest-server`) + - [x/gov] Can now query governance proposals by ProposalStatus + +* Gaia CLI (`gaiacli`) + - [x/gov] added `query-proposals` command. Can filter by `depositer`, `voter`, and `status` + - [x/stake] \#2043 Added staking query cli cmds for unbonding-delegations and redelegations + +* Gaia + - [networks] Added ansible scripts to upgrade seed nodes on a network + +* SDK + - [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 + - Simulates Tendermint's algorithm for validator set updates + - Simulates validator signing/downtime with a Markov chain, and occaisional double-signatures + - Includes simulated operations & invariants for staking, slashing, governance, and bank modules + - [store] \#1481 Add transient store + - [baseapp] Initialize validator set on ResponseInitChain + - [baseapp] added BaseApp.Seal - ability to seal baseapp parameters once they've been set + - [cosmos-sdk-cli] New `cosmos-sdk-cli` tool to quickly initialize a new + SDK-based project + - [scripts] added log output monitoring to DataDog using Ansible scripts + +IMPROVEMENTS + +* Gaia + - [spec] \#967 Inflation and distribution specs drastically improved + - [x/gov] \#1773 Votes on a proposal can now be queried + - [x/gov] Initial governance parameters can now be set in the genesis file + - [x/stake] \#1815 Sped up the processing of `EditValidator` txs. + - [config] \#1930 Transactions indexer indexes all tags by default. + - [ci] [#2057](https://github.com/cosmos/cosmos-sdk/pull/2057) Run `make localnet-start` on every commit and ensure network reaches at least 10 blocks + +* SDK + - [baseapp] \#1587 Allow any alphanumeric character in route + - [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 + - [x/bank] Unit tests are now table-driven + - [tests] Add tests to example apps in docs + - [tests] Fixes ansible scripts to work with AWS too + - [tests] \#1806 CLI tests are now behind the build flag 'cli_test', so go test works on a new repo + +BUG FIXES + +* Gaia CLI (`gaiacli`) + - \#1766 Fixes bad example for keybase identity + - [x/stake] \#2021 Fixed repeated CLI commands in staking + +* Gaia + - [x/stake] [#2077](https://github.com/cosmos/cosmos-sdk/pull/2077) Fixed invalid cliff power comparison + - \#1804 Fixes gen-tx genesis generation logic temporarily until upstream updates + - \#1799 Fix `gaiad export` + - \#1839 Fixed bug where intra-tx counter wasn't set correctly for genesis validators + - [x/stake] \#1858 Fixed bug where the cliff validator was not updated correctly + - [tests] \#1675 Fix non-deterministic `test_cover` + - [tests] \#1551 Fixed invalid LCD test JSON payload in `doIBCTransfer` + - [basecoin] Fixes coin transaction failure and account query [discussion](https://forum.cosmos.network/t/unmarshalbinarybare-expected-to-read-prefix-bytes-75fbfab8-since-it-is-registered-concrete-but-got-0a141dfa/664/6) + - [x/gov] \#1757 Fix VoteOption conversion to String + * [x/stake] [#2083] Fix broken invariant of bonded validator power decrease + ## 0.23.1 *July 27th, 2018* @@ -167,7 +290,7 @@ FEATURES * [types] Added MinInt and MinUint functions * [gaiad] `unsafe_reset_all` now resets addrbook.json * [democoin] add x/oracle, x/assoc -* [tests] created a randomized testing framework. +* [tests] created a randomized testing framework. - Currently bank has limited functionality in the framework - Auth has its invariants checked within the framework * [tests] Add WaitForNextNBlocksTM helper method diff --git a/CODEOWNERS b/CODEOWNERS deleted file mode 100644 index 2992bcf66f..0000000000 --- a/CODEOWNERS +++ /dev/null @@ -1,2 +0,0 @@ -* @jaekwon -* @ebuchman diff --git a/Gopkg.lock b/Gopkg.lock index de244c162c..73a2ff60fd 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -48,12 +48,12 @@ revision = "d4cc87b860166d00d6b5b9e0d3b3d71d6088d4d4" [[projects]] - digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39" + digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" name = "github.com/davecgh/go-spew" packages = ["spew"] pruneopts = "UT" - revision = "346938d642f2ec3594ed81d874461961cd0faa76" - version = "v1.1.0" + revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" + version = "v1.1.1" [[projects]] digest = "1:c7644c73a3d23741fdba8a99b1464e021a224b7e205be497271a8003a15ca41b" @@ -376,7 +376,7 @@ [[projects]] branch = "master" - digest = "1:b3cfb8d82b1601a846417c3f31c03a7961862cb2c98dcf0959c473843e6d9a2b" + digest = "1:f2ffd421680b0a3f7887501b3c6974bcf19217ecd301d0e2c9b681940ec363d5" name = "github.com/syndtr/goleveldb" packages = [ "leveldb", @@ -393,7 +393,7 @@ "leveldb/util", ] pruneopts = "UT" - revision = "c4c61651e9e37fa117f53c5a906d3b63090d8445" + revision = "ae2bd5eed72d46b28834ec3f60db3a3ebedd8dbd" [[projects]] branch = "master" @@ -408,12 +408,12 @@ revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" [[projects]] - digest = "1:e9113641c839c21d8eaeb2c907c7276af1eddeed988df8322168c56b7e06e0e1" + digest = "1:e0a2a4be1e20c305badc2b0a7a9ab7fef6da500763bec23ab81df3b5f9eec9ee" name = "github.com/tendermint/go-amino" packages = ["."] pruneopts = "UT" - revision = "2106ca61d91029c931fd54968c2bb02dc96b1412" - version = "0.10.1" + revision = "a8328986c1608950fa5d3d1c0472cccc4f8fc02c" + version = "v0.12.0-rc0" [[projects]] digest = "1:d4a15d404afbf591e8be16fcda7f5ac87948d5c7531f9d909fd84cc730ab16e2" @@ -490,6 +490,14 @@ revision = "013b9cef642f875634c614019ab13b17570778ad" version = "v0.23.0" +[[projects]] + digest = "1:bf6d9a827ea3cad964c2f863302e4f6823170d0b5ed16f72cf1184a7c615067e" + name = "github.com/tendermint/tmlibs" + packages = ["cli"] + pruneopts = "UT" + revision = "49596e0a1f48866603813df843c9409fc19805c6" + version = "v0.9.0" + [[projects]] digest = "1:4dcb0dd65feecb068ce23a234d1a07c7868a1e39f52a6defcae0bb371d03abf6" name = "github.com/zondax/ledger-goclient" @@ -499,7 +507,7 @@ [[projects]] branch = "master" - digest = "1:7a71fffde456d746c52f9cd09c50b034533a3180fb1f6320abb149f2ccc579e5" + digest = "1:27507554c6d4f060d8d700c31c624a43d3a92baa634e178ddc044bdf7d13b44a" name = "golang.org/x/crypto" packages = [ "blowfish", @@ -518,7 +526,7 @@ "salsa20/salsa", ] pruneopts = "UT" - revision = "de0752318171da717af4ce24d0a2e8626afaeb11" + revision = "614d502a4dac94afa3a6ce146bd1736da82514c6" [[projects]] digest = "1:d36f55a999540d29b6ea3c2ea29d71c76b1d9853fdcd3e5c5cb4836f2ba118f1" @@ -538,14 +546,14 @@ [[projects]] branch = "master" - digest = "1:4bd75b1a219bc590b05c976bbebf47f4e993314ebb5c7cbf2efe05a09a184d54" + digest = "1:a0e12bc26f317c0e2d497baf767285e1790e526e8dd46553c5a67fcbc8692157" name = "golang.org/x/sys" packages = [ "cpu", "unix", ] pruneopts = "UT" - revision = "4e1fef5609515ec7a2cee7b5de30ba6d9b438cbf" + revision = "3b58ed4ad3395d483fc92d5d14123ce2c3581fec" [[projects]] digest = "1:a2ab62866c75542dd18d2b069fec854577a20211d7c0ea6ae746072a1dccdd18" @@ -576,7 +584,7 @@ name = "google.golang.org/genproto" packages = ["googleapis/rpc/status"] pruneopts = "UT" - revision = "383e8b2c3b9e36c4076b235b32537292176bae20" + revision = "c66870c02cf823ceb633bcd05be3c7cda29976f4" [[projects]] digest = "1:2dab32a43451e320e49608ff4542fdfc653c95dcc35d0065ec9c6c3dd540ed74" @@ -666,6 +674,7 @@ "github.com/tendermint/tendermint/rpc/lib/server", "github.com/tendermint/tendermint/types", "github.com/tendermint/tendermint/version", + "github.com/tendermint/tmlibs/cli", "github.com/zondax/ledger-goclient", "golang.org/x/crypto/blowfish", "golang.org/x/crypto/ripemd160", diff --git a/Gopkg.toml b/Gopkg.toml index 0651fe1f5f..acc3e282aa 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -49,7 +49,7 @@ [[override]] name = "github.com/tendermint/go-amino" - version = "=0.10.1" + version = "=v0.12.0-rc0" [[override]] name = "github.com/tendermint/iavl" diff --git a/Makefile b/Makefile index 28b4256fbf..b35e3f5c9a 100644 --- a/Makefile +++ b/Makefile @@ -16,20 +16,20 @@ ci: get_tools get_vendor_deps install test_cover test_lint test ######################################## ### Build/Install -check-ledger: +check-ledger: ifeq ($(LEDGER_ENABLED),true) ifeq ($(UNAME_S),OpenBSD) $(info "OpenBSD detected, disabling ledger support (https://github.com/cosmos/cosmos-sdk/issues/1988)") - TMP_BUILD_TAGS := $(BUILD_TAGS) - BUILD_TAGS = $(filter-out ledger, $(TMP_BUILD_TAGS)) +TMP_BUILD_TAGS := $(BUILD_TAGS) +BUILD_TAGS = $(filter-out ledger, $(TMP_BUILD_TAGS)) else ifndef GCC $(error "gcc not installed for ledger support, please install or set LEDGER_ENABLED to false in the Makefile") endif endif else - TMP_BUILD_TAGS := $(BUILD_TAGS) - BUILD_TAGS = $(filter-out ledger, $(TMP_BUILD_TAGS)) +TMP_BUILD_TAGS := $(BUILD_TAGS) +BUILD_TAGS = $(filter-out ledger, $(TMP_BUILD_TAGS)) endif build: check-ledger @@ -138,15 +138,21 @@ test_unit: test_race: @go test -race $(PACKAGES_NOSIMULATION) -test_sim: - @echo "Running individual module simulations." - @go test $(PACKAGES_SIMTEST) -v - @echo "Running full Gaia simulation. This may take several minutes." - @echo "Pass the flag 'SimulationSeed' to run with a constant seed." - @echo "Pass the flag 'SimulationNumKeys' to run with the specified number of keys." - @echo "Pass the flag 'SimulationNumBlocks' to run with the specified number of blocks." - @echo "Pass the flag 'SimulationBlockSize' to run with the specified block size (operations per block)." - @go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationBlockSize=200 -v +test_sim_modules: + @echo "Running individual module simulations..." + @go test $(PACKAGES_SIMTEST) + +test_sim_gaia_nondeterminism: + @echo "Running nondeterminism test..." + @go test ./cmd/gaia/app -run TestAppStateDeterminism -SimulationEnabled=true -v -timeout 10m + +test_sim_gaia_fast: + @echo "Running quick Gaia simulation. This may take several minutes..." + @go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=200 -timeout 24h + +test_sim_gaia_slow: + @echo "Running full Gaia simulation. This may take awhile!" + @go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=1000 -SimulationVerbose=true -v -timeout 24h test_cover: @bash tests/test_cover.sh @@ -198,8 +204,8 @@ build-docker-gaiadnode: # Run a 4-node testnet locally localnet-start: localnet-stop - @if ! [ -f build/node0/gaiad/config/genesis.json ]; then docker run --rm -v $(CURDIR)/build:/gaiad:Z tendermint/gaiadnode testnet --v 4 --o . --starting-ip-address 192.168.10.2 ; fi - docker-compose up + @if ! [ -f build/node0/gaiad/config/genesis.json ]; then docker run --rm -v $(CURDIR)/build:/gaiad:Z tendermint/gaiadnode testnet --v 4 -o . --starting-ip-address 192.168.10.2 ; fi + docker-compose up -d # Stop testnet localnet-stop: @@ -212,4 +218,4 @@ localnet-stop: check_tools check_dev_tools get_tools get_dev_tools get_vendor_deps draw_deps test test_cli test_unit \ test_cover test_lint benchmark devdoc_init devdoc devdoc_save devdoc_update \ build-linux build-docker-gaiadnode localnet-start localnet-stop \ -format check-ledger test_sim update_tools update_dev_tools +format check-ledger test_sim_gaia_nondeterminism test_sim_modules test_sim_gaia_fast test_sim_gaia_slow update_tools update_dev_tools diff --git a/PENDING.md b/PENDING.md index 37da207a51..dca1e8fe93 100644 --- a/PENDING.md +++ b/PENDING.md @@ -1,105 +1,77 @@ -## v0.24.0 PENDING -^--- PENDING wasn't purged on sdk v0.23.0 release. - -BREAKING CHANGES -* Update to tendermint v0.23.0. This involves removing crypto.Pubkey, -maintaining a validator address to pubkey map, and using time.Time instead of int64 for time. [SDK PR](https://github.com/cosmos/cosmos-sdk/pull/1927) - ## PENDING BREAKING CHANGES -* API - - \#1880 and \#2000 [x/stake] changed the endpoints to be more REST-ful -* Update to tendermint v0.22.5. This involves changing all of the cryptography imports. [Ref](https://github.com/tendermint/tendermint/pull/1966) -* [baseapp] Msgs are no longer run on CheckTx, removed `ctx.IsCheckTx()` -* [x/gov] CLI flag changed from `proposalID` to `proposal-id` -* [x/stake] Fixed the period check for the inflation calculation -* [x/stake] Inflation doesn't use rationals in calculation (performance boost) -* [x/stake] CLI flags for identity changed from `--keybase-sig` to `--identity`, effects: - * `gaiacli stake create-validator` - * `gaiacli stake edit-validator` -* [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 -* [x/gov] Governance parameters are now stored in globalparams store -* [core] \#1807 Switch from use of rational to decimal -* [lcd] \#1866 Updated lcd /slashing/signing_info endpoint to take cosmosvalpub instead of cosmosvaladdr -* [types] sdk.NewCoin now takes sdk.Int, sdk.NewInt64Coin takes int64 -* [cli] #1551: Officially removed `--name` from CLI commands -* [cli] Genesis/key creation (`init`) now supports user-provided key passwords -* [cli] unsafe_reset_all, show_validator, and show_node_id have been renamed to unsafe-reset-all, show-validator, and show-node-id + +* Gaia REST API (`gaiacli advanced rest-server`) + * [x/stake] Validator.Owner renamed to Validator.Operator + +* Gaia CLI (`gaiacli`) + * [x/stake] Validator.Owner renamed to Validator.Operator + * [cli] unsafe_reset_all, show_validator, and show_node_id have been renamed to unsafe-reset-all, show-validator, and show-node-id + * [cli] \#1983 --print-response now defaults to true in commands that create and send a transaction + * [cli] \#1983 you can now pass --pubkey or --address to gaiacli keys show to return a plaintext representation of the key's address or public key for use with other commands + * [cli] \#2061 changed proposalID in governance REST endpoints to proposal-id + * [cli] \#2014 `gaiacli advanced` no longer exists - to access `ibc`, `rest-server`, and `validator-set` commands use `gaiacli ibc`, `gaiacli rest-server`, and `gaiacli tendermint`, respectively + +* Gaia + * Make the transient store key use a distinct store key. [#2013](https://github.com/cosmos/cosmos-sdk/pull/2013) + * [x/stake] \#1901 Validator type's Owner field renamed to Operator; Validator's GetOwner() renamed accordingly to comply with the SDK's Validator interface. + * [x/stake, x/slashing] [#1305](https://github.com/cosmos/cosmos-sdk/issues/1305) - Rename "revoked" to "jailed" + +* SDK + * [core] \#1807 Switch from use of rational to decimal + * [types] \#1901 Validator interface's GetOwner() renamed to GetOperator() + +* Tendermint + 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) -* [networks] Added ansible scripts to upgrade seed nodes on a network -* [store] Add transient store -* [gov] Add slashing for validators who do not vote on a proposal -* [cli] added `gov query-proposals` command to CLI. Can filter by `depositer`, `voter`, and `status` -* [core] added BaseApp.Seal - ability to seal baseapp parameters once they've been set -* [scripts] added log output monitoring to DataDog using Ansible scripts -* [gov] added TallyResult type that gets added stored in Proposal after tallying is finished + +* Gaia REST API (`gaiacli advanced rest-server`) + * [lcd] Endpoints to query staking pool and params + +* Gaia CLI (`gaiacli`) + * [cli] Cmds to query staking pool and params + * [gov][cli] #2062 added `--proposal` flag to `submit-proposal` that allows a JSON file containing a proposal to be passed in + +* Gaia + +* SDK + * [querier] added custom querier functionality, so ABCI query requests can be handled by keepers + +* Tendermint + IMPROVEMENTS -* [baseapp] Allow any alphanumeric character in route -* [cli] Improve error messages for all txs when the account doesn't exist -* [tools] Remove `rm -rf vendor/` from `make get_vendor_deps` -* [x/auth] Recover ErrorOutOfGas panic in order to set sdk.Result attributes correctly -* [x/stake] Add revoked to human-readable validator -* [spec] \#967 Inflation and distribution specs drastically improved -* [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 -* [tests] \#1806 CLI tests are now behind the build flag 'cli_test', so go test works on a new repo -* [x/gov] Initial governance parameters can now be set in the genesis file -* [x/stake] \#1815 Sped up the processing of `EditValidator` txs. -* [server] \#1930 Transactions indexer indexes all tags by default. -* [x/stake] \#2000 Added tests for new staking endpoints -* [x/stake] [#2023](https://github.com/cosmos/cosmos-sdk/pull/2023) Terminate iteration loop in `UpdateBondedValidators` and `UpdateBondedValidatorsFull` when the first revoked validator is encountered and perform a sanity check. -* [tools] Make get_vendor_deps deletes `.vendor-new` directories, in case scratch files are present. -* [spec] Added simple piggy bank distribution spec + +* Gaia REST API (`gaiacli advanced rest-server`) + * [x/stake] \#2000 Added tests for new staking endpoints + +* Gaia CLI (`gaiacli`) + * [cli] #2060 removed `--select` from `block` command + +* Gaia + * [x/stake] [#2023](https://github.com/cosmos/cosmos-sdk/pull/2023) Terminate iteration loop in `UpdateBondedValidators` and `UpdateBondedValidatorsFull` when the first revoked validator is encountered and perform a sanity check. + * [x/auth] Signature verification's gas cost now accounts for pubkey type. [#2046](https://github.com/tendermint/tendermint/pull/2046) + +* SDK + * [tools] Make get_vendor_deps deletes `.vendor-new` directories, in case scratch files are present. + * [spec] Added simple piggy bank distribution spec + +* Tendermint + BUG FIXES -* \#1988 Make us compile on OpenBSD (disable ledger) [#1988] (https://github.com/cosmos/cosmos-sdk/issues/1988) -* \#1666 Add intra-tx counter to the genesis validators -* \#1797 Fix off-by-one error in slashing for downtime -* \#1787 Fixed bug where Tally fails due to revoked/unbonding validator -* \#1766 Fixes bad example for keybase identity -* \#1804 Fixes gen-tx genesis generation logic temporarily until upstream updates -* \#1799 Fix `gaiad export` -* \#1828 Force user to specify amount on create-validator command by removing default -* \#1839 Fixed bug where intra-tx counter wasn't set correctly for genesis validators -* [staking] [#1858](https://github.com/cosmos/cosmos-sdk/pull/1858) Fixed bug where the cliff validator was not be updated correctly -* [tests] \#1675 Fix non-deterministic `test_cover` -* [client] \#1551: Refactored `CoreContext` - * Renamed `CoreContext` to `QueryContext` - * Removed all tx related fields and logic (building & signing) to separate - structure `TxContext` in `x/auth/client/context` - * Cleaned up documentation and API of what used to be `CoreContext` - * Implemented `KeyType` enum for key info -* \#1666 Add intra-tx counter to the genesis validators -* [tests] \#1551: Fixed invalid LCD test JSON payload in `doIBCTransfer` -* \#1787 Fixed bug where Tally fails due to revoked/unbonding validator -* \#1787 Fixed bug where Tally fails due to revoked/unbonding validator -* [basecoin] Fixes coin transaction failure and account query [discussion](https://forum.cosmos.network/t/unmarshalbinarybare-expected-to-read-prefix-bytes-75fbfab8-since-it-is-registered-concrete-but-got-0a141dfa/664/6) -* [cli] \#1997 Handle panics gracefully when `gaiacli stake {delegation,unbond}` fail to unmarshal delegation. + +* Gaia REST API (`gaiacli advanced rest-server`) + +* Gaia CLI (`gaiacli`) + * [cli] \#1997 Handle panics gracefully when `gaiacli stake {delegation,unbond}` fail to unmarshal delegation. + +* Gaia + +* SDK + * \#1988 Make us compile on OpenBSD (disable ledger) [#1988] (https://github.com/cosmos/cosmos-sdk/issues/1988) + * \#2105 Fix DB Iterator leak, which may leak a go routine. + +* Tendermint diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index d7398d8993..365d7b31f2 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -41,13 +41,14 @@ const ( // BaseApp reflects the ABCI application implementation. type BaseApp struct { // initialized on creation - Logger log.Logger - name string // application name from abci.Info - db dbm.DB // common DB backend - cms sdk.CommitMultiStore // Main (uncached) state - router Router // handle any kind of message - codespacer *sdk.Codespacer // handle module codespacing - txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx + Logger log.Logger + name string // application name from abci.Info + db dbm.DB // common DB backend + cms sdk.CommitMultiStore // Main (uncached) state + router Router // handle any kind of message + queryRouter QueryRouter // router for redirecting query calls + codespacer *sdk.Codespacer // handle module codespacing + txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx anteHandler sdk.AnteHandler // ante handler for fee and auth @@ -84,13 +85,14 @@ var _ abci.Application = (*BaseApp)(nil) // Accepts variable number of option functions, which act on the BaseApp to set configuration choices func NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp)) *BaseApp { app := &BaseApp{ - Logger: logger, - name: name, - db: db, - cms: store.NewCommitMultiStore(db), - router: NewRouter(), - codespacer: sdk.NewCodespacer(), - txDecoder: txDecoder, + Logger: logger, + name: name, + db: db, + cms: store.NewCommitMultiStore(db), + router: NewRouter(), + queryRouter: NewQueryRouter(), + codespacer: sdk.NewCodespacer(), + txDecoder: txDecoder, } // Register the undefined & root codespaces, which should not be used by @@ -266,6 +268,7 @@ func (app *BaseApp) FilterPeerByPubKey(info string) abci.ResponseQuery { return abci.ResponseQuery{} } +// Splits a string path using the delimter '/'. i.e. "this/is/funny" becomes []string{"this", "is", "funny"} func splitPath(requestPath string) (path []string) { path = strings.Split(requestPath, "/") // first element is empty string @@ -291,6 +294,8 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) { return handleQueryStore(app, path, req) case "p2p": return handleQueryP2P(app, path, req) + case "custom": + return handleQueryCustom(app, path, req) } msg := "unknown query path" @@ -362,6 +367,33 @@ func handleQueryP2P(app *BaseApp, path []string, req abci.RequestQuery) (res abc return sdk.ErrUnknownRequest(msg).QueryResult() } +func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) (res abci.ResponseQuery) { + // path[0] should be "custom" because "/custom" prefix is required for keeper queries. + // the queryRouter routes using path[1]. For example, in the path "custom/gov/proposal", queryRouter routes using "gov" + if path[1] == "" { + sdk.ErrUnknownRequest("No route for custom query specified").QueryResult() + } + querier := app.queryRouter.Route(path[1]) + if querier == nil { + sdk.ErrUnknownRequest(fmt.Sprintf("no custom querier found for route %s", path[1])).QueryResult() + } + + ctx := sdk.NewContext(app.cms.CacheMultiStore(), app.checkState.ctx.BlockHeader(), true, app.Logger) + // Passes the rest of the path as an argument to the querier. + // For example, in the path "custom/gov/proposal/test", the gov querier gets []string{"proposal", "test"} as the path + resBytes, err := querier(ctx, path[2:], req) + if err != nil { + return abci.ResponseQuery{ + Code: uint32(err.ABCICode()), + Log: err.ABCILog(), + } + } + return abci.ResponseQuery{ + Code: uint32(sdk.ABCICodeOK), + Value: resBytes, + } +} + // BeginBlock implements the ABCI application interface. func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeginBlock) { if app.cms.TracingEnabled() { @@ -379,7 +411,7 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg } else { // In the first block, app.deliverState.ctx will already be initialized // by InitChain. Context is now updated with Header information. - app.deliverState.ctx = app.deliverState.ctx.WithBlockHeader(req.Header) + app.deliverState.ctx = app.deliverState.ctx.WithBlockHeader(req.Header).WithBlockHeight(req.Header.Height) } if app.beginBlocker != nil { diff --git a/baseapp/queryrouter.go b/baseapp/queryrouter.go new file mode 100644 index 0000000000..23cfad0721 --- /dev/null +++ b/baseapp/queryrouter.go @@ -0,0 +1,41 @@ +package baseapp + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// QueryRouter provides queryables for each query path. +type QueryRouter interface { + AddRoute(r string, h sdk.Querier) (rtr QueryRouter) + Route(path string) (h sdk.Querier) +} + +type queryrouter struct { + routes map[string]sdk.Querier +} + +// nolint +// NewRouter - create new router +// TODO either make Function unexported or make return type (router) Exported +func NewQueryRouter() *queryrouter { + return &queryrouter{ + routes: map[string]sdk.Querier{}, + } +} + +// AddRoute - Adds an sdk.Querier to the route provided. Panics on duplicate +func (rtr *queryrouter) AddRoute(r string, q sdk.Querier) QueryRouter { + if !isAlphaNumeric(r) { + panic("route expressions can only contain alphanumeric characters") + } + if rtr.routes[r] != nil { + panic("route has already been initialized") + } + rtr.routes[r] = q + return rtr +} + +// Returns the sdk.Querier for a certain route path +func (rtr *queryrouter) Route(path string) (h sdk.Querier) { + return rtr.routes[path] +} diff --git a/baseapp/setters.go b/baseapp/setters.go index 86a647d32c..a8b1591a73 100644 --- a/baseapp/setters.go +++ b/baseapp/setters.go @@ -74,6 +74,9 @@ func (app *BaseApp) Router() Router { } return app.router } +func (app *BaseApp) QueryRouter() QueryRouter { + return app.queryRouter +} func (app *BaseApp) Seal() { app.sealed = true } func (app *BaseApp) IsSealed() bool { return app.sealed } func (app *BaseApp) enforceSeal() { diff --git a/client/context/query.go b/client/context/query.go index 081f723b5c..68676f7415 100644 --- a/client/context/query.go +++ b/client/context/query.go @@ -31,6 +31,11 @@ func (ctx CLIContext) Query(path string) (res []byte, err error) { return ctx.query(path, nil) } +// Query information about the connected node with a data payload +func (ctx CLIContext) QueryWithData(path string, data []byte) (res []byte, err error) { + return ctx.query(path, data) +} + // QueryStore performs a query from a Tendermint node with the provided key and // store name. func (ctx CLIContext) QueryStore(key cmn.HexBytes, storeName string) (res []byte, err error) { diff --git a/client/flags.go b/client/flags.go index 8616f9e78d..b020789057 100644 --- a/client/flags.go +++ b/client/flags.go @@ -52,7 +52,7 @@ func PostCommands(cmds ...*cobra.Command) []*cobra.Command { c.Flags().Int64(FlagGas, 200000, "gas limit to set per-transaction") c.Flags().Bool(FlagAsync, false, "broadcast transactions asynchronously") c.Flags().Bool(FlagJson, false, "return output in json format") - c.Flags().Bool(FlagPrintResponse, false, "return tx response (only works with async = false)") + c.Flags().Bool(FlagPrintResponse, true, "return tx response (only works with async = false)") } return cmds } diff --git a/client/keys/show.go b/client/keys/show.go index 873c45a4b6..e9d692ece5 100644 --- a/client/keys/show.go +++ b/client/keys/show.go @@ -4,10 +4,20 @@ import ( "encoding/json" "net/http" - keys "github.com/cosmos/cosmos-sdk/crypto/keys" + "github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/gorilla/mux" + "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/tendermint/tmlibs/cli" +) + +const ( + // FlagAddress is the flag for the user's address on the command line. + FlagAddress = "address" + // FlagPublicKey represents the user's public key on the command line. + FlagPublicKey = "pubkey" ) var showKeysCmd = &cobra.Command{ @@ -18,13 +28,38 @@ var showKeysCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { name := args[0] info, err := getKey(name) - if err == nil { - printInfo(info) + if err != nil { + return err } - return err + + showAddress := viper.GetBool(FlagAddress) + showPublicKey := viper.GetBool(FlagPublicKey) + outputSet := cmd.Flag(cli.OutputFlag).Changed + if showAddress && showPublicKey { + return errors.New("cannot use both --address and --pubkey at once") + } + if outputSet && (showAddress || showPublicKey) { + return errors.New("cannot use --output with --address or --pubkey") + } + if showAddress { + printKeyAddress(info) + return nil + } + if showPublicKey { + printPubKey(info) + return nil + } + + printInfo(info) + return nil }, } +func init() { + showKeysCmd.Flags().Bool(FlagAddress, false, "output the address only (overrides --output)") + showKeysCmd.Flags().Bool(FlagPublicKey, false, "output the public key only (overrides --output)") +} + func getKey(name string) (keys.Info, error) { kb, err := GetKeyBase() if err != nil { diff --git a/client/keys/utils.go b/client/keys/utils.go index 907f9eda80..aa1b4bed9c 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/viper" - keys "github.com/cosmos/cosmos-sdk/crypto/keys" + "github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/tendermint/tendermint/libs/cli" dbm "github.com/tendermint/tendermint/libs/db" @@ -173,3 +173,19 @@ func printInfos(infos []keys.Info) { func printKeyOutput(ko KeyOutput) { fmt.Printf("%s\t%s\t%s\t%s\n", ko.Name, ko.Type, ko.Address, ko.PubKey) } + +func printKeyAddress(info keys.Info) { + ko, err := Bech32KeyOutput(info) + if err != nil { + panic(err) + } + fmt.Println(ko.Address.String()) +} + +func printPubKey(info keys.Info) { + ko, err := Bech32KeyOutput(info) + if err != nil { + panic(err) + } + fmt.Println(ko.PubKey) +} diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index db584834af..2e7ab0af7c 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -353,6 +353,42 @@ func TestTxs(t *testing.T) { require.Equal(t, resultTx.Height, indexedTxs[0].Height) } +func TestPoolParamsQuery(t *testing.T) { + _, password := "test", "1234567890" + addr, _ := CreateAddr(t, "test", password, GetKeyBase(t)) + cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) + defer cleanup() + + defaultParams := stake.DefaultParams() + + res, body := Request(t, port, "GET", "/stake/parameters", nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var params stake.Params + err := cdc.UnmarshalJSON([]byte(body), ¶ms) + require.Nil(t, err) + require.True(t, defaultParams.Equal(params)) + + res, body = Request(t, port, "GET", "/stake/pool", nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + require.NotNil(t, body) + + initialPool := stake.InitialPool() + initialPool.LooseTokens = initialPool.LooseTokens.Add(sdk.NewDec(100)) + initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewDec(100)) // Delegate tx on GaiaAppGenState + initialPool.LooseTokens = initialPool.LooseTokens.Add(sdk.NewDec(int64(50))) // freeFermionsAcc = 50 on GaiaAppGenState + + var pool stake.Pool + err = cdc.UnmarshalJSON([]byte(body), &pool) + require.Nil(t, err) + require.Equal(t, initialPool.DateLastCommissionReset, pool.DateLastCommissionReset) + require.Equal(t, initialPool.PrevBondedShares, pool.PrevBondedShares) + require.Equal(t, initialPool.BondedTokens, pool.BondedTokens) + require.Equal(t, initialPool.NextInflation(params), pool.Inflation) + initialPool = initialPool.ProcessProvisions(params) // provisions are added to the pool every hour + require.Equal(t, initialPool.LooseTokens, pool.LooseTokens) +} + func TestValidatorsQuery(t *testing.T) { cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}) defer cleanup() @@ -361,13 +397,13 @@ func TestValidatorsQuery(t *testing.T) { validators := getValidators(t, port) require.Equal(t, len(validators), 1) - // make sure all the validators were found (order unknown because sorted by owner addr) + // make sure all the validators were found (order unknown because sorted by operator addr) foundVal := false pkBech := sdk.MustBech32ifyValPub(pks[0]) if validators[0].PubKey == pkBech { foundVal = true } - require.True(t, foundVal, "pkBech %v, owner %v", pkBech, validators[0].Owner) + require.True(t, foundVal, "pkBech %v, operator %v", pkBech, validators[0].Operator) } func TestValidatorQuery(t *testing.T) { @@ -375,9 +411,9 @@ func TestValidatorQuery(t *testing.T) { defer cleanup() require.Equal(t, 1, len(pks)) - validator1Owner := sdk.AccAddress(pks[0].Address()) - validator := getValidator(t, port, validator1Owner) - assert.Equal(t, validator.Owner, validator1Owner, "The returned validator does not hold the correct data") + validator1Operator := sdk.AccAddress(pks[0].Address()) + validator := getValidator(t, port, validator1Operator) + assert.Equal(t, validator.Operator, validator1Operator, "The returned validator does not hold the correct data") } func TestBonding(t *testing.T) { @@ -386,10 +422,11 @@ func TestBonding(t *testing.T) { cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) defer cleanup() - validator1Owner := sdk.AccAddress(pks[0].Address()) - validator := getValidator(t, port, validator1Owner) + validator1Operator := sdk.AccAddress(pks[0].Address()) + validator := getValidator(t, port, validator1Operator) - resultTx := doDelegate(t, port, seed, name, password, addr, validator1Owner, 60) + // create bond TX + resultTx := doDelegate(t, port, seed, name, password, addr, validator1Operator, 60) tests.WaitForHeight(resultTx.Height+1, port) require.Equal(t, uint32(0), resultTx.CheckTx.Code) @@ -400,7 +437,8 @@ func TestBonding(t *testing.T) { require.Equal(t, int64(40), coins.AmountOf(denom).Int64()) - bond := getDelegation(t, port, addr, validator1Owner) + // query validator + bond := getDelegation(t, port, addr, validator1Operator) require.Equal(t, "60.0000000000", bond.Shares) summary := getDelegationSummary(t, port, addr) @@ -411,16 +449,17 @@ func TestBonding(t *testing.T) { bondedValidators := getDelegatorValidators(t, port, addr) require.Len(t, bondedValidators, 1) - require.Equal(t, validator1Owner, bondedValidators[0].Owner) + require.Equal(t, validator1Operator, bondedValidators[0].Operator) require.Equal(t, validator.DelegatorShares.Add(sdk.NewDec(60)).String(), bondedValidators[0].DelegatorShares.String()) - bondedValidator := getDelegatorValidator(t, port, addr, validator1Owner) - require.Equal(t, validator1Owner, bondedValidator.Owner) + bondedValidator := getDelegatorValidator(t, port, addr, validator1Operator) + require.Equal(t, validator1Operator, bondedValidator.Operator) ////////////////////// // testing unbonding - resultTx = doBeginUnbonding(t, port, seed, name, password, addr, validator1Owner, 60) + // create unbond TX + resultTx = doBeginUnbonding(t, port, seed, name, password, addr, validator1Operator, 60) tests.WaitForHeight(resultTx.Height+1, port) require.Equal(t, uint32(0), resultTx.CheckTx.Code) @@ -431,7 +470,7 @@ func TestBonding(t *testing.T) { coins = acc.GetCoins() require.Equal(t, int64(40), coins.AmountOf("steak").Int64()) - unbondings := getUndelegations(t, port, addr, validator1Owner) + unbondings := getUndelegations(t, port, addr, validator1Operator) require.Len(t, unbondings, 1, "Unbondings holds all unbonding-delegations") require.Equal(t, "60", unbondings[0].Balance.Amount.String()) @@ -556,7 +595,7 @@ func TestVote(t *testing.T) { require.Equal(t, gov.OptionYes, vote.Option) } -func TestUnrevoke(t *testing.T) { +func TestUnjail(t *testing.T) { _, password := "test", "1234567890" addr, _ := CreateAddr(t, "test", password, GetKeyBase(t)) cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) diff --git a/client/rpc/block.go b/client/rpc/block.go index fb4376bc1a..d16f383424 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -12,10 +12,6 @@ import ( "github.com/spf13/cobra" ) -const ( - flagSelect = "select" -) - //BlockCommand returns the verified block data for a given heights func BlockCommand() *cobra.Command { cmd := &cobra.Command{ @@ -27,7 +23,6 @@ func BlockCommand() *cobra.Command { cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:26657", "Node to connect to") // TODO: change this to false when we can cmd.Flags().Bool(client.FlagTrustNode, true, "Don't verify proofs for responses") - cmd.Flags().StringSlice(flagSelect, []string{"header", "tx"}, "Fields to return (header|txs|results)") return cmd } @@ -38,7 +33,6 @@ func getBlock(cliCtx context.CLIContext, height *int64) ([]byte, error) { return nil, err } - // TODO: actually honor the --select flag! // header -> BlockchainInfo // header, tx -> Block // results -> BlockResults diff --git a/client/tx/search.go b/client/tx/search.go index adad29d7dd..06b3c09729 100644 --- a/client/tx/search.go +++ b/client/tx/search.go @@ -27,7 +27,20 @@ const ( func SearchTxCmd(cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "txs", - Short: "Search for all transactions that match the given tags", + Short: "Search for all transactions that match the given tags.", + Long: strings.TrimSpace(` +Search for transactions that match the given tags. By default, transactions must match ALL tags +passed to the --tags option. To match any transaction, use the --any option. + +For example: + +$ gaiacli tendermint txs --tag test1,test2 + +will match any transaction tagged with both test1,test2. To match a transaction tagged with either +test1 or test2, use: + +$ gaiacli tendermint txs --tag test1,test2 --any +`), RunE: func(cmd *cobra.Command, args []string) error { tags := viper.GetStringSlice(flagTags) @@ -52,7 +65,7 @@ func SearchTxCmd(cdc *wire.Codec) *cobra.Command { // TODO: change this to false once proofs built in cmd.Flags().Bool(client.FlagTrustNode, true, "Don't verify proofs for responses") - cmd.Flags().StringSlice(flagTags, nil, "Tags that must match (may provide multiple)") + cmd.Flags().StringSlice(flagTags, nil, "Comma-separated list of tags that must match") cmd.Flags().Bool(flagAny, false, "Return transactions that match ANY tag, rather than ALL") return cmd } diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 9b318c8b17..4ce6b2806d 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -78,7 +78,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio keyGov: sdk.NewKVStoreKey("gov"), keyFeeCollection: sdk.NewKVStoreKey("fee"), keyParams: sdk.NewKVStoreKey("params"), - tkeyParams: sdk.NewTransientStoreKey("params"), + tkeyParams: sdk.NewTransientStoreKey("transient_params"), } // define the accountMapper @@ -105,6 +105,9 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio AddRoute("slashing", slashing.NewHandler(app.slashingKeeper)). AddRoute("gov", gov.NewHandler(app.govKeeper)) + app.QueryRouter(). + AddRoute("gov", gov.NewQuerier(app.govKeeper)) + // initialize BaseApp app.SetInitChainer(app.initChainer) app.SetBeginBlocker(app.BeginBlocker) @@ -185,7 +188,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci // load the address to pubkey map slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.StakeData) - gov.InitGenesis(ctx, app.govKeeper, gov.DefaultGenesisState()) + gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData) return abci.ResponseInitChain{ Validators: validators, @@ -208,6 +211,7 @@ func (app *GaiaApp) ExportAppStateAndValidators() (appState json.RawMessage, val genState := GenesisState{ Accounts: accounts, StakeData: stake.WriteGenesis(ctx, app.stakeKeeper), + GovData: gov.WriteGenesis(ctx, app.govKeeper), } appState, err = wire.MarshalJSONIndent(app.cdc, genState) if err != nil { diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index e35b21c4b0..24b160a510 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -11,6 +11,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/stake" "github.com/spf13/pflag" @@ -32,6 +33,7 @@ var ( type GenesisState struct { Accounts []GenesisAccount `json:"accounts"` StakeData stake.GenesisState `json:"stake"` + GovData gov.GenesisState `json:"gov"` } // GenesisAccount doesn't need pubkey or sequence @@ -202,8 +204,8 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (genesisState // create the self-delegation from the issuedDelShares delegation := stake.Delegation{ - DelegatorAddr: validator.Owner, - ValidatorAddr: validator.Owner, + DelegatorAddr: validator.Operator, + ValidatorAddr: validator.Operator, Shares: issuedDelShares, Height: 0, } @@ -216,6 +218,7 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (genesisState genesisState = GenesisState{ Accounts: genaccs, StakeData: stakeData, + GovData: gov.DefaultGenesisState(), } return } diff --git a/cmd/gaia/app/sim_test.go b/cmd/gaia/app/sim_test.go index 6369b4ca66..5fa75a9313 100644 --- a/cmd/gaia/app/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -3,52 +3,74 @@ package app import ( "encoding/json" "flag" + "fmt" "math/rand" "testing" "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation" + govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation" "github.com/cosmos/cosmos-sdk/x/mock/simulation" + slashingsim "github.com/cosmos/cosmos-sdk/x/slashing/simulation" stake "github.com/cosmos/cosmos-sdk/x/stake" stakesim "github.com/cosmos/cosmos-sdk/x/stake/simulation" ) var ( seed int64 - numKeys int numBlocks int blockSize int enabled bool + verbose bool ) func init() { flag.Int64Var(&seed, "SimulationSeed", 42, "Simulation random seed") - flag.IntVar(&numKeys, "SimulationNumKeys", 10, "Number of keys (accounts)") - flag.IntVar(&numBlocks, "SimulationNumBlocks", 100, "Number of blocks") - flag.IntVar(&blockSize, "SimulationBlockSize", 100, "Operations per block") + flag.IntVar(&numBlocks, "SimulationNumBlocks", 500, "Number of blocks") + flag.IntVar(&blockSize, "SimulationBlockSize", 200, "Operations per block") flag.BoolVar(&enabled, "SimulationEnabled", false, "Enable the simulation") + flag.BoolVar(&verbose, "SimulationVerbose", false, "Verbose log output") } -func appStateFn(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage { +func appStateFn(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage { var genesisAccounts []GenesisAccount // Randomly generate some genesis accounts - for _, addr := range accs { + for _, acc := range accs { coins := sdk.Coins{sdk.Coin{"steak", sdk.NewInt(100)}} genesisAccounts = append(genesisAccounts, GenesisAccount{ - Address: addr, + Address: acc, Coins: coins, }) } // Default genesis state stakeGenesis := stake.DefaultGenesisState() - stakeGenesis.Pool.LooseTokens = sdk.NewDec(1000) + var validators []stake.Validator + var delegations []stake.Delegation + // XXX Try different numbers of initially bonded validators + numInitiallyBonded := int64(50) + for i := 0; i < int(numInitiallyBonded); i++ { + validator := stake.NewValidator(accs[i], keys[i].PubKey(), stake.Description{}) + validator.Tokens = sdk.NewDec(100) + validator.DelegatorShares = sdk.NewDec(100) + delegation := stake.Delegation{accs[i], accs[i], sdk.NewDec(100), 0} + validators = append(validators, validator) + delegations = append(delegations, delegation) + } + stakeGenesis.Pool.LooseTokens = sdk.NewDec(int64(100*250) + (numInitiallyBonded * 100)) + stakeGenesis.Validators = validators + stakeGenesis.Bonds = delegations + // No inflation, for now + stakeGenesis.Params.InflationMax = sdk.NewDec(0) + stakeGenesis.Params.InflationMin = sdk.NewDec(0) genesis := GenesisState{ Accounts: genesisAccounts, StakeData: stakeGenesis, @@ -63,13 +85,46 @@ func appStateFn(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage { return appState } +func testAndRunTxs(app *GaiaApp) []simulation.TestAndRunTx { + return []simulation.TestAndRunTx{ + banksim.TestAndRunSingleInputMsgSend(app.accountMapper), + govsim.SimulateMsgSubmitProposal(app.govKeeper, app.stakeKeeper), + govsim.SimulateMsgDeposit(app.govKeeper, app.stakeKeeper), + govsim.SimulateMsgVote(app.govKeeper, app.stakeKeeper), + stakesim.SimulateMsgCreateValidator(app.accountMapper, app.stakeKeeper), + stakesim.SimulateMsgEditValidator(app.stakeKeeper), + stakesim.SimulateMsgDelegate(app.accountMapper, app.stakeKeeper), + stakesim.SimulateMsgBeginUnbonding(app.accountMapper, app.stakeKeeper), + stakesim.SimulateMsgCompleteUnbonding(app.stakeKeeper), + stakesim.SimulateMsgBeginRedelegate(app.accountMapper, app.stakeKeeper), + stakesim.SimulateMsgCompleteRedelegate(app.stakeKeeper), + slashingsim.SimulateMsgUnjail(app.slashingKeeper), + } +} + +func invariants(app *GaiaApp) []simulation.Invariant { + return []simulation.Invariant{ + func(t *testing.T, baseapp *baseapp.BaseApp, log string) { + banksim.NonnegativeBalanceInvariant(app.accountMapper)(t, baseapp, log) + govsim.AllInvariants()(t, baseapp, log) + stakesim.AllInvariants(app.coinKeeper, app.stakeKeeper, app.accountMapper)(t, baseapp, log) + slashingsim.AllInvariants()(t, baseapp, log) + }, + } +} + func TestFullGaiaSimulation(t *testing.T) { if !enabled { t.Skip("Skipping Gaia simulation") } // Setup Gaia application - logger := log.NewNopLogger() + var logger log.Logger + if verbose { + logger = log.TestingLogger() + } else { + logger = log.NewNopLogger() + } db := dbm.NewMemDB() app := NewGaiaApp(logger, db, nil) require.Equal(t, "GaiaApp", app.Name()) @@ -77,24 +132,50 @@ func TestFullGaiaSimulation(t *testing.T) { // Run randomized simulation simulation.SimulateFromSeed( t, app.BaseApp, appStateFn, seed, - []simulation.TestAndRunTx{ - banksim.TestAndRunSingleInputMsgSend(app.accountMapper), - stakesim.SimulateMsgCreateValidator(app.accountMapper, app.stakeKeeper), - stakesim.SimulateMsgEditValidator(app.stakeKeeper), - stakesim.SimulateMsgDelegate(app.accountMapper, app.stakeKeeper), - stakesim.SimulateMsgBeginUnbonding(app.accountMapper, app.stakeKeeper), - stakesim.SimulateMsgCompleteUnbonding(app.stakeKeeper), - stakesim.SimulateMsgBeginRedelegate(app.accountMapper, app.stakeKeeper), - stakesim.SimulateMsgCompleteRedelegate(app.stakeKeeper), - }, + testAndRunTxs(app), []simulation.RandSetup{}, - []simulation.Invariant{ - banksim.NonnegativeBalanceInvariant(app.accountMapper), - stakesim.AllInvariants(app.coinKeeper, app.stakeKeeper, app.accountMapper), - }, - numKeys, + invariants(app), numBlocks, blockSize, + false, ) } + +// TODO: Make another test for the fuzzer itself, which just has noOp txs +// and doesn't depend on gaia +func TestAppStateDeterminism(t *testing.T) { + if !enabled { + t.Skip("Skipping Gaia simulation") + } + + numSeeds := 5 + numTimesToRunPerSeed := 5 + appHashList := make([]json.RawMessage, numTimesToRunPerSeed) + + for i := 0; i < numSeeds; i++ { + seed := rand.Int63() + for j := 0; j < numTimesToRunPerSeed; j++ { + logger := log.NewNopLogger() + db := dbm.NewMemDB() + app := NewGaiaApp(logger, db, nil) + + // Run randomized simulation + simulation.SimulateFromSeed( + t, app.BaseApp, appStateFn, seed, + testAndRunTxs(app), + []simulation.RandSetup{}, + []simulation.Invariant{}, + 20, + 20, + true, + ) + appHash := app.LastCommitID().Hash + fmt.Printf(">>> APP HASH: %v, %X\n", appHash, appHash) + appHashList[j] = appHash + } + for k := 1; k < numTimesToRunPerSeed; k++ { + require.Equal(t, appHashList[0], appHashList[k]) + } + } +} diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 244a9eb832..47a1949dd2 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -117,6 +117,11 @@ func TestGaiaCLICreateValidator(t *testing.T) { fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags)) require.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak").Int64()) + defaultParams := stake.DefaultParams() + initialPool := stake.InitialPool() + initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewDec(100)) // Delegate tx on GaiaAppGenState + initialPool = initialPool.ProcessProvisions(defaultParams) // provisions are added to the pool every hour + // create validator cvStr := fmt.Sprintf("gaiacli stake create-validator %v", flags) cvStr += fmt.Sprintf(" --from=%s", "bar") @@ -124,6 +129,8 @@ func TestGaiaCLICreateValidator(t *testing.T) { cvStr += fmt.Sprintf(" --amount=%v", "2steak") cvStr += fmt.Sprintf(" --moniker=%v", "bar-vally") + initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewDec(1)) + executeWrite(t, cvStr, app.DefaultKeyPass) tests.WaitForNextNBlocksTM(2, port) @@ -131,13 +138,13 @@ func TestGaiaCLICreateValidator(t *testing.T) { require.Equal(t, int64(8), barAcc.GetCoins().AmountOf("steak").Int64(), "%v", barAcc) validator := executeGetValidator(t, fmt.Sprintf("gaiacli stake validator %s --output=json %v", barAddr, flags)) - require.Equal(t, validator.Owner, barAddr) + require.Equal(t, validator.Operator, barAddr) require.True(sdk.DecEq(t, sdk.NewDec(2), validator.Tokens)) // unbond a single share unbondStr := fmt.Sprintf("gaiacli stake unbond begin %v", flags) unbondStr += fmt.Sprintf(" --from=%s", "bar") - unbondStr += fmt.Sprintf(" --address-validator=%s", barAddr) + unbondStr += fmt.Sprintf(" --validator=%s", barAddr) unbondStr += fmt.Sprintf(" --shares-amount=%v", "1") success := executeWrite(t, unbondStr, app.DefaultKeyPass) @@ -150,6 +157,14 @@ func TestGaiaCLICreateValidator(t *testing.T) { */ validator = executeGetValidator(t, fmt.Sprintf("gaiacli stake validator %s --output=json %v", barAddr, flags)) require.Equal(t, "1.0000000000", validator.Tokens.String()) + + params := executeGetParams(t, fmt.Sprintf("gaiacli stake parameters --output=json %v", flags)) + require.True(t, defaultParams.Equal(params)) + + pool := executeGetPool(t, fmt.Sprintf("gaiacli stake pool --output=json %v", flags)) + require.Equal(t, initialPool.DateLastCommissionReset, pool.DateLastCommissionReset) + require.Equal(t, initialPool.PrevBondedShares, pool.PrevBondedShares) + require.Equal(t, initialPool.BondedTokens, pool.BondedTokens) } func TestGaiaCLISubmitProposal(t *testing.T) { @@ -328,6 +343,9 @@ func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount { return acc } +//___________________________________________________________________________________ +// stake + func executeGetValidator(t *testing.T, cmdStr string) stake.Validator { out := tests.ExecuteT(t, cmdStr, "") var validator stake.Validator @@ -337,6 +355,27 @@ func executeGetValidator(t *testing.T, cmdStr string) stake.Validator { return validator } +func executeGetPool(t *testing.T, cmdStr string) stake.Pool { + out := tests.ExecuteT(t, cmdStr, "") + var pool stake.Pool + cdc := app.MakeCodec() + err := cdc.UnmarshalJSON([]byte(out), &pool) + require.NoError(t, err, "out %v\n, err %v", out, err) + return pool +} + +func executeGetParams(t *testing.T, cmdStr string) stake.Params { + out := tests.ExecuteT(t, cmdStr, "") + var params stake.Params + cdc := app.MakeCodec() + err := cdc.UnmarshalJSON([]byte(out), ¶ms) + require.NoError(t, err, "out %v\n, err %v", out, err) + return params +} + +//___________________________________________________________________________________ +// gov + func executeGetProposal(t *testing.T, cmdStr string) gov.Proposal { out := tests.ExecuteT(t, cmdStr, "") var proposal gov.Proposal diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go index 9c4d67b8c4..df0fd3c113 100644 --- a/cmd/gaia/cmd/gaiacli/main.go +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -62,18 +62,10 @@ func main() { ibccmd.IBCRelayCmd(cdc), )...) - advancedCmd := &cobra.Command{ - Use: "advanced", - Short: "Advanced subcommands", - } - - advancedCmd.AddCommand( + rootCmd.AddCommand( tendermintCmd, ibcCmd, lcd.ServeCommand(cdc), - ) - rootCmd.AddCommand( - advancedCmd, client.LineBreak, ) @@ -88,6 +80,12 @@ func main() { stakecmd.GetCmdQueryValidators("stake", cdc), stakecmd.GetCmdQueryDelegation("stake", cdc), stakecmd.GetCmdQueryDelegations("stake", cdc), + stakecmd.GetCmdQueryParams("stake", cdc), + stakecmd.GetCmdQueryPool("stake", cdc), + stakecmd.GetCmdQueryUnbondingDelegation("stake", cdc), + stakecmd.GetCmdQueryUnbondingDelegations("stake", cdc), + stakecmd.GetCmdQueryRedelegation("stake", cdc), + stakecmd.GetCmdQueryRedelegations("stake", cdc), slashingcmd.GetCmdQuerySigningInfo("slashing", cdc), )...) stakeCmd.AddCommand( @@ -97,7 +95,7 @@ func main() { stakecmd.GetCmdDelegate(cdc), stakecmd.GetCmdUnbond("stake", cdc), stakecmd.GetCmdRedelegate("stake", cdc), - slashingcmd.GetCmdUnrevoke(cdc), + slashingcmd.GetCmdUnjail(cdc), )...) rootCmd.AddCommand( stakeCmd, diff --git a/cmd/gaia/testnets/gaia-5001/adrian.json b/cmd/gaia/testnets/gaia-5001/adrian.json deleted file mode 100644 index 7ca99cb1e9..0000000000 --- a/cmd/gaia/testnets/gaia-5001/adrian.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "1ebc5ca705b3ae1c06a0888ff1287ada82149dc3", - "ip": "138.68.77.24", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - }, - "power": 100, - "name": "adrian" - }, - "app_gen_tx": { - "name": "default", - "address": "D9C12CB5186FE0018179742FD3110EE534C63460", - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/anton.json b/cmd/gaia/testnets/gaia-5001/anton.json deleted file mode 100644 index 701e858874..0000000000 --- a/cmd/gaia/testnets/gaia-5001/anton.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "c272ae3cff7558db2c6195eea38fd43fd08406dc", - "ip": "206.189.31.178", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "tJlZJWjOpYvRitYFTWNPTaUtvQVf+hoNjlfI84VPqvI=" - }, - "power": 100, - "name": "anton" - }, - "app_gen_tx": { - "name": "default", - "address": "E766088FD171906289617F60BF0014C46F0F85EC", - "pub_key": { - "type": "AC26791624DE60", - "value": "tJlZJWjOpYvRitYFTWNPTaUtvQVf+hoNjlfI84VPqvI=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/aurel.json b/cmd/gaia/testnets/gaia-5001/aurel.json deleted file mode 100644 index 0c2ea81668..0000000000 --- a/cmd/gaia/testnets/gaia-5001/aurel.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "aef085c4bfed0c1ffc6705f2e1e3bf85e5164600", - "ip": "45.77.53.208", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - }, - "power": 100, - "name": "aurel" - }, - "app_gen_tx": { - "name": "aurel", - "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/bucky.json b/cmd/gaia/testnets/gaia-5001/bucky.json deleted file mode 100644 index fc4bb51cde..0000000000 --- a/cmd/gaia/testnets/gaia-5001/bucky.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "b0dd378c3fbc4c156cd6d302a799f0d2e4227201", - "ip": "159.89.121.174", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - }, - "power": 100, - "name": "bucky" - }, - "app_gen_tx": { - "name": "bucky", - "address": "935E48ED79F1006ED135553768E1D9A768747CF6", - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/cwgoes.json b/cmd/gaia/testnets/gaia-5001/cwgoes.json deleted file mode 100644 index dce7e20c9f..0000000000 --- a/cmd/gaia/testnets/gaia-5001/cwgoes.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "e25603602d8cf8542570ad0e311d50f55f497f85", - "ip": "158.69.63.13", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - }, - "power": 100, - "name": "cwgoes" - }, - "app_gen_tx": { - "name": "cwgoes", - "address": "328FBB8EA315D070DF908982A5F91A3618001D20", - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/iris.json b/cmd/gaia/testnets/gaia-5001/iris.json deleted file mode 100644 index 1a1019672c..0000000000 --- a/cmd/gaia/testnets/gaia-5001/iris.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "aabf05a67b2f399807dc602d05bf97b0ed283ac2", - "ip": "116.62.62.39", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - }, - "power": 100, - "name": "iris" - }, - "app_gen_tx": { - "name": "=suyu", - "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - } - } -} \ No newline at end of file diff --git a/cmd/gaia/testnets/gaia-5001/lino.json b/cmd/gaia/testnets/gaia-5001/lino.json deleted file mode 100644 index 5bc98bb6ed..0000000000 --- a/cmd/gaia/testnets/gaia-5001/lino.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "79466a03e9d4b4648a7dd8cead1fa7121ce76ee3", - "ip": "34.235.130.1", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - }, - "power": 100, - "name": "lino" - }, - "app_gen_tx": { - "name": "lino", - "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/pbostrom.json b/cmd/gaia/testnets/gaia-5001/pbostrom.json deleted file mode 100644 index 59cd469504..0000000000 --- a/cmd/gaia/testnets/gaia-5001/pbostrom.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "adb290585a2753bf1a520c76802b0dab3dffa895", - "ip": "34.201.21.179", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - }, - "power": 100, - "name": "pbostrom" - }, - "app_gen_tx": { - "name": "default", - "address": "109720515B4F8C0858DA3521E448262334534FFD", - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/poldsam.json b/cmd/gaia/testnets/gaia-5001/poldsam.json deleted file mode 100644 index 8149a92592..0000000000 --- a/cmd/gaia/testnets/gaia-5001/poldsam.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "678503e6c8f50db7279c7da3cb9b072aac4bc0d5", - "ip": "35.193.188.125", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - }, - "power": 100, - "name": "polsdam" - }, - "app_gen_tx": { - "name": "poldsam", - "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/staked.json b/cmd/gaia/testnets/gaia-5001/staked.json deleted file mode 100644 index f39cced6b8..0000000000 --- a/cmd/gaia/testnets/gaia-5001/staked.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "3519f05985394107e0b2e285361b7e012adb1113", - "ip": "54.209.118.64", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "vq0V0BjpmIh6WyNnFpMaO5LyUK2FamkNt65eJYa5AaQ=" - }, - "power": 100, - "name": "staked" - }, - "app_gen_tx": { - "name": "default", - "address": "935E04662697134905706A4CCDB822AC6FC11C2E", - "pub_key": { - "type": "AC26791624DE60", - "value": "vq0V0BjpmIh6WyNnFpMaO5LyUK2FamkNt65eJYa5AaQ=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/zach.json b/cmd/gaia/testnets/gaia-5001/zach.json deleted file mode 100644 index 76a08cc925..0000000000 --- a/cmd/gaia/testnets/gaia-5001/zach.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "8a2802fb25d352f3e7e277559a4f683780c3ef22", - "ip": "167.99.191.184", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - }, - "power": 100, - "name": "" - }, - "app_gen_tx": { - "name": "zach", - "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/zaki.json b/cmd/gaia/testnets/gaia-5001/zaki.json deleted file mode 100644 index 956f2bf8ce..0000000000 --- a/cmd/gaia/testnets/gaia-5001/zaki.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "30b45459e4881680c0ef1750fde136fefa6c3b98", - "ip": "35.184.182.143", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - }, - "power": 100, - "name": "zaki" - }, - "app_gen_tx": { - "name": "zaki", - "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-6000/genesis.json b/cmd/gaia/testnets/gaia-6000/genesis.json deleted file mode 100644 index aefab92869..0000000000 --- a/cmd/gaia/testnets/gaia-6000/genesis.json +++ /dev/null @@ -1,1459 +0,0 @@ -{ - "genesis_time": "2018-05-15T18:29:12.38288148Z", - "chain_id": "gaia-6000", - "consensus_params": { - "block_size_params": { - "max_bytes": 22020096, - "max_txs": 100000, - "max_gas": -1 - }, - "tx_size_params": { - "max_bytes": 10240, - "max_gas": -1 - }, - "block_gossip_params": { - "block_part_size_bytes": 65536 - }, - "evidence_params": { - "max_age": 100000 - } - }, - "validators": [ - { - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - }, - "power": 1000, - "name": "adrian" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - }, - "power": 1000, - "name": "zaki" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" - }, - "power": 100, - "name": "staked" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - }, - "power": 1000, - "name": "polsdam" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - }, - "power": 1000, - "name": "lino" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - }, - "power": 100, - "name": "" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - }, - "power": 1000, - "name": "iris" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - }, - "power": 1000, - "name": "pbostrom" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - }, - "power": 1000, - "name": "aurel" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - }, - "power": 1000, - "name": "bucky" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - }, - "power": 100, - "name": "cwgoes" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" - }, - "power": 1000, - "name": "bdnet" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" - }, - "power": 1000, - "name": "melea-trust" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "power": 1000, - "name": "naruemon" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" - }, - "power": 1000, - "name": "idoor" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" - }, - "power": 1000, - "name": "ATEAM1" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" - }, - "power": 1000, - "name": "figmatt" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" - }, - "power": 1000, - "name": "jla-bsd" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" - }, - "power": 1000, - "name": "Gold" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" - }, - "power": 1000, - "name": "nylira" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" - }, - "power": 1000, - "name": "BKCM" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" - }, - "power": 1000, - "name": "Dev's Validator" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" - }, - "power": 1000, - "name": "Staking Facilities" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" - }, - "power": 1000, - "name": "nuevax" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" - }, - "power": 1000, - "name": "vultr.guest" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" - }, - "power": 1000, - "name": "forebole" - } - ], - "app_hash": "", - "app_state": { - "accounts": [ - { - "address": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "coins": [ - { - "denom": "devToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "coins": [ - { - "denom": "adrianToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "109720515B4F8C0858DA3521E448262334534FFD", - "coins": [ - { - "denom": "defaultToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "coins": [ - { - "denom": "aurelToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "328FBB8EA315D070DF908982A5F91A3618001D20", - "coins": [ - { - "denom": "cwgoesToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "coins": [ - { - "denom": "BKCMToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "coins": [ - { - "denom": "BDToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "coins": [ - { - "denom": "suyuToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "coins": [ - { - "denom": "linoToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "coins": [ - { - "denom": "stakingToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "935E04662697134905706A4CCDB822AC6FC11C2E", - "coins": [ - { - "denom": "defaultToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "935E48ED79F1006ED135553768E1D9A768747CF6", - "coins": [ - { - "denom": "buckyToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "99FFAEE5BF6040EADA2F26548C4A702619797C9F", - "coins": [ - { - "denom": "kwunyeungToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "zachToken", - "amount": 1000 - } - ] - }, - { - "address": "A323EC45243D600204BA3D298E3C20322D08C84C", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "nuevaxToken", - "amount": 1000 - } - ] - }, - { - "address": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "dokiaToken", - "amount": 1000 - } - ] - }, - { - "address": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "forboleToken", - "amount": 1000 - } - ] - }, - { - "address": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "coins": [ - { - "denom": "steak", - "amount": 100 - }, - { - "denom": "pengToken", - "amount": 1000 - } - ] - }, - { - "address": "FD30D5C983FFEDEC069C3DDFCF270E41A556A86E", - "coins": [ - { - "denom": "steak", - "amount": 900 - }, - { - "denom": "faucetToken", - "amount": 10000000 - } - ] - }, - { - "address": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "goldToken", - "amount": 100 - } - ] - }, - { - "address": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "jlaToken", - "amount": 100 - } - ] - }, - { - "address": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "figmattToken", - "amount": 100 - } - ] - }, - { - "address": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "ATEAM1Token", - "amount": 100 - } - ] - }, - { - "address": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "idoorToken", - "amount": 100 - } - ] - }, - { - "address": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "naruemonToken", - "amount": 100 - } - ] - }, - { - "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "zakiToken", - "amount": 1000 - } - ] - }, - { - "address": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "trustToken", - "amount": 1000 - } - ] - }, - { - "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "coins": [ - { - "denom": "poldsamToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - } - ], - "stake": { - "pool": { - "loose_unbonded_tokens": 2350, - "unbonded_tokens": 0, - "unbonding_tokens": 0, - "bonded_tokens": 25200, - "unbonded_shares": "0", - "unbonding_shares": "0", - "bonded_shares": "25200", - "inflation_last_time": 0, - "inflation": "9012837/100000000", - "date_last_commission_reset": 0, - "prev_bonded_shares": "0" - }, - "params": { - "inflation_rate_change": "13/100", - "inflation_max": "1/5", - "inflation_min": "7/100", - "goal_bonded": "67/100", - "max_validators": 100, - "bond_denom": "steak" - }, - "bonds": [ - { - "delegator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "validator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "109720515B4F8C0858DA3521E448262334534FFD", - "validator_addr": "109720515B4F8C0858DA3521E448262334534FFD", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "validator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", - "validator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "validator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "validator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "validator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "validator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "validator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", - "validator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", - "validator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "validator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", - "validator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "validator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "validator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "validator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "validator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "validator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "validator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "validator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "validator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "validator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "validator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "validator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "validator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "validator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "shares": "1000", - "height": 0 - } - ], - "validators": [ - { - "owner": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "pub_key": { - "type": "AC26791624DE60", - "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" - }, - "description": { - "moniker": "Dev's Validator", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "109720515B4F8C0858DA3521E448262334534FFD", - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - }, - "description": { - "moniker": "", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - }, - "description": { - "moniker": "aurel", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "328FBB8EA315D070DF908982A5F91A3618001D20", - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - }, - "description": { - "moniker": "cwgoes", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "pub_key": { - "type": "AC26791624DE60", - "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" - }, - "description": { - "moniker": "BKCM", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "pub_key": { - "type": "AC26791624DE60", - "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" - }, - "description": { - "moniker": "bdnet", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - }, - "description": { - "moniker": "suyu", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - }, - "description": { - "moniker": "lino", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "pub_key": { - "type": "AC26791624DE60", - "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" - }, - "description": { - "moniker": "Staking Facilities", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "935E04662697134905706A4CCDB822AC6FC11C2E", - "pub_key": { - "type": "AC26791624DE60", - "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" - }, - "description": { - "moniker": "default", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "935E48ED79F1006ED135553768E1D9A768747CF6", - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - }, - "description": { - "moniker": "bucky", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - }, - "description": { - "moniker": "zach", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "A323EC45243D600204BA3D298E3C20322D08C84C", - "pub_key": { - "type": "AC26791624DE60", - "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" - }, - "description": { - "moniker": "nuevax", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "pub_key": { - "type": "AC26791624DE60", - "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" - }, - "description": { - "moniker": "vultr.guest", - "identity": "", - "website": "https://ion.dokia.capital/", - "details": "DokiaValidator" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "pub_key": { - "type": "AC26791624DE60", - "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" - }, - "description": { - "moniker": "forbole", - "identity": "", - "website": "https://www.forbole.com", - "details": "Recommend. Refer. Reward" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "pub_key": { - "type": "AC26791624DE60", - "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" - }, - "description": { - "moniker": "nylira", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "pub_key": { - "type": "AC26791624DE60", - "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" - }, - "description": { - "moniker": "Gold", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "pub_key": { - "type": "AC26791624DE60", - "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" - }, - "description": { - "moniker": "jla-bsd", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "pub_key": { - "type": "AC26791624DE60", - "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" - }, - "description": { - "moniker": "figmatt", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "pub_key": { - "type": "AC26791624DE60", - "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" - }, - "description": { - "moniker": "ATEAM1", - "identity": "", - "website": "", - "details": "ATEAM1" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "pub_key": { - "type": "AC26791624DE60", - "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" - }, - "description": { - "moniker": "idoor", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "pub_key": { - "type": "AC26791624DE60", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "description": { - "moniker": "naruemon", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - }, - "description": { - "moniker": "Adrian Brink - Cryptium Labs", - "identity": "", - "website": "https://cryptium.ch", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - }, - "description": { - "moniker": "zaki", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "pub_key": { - "type": "AC26791624DE60", - "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" - }, - "description": { - "moniker": "trust", - "identity": "", - "website": "http://cosmos-trust.com", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - }, - "description": { - "moniker": "proof-of-audit", - "identity": "", - "website": "https://proof-of-audit.com", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - } - ] - } - } -} diff --git a/cmd/gaia/testnets/gaia-6001/genesis.json b/cmd/gaia/testnets/gaia-6001/genesis.json deleted file mode 100644 index 512d761bed..0000000000 --- a/cmd/gaia/testnets/gaia-6001/genesis.json +++ /dev/null @@ -1,1459 +0,0 @@ -{ - "genesis_time": "2018-05-15T18:29:12.38288148Z", - "chain_id": "gaia-6001", - "consensus_params": { - "block_size_params": { - "max_bytes": 22020096, - "max_txs": 100000, - "max_gas": -1 - }, - "tx_size_params": { - "max_bytes": 10240, - "max_gas": -1 - }, - "block_gossip_params": { - "block_part_size_bytes": 65536 - }, - "evidence_params": { - "max_age": 100000 - } - }, - "validators": [ - { - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - }, - "power": 1000, - "name": "adrian" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - }, - "power": 1000, - "name": "zaki" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" - }, - "power": 100, - "name": "staked" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - }, - "power": 1000, - "name": "polsdam" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - }, - "power": 1000, - "name": "lino" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - }, - "power": 100, - "name": "" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - }, - "power": 1000, - "name": "iris" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - }, - "power": 1000, - "name": "pbostrom" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - }, - "power": 1000, - "name": "aurel" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - }, - "power": 1000, - "name": "bucky" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - }, - "power": 100, - "name": "cwgoes" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" - }, - "power": 1000, - "name": "bdnet" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" - }, - "power": 1000, - "name": "melea-trust" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "power": 1000, - "name": "naruemon" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" - }, - "power": 1000, - "name": "idoor" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" - }, - "power": 1000, - "name": "ATEAM1" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" - }, - "power": 1000, - "name": "figmatt" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" - }, - "power": 1000, - "name": "jla-bsd" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" - }, - "power": 1000, - "name": "Gold" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" - }, - "power": 1000, - "name": "nylira" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" - }, - "power": 1000, - "name": "BKCM" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" - }, - "power": 1000, - "name": "Dev's Validator" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" - }, - "power": 1000, - "name": "Staking Facilities" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" - }, - "power": 1000, - "name": "nuevax" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" - }, - "power": 1000, - "name": "vultr.guest" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" - }, - "power": 1000, - "name": "forebole" - } - ], - "app_hash": "", - "app_state": { - "accounts": [ - { - "address": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "coins": [ - { - "denom": "devToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "coins": [ - { - "denom": "adrianToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "109720515B4F8C0858DA3521E448262334534FFD", - "coins": [ - { - "denom": "defaultToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "coins": [ - { - "denom": "aurelToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "328FBB8EA315D070DF908982A5F91A3618001D20", - "coins": [ - { - "denom": "cwgoesToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "coins": [ - { - "denom": "BKCMToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "coins": [ - { - "denom": "BDToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "coins": [ - { - "denom": "suyuToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "coins": [ - { - "denom": "linoToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "coins": [ - { - "denom": "stakingToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "935E04662697134905706A4CCDB822AC6FC11C2E", - "coins": [ - { - "denom": "defaultToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "935E48ED79F1006ED135553768E1D9A768747CF6", - "coins": [ - { - "denom": "buckyToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "99FFAEE5BF6040EADA2F26548C4A702619797C9F", - "coins": [ - { - "denom": "kwunyeungToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "zachToken", - "amount": 1000 - } - ] - }, - { - "address": "A323EC45243D600204BA3D298E3C20322D08C84C", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "nuevaxToken", - "amount": 1000 - } - ] - }, - { - "address": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "dokiaToken", - "amount": 1000 - } - ] - }, - { - "address": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "forboleToken", - "amount": 1000 - } - ] - }, - { - "address": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "coins": [ - { - "denom": "steak", - "amount": 100 - }, - { - "denom": "pengToken", - "amount": 1000 - } - ] - }, - { - "address": "FD30D5C983FFEDEC069C3DDFCF270E41A556A86E", - "coins": [ - { - "denom": "steak", - "amount": 900 - }, - { - "denom": "faucetToken", - "amount": 10000000 - } - ] - }, - { - "address": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "goldToken", - "amount": 100 - } - ] - }, - { - "address": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "jlaToken", - "amount": 100 - } - ] - }, - { - "address": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "figmattToken", - "amount": 100 - } - ] - }, - { - "address": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "ATEAM1Token", - "amount": 100 - } - ] - }, - { - "address": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "idoorToken", - "amount": 100 - } - ] - }, - { - "address": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "naruemonToken", - "amount": 100 - } - ] - }, - { - "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "zakiToken", - "amount": 1000 - } - ] - }, - { - "address": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "trustToken", - "amount": 1000 - } - ] - }, - { - "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "coins": [ - { - "denom": "poldsamToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - } - ], - "stake": { - "pool": { - "loose_unbonded_tokens": 2300, - "unbonded_tokens": 0, - "unbonding_tokens": 0, - "bonded_tokens": 23300, - "unbonded_shares": "0", - "unbonding_shares": "0", - "bonded_shares": "23300", - "inflation_last_time": 0, - "inflation": "9012837/100000000", - "date_last_commission_reset": 0, - "prev_bonded_shares": "0" - }, - "params": { - "inflation_rate_change": "13/100", - "inflation_max": "1/5", - "inflation_min": "7/100", - "goal_bonded": "67/100", - "max_validators": 100, - "bond_denom": "steak" - }, - "bonds": [ - { - "delegator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "validator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "109720515B4F8C0858DA3521E448262334534FFD", - "validator_addr": "109720515B4F8C0858DA3521E448262334534FFD", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "validator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", - "validator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "validator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "validator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "validator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "validator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "validator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", - "validator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", - "validator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "validator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", - "validator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "validator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "validator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "validator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "validator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "validator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "validator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "validator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "validator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "validator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "validator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "validator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "validator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "validator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "shares": "1000", - "height": 0 - } - ], - "validators": [ - { - "owner": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "pub_key": { - "type": "AC26791624DE60", - "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" - }, - "description": { - "moniker": "Dev's Validator", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "109720515B4F8C0858DA3521E448262334534FFD", - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - }, - "description": { - "moniker": "", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - }, - "description": { - "moniker": "aurel", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "328FBB8EA315D070DF908982A5F91A3618001D20", - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - }, - "description": { - "moniker": "cwgoes", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "pub_key": { - "type": "AC26791624DE60", - "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" - }, - "description": { - "moniker": "BKCM", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "pub_key": { - "type": "AC26791624DE60", - "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" - }, - "description": { - "moniker": "bdnet", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - }, - "description": { - "moniker": "suyu", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - }, - "description": { - "moniker": "lino", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "pub_key": { - "type": "AC26791624DE60", - "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" - }, - "description": { - "moniker": "Staking Facilities", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "935E04662697134905706A4CCDB822AC6FC11C2E", - "pub_key": { - "type": "AC26791624DE60", - "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" - }, - "description": { - "moniker": "default", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "935E48ED79F1006ED135553768E1D9A768747CF6", - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - }, - "description": { - "moniker": "bucky", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - }, - "description": { - "moniker": "zach", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "A323EC45243D600204BA3D298E3C20322D08C84C", - "pub_key": { - "type": "AC26791624DE60", - "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" - }, - "description": { - "moniker": "nuevax", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "pub_key": { - "type": "AC26791624DE60", - "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" - }, - "description": { - "moniker": "vultr.guest", - "identity": "", - "website": "https://ion.dokia.capital/", - "details": "DokiaValidator" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "pub_key": { - "type": "AC26791624DE60", - "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" - }, - "description": { - "moniker": "forbole", - "identity": "", - "website": "https://www.forbole.com", - "details": "Recommend. Refer. Reward" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "pub_key": { - "type": "AC26791624DE60", - "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" - }, - "description": { - "moniker": "nylira", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "pub_key": { - "type": "AC26791624DE60", - "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" - }, - "description": { - "moniker": "Gold", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "pub_key": { - "type": "AC26791624DE60", - "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" - }, - "description": { - "moniker": "jla-bsd", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "pub_key": { - "type": "AC26791624DE60", - "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" - }, - "description": { - "moniker": "figmatt", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "pub_key": { - "type": "AC26791624DE60", - "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" - }, - "description": { - "moniker": "ATEAM1", - "identity": "", - "website": "", - "details": "ATEAM1" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "pub_key": { - "type": "AC26791624DE60", - "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" - }, - "description": { - "moniker": "idoor", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "pub_key": { - "type": "AC26791624DE60", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "description": { - "moniker": "naruemon", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - }, - "description": { - "moniker": "Adrian Brink - Cryptium Labs", - "identity": "", - "website": "https://cryptium.ch", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - }, - "description": { - "moniker": "zaki", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "pub_key": { - "type": "AC26791624DE60", - "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" - }, - "description": { - "moniker": "trust", - "identity": "", - "website": "http://cosmos-trust.com", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - }, - "description": { - "moniker": "proof-of-audit", - "identity": "", - "website": "https://proof-of-audit.com", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - } - ] - } - } -} diff --git a/cmd/gaia/testnets/gaia-6002/genesis.json b/cmd/gaia/testnets/gaia-6002/genesis.json deleted file mode 100644 index 7f53893a86..0000000000 --- a/cmd/gaia/testnets/gaia-6002/genesis.json +++ /dev/null @@ -1,1459 +0,0 @@ -{ - "genesis_time": "2018-06-16T18:29:12.38288148Z", - "chain_id": "gaia-6002", - "consensus_params": { - "block_size_params": { - "max_bytes": 22020096, - "max_txs": 100000, - "max_gas": -1 - }, - "tx_size_params": { - "max_bytes": 10240, - "max_gas": -1 - }, - "block_gossip_params": { - "block_part_size_bytes": 65536 - }, - "evidence_params": { - "max_age": 100000 - } - }, - "validators": [ - { - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - }, - "power": 1000, - "name": "adrian" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - }, - "power": 1000, - "name": "zaki" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" - }, - "power": 100, - "name": "staked" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - }, - "power": 1000, - "name": "polsdam" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - }, - "power": 1000, - "name": "lino" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - }, - "power": 100, - "name": "" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - }, - "power": 1000, - "name": "iris" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - }, - "power": 1000, - "name": "pbostrom" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - }, - "power": 1000, - "name": "aurel" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - }, - "power": 1000, - "name": "bucky" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - }, - "power": 100, - "name": "cwgoes" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" - }, - "power": 1000, - "name": "bdnet" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" - }, - "power": 1000, - "name": "melea-trust" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "power": 1000, - "name": "naruemon" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" - }, - "power": 1000, - "name": "idoor" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" - }, - "power": 1000, - "name": "ATEAM1" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" - }, - "power": 1000, - "name": "figmatt" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" - }, - "power": 1000, - "name": "jla-bsd" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" - }, - "power": 1000, - "name": "Gold" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" - }, - "power": 1000, - "name": "nylira" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" - }, - "power": 1000, - "name": "BKCM" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" - }, - "power": 1000, - "name": "Dev's Validator" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" - }, - "power": 1000, - "name": "Staking Facilities" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" - }, - "power": 1000, - "name": "nuevax" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" - }, - "power": 1000, - "name": "vultr.guest" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" - }, - "power": 1000, - "name": "forebole" - } - ], - "app_hash": "", - "app_state": { - "accounts": [ - { - "address": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "coins": [ - { - "denom": "devToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "coins": [ - { - "denom": "adrianToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "109720515B4F8C0858DA3521E448262334534FFD", - "coins": [ - { - "denom": "defaultToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "coins": [ - { - "denom": "aurelToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "328FBB8EA315D070DF908982A5F91A3618001D20", - "coins": [ - { - "denom": "cwgoesToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "coins": [ - { - "denom": "BKCMToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "coins": [ - { - "denom": "BDToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "coins": [ - { - "denom": "suyuToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "coins": [ - { - "denom": "linoToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "coins": [ - { - "denom": "stakingToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "935E04662697134905706A4CCDB822AC6FC11C2E", - "coins": [ - { - "denom": "defaultToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "935E48ED79F1006ED135553768E1D9A768747CF6", - "coins": [ - { - "denom": "buckyToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "99FFAEE5BF6040EADA2F26548C4A702619797C9F", - "coins": [ - { - "denom": "kwunyeungToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "zachToken", - "amount": 1000 - } - ] - }, - { - "address": "A323EC45243D600204BA3D298E3C20322D08C84C", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "nuevaxToken", - "amount": 1000 - } - ] - }, - { - "address": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "dokiaToken", - "amount": 1000 - } - ] - }, - { - "address": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "forboleToken", - "amount": 1000 - } - ] - }, - { - "address": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "coins": [ - { - "denom": "steak", - "amount": 100 - }, - { - "denom": "pengToken", - "amount": 1000 - } - ] - }, - { - "address": "FD30D5C983FFEDEC069C3DDFCF270E41A556A86E", - "coins": [ - { - "denom": "steak", - "amount": 900 - }, - { - "denom": "faucetToken", - "amount": 10000000 - } - ] - }, - { - "address": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "goldToken", - "amount": 100 - } - ] - }, - { - "address": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "jlaToken", - "amount": 100 - } - ] - }, - { - "address": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "figmattToken", - "amount": 100 - } - ] - }, - { - "address": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "ATEAM1Token", - "amount": 100 - } - ] - }, - { - "address": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "idoorToken", - "amount": 100 - } - ] - }, - { - "address": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "naruemonToken", - "amount": 100 - } - ] - }, - { - "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "zakiToken", - "amount": 1000 - } - ] - }, - { - "address": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "trustToken", - "amount": 1000 - } - ] - }, - { - "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "coins": [ - { - "denom": "poldsamToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - } - ], - "stake": { - "pool": { - "loose_unbonded_tokens": 2300, - "unbonded_tokens": 0, - "unbonding_tokens": 0, - "bonded_tokens": 23300, - "unbonded_shares": "0", - "unbonding_shares": "0", - "bonded_shares": "23300", - "inflation_last_time": 0, - "inflation": "9012837/100000000", - "date_last_commission_reset": 0, - "prev_bonded_shares": "0" - }, - "params": { - "inflation_rate_change": "13/100", - "inflation_max": "1/5", - "inflation_min": "7/100", - "goal_bonded": "67/100", - "max_validators": 100, - "bond_denom": "steak" - }, - "bonds": [ - { - "delegator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "validator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "109720515B4F8C0858DA3521E448262334534FFD", - "validator_addr": "109720515B4F8C0858DA3521E448262334534FFD", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "validator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", - "validator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "validator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "validator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "validator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "validator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "validator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", - "validator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", - "validator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "validator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", - "validator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "validator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "validator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "validator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "validator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "validator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "validator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "validator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "validator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "validator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "validator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "validator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "validator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "validator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "shares": "1000", - "height": 0 - } - ], - "validators": [ - { - "owner": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "pub_key": { - "type": "AC26791624DE60", - "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" - }, - "description": { - "moniker": "Dev's Validator", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "109720515B4F8C0858DA3521E448262334534FFD", - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - }, - "description": { - "moniker": "", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - }, - "description": { - "moniker": "aurel", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "328FBB8EA315D070DF908982A5F91A3618001D20", - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - }, - "description": { - "moniker": "cwgoes", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "pub_key": { - "type": "AC26791624DE60", - "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" - }, - "description": { - "moniker": "BKCM", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "pub_key": { - "type": "AC26791624DE60", - "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" - }, - "description": { - "moniker": "bdnet", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - }, - "description": { - "moniker": "suyu", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - }, - "description": { - "moniker": "lino", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "pub_key": { - "type": "AC26791624DE60", - "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" - }, - "description": { - "moniker": "Staking Facilities", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "935E04662697134905706A4CCDB822AC6FC11C2E", - "pub_key": { - "type": "AC26791624DE60", - "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" - }, - "description": { - "moniker": "default", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "935E48ED79F1006ED135553768E1D9A768747CF6", - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - }, - "description": { - "moniker": "bucky", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - }, - "description": { - "moniker": "zach", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "A323EC45243D600204BA3D298E3C20322D08C84C", - "pub_key": { - "type": "AC26791624DE60", - "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" - }, - "description": { - "moniker": "nuevax", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "pub_key": { - "type": "AC26791624DE60", - "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" - }, - "description": { - "moniker": "vultr.guest", - "identity": "", - "website": "https://ion.dokia.capital/", - "details": "DokiaValidator" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "pub_key": { - "type": "AC26791624DE60", - "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" - }, - "description": { - "moniker": "forbole", - "identity": "", - "website": "https://www.forbole.com", - "details": "Recommend. Refer. Reward" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "pub_key": { - "type": "AC26791624DE60", - "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" - }, - "description": { - "moniker": "nylira", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "pub_key": { - "type": "AC26791624DE60", - "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" - }, - "description": { - "moniker": "Gold", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "pub_key": { - "type": "AC26791624DE60", - "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" - }, - "description": { - "moniker": "jla-bsd", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "pub_key": { - "type": "AC26791624DE60", - "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" - }, - "description": { - "moniker": "figmatt", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "pub_key": { - "type": "AC26791624DE60", - "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" - }, - "description": { - "moniker": "ATEAM1", - "identity": "", - "website": "", - "details": "ATEAM1" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "pub_key": { - "type": "AC26791624DE60", - "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" - }, - "description": { - "moniker": "idoor", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "pub_key": { - "type": "AC26791624DE60", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "description": { - "moniker": "naruemon", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - }, - "description": { - "moniker": "Adrian Brink - Cryptium Labs", - "identity": "", - "website": "https://cryptium.ch", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - }, - "description": { - "moniker": "zaki", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "pub_key": { - "type": "AC26791624DE60", - "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" - }, - "description": { - "moniker": "trust", - "identity": "", - "website": "http://cosmos-trust.com", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - }, - "description": { - "moniker": "proof-of-audit", - "identity": "", - "website": "https://proof-of-audit.com", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - } - ] - } - } -} diff --git a/cmd/gaia/testnets/gaia-7000/genesis.json b/cmd/gaia/testnets/gaia-7000/genesis.json deleted file mode 100644 index 7ada516d49..0000000000 --- a/cmd/gaia/testnets/gaia-7000/genesis.json +++ /dev/null @@ -1,5680 +0,0 @@ -{ - "genesis_time": "2018-07-16T19:57:28.971479541Z", - "chain_id": "gaia-7000", - "consensus_params": { - "block_size_params": { - "max_bytes": "22020096", - "max_txs": "10000", - "max_gas": "-1" - }, - "tx_size_params": { - "max_bytes": "10240", - "max_gas": "-1" - }, - "block_gossip_params": { - "block_part_size_bytes": "65536" - }, - "evidence_params": { - "max_age": "100000" - } - }, - "validators": [ - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "MRCeBDANSjH6IsxO0z6tRe+xqoZvIGhdfl1t+SXGUpM=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "tOEqjO2t51PEgO9Tv0B7qM0yPmy1n5tMa3Beg0tp3ns=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "S8s6fdAQNQ3bN9SNVAsHB/j8uv1CM1roxeLesL+fh4g=" - }, - "power": "100", - "name": "validatorluigi001" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2JoNf1gavJ1d6XFIumO1Mki5GVMOcg58AioHksU3maE=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2JoNf1gavJ1d6XFIumO1Mki5GVMOcg58AioHksU3maE=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "k3YLQYEN2QMP6XITRsBmgb+pNGhJ5Jbg0bzUW977kK0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "EREUrXXl1OJqLQag0P4h6vJ2H+8GEwyNAjgn1XEJU+I=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "heNintBalqaJwCOjLb9+mX/cQ1ytMlV7ZroPIlkwZqo=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nb2oRB12DlEQkFn7KSjSVkj5rDoSTsuBFa09+gmNJ7o=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "bZSEBDNIOr0xJ/PxaAScJIyG6hqFtryBAMNwghAOTTU=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8K3clCjVU33BTIpUhdahGmu++WxHj4NUE9krCRkk++s=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "RBuRRNEzA9RA1Wrdi9PPFQJ29/n/bqN9O2tQv9Gq248=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "RwPRoiY5C0covekqbr3VrQwxWGHioUUIf2+TOq8LIC0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2qtEBT+Tc+SD2wJsdrVMHXrBKfvesxtmtSKDK5fXwA0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "gU5mmVLUSzn/fIEMgiiB4LARRoWlqjUGHr3A4SndWO8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "xlO2cnii42KisAn8OcstC/3XV5+I0FlcSbWuyy5MVA8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "q5ezDn4DcWFPWvMayPJI35nXr//jjF8fGHsuiHjpDcU=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "PSqbJOwglJb1yrj3aWebBpXb2ujXcR037s1Cyj2HoW4=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "A6GzeXUM3vsXaDAEYMSDgSKkqn9AoUYjs8empH46MGY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "81fx09BivOOxeGL7QisF8aKRZjjcARpiSaCOX9mJfY8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "UjTvuOew2EaooduJBiYmBWeF5ai0yFJG8uio5YXpJgg=" - }, - "power": "1", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "y7p9JSVZBnRxjAI9v5Pxl37hMtyuHf6B4Ghqzm6+ii0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "oG8Q5o+SN4wqMLvlIfVgQPnsQzNEKeH0D/XGM8JlGrY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "PxJbo5FKA6mXtgwclRQVNIjOCQK3Q7WkLQrvM9lYbGI=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Q/UShqqVDOUSNYBrR1G/1X1s+YXEVXEJzeXmYvfYIr0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "uEWWDBwFW+/BpTCvNCLW7AP98hndBukzSbrwCb7sooo=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "MZi48DJZOgRbE0ZStR66omv6Ez1Wkjvf2D/41q6Nd0I=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Go9GXHI6SCQo2QKMxkAkgYLhfo3XrVjWLR2nE2AvYyk=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "P9RgE4RMQT/aHap2oICpwpgKeBAwxPUwuU9zIffKFNM=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "1+EkFYvTDmz4WQRbK+kznRHoaZVLludtkDrMuM6h++E=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "QEMDwUVoyJT7MNfOYKa25xU+Lnsz/ciH8rFUri4diLI=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "lUMCRAeu47BsOhNvCQTQJQeB68z0/VaElC9j5gDt9y8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "VnAr7ZIjvUXpWmzbkt8skHp0oRNc3V89SfvgaZydwfw=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "u4GEbsk9IEF56V1am5dRtAWXz4iFQkO03FVL87BZXIM=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "BaaCxmYHKJ6obIzTCdRtjw1cc8d2mUJcMbLWCjf1aLo=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "N3K5kDdfcKJurfaa6s2zfKgtYvz1Pagz7VWi9ZfX8yM=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "DsTbM0AgHfhSUKvOGkxudDOY3ojYT6bifhpelqHs8+s=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "j9be+ddLChInrFz6/820/uYh4WZBzlp61klyJBDy/ZY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Xi7nIgj4PqVXrpKLfJhcyxyVY1d3HRo72sKKPDmuU78=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2p8s/pRBZPjYWKKMlR7AOXypDzDmPo762iXlKpCwtco=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nsofE1FmSr1TiDR0gfnxfMDQ8o2pC+1NE7Oa9ceztSg=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "WvmTBjsCN4ueGpEdySRwsRC5knBRLfY439/e4mG+YAY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "c0i2uKsYBv8fubnI60lZIWA1y4zw1bFgsq5MmWBHKak=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "AJR2ex094A1nJEWQsZYjALWsrSl1/huGZ37z2ZsMrpg=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "LSDd6ab46sHxwJSrg5YLpsPG2o6EcsZ3rDikpHzMNmI=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "dnFjFoTM9sP/RjQkXBK1YpYn3v5W+j0+g/OfUHS4xu8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "L0I4JoDfktbDWe0fCDL/nQlBPkF5mNgqamnM5JKJ1Uc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "dPpZD53AbAMtW6sK+rTnXYe2GGGoSCNWsCtsmArLiIs=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "VakMQSPBEuSC9Nwuv8WWhrZVUmH31bUR4+G6pJhkgE8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "KI+kCESWD9cB8se4uxRrFVAI5viyNNUXUyMCc903yQc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8Qu1LFMt7qlZNmYQWrsXUA80aIx0rrFPPXs2s6NBdU8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "WRsXnLz3gf8o4lYYeCZjAXgPU1cdmOOYPdy7aY63iIA=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "R/3f7VruxWpu+2hiHlVpplTwoOou5kfQI1k/6/9H/y8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "HjSC7VkhKih6xMhudlqfaFE8ZZnP8RKJPv4iqR7RhcE=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "cLM/HeUFsXlnYnYod695u6NBDS0trMq8sVRdABnF7uc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Epd2FDKZwDybzT38Z7WB0y2jiLn9/2OLzmY3Zu18l6I=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "ENAVynNXVpj/IdYx9kCPKaPs4bWSxRIHNlmS9QiDuZQ=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "j2w5BFOnZTrPN4SFpmQyfRomnUwbEbz1A+kr3z1icjo=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "I2ILaY31gonxYQhlIk4PFUIN+Pk7+9dDTK1C/s+Vcb0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "3wRufybSUsTMnUeQkP74uJNDRKeM8jBLAS64T0BRfpY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2gOiMAdnIdND4cA75E7naQdyyIYDAdcjF3uO6OiEZlU=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2S8Y/vnLM3W+MYxNCxcUItIBfdZL/T4A8vRg89n0wLg=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "UBTju7UZfXLVPPYb1a8gPZ69BeCv2Fho7YVo2EUbxKc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "0HqB2x6x5HzeozpHatePECw07x1UcDdSz8kQGNznnA8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "H0SIA/BU6Xj8oT5bQkvLpEITN3CqFLbMeBcQ72NZrAE=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Xnh8TL3BbIs9VTUenmnx6r2UAHpGCj3G9FV0mzc+mU4=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "X62YB48gO2SsWGnjYxH+aGfLQcjnP+T0hnErdWZ859g=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8pfpbIxBBiu88hpxS3CeRpv7kClEjl8SwVgckDNBGlE=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "UuxXNPImsE5Wp+utGfJywZBHuuGE4RmL0CArc6td82w=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Sl3NKLaYEgDaovqTkKVZh2ihRFbSmyVjC63wpv3ecdc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "SYjCs2AlY04xdfJGPD+gyO9NZ/zQ0Lfb/TLrjgOLS68=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "oI1+4FoeI/knjsjDyCJtgZPaeyKON8tCTcM9QX0BHa8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nts1nu73aBgIdSaYye4coIuE1iBNeCuTZZC8LQ37ac8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "NQX4yKpOztKrmgBhGIC5WOALOLOq3LTpbzsN4ZLXGec=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "BB4a/Xh5z+dkGCRlF+pSGC3iDOoDrFse/xzQAtmxMF4=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "ydjx2ea+PVuChrny6X2dluJwyXta+BsNQRsgHXp8fXw=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "pPGLc4NhNaehdoV2antWuyr0GmBVEG1NhD9NiSRrTi0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "VBVHOLnWGptY26J0wqXoZI2Dnu96pccMb08zlsaxPCQ=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "aUViYC2znC55sleHfmsIN9hZ45SbYPbDcYA0gVzglsc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "riYrMXBFLavmf4MU/Ly7emDlciVqfB2/zxJoRsBUlfY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "F2wCn9rKafNZsYZwoLGkSQIpr3rk86cjYyuhSjsjRaE=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "ugb3W6W7WL9Vc4KiSBWIaowBfpqJlzbfBSfrIqZW06A=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "gJDxhwAE6GeGCKQeVaNZ5is7+7MFHXtOG0UsnguKdoA=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "b9RSkt+WmMxVHQExQH0IMPpnR9zDAaJwz/mv1gtyRVY=" - }, - "power": "100", - "name": "smartpesa" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "569Sb+Wpo8VFqXRi4cQhlOD9kS8uBgmJ2rntY3GLtzY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "SNwrT1B+A4g6TY7x0QzVrmVbcbl3cHXzXdD1tFHxLNo=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "K4kLogLtZxqrYSqRVJfrFm9tUG+Tc3QWXWIewnAgI9w=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "TwzOJ4GcN+ZTswub4R8488SrKeWXjY/PaqCF5neXJig=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "JXW8iTiWG28E05ZFJIKvCOBwI2RrH/BOBL/MluTZ6+I=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "A3zUdVcpj4H+HRZmRW5xixj4dzMgqD7be9GrdXcjdns=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "7RhnD9OAZEJ4SV6V3LOZ1gGWubtX25457wCQq+AYYPI=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "66j9af4xDJSblMLS+mFbp7d8TaFGu0FOo+0MwEYm2lE=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8DScmobjJQmkN44K2xiZkESM/O9MJK/DqlggnIPLpso=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "4JoJuRfaANhdM1x3AWRo1/Cj9DH3VA+fi1SynzknV+w=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "cCoFsZzKZ9SQZbHe4NueVObIezP6ts0tRTZ/aN96dig=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Zp4tk/ieqplJF8xMeef9HV8bYpHSY+3hJ2sH7PfCX1I=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "jj0Y/Fy8JSJR3g+PHU6Ce0ecYwHGUVJ4bVyR7WwcyLI=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "XQDVMXja3kFk5Jb47BsqJmzcDsM4lE9+r+f/J3O5Jms=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "oL/QCr7LEOivyTqpGrmwVd1r+hYI2WB5+kSVzpDMxx4=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "eeImG09hOPo1W7j7lKepN/Lx6I9GGHqVBVEKmznxACc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Abws3eXrUFAH8LeZJIcECakPL945TTmFsBlXONOUeII=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "PEg/D54SoiKZ+pic0Z0RzZa/vfYNAAf4kzSc5UKXDYk=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "omAzuJps8KX3/iOC1LjwkMPMH3c6tjfLXwCNWXRBdWw=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nctikQSpoLRl5kV6KarIS761QvEOZCWw6nvc48xWhic=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "NrTRAbZnBqJpW9lRW6LxXxE7EV++y7WiIRV0ifRLovA=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "W0rP8sv4Ae/LZOqlBA9evvYARDt79WpFaI26jw/9Tfk=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "JdfJDlE46456GWp+AkSZhzlkUQI41f8aX7611oiWUSc=" - }, - "power": "100", - "name": "" - } - ], - "app_hash": "", - "app_state": { - "accounts": [ - { - "address": "cosmosaccaddr1c2dkaym4teqw6jl9jkq8eu8nf4wzn2lgf4ydyt", - "coins": [ - { - "denom": "faucetToken", - "amount": "1000000" - }, - { - "denom": "steak", - "amount": "10000000" - } - ] - }, - { - "address": "cosmosaccaddr157mg9hnhchfrqvk3enrvmvj29yhmlwf759xrgw", - "coins": [ - { - "denom": "jlandrewsToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr193vn0gk3nsmjkxwz78gce8e8mkmagmvulpg5jt", - "coins": [ - { - "denom": "jackToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr16rcrnftjyl2mctz78825ng8tx5ss22jf6jcp9l", - "coins": [ - { - "denom": "luigi001Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1shuqhpl273t96yg6nnqvyfeewj3ew3mdcwvcnu", - "coins": [ - { - "denom": "irisToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1shuqhpl273t96yg6nnqvyfeewj3ew3mdcwvcnu", - "coins": [ - { - "denom": "irisToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1syhzpjwx6vv3erv2myq7txrjhrp95hrhgcl242", - "coins": [ - { - "denom": "TropicalMongoXToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1uga4nuresex5u8ajjh2pcr39l0s9hszdkp843j", - "coins": [ - { - "denom": "wingmanToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr12wnqvqg79s9jqrul0lva3h72rfmewm7jprrcp5", - "coins": [ - { - "denom": "Nemea7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1lq0mvtgnwe8mp0096un0v8ztcsj8ad92t2cwrq", - "coins": [ - { - "denom": "infinite-castingToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr14e774gfzt5l9ka766ehfgu6n5hgy9f3sehzyv8", - "coins": [ - { - "denom": "cwgoesToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr164jntjfk9zs8x29mc27qansfwvjqs60gj6ermu", - "coins": [ - { - "denom": "lunamintToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1qkc3tghc3fms7eye7vtu0g0370epr4jkje2ne7", - "coins": [ - { - "denom": "skoed-validator-7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr18m09d56pg5p2660de4sjfezpd8ud6jfghndfnt", - "coins": [ - { - "denom": "starfishToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1k9pqxd8fxqlk52uwfxnlsexqj6xnmw5swhss45", - "coins": [ - { - "denom": "jjangg96Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr13q937pwglh24knwa2v23ml0kkpl9vwzjmfmj3q", - "coins": [ - { - "denom": "iaspirationiToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1xvt4e7xd0j9dwv2w83g50tpcltsl90h5dfnz6h", - "coins": [ - { - "denom": "21e800Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1nnyel6v0kx8zmfh9edmre3ua4dt9306cfxsxgd", - "coins": [ - { - "denom": "spptest1Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr13cds7hwqyq9ja2hsv4sg7glq9arlk43gcl3cek", - "coins": [ - { - "denom": "windmillToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1y2z20pwqu5qpclque3pqkguruvheum2djtzjw3", - "coins": [ - { - "denom": "pbostrom/Mythos-1Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1anuuffusmq5ng3rhlndhnacy45et30jqygtn67", - "coins": [ - { - "denom": "BarytToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1wk0t6na230vxhf6ddresw2c40k5y3ayrww0s2m", - "coins": [ - { - "denom": "P2P.ORG ValidatorToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr12pn4p6r5wjpsep9kn655ng7fh59yez7t0rahru", - "coins": [ - { - "denom": "oleary-labsToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr15rrxdflhq4744qt9m5ysstq3zpykhacf908eez", - "coins": [ - { - "denom": "wancloudsentryToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr17rqsh3fw6rehnwzarz90jkqtt5fupmh50gy556", - "coins": [ - { - "denom": "space4Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1g4q87u438qdh2c8ue4dzdr9ldrqrs77ptm9c70", - "coins": [ - { - "denom": "colony-finderToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1dq7jt3pn7mrce2twac907jue7hjd0p0rgt3qnq", - "coins": [ - { - "denom": "sparkpool-validator-02Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1gg6natrtt5lf02xwr06ujcczvavl54wgljuaut", - "coins": [ - { - "denom": "mining-shipToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1zds6r7jyxyxcpf05r5yyyy3u8q2rvj9kkc6vcv", - "coins": [ - { - "denom": "StakedToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1l0qw5znfd6e8pshpjvyghjjzyr4l6ymla080lt", - "coins": [ - { - "denom": "nyliraToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1rxxcpkmsngd0azkh3n2467m66ls4rwq52yuv27", - "coins": [ - { - "denom": "liangpingToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jsch8k385shvse6j5dfx20483qym5uhq76xpjf", - "coins": [ - { - "denom": "SVNode01Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr19uhnhct0p45ek6qxp3cjjrjtz4pacwcsgzvpuj", - "coins": [ - { - "denom": "vhxnode1Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1gghhdtx2sceafvgg8dry5sqrvc8srxghm4qqsy", - "coins": [ - { - "denom": "gregToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1cyayv35tv47t829mel6jm0vqzmrdhf3jq87tqg", - "coins": [ - { - "denom": "bucksterToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr126ayk3hse5zvk9gxfmpsjr9565ef72pv9g20yx", - "coins": [ - { - "denom": "grass-fedToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1fskmzyt2hr8usr3s65dq3rfur3fy6g2hjp23tm", - "coins": [ - { - "denom": "ATEAM1Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1lhjta6nt0lewj05m8444tuyhalkrffgpm7njpp", - "coins": [ - { - "denom": "BFF-Validator-7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1pm0gx3lk46gf8vyj5my9w5tk06cuq66ll77ugj", - "coins": [ - { - "denom": "redbricks7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr15w2rengajq9js8hu57kjw88dly5vy7gsqedn0n", - "coins": [ - { - "denom": "kittyfishToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr10505nl7yftsme9jk2glhjhta7w0475uva87paj", - "coins": [ - { - "denom": "ForboleToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr18z3pnjgdtt337z8g5drfts7r3fm6n9a0896h0r", - "coins": [ - { - "denom": "coinoneToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1vmdgku2g0n5p2ef995r4fugu99ze9e5me9kh4d", - "coins": [ - { - "denom": "bmen-companyToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1j2frwt2vq2xer7f060wpsu3y3f63uys2w9lx2e", - "coins": [ - { - "denom": "2400bpsToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1whxd48da3r56n8eecym8zg0c6xmf35fn2myart", - "coins": [ - { - "denom": "devToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jkmn6asju47zuuzrf8rjt7sllaj5cx4kueyv8p", - "coins": [ - { - "denom": "w1m3lToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr120skmenn2a0ra8y6zassrxvnfc5rlme8rqarvs", - "coins": [ - { - "denom": "aetherToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jtt6al0acr8h0uvq489rt9zx9lnau7rlcu30pt", - "coins": [ - { - "denom": "JColToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr135dz5hdtvk3z8vl0zyy5l223kjanv0gudu4905", - "coins": [ - { - "denom": "SaiKrishnaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr182ujqw3r8p5fffjqkf0rxzj29pg5q96nxd2khq", - "coins": [ - { - "denom": "UmbrellaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1qrc3ed8tnz6vc24ftmnht8efs5ufhjmrjkds4x", - "coins": [ - { - "denom": "@MarceldeveloperToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1swydkj5u3jd4jwe7uygu4479zgs4qg6v4ds3c9", - "coins": [ - { - "denom": "stereo-watcherToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1l9jt8xgejkcm4sulhwj8c83ftprz5p9lyq4605", - "coins": [ - { - "denom": "cosmosToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr128ty3kzhcepjacu4q0xjgq60qa3zz8na3jl793", - "coins": [ - { - "denom": "stake.zoneToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1e3qm8jd9357zhdemwnaafmf0wy3f4yqmd307c2", - "coins": [ - { - "denom": "firstblock.ioToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr18wfz5vj26y079surms5sm6avjtezzspfvqs6g4", - "coins": [ - { - "denom": "shensiToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1vrc7zpg5teawwuzkfh6t7c6sy353sukhlarxpa", - "coins": [ - { - "denom": "figmentToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1umaajfgap5ef6yxvk5706kwk8j08l7wh6h9fp2", - "coins": [ - { - "denom": "iqlusionToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1670l5up6e5fddvlc027yvvlvedrzyx0mmsl622", - "coins": [ - { - "denom": "cosmosthecatToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1wx33m9dvglryga0saey0pr99ja0klhcfrwaw7l", - "coins": [ - { - "denom": "snaticoToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr15u9ve7fz8fqaf7r2u3p4f9ru4ze47pau5cxgcg", - "coins": [ - { - "denom": "mpaxeNodeToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1h4q0xkdg30cl9vw0u8ejm0rs337dszy98gnd4a", - "coins": [ - { - "denom": "joltz-secureware.ioToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr12zpkulxv7kn59sgf0tpf24qhqzxsvf3gamkl7g", - "coins": [ - { - "denom": "mwnode1Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1g6sc5t9t68vmcj3alk7dfqr54tvastpxac28k6", - "coins": [ - { - "denom": "VNode01Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jck6gp4mqy33sk6a0fr5c8maq53hf4245v3mgg", - "coins": [ - { - "denom": "7768Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jh3grawl62juvx5p8fz5xsy9hpw8w3mngqafe4", - "coins": [ - { - "denom": "block3.communityToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr17nlusdvrk34fq65jemy3umfjfwaxfzv4asyl60", - "coins": [ - { - "denom": "4455Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr18u2sqnuetfnkugp59e9pgyv2dpuvkkxmmsc7m8", - "coins": [ - { - "denom": "dooroomeeToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1xdp4pls4ryvchq2n8v0cpmtwsprvyh8wvg563q", - "coins": [ - { - "denom": "sheiudToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1pmntq5en2rgtr5rzr4e304efrve4lr43z32y5s", - "coins": [ - { - "denom": "Staking Facilities ValidatorToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr197p65z7ge5g55r68thvw4l5e43gnm70jhu5g75", - "coins": [ - { - "denom": "ritter-rammToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr15klp8pypkd8htppzt6pguej57yyvp5p442khcu", - "coins": [ - { - "denom": "meteor-discoverToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jsvgewy7h62v3q43m0l347wlcwyhd4un5q8aa3", - "coins": [ - { - "denom": "COSMODROMEToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr192yhf7f7f9304cy6cu6np3r8a3m9yqzqfeu9je", - "coins": [ - { - "denom": "broadleaf7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1pag7xgpl8njlaksvp2ur5un3htg85vcrxcp5rs", - "coins": [ - { - "denom": "ravenclubToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1p56gv748xfd74qek5e637vhcr6tyjd9ukqfecc", - "coins": [ - { - "denom": "dokia-capitalToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1kwftgznylzerft2ksgkzvvfn5rfpy4nk2ye8na", - "coins": [ - { - "denom": "chainflow08Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1rj74vaqm0xkxl5cjjam63mayh4x6at3m379ulv", - "coins": [ - { - "denom": "MiaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1zpx36km7tk5cksyzxgvcp6g552p3uhwx84r53q", - "coins": [ - { - "denom": "sikka.techToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1gq0qecxs8xdaarrqxxazwavwxm7qz5jzs5anvt", - "coins": [ - { - "denom": "certus.oneToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1cypmdvszcd9kd3jenmqxd03cpceql8rtuvxftp", - "coins": [ - { - "denom": "Gold2Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1klslzz2n2nqvdaa6gwflwpka7gc60vvmh3k450", - "coins": [ - { - "denom": "idoor7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1qkllv8f6qakkw3hk9dqvytys090lk6twsyv8vf", - "coins": [ - { - "denom": "ironforkToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1wf9nug554ugpw4t0wnlppxc6crl2n02qr8v3cd", - "coins": [ - { - "denom": "sunny-mintorToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1t3afuz2kt99jz4pe5k4vjvkdmldn2x0lqzv83w", - "coins": [ - { - "denom": "BlissDynamicsToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr14zfph0h8rexsca6gg6jkwqup3sgl6mwj6eu4e6", - "coins": [ - { - "denom": "smartpesaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1998p0xkdwvul952ydavnx88tmwkhlfa0vhrngj", - "coins": [ - { - "denom": "ianstreamToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jw554408yw2h438q200jyuqgln76xh4ax0q4s0", - "coins": [ - { - "denom": "TruNodeToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1mwmcpq5nhaen8zyy86mrrept2gmp0z5peapkhu", - "coins": [ - { - "denom": "abcinToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1emaa7mwgpnpmc7yptm728ytp9quamsvu9rk4hp", - "coins": [ - { - "denom": "kochacolajToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1tq0zwzyc88l2enrlhtzw0he8rm24xfd5s9aeer", - "coins": [ - { - "denom": "D2R-validator-7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1n9qsfp3x09rhhxptzrgmdlucqhg2ce95fm3fw8", - "coins": [ - { - "denom": "juelianshanaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1sqec04r28jfevkzfkdj4ql2qzr2zwrmg78qzj8", - "coins": [ - { - "denom": "lambda-mixerToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1hfygmryre7r8m9pfqmc85y7kw7ejphmp59k2x8", - "coins": [ - { - "denom": "bkcmToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jvh448tvk368k4md83ys7auledclek0vfpckz2", - "coins": [ - { - "denom": "ramihanToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1fhfcs5npydv8s96wrk9p5ychctslu92t4n5qd4", - "coins": [ - { - "denom": "davinchcodeToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1eg88jsn38mrael6cqu7d2u8j6dynya7fv2p2tl", - "coins": [ - { - "denom": "DoriToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1ukcuqpqw3eq505wkqd2adgn8ugewxr6jtakngs", - "coins": [ - { - "denom": "daefreecaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1na3wr7ujdp3qdej6l5y0k4znzrkaz77t2yjaqf", - "coins": [ - { - "denom": "nuevaxToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1xupfqk73y7rmc6qdgv7rtjy8wsngvt2g2t59t3", - "coins": [ - { - "denom": "inschain_validatorToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr17gvlvfpsfl6hffn5u2hahk22un4ynpykc44tat", - "coins": [ - { - "denom": "gruberxToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1yfseqtj5sjhzz2q2ym09jym4h4nc4yevae0jp2", - "coins": [ - { - "denom": "meleatrustToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1yd0rklq45zg89fywr89ccutlcwp9kehhh0z03k", - "coins": [ - { - "denom": "Cosmodator-7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1arlpxs2ftf5hgetqxxkvd7mqdc28mmaqclyv4y", - "coins": [ - { - "denom": "bharvestToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr12ceualfg92x7du73mtcv0zya4nxvq3tl2m52uz", - "coins": [ - { - "denom": "cryptiumToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1wxf0ck9h2e8p2wmecxtep6cefhexsp4kzc8fxy", - "coins": [ - { - "denom": "finalityToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1pzlud6lg8w9phcwetc5aqp24eflshtv4xlxthf", - "coins": [ - { - "denom": "coscloudToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr10qp8kqwm2cuql0hw2az5mngpmw5xm9ee32exlp", - "coins": [ - { - "denom": "xiaochinaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr14dwnmm6n7tjdpeylpwsdsatdl0umm75dfkqcpa", - "coins": [ - { - "denom": "gazua1Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - } - ], - "stake": { - "pool": { - "loose_tokens": "16200", - "bonded_tokens": "0", - "inflation_last_time": "0", - "inflation": "7/100", - "date_last_commission_reset": "0", - "prev_bonded_shares": "0" - }, - "params": { - "inflation_rate_change": "13/100", - "inflation_max": "1/5", - "inflation_min": "7/100", - "goal_bonded": "67/100", - "unbonding_time": "86400", - "max_validators": 100, - "bond_denom": "steak" - }, - "validators": [ - { - "owner": "cosmosaccaddr157mg9hnhchfrqvk3enrvmvj29yhmlwf759xrgw", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "MRCeBDANSjH6IsxO0z6tRe+xqoZvIGhdfl1t+SXGUpM=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "jlandrews", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr193vn0gk3nsmjkxwz78gce8e8mkmagmvulpg5jt", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "tOEqjO2t51PEgO9Tv0B7qM0yPmy1n5tMa3Beg0tp3ns=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "jack", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr16rcrnftjyl2mctz78825ng8tx5ss22jf6jcp9l", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "S8s6fdAQNQ3bN9SNVAsHB/j8uv1CM1roxeLesL+fh4g=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "luigi001", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1shuqhpl273t96yg6nnqvyfeewj3ew3mdcwvcnu", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2JoNf1gavJ1d6XFIumO1Mki5GVMOcg58AioHksU3maE=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "iris", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1shuqhpl273t96yg6nnqvyfeewj3ew3mdcwvcnu", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2JoNf1gavJ1d6XFIumO1Mki5GVMOcg58AioHksU3maE=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "iris", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1syhzpjwx6vv3erv2myq7txrjhrp95hrhgcl242", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "k3YLQYEN2QMP6XITRsBmgb+pNGhJ5Jbg0bzUW977kK0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "TropicalMongoX", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1uga4nuresex5u8ajjh2pcr39l0s9hszdkp843j", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "EREUrXXl1OJqLQag0P4h6vJ2H+8GEwyNAjgn1XEJU+I=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "wingman", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr12wnqvqg79s9jqrul0lva3h72rfmewm7jprrcp5", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "heNintBalqaJwCOjLb9+mX/cQ1ytMlV7ZroPIlkwZqo=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Nemea7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1lq0mvtgnwe8mp0096un0v8ztcsj8ad92t2cwrq", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nb2oRB12DlEQkFn7KSjSVkj5rDoSTsuBFa09+gmNJ7o=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "infinite-casting", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr14e774gfzt5l9ka766ehfgu6n5hgy9f3sehzyv8", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "bZSEBDNIOr0xJ/PxaAScJIyG6hqFtryBAMNwghAOTTU=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "cwgoes", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr164jntjfk9zs8x29mc27qansfwvjqs60gj6ermu", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8K3clCjVU33BTIpUhdahGmu++WxHj4NUE9krCRkk++s=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "lunamint", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1qkc3tghc3fms7eye7vtu0g0370epr4jkje2ne7", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "RBuRRNEzA9RA1Wrdi9PPFQJ29/n/bqN9O2tQv9Gq248=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "skoed-validator-7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr18m09d56pg5p2660de4sjfezpd8ud6jfghndfnt", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "RwPRoiY5C0covekqbr3VrQwxWGHioUUIf2+TOq8LIC0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "starfish", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1k9pqxd8fxqlk52uwfxnlsexqj6xnmw5swhss45", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2qtEBT+Tc+SD2wJsdrVMHXrBKfvesxtmtSKDK5fXwA0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "jjangg96", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr13q937pwglh24knwa2v23ml0kkpl9vwzjmfmj3q", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "gU5mmVLUSzn/fIEMgiiB4LARRoWlqjUGHr3A4SndWO8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "iaspirationi", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1xvt4e7xd0j9dwv2w83g50tpcltsl90h5dfnz6h", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "xlO2cnii42KisAn8OcstC/3XV5+I0FlcSbWuyy5MVA8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "21e800", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1nnyel6v0kx8zmfh9edmre3ua4dt9306cfxsxgd", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "q5ezDn4DcWFPWvMayPJI35nXr//jjF8fGHsuiHjpDcU=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "spptest1", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr13cds7hwqyq9ja2hsv4sg7glq9arlk43gcl3cek", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "PSqbJOwglJb1yrj3aWebBpXb2ujXcR037s1Cyj2HoW4=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "windmill", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1y2z20pwqu5qpclque3pqkguruvheum2djtzjw3", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "A6GzeXUM3vsXaDAEYMSDgSKkqn9AoUYjs8empH46MGY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "pbostrom/Mythos-1", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1anuuffusmq5ng3rhlndhnacy45et30jqygtn67", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "81fx09BivOOxeGL7QisF8aKRZjjcARpiSaCOX9mJfY8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Baryt", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1wk0t6na230vxhf6ddresw2c40k5y3ayrww0s2m", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "UjTvuOew2EaooduJBiYmBWeF5ai0yFJG8uio5YXpJgg=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "P2P.ORG Validator", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr12pn4p6r5wjpsep9kn655ng7fh59yez7t0rahru", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "y7p9JSVZBnRxjAI9v5Pxl37hMtyuHf6B4Ghqzm6+ii0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "oleary-labs", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr15rrxdflhq4744qt9m5ysstq3zpykhacf908eez", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "oG8Q5o+SN4wqMLvlIfVgQPnsQzNEKeH0D/XGM8JlGrY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "wancloudsentry", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr17rqsh3fw6rehnwzarz90jkqtt5fupmh50gy556", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "PxJbo5FKA6mXtgwclRQVNIjOCQK3Q7WkLQrvM9lYbGI=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "space4", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1g4q87u438qdh2c8ue4dzdr9ldrqrs77ptm9c70", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Q/UShqqVDOUSNYBrR1G/1X1s+YXEVXEJzeXmYvfYIr0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "colony-finder", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1dq7jt3pn7mrce2twac907jue7hjd0p0rgt3qnq", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "uEWWDBwFW+/BpTCvNCLW7AP98hndBukzSbrwCb7sooo=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "sparkpool-validator-02", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1gg6natrtt5lf02xwr06ujcczvavl54wgljuaut", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "MZi48DJZOgRbE0ZStR66omv6Ez1Wkjvf2D/41q6Nd0I=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "mining-ship", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1zds6r7jyxyxcpf05r5yyyy3u8q2rvj9kkc6vcv", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Go9GXHI6SCQo2QKMxkAkgYLhfo3XrVjWLR2nE2AvYyk=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Staked", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1l0qw5znfd6e8pshpjvyghjjzyr4l6ymla080lt", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "P9RgE4RMQT/aHap2oICpwpgKeBAwxPUwuU9zIffKFNM=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "nylira", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1rxxcpkmsngd0azkh3n2467m66ls4rwq52yuv27", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "1+EkFYvTDmz4WQRbK+kznRHoaZVLludtkDrMuM6h++E=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "liangping", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jsch8k385shvse6j5dfx20483qym5uhq76xpjf", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "QEMDwUVoyJT7MNfOYKa25xU+Lnsz/ciH8rFUri4diLI=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "SVNode01", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr19uhnhct0p45ek6qxp3cjjrjtz4pacwcsgzvpuj", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "lUMCRAeu47BsOhNvCQTQJQeB68z0/VaElC9j5gDt9y8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "vhxnode1", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1gghhdtx2sceafvgg8dry5sqrvc8srxghm4qqsy", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "VnAr7ZIjvUXpWmzbkt8skHp0oRNc3V89SfvgaZydwfw=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "greg", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1cyayv35tv47t829mel6jm0vqzmrdhf3jq87tqg", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "u4GEbsk9IEF56V1am5dRtAWXz4iFQkO03FVL87BZXIM=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "buckster", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr126ayk3hse5zvk9gxfmpsjr9565ef72pv9g20yx", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "BaaCxmYHKJ6obIzTCdRtjw1cc8d2mUJcMbLWCjf1aLo=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "grass-fed", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1fskmzyt2hr8usr3s65dq3rfur3fy6g2hjp23tm", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "N3K5kDdfcKJurfaa6s2zfKgtYvz1Pagz7VWi9ZfX8yM=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "ATEAM1", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1lhjta6nt0lewj05m8444tuyhalkrffgpm7njpp", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "DsTbM0AgHfhSUKvOGkxudDOY3ojYT6bifhpelqHs8+s=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "BFF-Validator-7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1pm0gx3lk46gf8vyj5my9w5tk06cuq66ll77ugj", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "j9be+ddLChInrFz6/820/uYh4WZBzlp61klyJBDy/ZY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "redbricks7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr15w2rengajq9js8hu57kjw88dly5vy7gsqedn0n", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Xi7nIgj4PqVXrpKLfJhcyxyVY1d3HRo72sKKPDmuU78=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "kittyfish", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr10505nl7yftsme9jk2glhjhta7w0475uva87paj", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2p8s/pRBZPjYWKKMlR7AOXypDzDmPo762iXlKpCwtco=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Forbole", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr18z3pnjgdtt337z8g5drfts7r3fm6n9a0896h0r", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nsofE1FmSr1TiDR0gfnxfMDQ8o2pC+1NE7Oa9ceztSg=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "coinone", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1vmdgku2g0n5p2ef995r4fugu99ze9e5me9kh4d", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "WvmTBjsCN4ueGpEdySRwsRC5knBRLfY439/e4mG+YAY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "bmen-company", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1j2frwt2vq2xer7f060wpsu3y3f63uys2w9lx2e", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "c0i2uKsYBv8fubnI60lZIWA1y4zw1bFgsq5MmWBHKak=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "2400bps", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1whxd48da3r56n8eecym8zg0c6xmf35fn2myart", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "AJR2ex094A1nJEWQsZYjALWsrSl1/huGZ37z2ZsMrpg=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "dev", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jkmn6asju47zuuzrf8rjt7sllaj5cx4kueyv8p", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "LSDd6ab46sHxwJSrg5YLpsPG2o6EcsZ3rDikpHzMNmI=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "w1m3l", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr120skmenn2a0ra8y6zassrxvnfc5rlme8rqarvs", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "dnFjFoTM9sP/RjQkXBK1YpYn3v5W+j0+g/OfUHS4xu8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "aether", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jtt6al0acr8h0uvq489rt9zx9lnau7rlcu30pt", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "L0I4JoDfktbDWe0fCDL/nQlBPkF5mNgqamnM5JKJ1Uc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "JCol", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr135dz5hdtvk3z8vl0zyy5l223kjanv0gudu4905", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "dPpZD53AbAMtW6sK+rTnXYe2GGGoSCNWsCtsmArLiIs=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "SaiKrishna", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr182ujqw3r8p5fffjqkf0rxzj29pg5q96nxd2khq", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "VakMQSPBEuSC9Nwuv8WWhrZVUmH31bUR4+G6pJhkgE8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Umbrella", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1qrc3ed8tnz6vc24ftmnht8efs5ufhjmrjkds4x", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "KI+kCESWD9cB8se4uxRrFVAI5viyNNUXUyMCc903yQc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "@Marceldeveloper", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1swydkj5u3jd4jwe7uygu4479zgs4qg6v4ds3c9", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8Qu1LFMt7qlZNmYQWrsXUA80aIx0rrFPPXs2s6NBdU8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "stereo-watcher", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1l9jt8xgejkcm4sulhwj8c83ftprz5p9lyq4605", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "WRsXnLz3gf8o4lYYeCZjAXgPU1cdmOOYPdy7aY63iIA=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "cosmos", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr128ty3kzhcepjacu4q0xjgq60qa3zz8na3jl793", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "R/3f7VruxWpu+2hiHlVpplTwoOou5kfQI1k/6/9H/y8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "stake.zone", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1e3qm8jd9357zhdemwnaafmf0wy3f4yqmd307c2", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "HjSC7VkhKih6xMhudlqfaFE8ZZnP8RKJPv4iqR7RhcE=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "firstblock.io", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr18wfz5vj26y079surms5sm6avjtezzspfvqs6g4", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "cLM/HeUFsXlnYnYod695u6NBDS0trMq8sVRdABnF7uc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "shensi", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1vrc7zpg5teawwuzkfh6t7c6sy353sukhlarxpa", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Epd2FDKZwDybzT38Z7WB0y2jiLn9/2OLzmY3Zu18l6I=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "figment", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1umaajfgap5ef6yxvk5706kwk8j08l7wh6h9fp2", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "ENAVynNXVpj/IdYx9kCPKaPs4bWSxRIHNlmS9QiDuZQ=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "iqlusion", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1670l5up6e5fddvlc027yvvlvedrzyx0mmsl622", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "j2w5BFOnZTrPN4SFpmQyfRomnUwbEbz1A+kr3z1icjo=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "cosmosthecat", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1wx33m9dvglryga0saey0pr99ja0klhcfrwaw7l", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "I2ILaY31gonxYQhlIk4PFUIN+Pk7+9dDTK1C/s+Vcb0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "snatico", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr15u9ve7fz8fqaf7r2u3p4f9ru4ze47pau5cxgcg", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "3wRufybSUsTMnUeQkP74uJNDRKeM8jBLAS64T0BRfpY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "mpaxeNode", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1h4q0xkdg30cl9vw0u8ejm0rs337dszy98gnd4a", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2gOiMAdnIdND4cA75E7naQdyyIYDAdcjF3uO6OiEZlU=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "joltz-secureware.io", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr12zpkulxv7kn59sgf0tpf24qhqzxsvf3gamkl7g", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2S8Y/vnLM3W+MYxNCxcUItIBfdZL/T4A8vRg89n0wLg=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "mwnode1", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1g6sc5t9t68vmcj3alk7dfqr54tvastpxac28k6", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "VNode01", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jck6gp4mqy33sk6a0fr5c8maq53hf4245v3mgg", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "UBTju7UZfXLVPPYb1a8gPZ69BeCv2Fho7YVo2EUbxKc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "7768", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jh3grawl62juvx5p8fz5xsy9hpw8w3mngqafe4", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "0HqB2x6x5HzeozpHatePECw07x1UcDdSz8kQGNznnA8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "block3.community", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr17nlusdvrk34fq65jemy3umfjfwaxfzv4asyl60", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "H0SIA/BU6Xj8oT5bQkvLpEITN3CqFLbMeBcQ72NZrAE=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "4455", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr18u2sqnuetfnkugp59e9pgyv2dpuvkkxmmsc7m8", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Xnh8TL3BbIs9VTUenmnx6r2UAHpGCj3G9FV0mzc+mU4=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "dooroomee", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1xdp4pls4ryvchq2n8v0cpmtwsprvyh8wvg563q", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "X62YB48gO2SsWGnjYxH+aGfLQcjnP+T0hnErdWZ859g=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "sheiud", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1pmntq5en2rgtr5rzr4e304efrve4lr43z32y5s", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8pfpbIxBBiu88hpxS3CeRpv7kClEjl8SwVgckDNBGlE=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Staking Facilities Validator", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr197p65z7ge5g55r68thvw4l5e43gnm70jhu5g75", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "UuxXNPImsE5Wp+utGfJywZBHuuGE4RmL0CArc6td82w=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "ritter-ramm", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr15klp8pypkd8htppzt6pguej57yyvp5p442khcu", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Sl3NKLaYEgDaovqTkKVZh2ihRFbSmyVjC63wpv3ecdc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "meteor-discover", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jsvgewy7h62v3q43m0l347wlcwyhd4un5q8aa3", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "SYjCs2AlY04xdfJGPD+gyO9NZ/zQ0Lfb/TLrjgOLS68=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "COSMODROME", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr192yhf7f7f9304cy6cu6np3r8a3m9yqzqfeu9je", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "oI1+4FoeI/knjsjDyCJtgZPaeyKON8tCTcM9QX0BHa8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "broadleaf7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1pag7xgpl8njlaksvp2ur5un3htg85vcrxcp5rs", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nts1nu73aBgIdSaYye4coIuE1iBNeCuTZZC8LQ37ac8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "ravenclub", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1p56gv748xfd74qek5e637vhcr6tyjd9ukqfecc", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "NQX4yKpOztKrmgBhGIC5WOALOLOq3LTpbzsN4ZLXGec=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "dokia-capital", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1kwftgznylzerft2ksgkzvvfn5rfpy4nk2ye8na", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "BB4a/Xh5z+dkGCRlF+pSGC3iDOoDrFse/xzQAtmxMF4=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "chainflow08", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1rj74vaqm0xkxl5cjjam63mayh4x6at3m379ulv", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "ydjx2ea+PVuChrny6X2dluJwyXta+BsNQRsgHXp8fXw=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Mia", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1zpx36km7tk5cksyzxgvcp6g552p3uhwx84r53q", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "pPGLc4NhNaehdoV2antWuyr0GmBVEG1NhD9NiSRrTi0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "sikka.tech", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1gq0qecxs8xdaarrqxxazwavwxm7qz5jzs5anvt", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "VBVHOLnWGptY26J0wqXoZI2Dnu96pccMb08zlsaxPCQ=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "certus.one", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1cypmdvszcd9kd3jenmqxd03cpceql8rtuvxftp", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "aUViYC2znC55sleHfmsIN9hZ45SbYPbDcYA0gVzglsc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Gold2", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1klslzz2n2nqvdaa6gwflwpka7gc60vvmh3k450", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "riYrMXBFLavmf4MU/Ly7emDlciVqfB2/zxJoRsBUlfY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "idoor7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1qkllv8f6qakkw3hk9dqvytys090lk6twsyv8vf", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "F2wCn9rKafNZsYZwoLGkSQIpr3rk86cjYyuhSjsjRaE=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "ironfork", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1wf9nug554ugpw4t0wnlppxc6crl2n02qr8v3cd", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "ugb3W6W7WL9Vc4KiSBWIaowBfpqJlzbfBSfrIqZW06A=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "sunny-mintor", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1t3afuz2kt99jz4pe5k4vjvkdmldn2x0lqzv83w", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "gJDxhwAE6GeGCKQeVaNZ5is7+7MFHXtOG0UsnguKdoA=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "BlissDynamics", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr14zfph0h8rexsca6gg6jkwqup3sgl6mwj6eu4e6", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "b9RSkt+WmMxVHQExQH0IMPpnR9zDAaJwz/mv1gtyRVY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "smartpesa", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1998p0xkdwvul952ydavnx88tmwkhlfa0vhrngj", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "569Sb+Wpo8VFqXRi4cQhlOD9kS8uBgmJ2rntY3GLtzY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "ianstream", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jw554408yw2h438q200jyuqgln76xh4ax0q4s0", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "SNwrT1B+A4g6TY7x0QzVrmVbcbl3cHXzXdD1tFHxLNo=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "TruNode", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1mwmcpq5nhaen8zyy86mrrept2gmp0z5peapkhu", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "K4kLogLtZxqrYSqRVJfrFm9tUG+Tc3QWXWIewnAgI9w=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "abcin", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1emaa7mwgpnpmc7yptm728ytp9quamsvu9rk4hp", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "TwzOJ4GcN+ZTswub4R8488SrKeWXjY/PaqCF5neXJig=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "kochacolaj", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1tq0zwzyc88l2enrlhtzw0he8rm24xfd5s9aeer", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "JXW8iTiWG28E05ZFJIKvCOBwI2RrH/BOBL/MluTZ6+I=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "D2R-validator-7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1n9qsfp3x09rhhxptzrgmdlucqhg2ce95fm3fw8", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "A3zUdVcpj4H+HRZmRW5xixj4dzMgqD7be9GrdXcjdns=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "juelianshana", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1sqec04r28jfevkzfkdj4ql2qzr2zwrmg78qzj8", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "7RhnD9OAZEJ4SV6V3LOZ1gGWubtX25457wCQq+AYYPI=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "lambda-mixer", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1hfygmryre7r8m9pfqmc85y7kw7ejphmp59k2x8", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "66j9af4xDJSblMLS+mFbp7d8TaFGu0FOo+0MwEYm2lE=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "bkcm", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jvh448tvk368k4md83ys7auledclek0vfpckz2", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8DScmobjJQmkN44K2xiZkESM/O9MJK/DqlggnIPLpso=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "ramihan", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1fhfcs5npydv8s96wrk9p5ychctslu92t4n5qd4", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "4JoJuRfaANhdM1x3AWRo1/Cj9DH3VA+fi1SynzknV+w=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "davinchcode", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1eg88jsn38mrael6cqu7d2u8j6dynya7fv2p2tl", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "cCoFsZzKZ9SQZbHe4NueVObIezP6ts0tRTZ/aN96dig=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Dori", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1ukcuqpqw3eq505wkqd2adgn8ugewxr6jtakngs", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Zp4tk/ieqplJF8xMeef9HV8bYpHSY+3hJ2sH7PfCX1I=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "daefreeca", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1na3wr7ujdp3qdej6l5y0k4znzrkaz77t2yjaqf", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "jj0Y/Fy8JSJR3g+PHU6Ce0ecYwHGUVJ4bVyR7WwcyLI=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "nuevax", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1xupfqk73y7rmc6qdgv7rtjy8wsngvt2g2t59t3", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "XQDVMXja3kFk5Jb47BsqJmzcDsM4lE9+r+f/J3O5Jms=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "inschain_validator", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr17gvlvfpsfl6hffn5u2hahk22un4ynpykc44tat", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "oL/QCr7LEOivyTqpGrmwVd1r+hYI2WB5+kSVzpDMxx4=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "gruberx", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1yfseqtj5sjhzz2q2ym09jym4h4nc4yevae0jp2", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "eeImG09hOPo1W7j7lKepN/Lx6I9GGHqVBVEKmznxACc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "meleatrust", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1yd0rklq45zg89fywr89ccutlcwp9kehhh0z03k", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Abws3eXrUFAH8LeZJIcECakPL945TTmFsBlXONOUeII=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Cosmodator-7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1arlpxs2ftf5hgetqxxkvd7mqdc28mmaqclyv4y", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "PEg/D54SoiKZ+pic0Z0RzZa/vfYNAAf4kzSc5UKXDYk=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "bharvest", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr12ceualfg92x7du73mtcv0zya4nxvq3tl2m52uz", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "omAzuJps8KX3/iOC1LjwkMPMH3c6tjfLXwCNWXRBdWw=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Adrian Brink - Cryptium Labs", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1wxf0ck9h2e8p2wmecxtep6cefhexsp4kzc8fxy", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nctikQSpoLRl5kV6KarIS761QvEOZCWw6nvc48xWhic=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "finality", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1pzlud6lg8w9phcwetc5aqp24eflshtv4xlxthf", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "NrTRAbZnBqJpW9lRW6LxXxE7EV++y7WiIRV0ifRLovA=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "coscloud", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr10qp8kqwm2cuql0hw2az5mngpmw5xm9ee32exlp", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "W0rP8sv4Ae/LZOqlBA9evvYARDt79WpFaI26jw/9Tfk=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "xiaochina", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr14dwnmm6n7tjdpeylpwsdsatdl0umm75dfkqcpa", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "JdfJDlE46456GWp+AkSZhzlkUQI41f8aX7611oiWUSc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "gazua1", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - } - ], - "bonds": [ - { - "delegator_addr": "cosmosaccaddr157mg9hnhchfrqvk3enrvmvj29yhmlwf759xrgw", - "validator_addr": "cosmosaccaddr157mg9hnhchfrqvk3enrvmvj29yhmlwf759xrgw", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr193vn0gk3nsmjkxwz78gce8e8mkmagmvulpg5jt", - "validator_addr": "cosmosaccaddr193vn0gk3nsmjkxwz78gce8e8mkmagmvulpg5jt", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr16rcrnftjyl2mctz78825ng8tx5ss22jf6jcp9l", - "validator_addr": "cosmosaccaddr16rcrnftjyl2mctz78825ng8tx5ss22jf6jcp9l", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1shuqhpl273t96yg6nnqvyfeewj3ew3mdcwvcnu", - "validator_addr": "cosmosaccaddr1shuqhpl273t96yg6nnqvyfeewj3ew3mdcwvcnu", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1shuqhpl273t96yg6nnqvyfeewj3ew3mdcwvcnu", - "validator_addr": "cosmosaccaddr1shuqhpl273t96yg6nnqvyfeewj3ew3mdcwvcnu", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1syhzpjwx6vv3erv2myq7txrjhrp95hrhgcl242", - "validator_addr": "cosmosaccaddr1syhzpjwx6vv3erv2myq7txrjhrp95hrhgcl242", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1uga4nuresex5u8ajjh2pcr39l0s9hszdkp843j", - "validator_addr": "cosmosaccaddr1uga4nuresex5u8ajjh2pcr39l0s9hszdkp843j", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr12wnqvqg79s9jqrul0lva3h72rfmewm7jprrcp5", - "validator_addr": "cosmosaccaddr12wnqvqg79s9jqrul0lva3h72rfmewm7jprrcp5", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1lq0mvtgnwe8mp0096un0v8ztcsj8ad92t2cwrq", - "validator_addr": "cosmosaccaddr1lq0mvtgnwe8mp0096un0v8ztcsj8ad92t2cwrq", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr14e774gfzt5l9ka766ehfgu6n5hgy9f3sehzyv8", - "validator_addr": "cosmosaccaddr14e774gfzt5l9ka766ehfgu6n5hgy9f3sehzyv8", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr164jntjfk9zs8x29mc27qansfwvjqs60gj6ermu", - "validator_addr": "cosmosaccaddr164jntjfk9zs8x29mc27qansfwvjqs60gj6ermu", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1qkc3tghc3fms7eye7vtu0g0370epr4jkje2ne7", - "validator_addr": "cosmosaccaddr1qkc3tghc3fms7eye7vtu0g0370epr4jkje2ne7", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr18m09d56pg5p2660de4sjfezpd8ud6jfghndfnt", - "validator_addr": "cosmosaccaddr18m09d56pg5p2660de4sjfezpd8ud6jfghndfnt", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1k9pqxd8fxqlk52uwfxnlsexqj6xnmw5swhss45", - "validator_addr": "cosmosaccaddr1k9pqxd8fxqlk52uwfxnlsexqj6xnmw5swhss45", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr13q937pwglh24knwa2v23ml0kkpl9vwzjmfmj3q", - "validator_addr": "cosmosaccaddr13q937pwglh24knwa2v23ml0kkpl9vwzjmfmj3q", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1xvt4e7xd0j9dwv2w83g50tpcltsl90h5dfnz6h", - "validator_addr": "cosmosaccaddr1xvt4e7xd0j9dwv2w83g50tpcltsl90h5dfnz6h", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1nnyel6v0kx8zmfh9edmre3ua4dt9306cfxsxgd", - "validator_addr": "cosmosaccaddr1nnyel6v0kx8zmfh9edmre3ua4dt9306cfxsxgd", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr13cds7hwqyq9ja2hsv4sg7glq9arlk43gcl3cek", - "validator_addr": "cosmosaccaddr13cds7hwqyq9ja2hsv4sg7glq9arlk43gcl3cek", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1y2z20pwqu5qpclque3pqkguruvheum2djtzjw3", - "validator_addr": "cosmosaccaddr1y2z20pwqu5qpclque3pqkguruvheum2djtzjw3", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1anuuffusmq5ng3rhlndhnacy45et30jqygtn67", - "validator_addr": "cosmosaccaddr1anuuffusmq5ng3rhlndhnacy45et30jqygtn67", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1wk0t6na230vxhf6ddresw2c40k5y3ayrww0s2m", - "validator_addr": "cosmosaccaddr1wk0t6na230vxhf6ddresw2c40k5y3ayrww0s2m", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr12pn4p6r5wjpsep9kn655ng7fh59yez7t0rahru", - "validator_addr": "cosmosaccaddr12pn4p6r5wjpsep9kn655ng7fh59yez7t0rahru", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr15rrxdflhq4744qt9m5ysstq3zpykhacf908eez", - "validator_addr": "cosmosaccaddr15rrxdflhq4744qt9m5ysstq3zpykhacf908eez", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr17rqsh3fw6rehnwzarz90jkqtt5fupmh50gy556", - "validator_addr": "cosmosaccaddr17rqsh3fw6rehnwzarz90jkqtt5fupmh50gy556", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1g4q87u438qdh2c8ue4dzdr9ldrqrs77ptm9c70", - "validator_addr": "cosmosaccaddr1g4q87u438qdh2c8ue4dzdr9ldrqrs77ptm9c70", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1dq7jt3pn7mrce2twac907jue7hjd0p0rgt3qnq", - "validator_addr": "cosmosaccaddr1dq7jt3pn7mrce2twac907jue7hjd0p0rgt3qnq", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1gg6natrtt5lf02xwr06ujcczvavl54wgljuaut", - "validator_addr": "cosmosaccaddr1gg6natrtt5lf02xwr06ujcczvavl54wgljuaut", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1zds6r7jyxyxcpf05r5yyyy3u8q2rvj9kkc6vcv", - "validator_addr": "cosmosaccaddr1zds6r7jyxyxcpf05r5yyyy3u8q2rvj9kkc6vcv", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1l0qw5znfd6e8pshpjvyghjjzyr4l6ymla080lt", - "validator_addr": "cosmosaccaddr1l0qw5znfd6e8pshpjvyghjjzyr4l6ymla080lt", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1rxxcpkmsngd0azkh3n2467m66ls4rwq52yuv27", - "validator_addr": "cosmosaccaddr1rxxcpkmsngd0azkh3n2467m66ls4rwq52yuv27", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jsch8k385shvse6j5dfx20483qym5uhq76xpjf", - "validator_addr": "cosmosaccaddr1jsch8k385shvse6j5dfx20483qym5uhq76xpjf", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr19uhnhct0p45ek6qxp3cjjrjtz4pacwcsgzvpuj", - "validator_addr": "cosmosaccaddr19uhnhct0p45ek6qxp3cjjrjtz4pacwcsgzvpuj", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1gghhdtx2sceafvgg8dry5sqrvc8srxghm4qqsy", - "validator_addr": "cosmosaccaddr1gghhdtx2sceafvgg8dry5sqrvc8srxghm4qqsy", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1cyayv35tv47t829mel6jm0vqzmrdhf3jq87tqg", - "validator_addr": "cosmosaccaddr1cyayv35tv47t829mel6jm0vqzmrdhf3jq87tqg", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr126ayk3hse5zvk9gxfmpsjr9565ef72pv9g20yx", - "validator_addr": "cosmosaccaddr126ayk3hse5zvk9gxfmpsjr9565ef72pv9g20yx", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1fskmzyt2hr8usr3s65dq3rfur3fy6g2hjp23tm", - "validator_addr": "cosmosaccaddr1fskmzyt2hr8usr3s65dq3rfur3fy6g2hjp23tm", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1lhjta6nt0lewj05m8444tuyhalkrffgpm7njpp", - "validator_addr": "cosmosaccaddr1lhjta6nt0lewj05m8444tuyhalkrffgpm7njpp", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1pm0gx3lk46gf8vyj5my9w5tk06cuq66ll77ugj", - "validator_addr": "cosmosaccaddr1pm0gx3lk46gf8vyj5my9w5tk06cuq66ll77ugj", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr15w2rengajq9js8hu57kjw88dly5vy7gsqedn0n", - "validator_addr": "cosmosaccaddr15w2rengajq9js8hu57kjw88dly5vy7gsqedn0n", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr10505nl7yftsme9jk2glhjhta7w0475uva87paj", - "validator_addr": "cosmosaccaddr10505nl7yftsme9jk2glhjhta7w0475uva87paj", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr18z3pnjgdtt337z8g5drfts7r3fm6n9a0896h0r", - "validator_addr": "cosmosaccaddr18z3pnjgdtt337z8g5drfts7r3fm6n9a0896h0r", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1vmdgku2g0n5p2ef995r4fugu99ze9e5me9kh4d", - "validator_addr": "cosmosaccaddr1vmdgku2g0n5p2ef995r4fugu99ze9e5me9kh4d", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1j2frwt2vq2xer7f060wpsu3y3f63uys2w9lx2e", - "validator_addr": "cosmosaccaddr1j2frwt2vq2xer7f060wpsu3y3f63uys2w9lx2e", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1whxd48da3r56n8eecym8zg0c6xmf35fn2myart", - "validator_addr": "cosmosaccaddr1whxd48da3r56n8eecym8zg0c6xmf35fn2myart", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jkmn6asju47zuuzrf8rjt7sllaj5cx4kueyv8p", - "validator_addr": "cosmosaccaddr1jkmn6asju47zuuzrf8rjt7sllaj5cx4kueyv8p", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr120skmenn2a0ra8y6zassrxvnfc5rlme8rqarvs", - "validator_addr": "cosmosaccaddr120skmenn2a0ra8y6zassrxvnfc5rlme8rqarvs", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jtt6al0acr8h0uvq489rt9zx9lnau7rlcu30pt", - "validator_addr": "cosmosaccaddr1jtt6al0acr8h0uvq489rt9zx9lnau7rlcu30pt", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr135dz5hdtvk3z8vl0zyy5l223kjanv0gudu4905", - "validator_addr": "cosmosaccaddr135dz5hdtvk3z8vl0zyy5l223kjanv0gudu4905", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr182ujqw3r8p5fffjqkf0rxzj29pg5q96nxd2khq", - "validator_addr": "cosmosaccaddr182ujqw3r8p5fffjqkf0rxzj29pg5q96nxd2khq", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1qrc3ed8tnz6vc24ftmnht8efs5ufhjmrjkds4x", - "validator_addr": "cosmosaccaddr1qrc3ed8tnz6vc24ftmnht8efs5ufhjmrjkds4x", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1swydkj5u3jd4jwe7uygu4479zgs4qg6v4ds3c9", - "validator_addr": "cosmosaccaddr1swydkj5u3jd4jwe7uygu4479zgs4qg6v4ds3c9", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1l9jt8xgejkcm4sulhwj8c83ftprz5p9lyq4605", - "validator_addr": "cosmosaccaddr1l9jt8xgejkcm4sulhwj8c83ftprz5p9lyq4605", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr128ty3kzhcepjacu4q0xjgq60qa3zz8na3jl793", - "validator_addr": "cosmosaccaddr128ty3kzhcepjacu4q0xjgq60qa3zz8na3jl793", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1e3qm8jd9357zhdemwnaafmf0wy3f4yqmd307c2", - "validator_addr": "cosmosaccaddr1e3qm8jd9357zhdemwnaafmf0wy3f4yqmd307c2", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr18wfz5vj26y079surms5sm6avjtezzspfvqs6g4", - "validator_addr": "cosmosaccaddr18wfz5vj26y079surms5sm6avjtezzspfvqs6g4", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1vrc7zpg5teawwuzkfh6t7c6sy353sukhlarxpa", - "validator_addr": "cosmosaccaddr1vrc7zpg5teawwuzkfh6t7c6sy353sukhlarxpa", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1umaajfgap5ef6yxvk5706kwk8j08l7wh6h9fp2", - "validator_addr": "cosmosaccaddr1umaajfgap5ef6yxvk5706kwk8j08l7wh6h9fp2", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1670l5up6e5fddvlc027yvvlvedrzyx0mmsl622", - "validator_addr": "cosmosaccaddr1670l5up6e5fddvlc027yvvlvedrzyx0mmsl622", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1wx33m9dvglryga0saey0pr99ja0klhcfrwaw7l", - "validator_addr": "cosmosaccaddr1wx33m9dvglryga0saey0pr99ja0klhcfrwaw7l", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr15u9ve7fz8fqaf7r2u3p4f9ru4ze47pau5cxgcg", - "validator_addr": "cosmosaccaddr15u9ve7fz8fqaf7r2u3p4f9ru4ze47pau5cxgcg", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1h4q0xkdg30cl9vw0u8ejm0rs337dszy98gnd4a", - "validator_addr": "cosmosaccaddr1h4q0xkdg30cl9vw0u8ejm0rs337dszy98gnd4a", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr12zpkulxv7kn59sgf0tpf24qhqzxsvf3gamkl7g", - "validator_addr": "cosmosaccaddr12zpkulxv7kn59sgf0tpf24qhqzxsvf3gamkl7g", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1g6sc5t9t68vmcj3alk7dfqr54tvastpxac28k6", - "validator_addr": "cosmosaccaddr1g6sc5t9t68vmcj3alk7dfqr54tvastpxac28k6", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jck6gp4mqy33sk6a0fr5c8maq53hf4245v3mgg", - "validator_addr": "cosmosaccaddr1jck6gp4mqy33sk6a0fr5c8maq53hf4245v3mgg", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jh3grawl62juvx5p8fz5xsy9hpw8w3mngqafe4", - "validator_addr": "cosmosaccaddr1jh3grawl62juvx5p8fz5xsy9hpw8w3mngqafe4", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr17nlusdvrk34fq65jemy3umfjfwaxfzv4asyl60", - "validator_addr": "cosmosaccaddr17nlusdvrk34fq65jemy3umfjfwaxfzv4asyl60", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr18u2sqnuetfnkugp59e9pgyv2dpuvkkxmmsc7m8", - "validator_addr": "cosmosaccaddr18u2sqnuetfnkugp59e9pgyv2dpuvkkxmmsc7m8", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1xdp4pls4ryvchq2n8v0cpmtwsprvyh8wvg563q", - "validator_addr": "cosmosaccaddr1xdp4pls4ryvchq2n8v0cpmtwsprvyh8wvg563q", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1pmntq5en2rgtr5rzr4e304efrve4lr43z32y5s", - "validator_addr": "cosmosaccaddr1pmntq5en2rgtr5rzr4e304efrve4lr43z32y5s", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr197p65z7ge5g55r68thvw4l5e43gnm70jhu5g75", - "validator_addr": "cosmosaccaddr197p65z7ge5g55r68thvw4l5e43gnm70jhu5g75", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr15klp8pypkd8htppzt6pguej57yyvp5p442khcu", - "validator_addr": "cosmosaccaddr15klp8pypkd8htppzt6pguej57yyvp5p442khcu", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jsvgewy7h62v3q43m0l347wlcwyhd4un5q8aa3", - "validator_addr": "cosmosaccaddr1jsvgewy7h62v3q43m0l347wlcwyhd4un5q8aa3", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr192yhf7f7f9304cy6cu6np3r8a3m9yqzqfeu9je", - "validator_addr": "cosmosaccaddr192yhf7f7f9304cy6cu6np3r8a3m9yqzqfeu9je", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1pag7xgpl8njlaksvp2ur5un3htg85vcrxcp5rs", - "validator_addr": "cosmosaccaddr1pag7xgpl8njlaksvp2ur5un3htg85vcrxcp5rs", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1p56gv748xfd74qek5e637vhcr6tyjd9ukqfecc", - "validator_addr": "cosmosaccaddr1p56gv748xfd74qek5e637vhcr6tyjd9ukqfecc", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1kwftgznylzerft2ksgkzvvfn5rfpy4nk2ye8na", - "validator_addr": "cosmosaccaddr1kwftgznylzerft2ksgkzvvfn5rfpy4nk2ye8na", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1rj74vaqm0xkxl5cjjam63mayh4x6at3m379ulv", - "validator_addr": "cosmosaccaddr1rj74vaqm0xkxl5cjjam63mayh4x6at3m379ulv", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1zpx36km7tk5cksyzxgvcp6g552p3uhwx84r53q", - "validator_addr": "cosmosaccaddr1zpx36km7tk5cksyzxgvcp6g552p3uhwx84r53q", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1gq0qecxs8xdaarrqxxazwavwxm7qz5jzs5anvt", - "validator_addr": "cosmosaccaddr1gq0qecxs8xdaarrqxxazwavwxm7qz5jzs5anvt", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1cypmdvszcd9kd3jenmqxd03cpceql8rtuvxftp", - "validator_addr": "cosmosaccaddr1cypmdvszcd9kd3jenmqxd03cpceql8rtuvxftp", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1klslzz2n2nqvdaa6gwflwpka7gc60vvmh3k450", - "validator_addr": "cosmosaccaddr1klslzz2n2nqvdaa6gwflwpka7gc60vvmh3k450", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1qkllv8f6qakkw3hk9dqvytys090lk6twsyv8vf", - "validator_addr": "cosmosaccaddr1qkllv8f6qakkw3hk9dqvytys090lk6twsyv8vf", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1wf9nug554ugpw4t0wnlppxc6crl2n02qr8v3cd", - "validator_addr": "cosmosaccaddr1wf9nug554ugpw4t0wnlppxc6crl2n02qr8v3cd", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1t3afuz2kt99jz4pe5k4vjvkdmldn2x0lqzv83w", - "validator_addr": "cosmosaccaddr1t3afuz2kt99jz4pe5k4vjvkdmldn2x0lqzv83w", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr14zfph0h8rexsca6gg6jkwqup3sgl6mwj6eu4e6", - "validator_addr": "cosmosaccaddr14zfph0h8rexsca6gg6jkwqup3sgl6mwj6eu4e6", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1998p0xkdwvul952ydavnx88tmwkhlfa0vhrngj", - "validator_addr": "cosmosaccaddr1998p0xkdwvul952ydavnx88tmwkhlfa0vhrngj", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jw554408yw2h438q200jyuqgln76xh4ax0q4s0", - "validator_addr": "cosmosaccaddr1jw554408yw2h438q200jyuqgln76xh4ax0q4s0", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1mwmcpq5nhaen8zyy86mrrept2gmp0z5peapkhu", - "validator_addr": "cosmosaccaddr1mwmcpq5nhaen8zyy86mrrept2gmp0z5peapkhu", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1emaa7mwgpnpmc7yptm728ytp9quamsvu9rk4hp", - "validator_addr": "cosmosaccaddr1emaa7mwgpnpmc7yptm728ytp9quamsvu9rk4hp", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1tq0zwzyc88l2enrlhtzw0he8rm24xfd5s9aeer", - "validator_addr": "cosmosaccaddr1tq0zwzyc88l2enrlhtzw0he8rm24xfd5s9aeer", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1n9qsfp3x09rhhxptzrgmdlucqhg2ce95fm3fw8", - "validator_addr": "cosmosaccaddr1n9qsfp3x09rhhxptzrgmdlucqhg2ce95fm3fw8", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1sqec04r28jfevkzfkdj4ql2qzr2zwrmg78qzj8", - "validator_addr": "cosmosaccaddr1sqec04r28jfevkzfkdj4ql2qzr2zwrmg78qzj8", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1hfygmryre7r8m9pfqmc85y7kw7ejphmp59k2x8", - "validator_addr": "cosmosaccaddr1hfygmryre7r8m9pfqmc85y7kw7ejphmp59k2x8", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jvh448tvk368k4md83ys7auledclek0vfpckz2", - "validator_addr": "cosmosaccaddr1jvh448tvk368k4md83ys7auledclek0vfpckz2", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1fhfcs5npydv8s96wrk9p5ychctslu92t4n5qd4", - "validator_addr": "cosmosaccaddr1fhfcs5npydv8s96wrk9p5ychctslu92t4n5qd4", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1eg88jsn38mrael6cqu7d2u8j6dynya7fv2p2tl", - "validator_addr": "cosmosaccaddr1eg88jsn38mrael6cqu7d2u8j6dynya7fv2p2tl", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1ukcuqpqw3eq505wkqd2adgn8ugewxr6jtakngs", - "validator_addr": "cosmosaccaddr1ukcuqpqw3eq505wkqd2adgn8ugewxr6jtakngs", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1na3wr7ujdp3qdej6l5y0k4znzrkaz77t2yjaqf", - "validator_addr": "cosmosaccaddr1na3wr7ujdp3qdej6l5y0k4znzrkaz77t2yjaqf", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1xupfqk73y7rmc6qdgv7rtjy8wsngvt2g2t59t3", - "validator_addr": "cosmosaccaddr1xupfqk73y7rmc6qdgv7rtjy8wsngvt2g2t59t3", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr17gvlvfpsfl6hffn5u2hahk22un4ynpykc44tat", - "validator_addr": "cosmosaccaddr17gvlvfpsfl6hffn5u2hahk22un4ynpykc44tat", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1yfseqtj5sjhzz2q2ym09jym4h4nc4yevae0jp2", - "validator_addr": "cosmosaccaddr1yfseqtj5sjhzz2q2ym09jym4h4nc4yevae0jp2", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1yd0rklq45zg89fywr89ccutlcwp9kehhh0z03k", - "validator_addr": "cosmosaccaddr1yd0rklq45zg89fywr89ccutlcwp9kehhh0z03k", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1arlpxs2ftf5hgetqxxkvd7mqdc28mmaqclyv4y", - "validator_addr": "cosmosaccaddr1arlpxs2ftf5hgetqxxkvd7mqdc28mmaqclyv4y", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr12ceualfg92x7du73mtcv0zya4nxvq3tl2m52uz", - "validator_addr": "cosmosaccaddr12ceualfg92x7du73mtcv0zya4nxvq3tl2m52uz", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1wxf0ck9h2e8p2wmecxtep6cefhexsp4kzc8fxy", - "validator_addr": "cosmosaccaddr1wxf0ck9h2e8p2wmecxtep6cefhexsp4kzc8fxy", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1pzlud6lg8w9phcwetc5aqp24eflshtv4xlxthf", - "validator_addr": "cosmosaccaddr1pzlud6lg8w9phcwetc5aqp24eflshtv4xlxthf", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr10qp8kqwm2cuql0hw2az5mngpmw5xm9ee32exlp", - "validator_addr": "cosmosaccaddr10qp8kqwm2cuql0hw2az5mngpmw5xm9ee32exlp", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr14dwnmm6n7tjdpeylpwsdsatdl0umm75dfkqcpa", - "validator_addr": "cosmosaccaddr14dwnmm6n7tjdpeylpwsdsatdl0umm75dfkqcpa", - "shares": "100", - "height": "0" - } - ] - } - } -} \ No newline at end of file diff --git a/cmd/gaia/testnets/gaia-7001/genesis.json b/cmd/gaia/testnets/gaia-7001/genesis.json deleted file mode 100644 index 48db5a4edc..0000000000 --- a/cmd/gaia/testnets/gaia-7001/genesis.json +++ /dev/null @@ -1,5628 +0,0 @@ -{ - "genesis_time": "2018-07-17T07:19:26.795692941Z", - "chain_id": "gaia-7001", - "consensus_params": { - "block_size_params": { - "max_bytes": "22020096", - "max_txs": "10000", - "max_gas": "-1" - }, - "tx_size_params": { - "max_bytes": "10240", - "max_gas": "-1" - }, - "block_gossip_params": { - "block_part_size_bytes": "65536" - }, - "evidence_params": { - "max_age": "100000" - } - }, - "validators": [ - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "MRCeBDANSjH6IsxO0z6tRe+xqoZvIGhdfl1t+SXGUpM=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "tOEqjO2t51PEgO9Tv0B7qM0yPmy1n5tMa3Beg0tp3ns=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "S8s6fdAQNQ3bN9SNVAsHB/j8uv1CM1roxeLesL+fh4g=" - }, - "power": "100", - "name": "validatorluigi001" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2JoNf1gavJ1d6XFIumO1Mki5GVMOcg58AioHksU3maE=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "k3YLQYEN2QMP6XITRsBmgb+pNGhJ5Jbg0bzUW977kK0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "EREUrXXl1OJqLQag0P4h6vJ2H+8GEwyNAjgn1XEJU+I=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "heNintBalqaJwCOjLb9+mX/cQ1ytMlV7ZroPIlkwZqo=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nb2oRB12DlEQkFn7KSjSVkj5rDoSTsuBFa09+gmNJ7o=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "bZSEBDNIOr0xJ/PxaAScJIyG6hqFtryBAMNwghAOTTU=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8K3clCjVU33BTIpUhdahGmu++WxHj4NUE9krCRkk++s=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "RBuRRNEzA9RA1Wrdi9PPFQJ29/n/bqN9O2tQv9Gq248=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "RwPRoiY5C0covekqbr3VrQwxWGHioUUIf2+TOq8LIC0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2qtEBT+Tc+SD2wJsdrVMHXrBKfvesxtmtSKDK5fXwA0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "gU5mmVLUSzn/fIEMgiiB4LARRoWlqjUGHr3A4SndWO8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "xlO2cnii42KisAn8OcstC/3XV5+I0FlcSbWuyy5MVA8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "q5ezDn4DcWFPWvMayPJI35nXr//jjF8fGHsuiHjpDcU=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "PSqbJOwglJb1yrj3aWebBpXb2ujXcR037s1Cyj2HoW4=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "A6GzeXUM3vsXaDAEYMSDgSKkqn9AoUYjs8empH46MGY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "81fx09BivOOxeGL7QisF8aKRZjjcARpiSaCOX9mJfY8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "UjTvuOew2EaooduJBiYmBWeF5ai0yFJG8uio5YXpJgg=" - }, - "power": "1", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "y7p9JSVZBnRxjAI9v5Pxl37hMtyuHf6B4Ghqzm6+ii0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "oG8Q5o+SN4wqMLvlIfVgQPnsQzNEKeH0D/XGM8JlGrY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "PxJbo5FKA6mXtgwclRQVNIjOCQK3Q7WkLQrvM9lYbGI=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Q/UShqqVDOUSNYBrR1G/1X1s+YXEVXEJzeXmYvfYIr0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "uEWWDBwFW+/BpTCvNCLW7AP98hndBukzSbrwCb7sooo=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "MZi48DJZOgRbE0ZStR66omv6Ez1Wkjvf2D/41q6Nd0I=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Go9GXHI6SCQo2QKMxkAkgYLhfo3XrVjWLR2nE2AvYyk=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "P9RgE4RMQT/aHap2oICpwpgKeBAwxPUwuU9zIffKFNM=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "1+EkFYvTDmz4WQRbK+kznRHoaZVLludtkDrMuM6h++E=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "QEMDwUVoyJT7MNfOYKa25xU+Lnsz/ciH8rFUri4diLI=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "lUMCRAeu47BsOhNvCQTQJQeB68z0/VaElC9j5gDt9y8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "VnAr7ZIjvUXpWmzbkt8skHp0oRNc3V89SfvgaZydwfw=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "u4GEbsk9IEF56V1am5dRtAWXz4iFQkO03FVL87BZXIM=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "BaaCxmYHKJ6obIzTCdRtjw1cc8d2mUJcMbLWCjf1aLo=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "N3K5kDdfcKJurfaa6s2zfKgtYvz1Pagz7VWi9ZfX8yM=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "DsTbM0AgHfhSUKvOGkxudDOY3ojYT6bifhpelqHs8+s=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "j9be+ddLChInrFz6/820/uYh4WZBzlp61klyJBDy/ZY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Xi7nIgj4PqVXrpKLfJhcyxyVY1d3HRo72sKKPDmuU78=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2p8s/pRBZPjYWKKMlR7AOXypDzDmPo762iXlKpCwtco=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nsofE1FmSr1TiDR0gfnxfMDQ8o2pC+1NE7Oa9ceztSg=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "WvmTBjsCN4ueGpEdySRwsRC5knBRLfY439/e4mG+YAY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "c0i2uKsYBv8fubnI60lZIWA1y4zw1bFgsq5MmWBHKak=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "AJR2ex094A1nJEWQsZYjALWsrSl1/huGZ37z2ZsMrpg=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "LSDd6ab46sHxwJSrg5YLpsPG2o6EcsZ3rDikpHzMNmI=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "dnFjFoTM9sP/RjQkXBK1YpYn3v5W+j0+g/OfUHS4xu8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "L0I4JoDfktbDWe0fCDL/nQlBPkF5mNgqamnM5JKJ1Uc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "dPpZD53AbAMtW6sK+rTnXYe2GGGoSCNWsCtsmArLiIs=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "VakMQSPBEuSC9Nwuv8WWhrZVUmH31bUR4+G6pJhkgE8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "KI+kCESWD9cB8se4uxRrFVAI5viyNNUXUyMCc903yQc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8Qu1LFMt7qlZNmYQWrsXUA80aIx0rrFPPXs2s6NBdU8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "WRsXnLz3gf8o4lYYeCZjAXgPU1cdmOOYPdy7aY63iIA=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "R/3f7VruxWpu+2hiHlVpplTwoOou5kfQI1k/6/9H/y8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "HjSC7VkhKih6xMhudlqfaFE8ZZnP8RKJPv4iqR7RhcE=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "cLM/HeUFsXlnYnYod695u6NBDS0trMq8sVRdABnF7uc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Epd2FDKZwDybzT38Z7WB0y2jiLn9/2OLzmY3Zu18l6I=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "ENAVynNXVpj/IdYx9kCPKaPs4bWSxRIHNlmS9QiDuZQ=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "j2w5BFOnZTrPN4SFpmQyfRomnUwbEbz1A+kr3z1icjo=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "I2ILaY31gonxYQhlIk4PFUIN+Pk7+9dDTK1C/s+Vcb0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "3wRufybSUsTMnUeQkP74uJNDRKeM8jBLAS64T0BRfpY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2gOiMAdnIdND4cA75E7naQdyyIYDAdcjF3uO6OiEZlU=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2S8Y/vnLM3W+MYxNCxcUItIBfdZL/T4A8vRg89n0wLg=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "UBTju7UZfXLVPPYb1a8gPZ69BeCv2Fho7YVo2EUbxKc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "0HqB2x6x5HzeozpHatePECw07x1UcDdSz8kQGNznnA8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "H0SIA/BU6Xj8oT5bQkvLpEITN3CqFLbMeBcQ72NZrAE=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Xnh8TL3BbIs9VTUenmnx6r2UAHpGCj3G9FV0mzc+mU4=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "X62YB48gO2SsWGnjYxH+aGfLQcjnP+T0hnErdWZ859g=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8pfpbIxBBiu88hpxS3CeRpv7kClEjl8SwVgckDNBGlE=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "UuxXNPImsE5Wp+utGfJywZBHuuGE4RmL0CArc6td82w=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Sl3NKLaYEgDaovqTkKVZh2ihRFbSmyVjC63wpv3ecdc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "SYjCs2AlY04xdfJGPD+gyO9NZ/zQ0Lfb/TLrjgOLS68=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "oI1+4FoeI/knjsjDyCJtgZPaeyKON8tCTcM9QX0BHa8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nts1nu73aBgIdSaYye4coIuE1iBNeCuTZZC8LQ37ac8=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "NQX4yKpOztKrmgBhGIC5WOALOLOq3LTpbzsN4ZLXGec=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "BB4a/Xh5z+dkGCRlF+pSGC3iDOoDrFse/xzQAtmxMF4=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "ydjx2ea+PVuChrny6X2dluJwyXta+BsNQRsgHXp8fXw=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "pPGLc4NhNaehdoV2antWuyr0GmBVEG1NhD9NiSRrTi0=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "VBVHOLnWGptY26J0wqXoZI2Dnu96pccMb08zlsaxPCQ=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "aUViYC2znC55sleHfmsIN9hZ45SbYPbDcYA0gVzglsc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "riYrMXBFLavmf4MU/Ly7emDlciVqfB2/zxJoRsBUlfY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "F2wCn9rKafNZsYZwoLGkSQIpr3rk86cjYyuhSjsjRaE=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "ugb3W6W7WL9Vc4KiSBWIaowBfpqJlzbfBSfrIqZW06A=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "gJDxhwAE6GeGCKQeVaNZ5is7+7MFHXtOG0UsnguKdoA=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "b9RSkt+WmMxVHQExQH0IMPpnR9zDAaJwz/mv1gtyRVY=" - }, - "power": "100", - "name": "smartpesa" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "569Sb+Wpo8VFqXRi4cQhlOD9kS8uBgmJ2rntY3GLtzY=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "SNwrT1B+A4g6TY7x0QzVrmVbcbl3cHXzXdD1tFHxLNo=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "K4kLogLtZxqrYSqRVJfrFm9tUG+Tc3QWXWIewnAgI9w=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "TwzOJ4GcN+ZTswub4R8488SrKeWXjY/PaqCF5neXJig=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "JXW8iTiWG28E05ZFJIKvCOBwI2RrH/BOBL/MluTZ6+I=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "A3zUdVcpj4H+HRZmRW5xixj4dzMgqD7be9GrdXcjdns=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "7RhnD9OAZEJ4SV6V3LOZ1gGWubtX25457wCQq+AYYPI=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "66j9af4xDJSblMLS+mFbp7d8TaFGu0FOo+0MwEYm2lE=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8DScmobjJQmkN44K2xiZkESM/O9MJK/DqlggnIPLpso=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "4JoJuRfaANhdM1x3AWRo1/Cj9DH3VA+fi1SynzknV+w=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "cCoFsZzKZ9SQZbHe4NueVObIezP6ts0tRTZ/aN96dig=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Zp4tk/ieqplJF8xMeef9HV8bYpHSY+3hJ2sH7PfCX1I=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "jj0Y/Fy8JSJR3g+PHU6Ce0ecYwHGUVJ4bVyR7WwcyLI=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "XQDVMXja3kFk5Jb47BsqJmzcDsM4lE9+r+f/J3O5Jms=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "oL/QCr7LEOivyTqpGrmwVd1r+hYI2WB5+kSVzpDMxx4=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "eeImG09hOPo1W7j7lKepN/Lx6I9GGHqVBVEKmznxACc=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Abws3eXrUFAH8LeZJIcECakPL945TTmFsBlXONOUeII=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "PEg/D54SoiKZ+pic0Z0RzZa/vfYNAAf4kzSc5UKXDYk=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "omAzuJps8KX3/iOC1LjwkMPMH3c6tjfLXwCNWXRBdWw=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nctikQSpoLRl5kV6KarIS761QvEOZCWw6nvc48xWhic=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "NrTRAbZnBqJpW9lRW6LxXxE7EV++y7WiIRV0ifRLovA=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "W0rP8sv4Ae/LZOqlBA9evvYARDt79WpFaI26jw/9Tfk=" - }, - "power": "100", - "name": "" - }, - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "JdfJDlE46456GWp+AkSZhzlkUQI41f8aX7611oiWUSc=" - }, - "power": "100", - "name": "" - } - ], - "app_hash": "", - "app_state": { - "accounts": [ - { - "address": "cosmosaccaddr1c2dkaym4teqw6jl9jkq8eu8nf4wzn2lgf4ydyt", - "coins": [ - { - "denom": "faucetToken", - "amount": "10000000" - }, - { - "denom": "steak", - "amount": "10000000" - } - ] - }, - { - "address": "cosmosaccaddr157mg9hnhchfrqvk3enrvmvj29yhmlwf759xrgw", - "coins": [ - { - "denom": "jlandrewsToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr193vn0gk3nsmjkxwz78gce8e8mkmagmvulpg5jt", - "coins": [ - { - "denom": "jackToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr16rcrnftjyl2mctz78825ng8tx5ss22jf6jcp9l", - "coins": [ - { - "denom": "luigi001Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1shuqhpl273t96yg6nnqvyfeewj3ew3mdcwvcnu", - "coins": [ - { - "denom": "irisToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1syhzpjwx6vv3erv2myq7txrjhrp95hrhgcl242", - "coins": [ - { - "denom": "TropicalMongoXToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1uga4nuresex5u8ajjh2pcr39l0s9hszdkp843j", - "coins": [ - { - "denom": "wingmanToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr12wnqvqg79s9jqrul0lva3h72rfmewm7jprrcp5", - "coins": [ - { - "denom": "Nemea7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1lq0mvtgnwe8mp0096un0v8ztcsj8ad92t2cwrq", - "coins": [ - { - "denom": "infinite-castingToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr14e774gfzt5l9ka766ehfgu6n5hgy9f3sehzyv8", - "coins": [ - { - "denom": "cwgoesToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr164jntjfk9zs8x29mc27qansfwvjqs60gj6ermu", - "coins": [ - { - "denom": "lunamintToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1qkc3tghc3fms7eye7vtu0g0370epr4jkje2ne7", - "coins": [ - { - "denom": "skoed-validator-7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr18m09d56pg5p2660de4sjfezpd8ud6jfghndfnt", - "coins": [ - { - "denom": "starfishToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1k9pqxd8fxqlk52uwfxnlsexqj6xnmw5swhss45", - "coins": [ - { - "denom": "jjangg96Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr13q937pwglh24knwa2v23ml0kkpl9vwzjmfmj3q", - "coins": [ - { - "denom": "iaspirationiToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1xvt4e7xd0j9dwv2w83g50tpcltsl90h5dfnz6h", - "coins": [ - { - "denom": "21e800Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1nnyel6v0kx8zmfh9edmre3ua4dt9306cfxsxgd", - "coins": [ - { - "denom": "spptest1Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr13cds7hwqyq9ja2hsv4sg7glq9arlk43gcl3cek", - "coins": [ - { - "denom": "windmillToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1y2z20pwqu5qpclque3pqkguruvheum2djtzjw3", - "coins": [ - { - "denom": "pbostrom/Mythos-1Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1anuuffusmq5ng3rhlndhnacy45et30jqygtn67", - "coins": [ - { - "denom": "BarytToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1wk0t6na230vxhf6ddresw2c40k5y3ayrww0s2m", - "coins": [ - { - "denom": "P2P.ORG ValidatorToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr12pn4p6r5wjpsep9kn655ng7fh59yez7t0rahru", - "coins": [ - { - "denom": "oleary-labsToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr15rrxdflhq4744qt9m5ysstq3zpykhacf908eez", - "coins": [ - { - "denom": "wancloudsentryToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr17rqsh3fw6rehnwzarz90jkqtt5fupmh50gy556", - "coins": [ - { - "denom": "space4Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1g4q87u438qdh2c8ue4dzdr9ldrqrs77ptm9c70", - "coins": [ - { - "denom": "colony-finderToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1dq7jt3pn7mrce2twac907jue7hjd0p0rgt3qnq", - "coins": [ - { - "denom": "sparkpool-validator-02Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1gg6natrtt5lf02xwr06ujcczvavl54wgljuaut", - "coins": [ - { - "denom": "mining-shipToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1zds6r7jyxyxcpf05r5yyyy3u8q2rvj9kkc6vcv", - "coins": [ - { - "denom": "StakedToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1l0qw5znfd6e8pshpjvyghjjzyr4l6ymla080lt", - "coins": [ - { - "denom": "nyliraToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1rxxcpkmsngd0azkh3n2467m66ls4rwq52yuv27", - "coins": [ - { - "denom": "liangpingToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jsch8k385shvse6j5dfx20483qym5uhq76xpjf", - "coins": [ - { - "denom": "SVNode01Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr19uhnhct0p45ek6qxp3cjjrjtz4pacwcsgzvpuj", - "coins": [ - { - "denom": "vhxnode1Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1gghhdtx2sceafvgg8dry5sqrvc8srxghm4qqsy", - "coins": [ - { - "denom": "gregToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1cyayv35tv47t829mel6jm0vqzmrdhf3jq87tqg", - "coins": [ - { - "denom": "bucksterToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr126ayk3hse5zvk9gxfmpsjr9565ef72pv9g20yx", - "coins": [ - { - "denom": "grass-fedToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1fskmzyt2hr8usr3s65dq3rfur3fy6g2hjp23tm", - "coins": [ - { - "denom": "ATEAM1Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1lhjta6nt0lewj05m8444tuyhalkrffgpm7njpp", - "coins": [ - { - "denom": "BFF-Validator-7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1pm0gx3lk46gf8vyj5my9w5tk06cuq66ll77ugj", - "coins": [ - { - "denom": "redbricks7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr15w2rengajq9js8hu57kjw88dly5vy7gsqedn0n", - "coins": [ - { - "denom": "kittyfishToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr10505nl7yftsme9jk2glhjhta7w0475uva87paj", - "coins": [ - { - "denom": "ForboleToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr18z3pnjgdtt337z8g5drfts7r3fm6n9a0896h0r", - "coins": [ - { - "denom": "coinoneToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1vmdgku2g0n5p2ef995r4fugu99ze9e5me9kh4d", - "coins": [ - { - "denom": "bmen-companyToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1j2frwt2vq2xer7f060wpsu3y3f63uys2w9lx2e", - "coins": [ - { - "denom": "2400bpsToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1whxd48da3r56n8eecym8zg0c6xmf35fn2myart", - "coins": [ - { - "denom": "devToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jkmn6asju47zuuzrf8rjt7sllaj5cx4kueyv8p", - "coins": [ - { - "denom": "w1m3lToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr120skmenn2a0ra8y6zassrxvnfc5rlme8rqarvs", - "coins": [ - { - "denom": "aetherToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jtt6al0acr8h0uvq489rt9zx9lnau7rlcu30pt", - "coins": [ - { - "denom": "JColToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr135dz5hdtvk3z8vl0zyy5l223kjanv0gudu4905", - "coins": [ - { - "denom": "SaiKrishnaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr182ujqw3r8p5fffjqkf0rxzj29pg5q96nxd2khq", - "coins": [ - { - "denom": "UmbrellaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1qrc3ed8tnz6vc24ftmnht8efs5ufhjmrjkds4x", - "coins": [ - { - "denom": "@MarceldeveloperToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1swydkj5u3jd4jwe7uygu4479zgs4qg6v4ds3c9", - "coins": [ - { - "denom": "stereo-watcherToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1l9jt8xgejkcm4sulhwj8c83ftprz5p9lyq4605", - "coins": [ - { - "denom": "cosmosToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr128ty3kzhcepjacu4q0xjgq60qa3zz8na3jl793", - "coins": [ - { - "denom": "stake.zoneToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1e3qm8jd9357zhdemwnaafmf0wy3f4yqmd307c2", - "coins": [ - { - "denom": "firstblock.ioToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr18wfz5vj26y079surms5sm6avjtezzspfvqs6g4", - "coins": [ - { - "denom": "shensiToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1vrc7zpg5teawwuzkfh6t7c6sy353sukhlarxpa", - "coins": [ - { - "denom": "figmentToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1umaajfgap5ef6yxvk5706kwk8j08l7wh6h9fp2", - "coins": [ - { - "denom": "iqlusionToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1670l5up6e5fddvlc027yvvlvedrzyx0mmsl622", - "coins": [ - { - "denom": "cosmosthecatToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1wx33m9dvglryga0saey0pr99ja0klhcfrwaw7l", - "coins": [ - { - "denom": "snaticoToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr15u9ve7fz8fqaf7r2u3p4f9ru4ze47pau5cxgcg", - "coins": [ - { - "denom": "mpaxeNodeToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1h4q0xkdg30cl9vw0u8ejm0rs337dszy98gnd4a", - "coins": [ - { - "denom": "joltz-secureware.ioToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr12zpkulxv7kn59sgf0tpf24qhqzxsvf3gamkl7g", - "coins": [ - { - "denom": "mwnode1Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1g6sc5t9t68vmcj3alk7dfqr54tvastpxac28k6", - "coins": [ - { - "denom": "VNode01Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jck6gp4mqy33sk6a0fr5c8maq53hf4245v3mgg", - "coins": [ - { - "denom": "7768Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jh3grawl62juvx5p8fz5xsy9hpw8w3mngqafe4", - "coins": [ - { - "denom": "block3.communityToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr17nlusdvrk34fq65jemy3umfjfwaxfzv4asyl60", - "coins": [ - { - "denom": "4455Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr18u2sqnuetfnkugp59e9pgyv2dpuvkkxmmsc7m8", - "coins": [ - { - "denom": "dooroomeeToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1xdp4pls4ryvchq2n8v0cpmtwsprvyh8wvg563q", - "coins": [ - { - "denom": "sheiudToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1pmntq5en2rgtr5rzr4e304efrve4lr43z32y5s", - "coins": [ - { - "denom": "Staking Facilities ValidatorToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr197p65z7ge5g55r68thvw4l5e43gnm70jhu5g75", - "coins": [ - { - "denom": "ritter-rammToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr15klp8pypkd8htppzt6pguej57yyvp5p442khcu", - "coins": [ - { - "denom": "meteor-discoverToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jsvgewy7h62v3q43m0l347wlcwyhd4un5q8aa3", - "coins": [ - { - "denom": "COSMODROMEToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr192yhf7f7f9304cy6cu6np3r8a3m9yqzqfeu9je", - "coins": [ - { - "denom": "broadleaf7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1pag7xgpl8njlaksvp2ur5un3htg85vcrxcp5rs", - "coins": [ - { - "denom": "ravenclubToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1p56gv748xfd74qek5e637vhcr6tyjd9ukqfecc", - "coins": [ - { - "denom": "dokia-capitalToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1kwftgznylzerft2ksgkzvvfn5rfpy4nk2ye8na", - "coins": [ - { - "denom": "chainflow08Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1rj74vaqm0xkxl5cjjam63mayh4x6at3m379ulv", - "coins": [ - { - "denom": "MiaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1zpx36km7tk5cksyzxgvcp6g552p3uhwx84r53q", - "coins": [ - { - "denom": "sikka.techToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1gq0qecxs8xdaarrqxxazwavwxm7qz5jzs5anvt", - "coins": [ - { - "denom": "certus.oneToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1cypmdvszcd9kd3jenmqxd03cpceql8rtuvxftp", - "coins": [ - { - "denom": "Gold2Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1klslzz2n2nqvdaa6gwflwpka7gc60vvmh3k450", - "coins": [ - { - "denom": "idoor7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1qkllv8f6qakkw3hk9dqvytys090lk6twsyv8vf", - "coins": [ - { - "denom": "ironforkToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1wf9nug554ugpw4t0wnlppxc6crl2n02qr8v3cd", - "coins": [ - { - "denom": "sunny-mintorToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1t3afuz2kt99jz4pe5k4vjvkdmldn2x0lqzv83w", - "coins": [ - { - "denom": "BlissDynamicsToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr14zfph0h8rexsca6gg6jkwqup3sgl6mwj6eu4e6", - "coins": [ - { - "denom": "smartpesaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1998p0xkdwvul952ydavnx88tmwkhlfa0vhrngj", - "coins": [ - { - "denom": "ianstreamToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jw554408yw2h438q200jyuqgln76xh4ax0q4s0", - "coins": [ - { - "denom": "TruNodeToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1mwmcpq5nhaen8zyy86mrrept2gmp0z5peapkhu", - "coins": [ - { - "denom": "abcinToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1emaa7mwgpnpmc7yptm728ytp9quamsvu9rk4hp", - "coins": [ - { - "denom": "kochacolajToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1tq0zwzyc88l2enrlhtzw0he8rm24xfd5s9aeer", - "coins": [ - { - "denom": "D2R-validator-7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1n9qsfp3x09rhhxptzrgmdlucqhg2ce95fm3fw8", - "coins": [ - { - "denom": "juelianshanaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1sqec04r28jfevkzfkdj4ql2qzr2zwrmg78qzj8", - "coins": [ - { - "denom": "lambda-mixerToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1hfygmryre7r8m9pfqmc85y7kw7ejphmp59k2x8", - "coins": [ - { - "denom": "bkcmToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1jvh448tvk368k4md83ys7auledclek0vfpckz2", - "coins": [ - { - "denom": "ramihanToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1fhfcs5npydv8s96wrk9p5ychctslu92t4n5qd4", - "coins": [ - { - "denom": "davinchcodeToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1eg88jsn38mrael6cqu7d2u8j6dynya7fv2p2tl", - "coins": [ - { - "denom": "DoriToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1ukcuqpqw3eq505wkqd2adgn8ugewxr6jtakngs", - "coins": [ - { - "denom": "daefreecaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1na3wr7ujdp3qdej6l5y0k4znzrkaz77t2yjaqf", - "coins": [ - { - "denom": "nuevaxToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1xupfqk73y7rmc6qdgv7rtjy8wsngvt2g2t59t3", - "coins": [ - { - "denom": "inschain_validatorToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr17gvlvfpsfl6hffn5u2hahk22un4ynpykc44tat", - "coins": [ - { - "denom": "gruberxToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1yfseqtj5sjhzz2q2ym09jym4h4nc4yevae0jp2", - "coins": [ - { - "denom": "meleatrustToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1yd0rklq45zg89fywr89ccutlcwp9kehhh0z03k", - "coins": [ - { - "denom": "Cosmodator-7000Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1arlpxs2ftf5hgetqxxkvd7mqdc28mmaqclyv4y", - "coins": [ - { - "denom": "bharvestToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr12ceualfg92x7du73mtcv0zya4nxvq3tl2m52uz", - "coins": [ - { - "denom": "cryptiumToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1wxf0ck9h2e8p2wmecxtep6cefhexsp4kzc8fxy", - "coins": [ - { - "denom": "finalityToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr1pzlud6lg8w9phcwetc5aqp24eflshtv4xlxthf", - "coins": [ - { - "denom": "coscloudToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr10qp8kqwm2cuql0hw2az5mngpmw5xm9ee32exlp", - "coins": [ - { - "denom": "xiaochinaToken", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - }, - { - "address": "cosmosaccaddr14dwnmm6n7tjdpeylpwsdsatdl0umm75dfkqcpa", - "coins": [ - { - "denom": "gazua1Token", - "amount": "1000" - }, - { - "denom": "steak", - "amount": "50" - } - ] - } - ], - "stake": { - "pool": { - "loose_tokens": "16050", - "bonded_tokens": "0", - "inflation_last_time": "0", - "inflation": "7/100", - "date_last_commission_reset": "0", - "prev_bonded_shares": "0" - }, - "params": { - "inflation_rate_change": "13/100", - "inflation_max": "1/5", - "inflation_min": "7/100", - "goal_bonded": "67/100", - "unbonding_time": "86400", - "max_validators": 128, - "bond_denom": "steak" - }, - "validators": [ - { - "owner": "cosmosaccaddr157mg9hnhchfrqvk3enrvmvj29yhmlwf759xrgw", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "MRCeBDANSjH6IsxO0z6tRe+xqoZvIGhdfl1t+SXGUpM=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "jlandrews", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr193vn0gk3nsmjkxwz78gce8e8mkmagmvulpg5jt", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "tOEqjO2t51PEgO9Tv0B7qM0yPmy1n5tMa3Beg0tp3ns=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "jack", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr16rcrnftjyl2mctz78825ng8tx5ss22jf6jcp9l", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "S8s6fdAQNQ3bN9SNVAsHB/j8uv1CM1roxeLesL+fh4g=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "luigi001", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1shuqhpl273t96yg6nnqvyfeewj3ew3mdcwvcnu", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2JoNf1gavJ1d6XFIumO1Mki5GVMOcg58AioHksU3maE=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "iris", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1syhzpjwx6vv3erv2myq7txrjhrp95hrhgcl242", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "k3YLQYEN2QMP6XITRsBmgb+pNGhJ5Jbg0bzUW977kK0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "TropicalMongoX", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1uga4nuresex5u8ajjh2pcr39l0s9hszdkp843j", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "EREUrXXl1OJqLQag0P4h6vJ2H+8GEwyNAjgn1XEJU+I=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "wingman", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr12wnqvqg79s9jqrul0lva3h72rfmewm7jprrcp5", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "heNintBalqaJwCOjLb9+mX/cQ1ytMlV7ZroPIlkwZqo=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Nemea7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1lq0mvtgnwe8mp0096un0v8ztcsj8ad92t2cwrq", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nb2oRB12DlEQkFn7KSjSVkj5rDoSTsuBFa09+gmNJ7o=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "infinite-casting", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr14e774gfzt5l9ka766ehfgu6n5hgy9f3sehzyv8", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "bZSEBDNIOr0xJ/PxaAScJIyG6hqFtryBAMNwghAOTTU=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "cwgoes", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr164jntjfk9zs8x29mc27qansfwvjqs60gj6ermu", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8K3clCjVU33BTIpUhdahGmu++WxHj4NUE9krCRkk++s=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "lunamint", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1qkc3tghc3fms7eye7vtu0g0370epr4jkje2ne7", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "RBuRRNEzA9RA1Wrdi9PPFQJ29/n/bqN9O2tQv9Gq248=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "skoed-validator-7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr18m09d56pg5p2660de4sjfezpd8ud6jfghndfnt", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "RwPRoiY5C0covekqbr3VrQwxWGHioUUIf2+TOq8LIC0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "starfish", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1k9pqxd8fxqlk52uwfxnlsexqj6xnmw5swhss45", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2qtEBT+Tc+SD2wJsdrVMHXrBKfvesxtmtSKDK5fXwA0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "jjangg96", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr13q937pwglh24knwa2v23ml0kkpl9vwzjmfmj3q", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "gU5mmVLUSzn/fIEMgiiB4LARRoWlqjUGHr3A4SndWO8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "iaspirationi", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1xvt4e7xd0j9dwv2w83g50tpcltsl90h5dfnz6h", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "xlO2cnii42KisAn8OcstC/3XV5+I0FlcSbWuyy5MVA8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "21e800", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1nnyel6v0kx8zmfh9edmre3ua4dt9306cfxsxgd", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "q5ezDn4DcWFPWvMayPJI35nXr//jjF8fGHsuiHjpDcU=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "spptest1", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr13cds7hwqyq9ja2hsv4sg7glq9arlk43gcl3cek", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "PSqbJOwglJb1yrj3aWebBpXb2ujXcR037s1Cyj2HoW4=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "windmill", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1y2z20pwqu5qpclque3pqkguruvheum2djtzjw3", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "A6GzeXUM3vsXaDAEYMSDgSKkqn9AoUYjs8empH46MGY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "pbostrom/Mythos-1", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1anuuffusmq5ng3rhlndhnacy45et30jqygtn67", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "81fx09BivOOxeGL7QisF8aKRZjjcARpiSaCOX9mJfY8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Baryt", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1wk0t6na230vxhf6ddresw2c40k5y3ayrww0s2m", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "UjTvuOew2EaooduJBiYmBWeF5ai0yFJG8uio5YXpJgg=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "P2P.ORG Validator", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr12pn4p6r5wjpsep9kn655ng7fh59yez7t0rahru", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "y7p9JSVZBnRxjAI9v5Pxl37hMtyuHf6B4Ghqzm6+ii0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "oleary-labs", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr15rrxdflhq4744qt9m5ysstq3zpykhacf908eez", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "oG8Q5o+SN4wqMLvlIfVgQPnsQzNEKeH0D/XGM8JlGrY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "wancloudsentry", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr17rqsh3fw6rehnwzarz90jkqtt5fupmh50gy556", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "PxJbo5FKA6mXtgwclRQVNIjOCQK3Q7WkLQrvM9lYbGI=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "space4", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1g4q87u438qdh2c8ue4dzdr9ldrqrs77ptm9c70", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Q/UShqqVDOUSNYBrR1G/1X1s+YXEVXEJzeXmYvfYIr0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "colony-finder", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1dq7jt3pn7mrce2twac907jue7hjd0p0rgt3qnq", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "uEWWDBwFW+/BpTCvNCLW7AP98hndBukzSbrwCb7sooo=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "sparkpool-validator-02", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1gg6natrtt5lf02xwr06ujcczvavl54wgljuaut", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "MZi48DJZOgRbE0ZStR66omv6Ez1Wkjvf2D/41q6Nd0I=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "mining-ship", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1zds6r7jyxyxcpf05r5yyyy3u8q2rvj9kkc6vcv", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Go9GXHI6SCQo2QKMxkAkgYLhfo3XrVjWLR2nE2AvYyk=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Staked", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1l0qw5znfd6e8pshpjvyghjjzyr4l6ymla080lt", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "P9RgE4RMQT/aHap2oICpwpgKeBAwxPUwuU9zIffKFNM=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "nylira", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1rxxcpkmsngd0azkh3n2467m66ls4rwq52yuv27", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "1+EkFYvTDmz4WQRbK+kznRHoaZVLludtkDrMuM6h++E=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "liangping", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jsch8k385shvse6j5dfx20483qym5uhq76xpjf", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "QEMDwUVoyJT7MNfOYKa25xU+Lnsz/ciH8rFUri4diLI=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "SVNode01", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr19uhnhct0p45ek6qxp3cjjrjtz4pacwcsgzvpuj", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "lUMCRAeu47BsOhNvCQTQJQeB68z0/VaElC9j5gDt9y8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "vhxnode1", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1gghhdtx2sceafvgg8dry5sqrvc8srxghm4qqsy", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "VnAr7ZIjvUXpWmzbkt8skHp0oRNc3V89SfvgaZydwfw=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "greg", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1cyayv35tv47t829mel6jm0vqzmrdhf3jq87tqg", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "u4GEbsk9IEF56V1am5dRtAWXz4iFQkO03FVL87BZXIM=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "buckster", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr126ayk3hse5zvk9gxfmpsjr9565ef72pv9g20yx", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "BaaCxmYHKJ6obIzTCdRtjw1cc8d2mUJcMbLWCjf1aLo=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "grass-fed", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1fskmzyt2hr8usr3s65dq3rfur3fy6g2hjp23tm", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "N3K5kDdfcKJurfaa6s2zfKgtYvz1Pagz7VWi9ZfX8yM=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "ATEAM1", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1lhjta6nt0lewj05m8444tuyhalkrffgpm7njpp", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "DsTbM0AgHfhSUKvOGkxudDOY3ojYT6bifhpelqHs8+s=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "BFF-Validator-7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1pm0gx3lk46gf8vyj5my9w5tk06cuq66ll77ugj", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "j9be+ddLChInrFz6/820/uYh4WZBzlp61klyJBDy/ZY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "redbricks7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr15w2rengajq9js8hu57kjw88dly5vy7gsqedn0n", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Xi7nIgj4PqVXrpKLfJhcyxyVY1d3HRo72sKKPDmuU78=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "kittyfish", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr10505nl7yftsme9jk2glhjhta7w0475uva87paj", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2p8s/pRBZPjYWKKMlR7AOXypDzDmPo762iXlKpCwtco=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Forbole", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr18z3pnjgdtt337z8g5drfts7r3fm6n9a0896h0r", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nsofE1FmSr1TiDR0gfnxfMDQ8o2pC+1NE7Oa9ceztSg=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "coinone", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1vmdgku2g0n5p2ef995r4fugu99ze9e5me9kh4d", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "WvmTBjsCN4ueGpEdySRwsRC5knBRLfY439/e4mG+YAY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "bmen-company", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1j2frwt2vq2xer7f060wpsu3y3f63uys2w9lx2e", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "c0i2uKsYBv8fubnI60lZIWA1y4zw1bFgsq5MmWBHKak=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "2400bps", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1whxd48da3r56n8eecym8zg0c6xmf35fn2myart", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "AJR2ex094A1nJEWQsZYjALWsrSl1/huGZ37z2ZsMrpg=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "dev", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jkmn6asju47zuuzrf8rjt7sllaj5cx4kueyv8p", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "LSDd6ab46sHxwJSrg5YLpsPG2o6EcsZ3rDikpHzMNmI=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "w1m3l", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr120skmenn2a0ra8y6zassrxvnfc5rlme8rqarvs", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "dnFjFoTM9sP/RjQkXBK1YpYn3v5W+j0+g/OfUHS4xu8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "aether", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jtt6al0acr8h0uvq489rt9zx9lnau7rlcu30pt", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "L0I4JoDfktbDWe0fCDL/nQlBPkF5mNgqamnM5JKJ1Uc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "JCol", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr135dz5hdtvk3z8vl0zyy5l223kjanv0gudu4905", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "dPpZD53AbAMtW6sK+rTnXYe2GGGoSCNWsCtsmArLiIs=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "SaiKrishna", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr182ujqw3r8p5fffjqkf0rxzj29pg5q96nxd2khq", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "VakMQSPBEuSC9Nwuv8WWhrZVUmH31bUR4+G6pJhkgE8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Umbrella", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1qrc3ed8tnz6vc24ftmnht8efs5ufhjmrjkds4x", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "KI+kCESWD9cB8se4uxRrFVAI5viyNNUXUyMCc903yQc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "@Marceldeveloper", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1swydkj5u3jd4jwe7uygu4479zgs4qg6v4ds3c9", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8Qu1LFMt7qlZNmYQWrsXUA80aIx0rrFPPXs2s6NBdU8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "stereo-watcher", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1l9jt8xgejkcm4sulhwj8c83ftprz5p9lyq4605", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "WRsXnLz3gf8o4lYYeCZjAXgPU1cdmOOYPdy7aY63iIA=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "cosmos", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr128ty3kzhcepjacu4q0xjgq60qa3zz8na3jl793", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "R/3f7VruxWpu+2hiHlVpplTwoOou5kfQI1k/6/9H/y8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "stake.zone", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1e3qm8jd9357zhdemwnaafmf0wy3f4yqmd307c2", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "HjSC7VkhKih6xMhudlqfaFE8ZZnP8RKJPv4iqR7RhcE=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "firstblock.io", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr18wfz5vj26y079surms5sm6avjtezzspfvqs6g4", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "cLM/HeUFsXlnYnYod695u6NBDS0trMq8sVRdABnF7uc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "shensi", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1vrc7zpg5teawwuzkfh6t7c6sy353sukhlarxpa", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Epd2FDKZwDybzT38Z7WB0y2jiLn9/2OLzmY3Zu18l6I=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "figment", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1umaajfgap5ef6yxvk5706kwk8j08l7wh6h9fp2", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "ENAVynNXVpj/IdYx9kCPKaPs4bWSxRIHNlmS9QiDuZQ=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "iqlusion", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1670l5up6e5fddvlc027yvvlvedrzyx0mmsl622", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "j2w5BFOnZTrPN4SFpmQyfRomnUwbEbz1A+kr3z1icjo=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "cosmosthecat", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1wx33m9dvglryga0saey0pr99ja0klhcfrwaw7l", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "I2ILaY31gonxYQhlIk4PFUIN+Pk7+9dDTK1C/s+Vcb0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "snatico", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr15u9ve7fz8fqaf7r2u3p4f9ru4ze47pau5cxgcg", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "3wRufybSUsTMnUeQkP74uJNDRKeM8jBLAS64T0BRfpY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "mpaxeNode", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1h4q0xkdg30cl9vw0u8ejm0rs337dszy98gnd4a", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2gOiMAdnIdND4cA75E7naQdyyIYDAdcjF3uO6OiEZlU=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "joltz-secureware.io", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr12zpkulxv7kn59sgf0tpf24qhqzxsvf3gamkl7g", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "2S8Y/vnLM3W+MYxNCxcUItIBfdZL/T4A8vRg89n0wLg=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "mwnode1", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1g6sc5t9t68vmcj3alk7dfqr54tvastpxac28k6", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "VNode01", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jck6gp4mqy33sk6a0fr5c8maq53hf4245v3mgg", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "UBTju7UZfXLVPPYb1a8gPZ69BeCv2Fho7YVo2EUbxKc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "7768", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jh3grawl62juvx5p8fz5xsy9hpw8w3mngqafe4", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "0HqB2x6x5HzeozpHatePECw07x1UcDdSz8kQGNznnA8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "block3.community", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr17nlusdvrk34fq65jemy3umfjfwaxfzv4asyl60", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "H0SIA/BU6Xj8oT5bQkvLpEITN3CqFLbMeBcQ72NZrAE=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "4455", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr18u2sqnuetfnkugp59e9pgyv2dpuvkkxmmsc7m8", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Xnh8TL3BbIs9VTUenmnx6r2UAHpGCj3G9FV0mzc+mU4=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "dooroomee", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1xdp4pls4ryvchq2n8v0cpmtwsprvyh8wvg563q", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "X62YB48gO2SsWGnjYxH+aGfLQcjnP+T0hnErdWZ859g=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "sheiud", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1pmntq5en2rgtr5rzr4e304efrve4lr43z32y5s", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8pfpbIxBBiu88hpxS3CeRpv7kClEjl8SwVgckDNBGlE=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Staking Facilities Validator", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr197p65z7ge5g55r68thvw4l5e43gnm70jhu5g75", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "UuxXNPImsE5Wp+utGfJywZBHuuGE4RmL0CArc6td82w=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "ritter-ramm", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr15klp8pypkd8htppzt6pguej57yyvp5p442khcu", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Sl3NKLaYEgDaovqTkKVZh2ihRFbSmyVjC63wpv3ecdc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "meteor-discover", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jsvgewy7h62v3q43m0l347wlcwyhd4un5q8aa3", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "SYjCs2AlY04xdfJGPD+gyO9NZ/zQ0Lfb/TLrjgOLS68=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "COSMODROME", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr192yhf7f7f9304cy6cu6np3r8a3m9yqzqfeu9je", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "oI1+4FoeI/knjsjDyCJtgZPaeyKON8tCTcM9QX0BHa8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "broadleaf7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1pag7xgpl8njlaksvp2ur5un3htg85vcrxcp5rs", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nts1nu73aBgIdSaYye4coIuE1iBNeCuTZZC8LQ37ac8=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "ravenclub", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1p56gv748xfd74qek5e637vhcr6tyjd9ukqfecc", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "NQX4yKpOztKrmgBhGIC5WOALOLOq3LTpbzsN4ZLXGec=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "dokia-capital", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1kwftgznylzerft2ksgkzvvfn5rfpy4nk2ye8na", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "BB4a/Xh5z+dkGCRlF+pSGC3iDOoDrFse/xzQAtmxMF4=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "chainflow08", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1rj74vaqm0xkxl5cjjam63mayh4x6at3m379ulv", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "ydjx2ea+PVuChrny6X2dluJwyXta+BsNQRsgHXp8fXw=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Mia", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1zpx36km7tk5cksyzxgvcp6g552p3uhwx84r53q", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "pPGLc4NhNaehdoV2antWuyr0GmBVEG1NhD9NiSRrTi0=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "sikka.tech", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1gq0qecxs8xdaarrqxxazwavwxm7qz5jzs5anvt", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "VBVHOLnWGptY26J0wqXoZI2Dnu96pccMb08zlsaxPCQ=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "certus.one", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1cypmdvszcd9kd3jenmqxd03cpceql8rtuvxftp", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "aUViYC2znC55sleHfmsIN9hZ45SbYPbDcYA0gVzglsc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Gold2", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1klslzz2n2nqvdaa6gwflwpka7gc60vvmh3k450", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "riYrMXBFLavmf4MU/Ly7emDlciVqfB2/zxJoRsBUlfY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "idoor7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1qkllv8f6qakkw3hk9dqvytys090lk6twsyv8vf", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "F2wCn9rKafNZsYZwoLGkSQIpr3rk86cjYyuhSjsjRaE=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "ironfork", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1wf9nug554ugpw4t0wnlppxc6crl2n02qr8v3cd", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "ugb3W6W7WL9Vc4KiSBWIaowBfpqJlzbfBSfrIqZW06A=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "sunny-mintor", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1t3afuz2kt99jz4pe5k4vjvkdmldn2x0lqzv83w", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "gJDxhwAE6GeGCKQeVaNZ5is7+7MFHXtOG0UsnguKdoA=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "BlissDynamics", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr14zfph0h8rexsca6gg6jkwqup3sgl6mwj6eu4e6", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "b9RSkt+WmMxVHQExQH0IMPpnR9zDAaJwz/mv1gtyRVY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "smartpesa", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1998p0xkdwvul952ydavnx88tmwkhlfa0vhrngj", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "569Sb+Wpo8VFqXRi4cQhlOD9kS8uBgmJ2rntY3GLtzY=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "ianstream", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jw554408yw2h438q200jyuqgln76xh4ax0q4s0", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "SNwrT1B+A4g6TY7x0QzVrmVbcbl3cHXzXdD1tFHxLNo=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "TruNode", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1mwmcpq5nhaen8zyy86mrrept2gmp0z5peapkhu", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "K4kLogLtZxqrYSqRVJfrFm9tUG+Tc3QWXWIewnAgI9w=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "abcin", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1emaa7mwgpnpmc7yptm728ytp9quamsvu9rk4hp", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "TwzOJ4GcN+ZTswub4R8488SrKeWXjY/PaqCF5neXJig=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "kochacolaj", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1tq0zwzyc88l2enrlhtzw0he8rm24xfd5s9aeer", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "JXW8iTiWG28E05ZFJIKvCOBwI2RrH/BOBL/MluTZ6+I=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "D2R-validator-7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1n9qsfp3x09rhhxptzrgmdlucqhg2ce95fm3fw8", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "A3zUdVcpj4H+HRZmRW5xixj4dzMgqD7be9GrdXcjdns=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "juelianshana", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1sqec04r28jfevkzfkdj4ql2qzr2zwrmg78qzj8", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "7RhnD9OAZEJ4SV6V3LOZ1gGWubtX25457wCQq+AYYPI=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "lambda-mixer", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1hfygmryre7r8m9pfqmc85y7kw7ejphmp59k2x8", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "66j9af4xDJSblMLS+mFbp7d8TaFGu0FOo+0MwEYm2lE=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "bkcm", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1jvh448tvk368k4md83ys7auledclek0vfpckz2", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "8DScmobjJQmkN44K2xiZkESM/O9MJK/DqlggnIPLpso=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "ramihan", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1fhfcs5npydv8s96wrk9p5ychctslu92t4n5qd4", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "4JoJuRfaANhdM1x3AWRo1/Cj9DH3VA+fi1SynzknV+w=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "davinchcode", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1eg88jsn38mrael6cqu7d2u8j6dynya7fv2p2tl", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "cCoFsZzKZ9SQZbHe4NueVObIezP6ts0tRTZ/aN96dig=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Dori", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1ukcuqpqw3eq505wkqd2adgn8ugewxr6jtakngs", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Zp4tk/ieqplJF8xMeef9HV8bYpHSY+3hJ2sH7PfCX1I=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "daefreeca", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1na3wr7ujdp3qdej6l5y0k4znzrkaz77t2yjaqf", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "jj0Y/Fy8JSJR3g+PHU6Ce0ecYwHGUVJ4bVyR7WwcyLI=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "nuevax", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1xupfqk73y7rmc6qdgv7rtjy8wsngvt2g2t59t3", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "XQDVMXja3kFk5Jb47BsqJmzcDsM4lE9+r+f/J3O5Jms=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "inschain_validator", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr17gvlvfpsfl6hffn5u2hahk22un4ynpykc44tat", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "oL/QCr7LEOivyTqpGrmwVd1r+hYI2WB5+kSVzpDMxx4=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "gruberx", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1yfseqtj5sjhzz2q2ym09jym4h4nc4yevae0jp2", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "eeImG09hOPo1W7j7lKepN/Lx6I9GGHqVBVEKmznxACc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "meleatrust", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1yd0rklq45zg89fywr89ccutlcwp9kehhh0z03k", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "Abws3eXrUFAH8LeZJIcECakPL945TTmFsBlXONOUeII=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Cosmodator-7000", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1arlpxs2ftf5hgetqxxkvd7mqdc28mmaqclyv4y", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "PEg/D54SoiKZ+pic0Z0RzZa/vfYNAAf4kzSc5UKXDYk=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "bharvest", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr12ceualfg92x7du73mtcv0zya4nxvq3tl2m52uz", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "omAzuJps8KX3/iOC1LjwkMPMH3c6tjfLXwCNWXRBdWw=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "Adrian Brink - Cryptium Labs", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1wxf0ck9h2e8p2wmecxtep6cefhexsp4kzc8fxy", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "nctikQSpoLRl5kV6KarIS761QvEOZCWw6nvc48xWhic=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "finality", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr1pzlud6lg8w9phcwetc5aqp24eflshtv4xlxthf", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "NrTRAbZnBqJpW9lRW6LxXxE7EV++y7WiIRV0ifRLovA=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "coscloud", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr10qp8kqwm2cuql0hw2az5mngpmw5xm9ee32exlp", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "W0rP8sv4Ae/LZOqlBA9evvYARDt79WpFaI26jw/9Tfk=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "xiaochina", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - }, - { - "owner": "cosmosaccaddr14dwnmm6n7tjdpeylpwsdsatdl0umm75dfkqcpa", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "JdfJDlE46456GWp+AkSZhzlkUQI41f8aX7611oiWUSc=" - }, - "revoked": false, - "status": 0, - "tokens": "100", - "delegator_shares": "100", - "description": { - "moniker": "gazua1", - "identity": "", - "website": "", - "details": "" - }, - "bond_height": "0", - "bond_intra_tx_counter": 0, - "proposer_reward_pool": [], - "commission": "0", - "commission_max": "0", - "commission_change_rate": "0", - "commission_change_today": "0", - "prev_bonded_tokens": "0" - } - ], - "bonds": [ - { - "delegator_addr": "cosmosaccaddr157mg9hnhchfrqvk3enrvmvj29yhmlwf759xrgw", - "validator_addr": "cosmosaccaddr157mg9hnhchfrqvk3enrvmvj29yhmlwf759xrgw", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr193vn0gk3nsmjkxwz78gce8e8mkmagmvulpg5jt", - "validator_addr": "cosmosaccaddr193vn0gk3nsmjkxwz78gce8e8mkmagmvulpg5jt", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr16rcrnftjyl2mctz78825ng8tx5ss22jf6jcp9l", - "validator_addr": "cosmosaccaddr16rcrnftjyl2mctz78825ng8tx5ss22jf6jcp9l", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1shuqhpl273t96yg6nnqvyfeewj3ew3mdcwvcnu", - "validator_addr": "cosmosaccaddr1shuqhpl273t96yg6nnqvyfeewj3ew3mdcwvcnu", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1syhzpjwx6vv3erv2myq7txrjhrp95hrhgcl242", - "validator_addr": "cosmosaccaddr1syhzpjwx6vv3erv2myq7txrjhrp95hrhgcl242", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1uga4nuresex5u8ajjh2pcr39l0s9hszdkp843j", - "validator_addr": "cosmosaccaddr1uga4nuresex5u8ajjh2pcr39l0s9hszdkp843j", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr12wnqvqg79s9jqrul0lva3h72rfmewm7jprrcp5", - "validator_addr": "cosmosaccaddr12wnqvqg79s9jqrul0lva3h72rfmewm7jprrcp5", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1lq0mvtgnwe8mp0096un0v8ztcsj8ad92t2cwrq", - "validator_addr": "cosmosaccaddr1lq0mvtgnwe8mp0096un0v8ztcsj8ad92t2cwrq", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr14e774gfzt5l9ka766ehfgu6n5hgy9f3sehzyv8", - "validator_addr": "cosmosaccaddr14e774gfzt5l9ka766ehfgu6n5hgy9f3sehzyv8", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr164jntjfk9zs8x29mc27qansfwvjqs60gj6ermu", - "validator_addr": "cosmosaccaddr164jntjfk9zs8x29mc27qansfwvjqs60gj6ermu", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1qkc3tghc3fms7eye7vtu0g0370epr4jkje2ne7", - "validator_addr": "cosmosaccaddr1qkc3tghc3fms7eye7vtu0g0370epr4jkje2ne7", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr18m09d56pg5p2660de4sjfezpd8ud6jfghndfnt", - "validator_addr": "cosmosaccaddr18m09d56pg5p2660de4sjfezpd8ud6jfghndfnt", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1k9pqxd8fxqlk52uwfxnlsexqj6xnmw5swhss45", - "validator_addr": "cosmosaccaddr1k9pqxd8fxqlk52uwfxnlsexqj6xnmw5swhss45", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr13q937pwglh24knwa2v23ml0kkpl9vwzjmfmj3q", - "validator_addr": "cosmosaccaddr13q937pwglh24knwa2v23ml0kkpl9vwzjmfmj3q", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1xvt4e7xd0j9dwv2w83g50tpcltsl90h5dfnz6h", - "validator_addr": "cosmosaccaddr1xvt4e7xd0j9dwv2w83g50tpcltsl90h5dfnz6h", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1nnyel6v0kx8zmfh9edmre3ua4dt9306cfxsxgd", - "validator_addr": "cosmosaccaddr1nnyel6v0kx8zmfh9edmre3ua4dt9306cfxsxgd", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr13cds7hwqyq9ja2hsv4sg7glq9arlk43gcl3cek", - "validator_addr": "cosmosaccaddr13cds7hwqyq9ja2hsv4sg7glq9arlk43gcl3cek", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1y2z20pwqu5qpclque3pqkguruvheum2djtzjw3", - "validator_addr": "cosmosaccaddr1y2z20pwqu5qpclque3pqkguruvheum2djtzjw3", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1anuuffusmq5ng3rhlndhnacy45et30jqygtn67", - "validator_addr": "cosmosaccaddr1anuuffusmq5ng3rhlndhnacy45et30jqygtn67", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1wk0t6na230vxhf6ddresw2c40k5y3ayrww0s2m", - "validator_addr": "cosmosaccaddr1wk0t6na230vxhf6ddresw2c40k5y3ayrww0s2m", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr12pn4p6r5wjpsep9kn655ng7fh59yez7t0rahru", - "validator_addr": "cosmosaccaddr12pn4p6r5wjpsep9kn655ng7fh59yez7t0rahru", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr15rrxdflhq4744qt9m5ysstq3zpykhacf908eez", - "validator_addr": "cosmosaccaddr15rrxdflhq4744qt9m5ysstq3zpykhacf908eez", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr17rqsh3fw6rehnwzarz90jkqtt5fupmh50gy556", - "validator_addr": "cosmosaccaddr17rqsh3fw6rehnwzarz90jkqtt5fupmh50gy556", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1g4q87u438qdh2c8ue4dzdr9ldrqrs77ptm9c70", - "validator_addr": "cosmosaccaddr1g4q87u438qdh2c8ue4dzdr9ldrqrs77ptm9c70", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1dq7jt3pn7mrce2twac907jue7hjd0p0rgt3qnq", - "validator_addr": "cosmosaccaddr1dq7jt3pn7mrce2twac907jue7hjd0p0rgt3qnq", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1gg6natrtt5lf02xwr06ujcczvavl54wgljuaut", - "validator_addr": "cosmosaccaddr1gg6natrtt5lf02xwr06ujcczvavl54wgljuaut", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1zds6r7jyxyxcpf05r5yyyy3u8q2rvj9kkc6vcv", - "validator_addr": "cosmosaccaddr1zds6r7jyxyxcpf05r5yyyy3u8q2rvj9kkc6vcv", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1l0qw5znfd6e8pshpjvyghjjzyr4l6ymla080lt", - "validator_addr": "cosmosaccaddr1l0qw5znfd6e8pshpjvyghjjzyr4l6ymla080lt", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1rxxcpkmsngd0azkh3n2467m66ls4rwq52yuv27", - "validator_addr": "cosmosaccaddr1rxxcpkmsngd0azkh3n2467m66ls4rwq52yuv27", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jsch8k385shvse6j5dfx20483qym5uhq76xpjf", - "validator_addr": "cosmosaccaddr1jsch8k385shvse6j5dfx20483qym5uhq76xpjf", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr19uhnhct0p45ek6qxp3cjjrjtz4pacwcsgzvpuj", - "validator_addr": "cosmosaccaddr19uhnhct0p45ek6qxp3cjjrjtz4pacwcsgzvpuj", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1gghhdtx2sceafvgg8dry5sqrvc8srxghm4qqsy", - "validator_addr": "cosmosaccaddr1gghhdtx2sceafvgg8dry5sqrvc8srxghm4qqsy", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1cyayv35tv47t829mel6jm0vqzmrdhf3jq87tqg", - "validator_addr": "cosmosaccaddr1cyayv35tv47t829mel6jm0vqzmrdhf3jq87tqg", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr126ayk3hse5zvk9gxfmpsjr9565ef72pv9g20yx", - "validator_addr": "cosmosaccaddr126ayk3hse5zvk9gxfmpsjr9565ef72pv9g20yx", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1fskmzyt2hr8usr3s65dq3rfur3fy6g2hjp23tm", - "validator_addr": "cosmosaccaddr1fskmzyt2hr8usr3s65dq3rfur3fy6g2hjp23tm", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1lhjta6nt0lewj05m8444tuyhalkrffgpm7njpp", - "validator_addr": "cosmosaccaddr1lhjta6nt0lewj05m8444tuyhalkrffgpm7njpp", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1pm0gx3lk46gf8vyj5my9w5tk06cuq66ll77ugj", - "validator_addr": "cosmosaccaddr1pm0gx3lk46gf8vyj5my9w5tk06cuq66ll77ugj", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr15w2rengajq9js8hu57kjw88dly5vy7gsqedn0n", - "validator_addr": "cosmosaccaddr15w2rengajq9js8hu57kjw88dly5vy7gsqedn0n", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr10505nl7yftsme9jk2glhjhta7w0475uva87paj", - "validator_addr": "cosmosaccaddr10505nl7yftsme9jk2glhjhta7w0475uva87paj", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr18z3pnjgdtt337z8g5drfts7r3fm6n9a0896h0r", - "validator_addr": "cosmosaccaddr18z3pnjgdtt337z8g5drfts7r3fm6n9a0896h0r", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1vmdgku2g0n5p2ef995r4fugu99ze9e5me9kh4d", - "validator_addr": "cosmosaccaddr1vmdgku2g0n5p2ef995r4fugu99ze9e5me9kh4d", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1j2frwt2vq2xer7f060wpsu3y3f63uys2w9lx2e", - "validator_addr": "cosmosaccaddr1j2frwt2vq2xer7f060wpsu3y3f63uys2w9lx2e", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1whxd48da3r56n8eecym8zg0c6xmf35fn2myart", - "validator_addr": "cosmosaccaddr1whxd48da3r56n8eecym8zg0c6xmf35fn2myart", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jkmn6asju47zuuzrf8rjt7sllaj5cx4kueyv8p", - "validator_addr": "cosmosaccaddr1jkmn6asju47zuuzrf8rjt7sllaj5cx4kueyv8p", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr120skmenn2a0ra8y6zassrxvnfc5rlme8rqarvs", - "validator_addr": "cosmosaccaddr120skmenn2a0ra8y6zassrxvnfc5rlme8rqarvs", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jtt6al0acr8h0uvq489rt9zx9lnau7rlcu30pt", - "validator_addr": "cosmosaccaddr1jtt6al0acr8h0uvq489rt9zx9lnau7rlcu30pt", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr135dz5hdtvk3z8vl0zyy5l223kjanv0gudu4905", - "validator_addr": "cosmosaccaddr135dz5hdtvk3z8vl0zyy5l223kjanv0gudu4905", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr182ujqw3r8p5fffjqkf0rxzj29pg5q96nxd2khq", - "validator_addr": "cosmosaccaddr182ujqw3r8p5fffjqkf0rxzj29pg5q96nxd2khq", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1qrc3ed8tnz6vc24ftmnht8efs5ufhjmrjkds4x", - "validator_addr": "cosmosaccaddr1qrc3ed8tnz6vc24ftmnht8efs5ufhjmrjkds4x", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1swydkj5u3jd4jwe7uygu4479zgs4qg6v4ds3c9", - "validator_addr": "cosmosaccaddr1swydkj5u3jd4jwe7uygu4479zgs4qg6v4ds3c9", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1l9jt8xgejkcm4sulhwj8c83ftprz5p9lyq4605", - "validator_addr": "cosmosaccaddr1l9jt8xgejkcm4sulhwj8c83ftprz5p9lyq4605", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr128ty3kzhcepjacu4q0xjgq60qa3zz8na3jl793", - "validator_addr": "cosmosaccaddr128ty3kzhcepjacu4q0xjgq60qa3zz8na3jl793", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1e3qm8jd9357zhdemwnaafmf0wy3f4yqmd307c2", - "validator_addr": "cosmosaccaddr1e3qm8jd9357zhdemwnaafmf0wy3f4yqmd307c2", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr18wfz5vj26y079surms5sm6avjtezzspfvqs6g4", - "validator_addr": "cosmosaccaddr18wfz5vj26y079surms5sm6avjtezzspfvqs6g4", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1vrc7zpg5teawwuzkfh6t7c6sy353sukhlarxpa", - "validator_addr": "cosmosaccaddr1vrc7zpg5teawwuzkfh6t7c6sy353sukhlarxpa", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1umaajfgap5ef6yxvk5706kwk8j08l7wh6h9fp2", - "validator_addr": "cosmosaccaddr1umaajfgap5ef6yxvk5706kwk8j08l7wh6h9fp2", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1670l5up6e5fddvlc027yvvlvedrzyx0mmsl622", - "validator_addr": "cosmosaccaddr1670l5up6e5fddvlc027yvvlvedrzyx0mmsl622", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1wx33m9dvglryga0saey0pr99ja0klhcfrwaw7l", - "validator_addr": "cosmosaccaddr1wx33m9dvglryga0saey0pr99ja0klhcfrwaw7l", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr15u9ve7fz8fqaf7r2u3p4f9ru4ze47pau5cxgcg", - "validator_addr": "cosmosaccaddr15u9ve7fz8fqaf7r2u3p4f9ru4ze47pau5cxgcg", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1h4q0xkdg30cl9vw0u8ejm0rs337dszy98gnd4a", - "validator_addr": "cosmosaccaddr1h4q0xkdg30cl9vw0u8ejm0rs337dszy98gnd4a", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr12zpkulxv7kn59sgf0tpf24qhqzxsvf3gamkl7g", - "validator_addr": "cosmosaccaddr12zpkulxv7kn59sgf0tpf24qhqzxsvf3gamkl7g", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1g6sc5t9t68vmcj3alk7dfqr54tvastpxac28k6", - "validator_addr": "cosmosaccaddr1g6sc5t9t68vmcj3alk7dfqr54tvastpxac28k6", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jck6gp4mqy33sk6a0fr5c8maq53hf4245v3mgg", - "validator_addr": "cosmosaccaddr1jck6gp4mqy33sk6a0fr5c8maq53hf4245v3mgg", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jh3grawl62juvx5p8fz5xsy9hpw8w3mngqafe4", - "validator_addr": "cosmosaccaddr1jh3grawl62juvx5p8fz5xsy9hpw8w3mngqafe4", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr17nlusdvrk34fq65jemy3umfjfwaxfzv4asyl60", - "validator_addr": "cosmosaccaddr17nlusdvrk34fq65jemy3umfjfwaxfzv4asyl60", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr18u2sqnuetfnkugp59e9pgyv2dpuvkkxmmsc7m8", - "validator_addr": "cosmosaccaddr18u2sqnuetfnkugp59e9pgyv2dpuvkkxmmsc7m8", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1xdp4pls4ryvchq2n8v0cpmtwsprvyh8wvg563q", - "validator_addr": "cosmosaccaddr1xdp4pls4ryvchq2n8v0cpmtwsprvyh8wvg563q", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1pmntq5en2rgtr5rzr4e304efrve4lr43z32y5s", - "validator_addr": "cosmosaccaddr1pmntq5en2rgtr5rzr4e304efrve4lr43z32y5s", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr197p65z7ge5g55r68thvw4l5e43gnm70jhu5g75", - "validator_addr": "cosmosaccaddr197p65z7ge5g55r68thvw4l5e43gnm70jhu5g75", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr15klp8pypkd8htppzt6pguej57yyvp5p442khcu", - "validator_addr": "cosmosaccaddr15klp8pypkd8htppzt6pguej57yyvp5p442khcu", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jsvgewy7h62v3q43m0l347wlcwyhd4un5q8aa3", - "validator_addr": "cosmosaccaddr1jsvgewy7h62v3q43m0l347wlcwyhd4un5q8aa3", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr192yhf7f7f9304cy6cu6np3r8a3m9yqzqfeu9je", - "validator_addr": "cosmosaccaddr192yhf7f7f9304cy6cu6np3r8a3m9yqzqfeu9je", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1pag7xgpl8njlaksvp2ur5un3htg85vcrxcp5rs", - "validator_addr": "cosmosaccaddr1pag7xgpl8njlaksvp2ur5un3htg85vcrxcp5rs", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1p56gv748xfd74qek5e637vhcr6tyjd9ukqfecc", - "validator_addr": "cosmosaccaddr1p56gv748xfd74qek5e637vhcr6tyjd9ukqfecc", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1kwftgznylzerft2ksgkzvvfn5rfpy4nk2ye8na", - "validator_addr": "cosmosaccaddr1kwftgznylzerft2ksgkzvvfn5rfpy4nk2ye8na", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1rj74vaqm0xkxl5cjjam63mayh4x6at3m379ulv", - "validator_addr": "cosmosaccaddr1rj74vaqm0xkxl5cjjam63mayh4x6at3m379ulv", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1zpx36km7tk5cksyzxgvcp6g552p3uhwx84r53q", - "validator_addr": "cosmosaccaddr1zpx36km7tk5cksyzxgvcp6g552p3uhwx84r53q", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1gq0qecxs8xdaarrqxxazwavwxm7qz5jzs5anvt", - "validator_addr": "cosmosaccaddr1gq0qecxs8xdaarrqxxazwavwxm7qz5jzs5anvt", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1cypmdvszcd9kd3jenmqxd03cpceql8rtuvxftp", - "validator_addr": "cosmosaccaddr1cypmdvszcd9kd3jenmqxd03cpceql8rtuvxftp", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1klslzz2n2nqvdaa6gwflwpka7gc60vvmh3k450", - "validator_addr": "cosmosaccaddr1klslzz2n2nqvdaa6gwflwpka7gc60vvmh3k450", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1qkllv8f6qakkw3hk9dqvytys090lk6twsyv8vf", - "validator_addr": "cosmosaccaddr1qkllv8f6qakkw3hk9dqvytys090lk6twsyv8vf", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1wf9nug554ugpw4t0wnlppxc6crl2n02qr8v3cd", - "validator_addr": "cosmosaccaddr1wf9nug554ugpw4t0wnlppxc6crl2n02qr8v3cd", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1t3afuz2kt99jz4pe5k4vjvkdmldn2x0lqzv83w", - "validator_addr": "cosmosaccaddr1t3afuz2kt99jz4pe5k4vjvkdmldn2x0lqzv83w", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr14zfph0h8rexsca6gg6jkwqup3sgl6mwj6eu4e6", - "validator_addr": "cosmosaccaddr14zfph0h8rexsca6gg6jkwqup3sgl6mwj6eu4e6", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1998p0xkdwvul952ydavnx88tmwkhlfa0vhrngj", - "validator_addr": "cosmosaccaddr1998p0xkdwvul952ydavnx88tmwkhlfa0vhrngj", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jw554408yw2h438q200jyuqgln76xh4ax0q4s0", - "validator_addr": "cosmosaccaddr1jw554408yw2h438q200jyuqgln76xh4ax0q4s0", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1mwmcpq5nhaen8zyy86mrrept2gmp0z5peapkhu", - "validator_addr": "cosmosaccaddr1mwmcpq5nhaen8zyy86mrrept2gmp0z5peapkhu", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1emaa7mwgpnpmc7yptm728ytp9quamsvu9rk4hp", - "validator_addr": "cosmosaccaddr1emaa7mwgpnpmc7yptm728ytp9quamsvu9rk4hp", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1tq0zwzyc88l2enrlhtzw0he8rm24xfd5s9aeer", - "validator_addr": "cosmosaccaddr1tq0zwzyc88l2enrlhtzw0he8rm24xfd5s9aeer", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1n9qsfp3x09rhhxptzrgmdlucqhg2ce95fm3fw8", - "validator_addr": "cosmosaccaddr1n9qsfp3x09rhhxptzrgmdlucqhg2ce95fm3fw8", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1sqec04r28jfevkzfkdj4ql2qzr2zwrmg78qzj8", - "validator_addr": "cosmosaccaddr1sqec04r28jfevkzfkdj4ql2qzr2zwrmg78qzj8", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1hfygmryre7r8m9pfqmc85y7kw7ejphmp59k2x8", - "validator_addr": "cosmosaccaddr1hfygmryre7r8m9pfqmc85y7kw7ejphmp59k2x8", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1jvh448tvk368k4md83ys7auledclek0vfpckz2", - "validator_addr": "cosmosaccaddr1jvh448tvk368k4md83ys7auledclek0vfpckz2", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1fhfcs5npydv8s96wrk9p5ychctslu92t4n5qd4", - "validator_addr": "cosmosaccaddr1fhfcs5npydv8s96wrk9p5ychctslu92t4n5qd4", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1eg88jsn38mrael6cqu7d2u8j6dynya7fv2p2tl", - "validator_addr": "cosmosaccaddr1eg88jsn38mrael6cqu7d2u8j6dynya7fv2p2tl", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1ukcuqpqw3eq505wkqd2adgn8ugewxr6jtakngs", - "validator_addr": "cosmosaccaddr1ukcuqpqw3eq505wkqd2adgn8ugewxr6jtakngs", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1na3wr7ujdp3qdej6l5y0k4znzrkaz77t2yjaqf", - "validator_addr": "cosmosaccaddr1na3wr7ujdp3qdej6l5y0k4znzrkaz77t2yjaqf", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1xupfqk73y7rmc6qdgv7rtjy8wsngvt2g2t59t3", - "validator_addr": "cosmosaccaddr1xupfqk73y7rmc6qdgv7rtjy8wsngvt2g2t59t3", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr17gvlvfpsfl6hffn5u2hahk22un4ynpykc44tat", - "validator_addr": "cosmosaccaddr17gvlvfpsfl6hffn5u2hahk22un4ynpykc44tat", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1yfseqtj5sjhzz2q2ym09jym4h4nc4yevae0jp2", - "validator_addr": "cosmosaccaddr1yfseqtj5sjhzz2q2ym09jym4h4nc4yevae0jp2", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1yd0rklq45zg89fywr89ccutlcwp9kehhh0z03k", - "validator_addr": "cosmosaccaddr1yd0rklq45zg89fywr89ccutlcwp9kehhh0z03k", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1arlpxs2ftf5hgetqxxkvd7mqdc28mmaqclyv4y", - "validator_addr": "cosmosaccaddr1arlpxs2ftf5hgetqxxkvd7mqdc28mmaqclyv4y", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr12ceualfg92x7du73mtcv0zya4nxvq3tl2m52uz", - "validator_addr": "cosmosaccaddr12ceualfg92x7du73mtcv0zya4nxvq3tl2m52uz", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1wxf0ck9h2e8p2wmecxtep6cefhexsp4kzc8fxy", - "validator_addr": "cosmosaccaddr1wxf0ck9h2e8p2wmecxtep6cefhexsp4kzc8fxy", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr1pzlud6lg8w9phcwetc5aqp24eflshtv4xlxthf", - "validator_addr": "cosmosaccaddr1pzlud6lg8w9phcwetc5aqp24eflshtv4xlxthf", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr10qp8kqwm2cuql0hw2az5mngpmw5xm9ee32exlp", - "validator_addr": "cosmosaccaddr10qp8kqwm2cuql0hw2az5mngpmw5xm9ee32exlp", - "shares": "100", - "height": "0" - }, - { - "delegator_addr": "cosmosaccaddr14dwnmm6n7tjdpeylpwsdsatdl0umm75dfkqcpa", - "validator_addr": "cosmosaccaddr14dwnmm6n7tjdpeylpwsdsatdl0umm75dfkqcpa", - "shares": "100", - "height": "0" - } - ] - } - } -} \ No newline at end of file diff --git a/docs/RELEASE_PROCESS.md b/docs/RELEASE_PROCESS.md index 1f83b21bfa..503c5d3fa0 100644 --- a/docs/RELEASE_PROCESS.md +++ b/docs/RELEASE_PROCESS.md @@ -6,6 +6,6 @@ - [ ] 4. Summarize breaking API changes section under “Breaking Changes” section to the `CHANGELOG.md` to bring attention to any breaking API changes that affect RPC consumers. - [ ] 5. Tag the commit `{{ .Release.Name }}-rcN` - [ ] 6. Kick off 1 day of automated fuzz testing -- [ ] 7. Release Lead assigns 2 people to perform buddy testing script +- [ ] 7. Release Lead assigns 2 people to perform [buddy testing script](/docs/RELEASE_TEST_SCRIPT.md) and update the relevant documentation - [ ] 8. If errors are found in either #6 or #7 go back to #2 (*NOTE*: be sure to increment the `rcN`) - [ ] 9. After #6 and #7 have successfully completed then merge the release PR and push the final release tag diff --git a/docs/RELEASE_TEST_SCRIPT.md b/docs/RELEASE_TEST_SCRIPT.md new file mode 100644 index 0000000000..725507958c --- /dev/null +++ b/docs/RELEASE_TEST_SCRIPT.md @@ -0,0 +1,17 @@ +This document should contain plain english instructions for testing functionality on `gaiad`. This “Script” is supposed to be run by 2 people who will each spin up a `gaiad` node and run the series of prompts below. + +- [Create a network of 2 nodes](getting-started/create-testnet.md) +- [Generate an account](sdk/clients.md) +- [Send funds from one account to the other](sdk/clients.md) +- [Create a validator](validators/validator-setup.md) +- [Edit a validator](validators/validator-setup.md) +- [Delegate to validator](sdk/clients.md) +- [Unbond from a validator](sdk/clients.md) +- [View validators and verify output](validators/validator-setup.md) +- [Query network status](getting-started/full-node.md) +- [Create a proposal](validators/validator-setup.md) +- [Query a proposal](validators/validator-setup.md) +- [Vote on a proposal](validators/validator-setup.md) +- [Query status of a proposal](validators/validator-setup.md) +- [Query the votes on a proposal](validators/validator-setup.md) +- [Export state and reload](getting-started/create-testnet.md) diff --git a/docs/clients/lcd-rest-api.yaml b/docs/clients/lcd-rest-api.yaml index 3b8349f4bd..5be69302d5 100644 --- a/docs/clients/lcd-rest-api.yaml +++ b/docs/clients/lcd-rest-api.yaml @@ -2,7 +2,7 @@ swagger: '2.0' info: version: '1.1.0' title: Gaia-Lite (former LCD) to interface with Cosmos BaseServer via REST - description: Specification for Gaia-lite provided by `gaiacli advanced rest-server` + description: Specification for Gaia-lite provided by `gaiacli rest-server` tags: - name: keys diff --git a/docs/clients/rest.md b/docs/clients/rest.md index 190eeb1f34..b48ec7d8fc 100644 --- a/docs/clients/rest.md +++ b/docs/clients/rest.md @@ -1,6 +1,6 @@ # REST -See `gaiacli advanced rest-server --help` for more. +See `gaiacli rest-server --help` for more. Also see the [work in progress API specification](https://github.com/cosmos/cosmos-sdk/pull/1314) diff --git a/docs/getting-started/create-testnet.md b/docs/getting-started/create-testnet.md new file mode 100644 index 0000000000..0b68b3287b --- /dev/null +++ b/docs/getting-started/create-testnet.md @@ -0,0 +1,27 @@ +## Create your Own Testnet + +To create your own testnet, first each validator will need to install gaiad and run gen-tx + +```bash +gaiad init gen-tx --name +``` + +This populations `$HOME/.gaiad/gen-tx/` with a json file. + +Now these json files need to be aggregated together via Github, a Google form, pastebin or other methods. + +Place all files on one computer in `$HOME/.gaiad/gen-tx/` + +```bash +gaiad init --gen-txs -o --chain= +``` + +This will generate a `genesis.json` in `$HOME/.gaiad/config/genesis.json` distribute this file to all validators on your testnet. + +### Export state + +To export state and reload (useful for testing purposes): + +``` +gaiad export > genesis.json; cp genesis.json ~/.gaiad/config/genesis.json; gaiad start +``` diff --git a/docs/ics/ics-030-signed-messages.md b/docs/ics/ics-030-signed-messages.md new file mode 100644 index 0000000000..e73d9f5803 --- /dev/null +++ b/docs/ics/ics-030-signed-messages.md @@ -0,0 +1,193 @@ +# ICS 030: Cosmos Signed Messages + +>TODO: Replace with valid ICS number and possibly move to new location. + +* [Changelog](#changelog) +* [Abstract](#abstract) +* [Preliminary](#preliminary) +* [Specification](#specification) +* [Future Adaptations](#future-adaptations) +* [API](#api) +* [References](#references) + +## Status + +Proposed. + +## Changelog + +## Abstract + +Having the ability to sign messages off-chain has proven to be a fundamental aspect +of nearly any blockchain. The notion of signing messages off-chain has many +added benefits such as saving on computational costs and reducing transaction +throughput and overhead. Within the context of the Cosmos, some of the major +applications of signing such data includes, but is not limited to, providing a +cryptographic secure and verifiable means of proving validator identity and +possibly associating it with some other framework or organization. In addition, +having the ability to sign Cosmos messages with a Ledger or similar HSM device. + +A standardized protocol for hashing, signing, and verifying messages that can be +implemented by the Cosmos SDK and other third-party organizations is needed. Such a +standardized protocol subscribes to the following: + +* Contains a specification of human-readable and machine-verifiable typed structured data +* Contains a framework for deterministic and injective encoding of structured data +* Utilizes cryptographic secure hashing and signing algorithms +* A framework for supporting extensions and domain separation +* Is invulnerable to chosen ciphertext attacks +* Has protection against potentially signing transactions a user did not intend to + +This specification is only concerned with the rationale and the standardized +implementation of Cosmos signed messages. It does **not** concern itself with the +concept of replay attacks as that will be left up to the higher-level application +implementation. If you view signed messages in the means of authorizing some +action or data, then such an application would have to either treat this as +idempotent or have mechanisms in place to reject known signed messages. + +## Preliminary + +The Cosmos message signing protocol will be parameterized with a cryptographic +secure hashing algorithm `SHA-256` and a signing algorithm `S` that contains +the operations `sign` and `verify` which provide a digital signature over a set +of bytes and verification of a signature respectively. + +Note, our goal here is not to provide context and reasoning about why necessarily +these algorithms were chosen apart from the fact they are the defacto algorithms +used in Tendermint and the Cosmos SDK and that they satisfy our needs for such +cryptographic algorithms such as having resistance to collision and second +pre-image attacks, as well as being [deterministic](https://en.wikipedia.org/wiki/Hash_function#Determinism) and [uniform](https://en.wikipedia.org/wiki/Hash_function#Uniformity). + +## Specification + +Tendermint has a well established protocol for signing messages using a canonical +JSON representation as defined [here](https://github.com/tendermint/tendermint/blob/master/types/canonical_json.go). + +An example of such a canonical JSON structure is Tendermint's vote structure: + +```golang +type CanonicalJSONVote struct { + ChainID string `json:"@chain_id"` + Type string `json:"@type"` + BlockID CanonicalJSONBlockID `json:"block_id"` + Height int64 `json:"height"` + Round int `json:"round"` + Timestamp string `json:"timestamp"` + VoteType byte `json:"type"` +} +``` + +With such canonical JSON structures, the specification requires that they include +meta fields: `@chain_id` and `@type`. These meta fields are reserved and must be +included. They are both of type `string`. In addition, fields must be ordered +in lexicographically ascending order. + +For the purposes of signing Cosmos messages, the `@chain_id` field must correspond +to the Cosmos chain identifier. The user-agent should **refuse** signing if the +`@chain_id` field does not match the currently active chain! The `@type` field +must equal the constant `"message"`. The `@type` field corresponds to the type of +structure the user will be signing in an application. For now, a user is only +allowed to sign bytes of valid ASCII text ([see here](https://github.com/tendermint/tendermint/blob/master/libs/common/string.go#L61-L74)). +However, this will change and evolve to support additional application-specific +structures that are human-readable and machine-verifiable ([see Future Adaptations](#futureadaptations)). + +Thus, we can have a canonical JSON structure for signing Cosmos messages using +the [JSON schema](http://json-schema.org/) specification as such: + +```json +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "$id": "cosmos/signing/typeData/schema", + "title": "The Cosmos signed message typed data schema.", + "type": "object", + "properties": { + "@chain_id": { + "type": "string", + "description": "The corresponding Cosmos chain identifier.", + "minLength": 1 + }, + "@type": { + "type": "string", + "description": "The message type. It must be 'message'.", + "enum": [ + "message" + ] + }, + "text": { + "type": "string", + "description": "The valid ASCII text to sign.", + "pattern": "^[\\x20-\\x7E]+$", + "minLength": 1 + } + }, + "required": [ + "@chain_id", + "@type", + "text" + ] +} +``` + +e.g. + +```json +{ + "@chain_id": "1", + "@type": "message", + "text": "Hello, you can identify me as XYZ on keybase." +} +``` + +## Future Adaptations + +As applications can vary greatly in domain, it will be vital to support both +domain separation and human-readable and machine-verifiable structures. + +Domain separation will allow for application developers to prevent collisions of +otherwise identical structures. It should be designed to be unique per application +use and should directly be used in the signature encoding itself. + +Human-readable and machine-verifiable structures will allow end users to sign +more complex structures, apart from just string messages, and still be able to +know exactly what they are signing (opposed to signing a bunch of arbitrary bytes). + +Thus, in the future, the Cosmos signing message specification will be expected +to expand upon it's canonical JSON structure to include such functionality. + + +## API + +Application developers and designers should formalize a standard set of APIs that +adhere to the following specification: + +----- + +### **cosmosSignBytes** + +Params: + +* `data`: the Cosmos signed message canonical JSON structure +* `address`: the Bech32 Cosmos account address to sign data with + +Returns: + +* `signature`: the Cosmos signature derived using signing algorithm `S` + +----- + +### Examples + +Using the `secp256k1` as the DSA, `S`: + +```javascript +data = { + "@chain_id": "1", + "@type": "message", + "text": "I hereby claim I am ABC on Keybase!" +} + +cosmosSignBytes(data, "cosmosaccaddr1pvsch6cddahhrn5e8ekw0us50dpnugwnlfngt3") +> "0x7fc4a495473045022100dec81a9820df0102381cdbf7e8b0f1e2cb64c58e0ecda1324543742e0388e41a02200df37905a6505c1b56a404e23b7473d2c0bc5bcda96771d2dda59df6ed2b98f8" +``` + +## References diff --git a/docs/light/api.md b/docs/light/api.md index d4e66eaf15..6c5e8aa5f0 100644 --- a/docs/light/api.md +++ b/docs/light/api.md @@ -1,39 +1,42 @@ -# Cosmos Hub (Gaia) LCD API +# Cosmos Hub (Gaia-Lite) LCD API -This document describes the API that is exposed by the specific LCD implementation of the Cosmos -Hub (Gaia). Those APIs are exposed by a REST server and can easily be accessed over HTTP/WS(websocket) +This document describes the API that is exposed by the specific Light Client Daemon (LCD) implementation of the Cosmos Hub (Gaia). Those APIs are exposed by a REST server and can easily be accessed over HTTP/WS (websocket) connections. -The complete API is comprised of the sub-APIs of different modules. The modules in the Cosmos Hub -(Gaia) API are: +The complete API is comprised of the sub-APIs of different modules. The modules in the Cosmos Hub (Gaia-Lite) API are: -* ICS0 (TendermintAPI) -* ICS1 (KeyAPI) -* ICS20 (TokenAPI) -* ICS21 (StakingAPI) - not yet implemented -* ICS22 (GovernanceAPI) - not yet implemented +- ICS0 ([TendermintAPI](api.md#ics0---tendermintapi)) +- ICS1 ([KeyAPI](api.md#ics1---keyapi)) +- ICS20 ([TokenAPI](api.md#ics20---tokenapi)) +- ICS21 ([StakingAPI](api.md#ics21---stakingapi)) +- ICS22 ([GovernanceAPI](api.md#ics22---governanceapi)) +- ICS23 ([SlashingAPI](api.md#ics23---slashingapi)) Error messages my change and should be only used for display purposes. Error messages should not be used for determining the error type. -## ICS0 - TendermintAPI - not yet implemented +## ICS0 - TendermintAPI -Exposes the same functionality as the Tendermint RPC from a full node. It aims to have a very -similar API. +Exposes the same functionality as the Tendermint RPC from a full node. It aims to have a very similar API. -### /broadcast_tx_sync - POST +### POST /txs -url: /broadcast_tx_sync +- **URL**: `/txs` +- Query Parameters: + - `?return={sync|async|block}`: + - `return=sync`: Waits for the transaction to pass `CheckTx` + - `return=async`: Returns the request immediately after it is received by the server + - `return=block`: waits for for the transaction to be committed in a block +- POST Body: -Functionality: Submit a signed transaction synchronously. This returns a response from CheckTx. +```json +{ + "transaction": "string", + "return": "string", +} +``` -Parameters: - -| Parameter | Type | Default | Required | Description | -| ----------- | ------ | ------- | -------- | --------------- | -| transaction | string | null | true | signed tx bytes | - -Returns on success: +- Returns on success: ```json { @@ -49,121 +52,23 @@ Returns on success: } ``` -Returns on failure: - -```json -{ - "rest api":"2.0", - "code":500, - "error":"Could not submit the transaction synchronously.", - "result":{} -} -``` - -### /broadcast_tx_async - POST - -url: /broadcast_tx_async - -Functionality: Submit a signed transaction asynchronously. This does not return a response from CheckTx. - -Parameters: - -| Parameter | Type | Default | Required | Description | -| ----------- | ------ | ------- | -------- | --------------- | -| transaction | string | null | true | signed tx bytes | - -Returns on success: - -```json -{ - "rest api":"2.0", - "code":200, - "error":"", - "result": { - "code":0, - "hash":"E39AAB7A537ABAA237831742DCE1117F187C3C52", - "data":"", - "log":"" - } -} -``` - -Returns on failure: - -```json -{ - "rest api":"2.0", - "code":500, - "error":"Could not submit the transaction asynchronously.", - "result":{} -} -``` - -### /broadcast_tx_commit - POST - -url: /broadcast_tx_commit - -Functionality: Submit a signed transaction and waits for it to be committed in a block. - -Parameters: - -| Parameter | Type | Default | Required | Description | -| ----------- | ------ | ------- | -------- | --------------- | -| transaction | string | null | true | signed tx bytes | - -Returns on success: - -```json -{ - "rest api":"2.0", - "code":200, - "error":"", - "result":{ - "height":26682, - "hash":"75CA0F856A4DA078FC4911580360E70CEFB2EBEE", - "deliver_tx":{ - "log":"", - "data":"", - "code":0 - }, - "check_tx":{ - "log":"", - "data":"", - "code":0 - } -} -``` - -Returns on failure: - -```json -{ - "rest api":"2.0", - "code":500, - "error":"Could not commit the transaction.", - "result":{} -} -``` - ## ICS1 - KeyAPI This API exposes all functionality needed for key creation, signing and management. -### /keys - GET +### GET /keys -url: /keys - -Functionality: Gets a list of all the keys. - -Returns on success: +- **URL**: `/keys` +- **Functionality**: Gets a list of all the keys. +- Returns on success: ```json { - "rest api":"2.0", + "rest api":"1.0", "code":200, "error":"", "result":{ - "keys":[ + "account":[ { "name":"monkey", "address":"cosmosaccaddr1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd", @@ -180,73 +85,25 @@ Returns on success: } ``` -Returns on failure: +### POST /keys + +- **URL**: `/keys` +- **Functionality**: Create a new key. +- POST Body: ```json { - "rest api":"2.0", - "code":500, - "error":"Could not retrieve the keys.", - "result":{} + "name": "string", + "password": "string", + "seed": "string", } ``` -### /keys/recover - POST - -url: /keys/recover - -Functionality: Recover your key from seed and persist it encrypted with the password. - -Parameter: - -| Parameter | Type | Default | Required | Description | -| --------- | ------ | ------- | -------- | ---------------- | -| name | string | null | true | name of key | -| password | string | null | true | password of key | -| seed | string | null | true | seed of key | - Returns on success: ```json { - "rest api":"2.0", - "code":200, - "error":"", - "result":{ - "address":"BD607C37147656A507A5A521AA9446EB72B2C907" - } -} -``` - -Returns on failure: - -```json -{ - "rest api":"2.0", - "code":500, - "error":"Could not recover the key.", - "result":{} -} -``` - -### /keys/create - POST - -url: /keys/create - -Functionality: Create a new key. - -Parameter: - -| Parameter | Type | Default | Required | Description | -| --------- | ------ | ------- | -------- | ---------------- | -| name | string | null | true | name of key | -| password | string | null | true | password of key | - -Returns on success: - -```json -{ - "rest api":"2.0", + "rest api":"1.0", "code":200, "error":"", "result":{ @@ -255,28 +112,15 @@ Returns on success: } ``` -Returns on failure: +### GET /keys/{name} + +- **URL** : `/keys/{name}` +- **Functionality**: Get the information for the specified key. +- Returns on success: ```json { - "rest api":"2.0", - "code":500, - "error":"Could not create new key.", - "result":{} -} -``` - -### /keys/{name} - GET - -url: /keys/{name} - -Functionality: Get the information for the specified key. - -Returns on success: - -```json -{ - "rest api":"2.0", + "rest api":"1.0", "code":200, "error":"", "result":{ @@ -287,31 +131,20 @@ Returns on success: } ``` -Returns on failure: +### PUT /keys/{name} + +- **URL** : `/keys/{name}` +- **Functionality**: Change the encryption password for the specified key. +- PUT Body: ```json { - "rest api":"2.0", - "code":500, - "error":"Could not find information on the specified key.", - "result":{} + "old_password": "string", + "new_password": "string", } ``` -### /keys/{name} - PUT - -url: /keys/{name} - -Functionality: Change the encryption password for the specified key. - -Parameters: - -| Parameter | Type | Default | Required | Description | -| --------------- | ------ | ------- | -------- | --------------- | -| old_password | string | null | true | old password | -| new_password | string | null | true | new password | - -Returns on success: +- Returns on success: ```json { @@ -322,48 +155,77 @@ Returns on success: } ``` -Returns on failure: +### DELETE /keys/{name} + +- **URL**: `/keys/{name}` +- **Functionality**: Delete the specified key. +- DELETE Body: ```json { - "rest api":"2.0", - "code":500, - "error":"Could not update the specified key.", - "result":{} + "password": "string", } ``` -### /keys/{name} - DELETE - -url: /keys/{name} - -Functionality: Delete the specified key. - -Parameters: - -| Parameter | Type | Default | Required | Description | -| --------- | ------ | ------- | -------- | ---------------- | -| password | string | null | true | password of key | - -Returns on success: +- Returns on success: ```json { - "rest api":"2.0", + "rest api":"1.0", "code":200, "error":"", "result":{} } ``` -Returns on failure: +### POST /keys/{name}/recover + +- **URL**: `/keys/{name}/recover` +- **Functionality**: Recover your key from seed and persist it encrypted with the password. +- POST Body: ```json { - "rest api":"2.0", - "code":500, - "error":"Could not delete the specified key.", - "result":{} + "password": "string", + "seed": "string", +} +``` + +- Returns on success: + +```json +{ + "rest api":"1.0", + "code":200, + "error":"", + "result":{ + "address":"BD607C37147656A507A5A521AA9446EB72B2C907" + } +} +``` + +### GET /auth/accounts/{address} + +- **URL**: `/auth/accounts/{address}` +- **Functionality**: Query the information of an account . +- Returns on success: + +```json +{ + "rest api":"1.0", + "code":200, + "error":"", + "result":{ + "address": "82A57F8575BDFA22F5164C75361A21D2B0E11089", + "public_key": "PubKeyEd25519{A0EEEED3C9CE1A6988DEBFE347635834A1C0EBA0B4BB1125896A7072D22E650D}", + "coins": [ + {"atom": 300}, + {"photon": 15} + ], + "account_number": 1, + "sequence": 7 + } +} } ``` @@ -371,13 +233,11 @@ Returns on failure: The TokenAPI exposes all functionality needed to query account balances and send transactions. -### /bank/balance/{account} - GET +### GET /bank/balance/{account} -url: /bank/balance/{account} - -Functionality: Query the specified account. - -Returns on success: +- **URL**: `/bank/balance/{account}` +- **Functionality**: Query the specified account's balance. +- Returns on success: ```json { @@ -392,34 +252,30 @@ Returns on success: } ``` -Returns on error: +### POST /bank/transfers + +- **URL**: `/bank/transfers` +- **Functionality**: Create a transfer in the bank module. +- POST Body: ```json { - "rest api":"2.0", - "code":500, - "error":"Could not find any balance for the specified account.", - "result":{} + "amount": [ + { + "denom": "string", + "amount": 64, + } + ], + "name": "string", + "password": "string", + "chain_id": "string", + "account_number": 64, + "sequence": 64, + "gas": 64, } ``` -### /bank/create_transfer - POST - -url: /bank/create_transfer - -Functionality: Create a transfer in the bank module. - -Parameters: - -| Parameter | Type | Default | Required | Description | -| ------------ | ------ | ------- | -------- | ------------------------- | -| sender | string | null | true | Address of sender | -| receiver | string | null | true | address of receiver | -| chain_id | string | null | true | chain id | -| amount | int | null | true | amount of the token | -| denomonation | string | null | true | denomonation of the token | - -Returns on success: +- Returns on success: ```json { @@ -432,32 +288,19 @@ Returns on success: } ``` -Returns on failure: - -```json -{ - "rest api":"2.0", - "code":500, - "error":"Could not create the transaction.", - "result":{} -} -``` - ## ICS21 - StakingAPI The StakingAPI exposes all functionality needed for validation and delegation in Proof-of-Stake. -### /stake/delegators/{delegatorAddr} - GET +### GET /stake/delegators/{delegatorAddr} -url: /stake/delegators/{delegatorAddr} - -Functionality: Get all delegations (delegation, undelegation) from a delegator. - -Returns on success: +- **URL**: `/stake/delegators/{delegatorAddr}` +- **Functionality**: Get all delegations (delegation, undelegation) from a delegator. +- Returns on success: ```json { - "rest api":"2.0", + "rest api":"2.1", "code":200, "error":"", "result": { @@ -468,84 +311,45 @@ Returns on success: } ``` -Returns on error: +### GET /stake/delegators/{delegatorAddr}/validators + +- **URL**: `/stake/delegators/{delegatorAddr}/validators` +- **Functionality**: Query all validators that a delegator is bonded to. +- Returns on success: ```json { - "rest api":"2.0", - "code":500, - "error":"Could not find any balance for the specified account.", - "result":{} -} -``` - -### /stake/delegators/{delegatorAddr}/validators - GET - -url: /stake/delegators/{delegatorAddr}/validators - -Functionality: Query all validators that a delegator is bonded to. - -Returns on success: - -```json -{ - "rest api":"2.0", + "rest api":"2.1", "code":200, "error":"", "result":{} } ``` -Returns on failure: +### GET /stake/delegators/{delegatorAddr}/validators/{validatorAddr} + +- **URL**: `/stake/delegators/{delegatorAddr}/validators/{validatorAddr}` +- **Functionality**: Query a validator that a delegator is bonded to +- Returns on success: ```json { - "rest api":"2.0", - "code":500, - "error":"TODO", - "result":{} -} -``` - -### /stake/delegators/{delegatorAddr}/validators/{validatorAddr} - GET - -url: /stake/delegators/{delegatorAddr}/validators/{validatorAddr} - -Functionality: Query a validator that a delegator is bonded to - -Returns on success: - -```json -{ - "rest api":"2.0", + "rest api":"2.1", "code":200, "error":"", "result":{} } ``` -Returns on failure: +### GET /stake/delegators/{delegatorAddr}/txs + +- **URL**: `/stake/delegators/{delegatorAddr}/txs` +- **Functionality**: Get all staking txs (i.e msgs) from a delegator. +- Returns on success: ```json { - "rest api":"2.0", - "code":500, - "error":"TODO", - "result":{} -} -``` - -### /stake/delegators/{delegatorAddr}/txs - GET - -url: /stake/delegators/{delegatorAddr}/txs - -Functionality: Get all staking txs (i.e msgs) from a delegator. - -Returns on success: - -```json -{ - "rest api":"2.0", + "rest api":"2.1", "code":200, "error":"", "result":{ @@ -554,28 +358,68 @@ Returns on success: } ``` -Returns on failure: +### POST /stake/delegators/{delegatorAddr}/delegations + +- **URL**: `/stake/delegators/{delegatorAddr}/delegations` +- **Functionality**: Submit or edit a delegation. + +- POST Body: ```json { - "rest api":"2.0", - "code":500, - "error":"Could not create the transaction.", - "result":{} + "name": "string", + "password": "string", + "chain_id": "string", + "account_number": 64, + "sequence": 64, + "gas": 64, + "delegations": [ + { + "delegator_addr": "string", + "validator_addr": "string", + "delegation": { + "denom": "string", + "amount": 1234 + } + } + ], + "begin_unbondings": [ + { + "delegator_addr": "string", + "validator_addr": "string", + "shares": "string", + } + ], + "complete_unbondings": [ + { + "delegator_addr": "string", + "validator_addr": "string", + } + ], + "begin_redelegates": [ + { + "delegator_addr": "string", + "validator_src_addr": "string", + "validator_dst_addr": "string", + "shares": "string", + } + ], + "complete_redelegates": [ + { + "delegator_addr": "string", + "validator_src_addr": "string", + "validator_dst_addr": "string", + } + ] } + ``` -### /stake/delegators/{delegatorAddr}/delegations - POST - -url: /stake/delegators/{delegatorAddr}/delegations - -Functionality: Submit a delegation. - -Returns on success: +- Returns on success: ```json { - "rest api":"2.0", + "rest api":"2.1", "code":200, "error":"", "result":{ @@ -584,28 +428,15 @@ Returns on success: } ``` -Returns on failure: +### GET /stake/delegators/{delegatorAddr}/delegations/{validatorAddr} + +- **URL**: `/stake/delegators/{delegatorAddr}/delegations/{validatorAddr}` +- **Functionality**: Query the current delegation status between a delegator and a validator. +- Returns on success: ```json { - "rest api":"2.0", - "code":500, - "error":"Could not create the transaction.", - "result":{} -} -``` - -### /stake/delegators/{delegatorAddr}/delegations/{validatorAddr} - GET - -url: /stake/delegators/{delegatorAddr}/delegations/{validatorAddr} - -Functionality: Query the current delegation status between a delegator and a validator. - -Returns on success: - -```json -{ - "rest api":"2.0", + "rest api":"2.1", "code":200, "error":"", "result":{ @@ -614,28 +445,15 @@ Returns on success: } ``` -Returns on failure: +### GET /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr} + +- **URL**: `/stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}` +- **Functionality**: Query all unbonding delegations between a delegator and a validator. +- Returns on success: ```json { - "rest api":"2.0", - "code":500, - "error":"Could not create the transaction.", - "result":{} -} -``` - -### /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr} - GET - -url: /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr} - -Functionality: Query all unbonding delegations between a delegator and a validator. - -Returns on success: - -```json -{ - "rest api":"2.0", + "rest api":"2.1", "code":200, "error":"", "result":{ @@ -644,28 +462,15 @@ Returns on success: } ``` -Returns on failure: +### GET /stake/validators + +- **URL**: `/stake/validators` +- **Functionality**: Get all validator candidates. +- Returns on success: ```json { - "rest api":"2.0", - "code":500, - "error":"Could not create the transaction.", - "result":{} -} -``` - -### /stake/validators - GET - -url: /stake/validators - -Functionality: Get all validator candidates. - -Returns on success: - -```json -{ - "rest api":"2.0", + "rest api":"2.1", "code":200, "error":"", "result":{ @@ -674,28 +479,15 @@ Returns on success: } ``` -Returns on failure: +### GET /stake/validators/{validatorAddr} + +- **URL**: `/stake/validators/{validatorAddr}` +- **Functionality**: Query the information from a single validator. +- Returns on success: ```json { - "rest api":"2.0", - "code":500, - "error":"Could not create the transaction.", - "result":{} -} -``` - -### /stake/validators/{validatorAddr} - GET - -url: /stake/validators/{validatorAddr} - -Functionality: Query the information from a single validator. - -Returns on success: - -```json -{ - "rest api":"2.0", + "rest api":"2.1", "code":200, "error":"", "result":{ @@ -704,13 +496,359 @@ Returns on success: } ``` -Returns on failure: +### GET /stake/parameters + +- **URL**: `/stake/parameters` +- **Functionality**: Get the current value of staking parameters. +- Returns on success: ```json { - "rest api":"2.0", - "code":500, - "error":"Could not create the transaction.", - "result":{} + "rest api":"2.1", + "code":200, + "error":"", + "result":{ + "inflation_rate_change": 1300000000, + "inflation_max": 2000000000, + "inflation_min": 700000000, + "goal_bonded": 6700000000, + "unbonding_time": "72h0m0s", + "max_validators": 100, + "bond_denom": "atom" + } +} +``` + +### GET /stake/pool + +- **URL**: `/stake/pool` +- **Functionality**: Get the current value of the dynamic parameters of the current state (*i.e* `Pool`). +- Returns on success: + +```json +{ + "rest api":"2.1", + "code":200, + "error":"", + "result":{ + "loose_tokens": 0, + "bonded_tokens": 0, + "inflation_last_time": "1970-01-01 01:00:00 +0100 CET", + "inflation": 700000000, + "date_last_commission_reset": 0, + "prev_bonded_shares": 0, + } +} +``` + +## ICS22 - GovernanceAPI + +The GovernanceAPI exposes all functionality needed for casting votes on plain text, software upgrades and parameter change proposals. + +### GET /gov/proposals + +- **URL**: `/gov/proposals` +- **Functionality**: Query all submited proposals +- Response on Success: + +```json +{ + "rest api":"2.2", + "code":200, + "error":"", + "result":{ + "proposals":[ + "TODO" + ] + } +} +``` + +### POST /gov/proposals + +- **URL**: `/gov/proposals` +- **Functionality**: Submit a proposal +- POST Body: + +```js +{ + "base_req": { + // Name of key to use + "name": "string", + // Password for that key + "password": "string", + "chain_id": "string", + "account_number": 64, + "sequence": 64, + "gas": 64 + }, + // Title of the proposal + "title": "string", + // Description of the proposal + "description": "string", + // PlainTextProposal supported now. SoftwareUpgradeProposal and other types may be supported soon + "proposal_type": "string", + // A cosmosaccaddr address + "proposer": "string", + "initial_deposit": [ + { + "denom": "string", + "amount": 64, + } + ] +} +``` + +- Returns on success: + +```json +{ + "rest api":"2.2", + "code":200, + "error":"", + "result":{ + "TODO": "TODO", + } +} +``` + +### GET /gov/proposals/{proposal-id} + +- **URL**: `/gov/proposals/{proposal-id}` +- **Functionality**: Query a proposal +- Response on Success: + +```json +{ + "rest api":"2.2", + "code":200, + "error":"", + "result":{ + "proposal_id": 1, + "title": "Example title", + "description": "a larger description with the details of the proposal", + "proposal_type": "Text", + "proposal_status": "DepositPeriod", + "tally_result": { + "yes": 0, + "abstain": 0, + "no": 0, + "no_with_veto": 0 + }, + "submit_block": 5238512, + "total_deposit": {"atom": 50}, + "voting_start_block": -1 + } +} +``` + +### POST /gov/proposals/{proposal-id}/deposits + +- **URL**: `/gov/proposals/{proposal-id}/deposits` +- **Functionality**: Submit or rise a deposit to a proposal in order to make it active +- POST Body: + +```json +{ + "base_req": { + "name": "string", + "password": "string", + "chain_id": "string", + "account_number": 0, + "sequence": 0, + "gas": 0 + }, + "depositer": "string", + "amount": 0, +} +``` + +- Returns on success: + +```json +{ + "rest api":"2.2", + "code":200, + "error":"", + "result":{ + "TODO": "TODO", + } +} +``` + +### GET /gov/proposals/{proposal-id}/deposits/{address} + +- **URL**: `/gov/proposals/{proposal-id}/deposits/{address}` +- **Functionality**: Query a validator's deposit to submit a proposal +- Returns on success: + +```json +{ + "rest api":"2.2", + "code":200, + "error":"", + "result":{ + "amount": {"atom": 150}, + "depositer": "cosmosaccaddr1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd", + "proposal-id": 16 + } +} +``` + +### GET /gov/proposals/{proposal-id}/tally + +- **URL**: `/gov/proposals/{proposal-id}/tally` +- **Functionality**: Get the tally of a given proposal. +- Returns on success: + +```json +{ + "rest api":"2.2", + "code":200, + "error":"", + "result": { + "yes": 0, + "abstain": 0, + "no": 0, + "no_with_veto": 0 + } +} +``` + + + +### GET /gov/proposals/{proposal-id}/votes + +- **URL**: `/gov/proposals/{proposal-id}/votes` +- **Functionality**: Query all votes from a specific proposal +- Returns on success: + +```json +{ + "rest api":"2.2", + "code":200, + "error":"", + "result": [ + { + "proposal-id": 1, + "voter": "cosmosaccaddr1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd", + "option": "no_with_veto" + }, + { + "proposal-id": 1, + "voter": "cosmosaccaddr1849m9wncrqp6v4tkss6a3j8uzvuv0cp7f75lrq", + "option": "yes" + }, + ] +} +``` + + + +### POST /gov/proposals/{proposal-id}/votes + +- **URL**: `/gov/proposals/{proposal-id}/votes` +- **Functionality**: Vote for a specific proposal +- POST Body: + +```js +{ + "base_req": { + "name": "string", + "password": "string", + "chain_id": "string", + "account_number": 0, + "sequence": 0, + "gas": 0 + }, + // A cosmosaccaddr address + "voter": "string", + // Value of the vote option `Yes`, `No` `Abstain`, `NoWithVeto` + "option": "string", +} +``` + +- Returns on success: + +```json +{ + "rest api":"2.2", + "code":200, + "error":"", + "result":{ + "TODO": "TODO", + } +} +``` + +### GET /gov/proposals/{proposal-id}/votes/{address} + +- **URL** : `/gov/proposals/{proposal-id}/votes/{address}` +- **Functionality**: Get the current `Option` submited by an address +- Returns on success: + +```json +{ + "rest api":"2.2", + "code":200, + "error":"", + "result":{ + "proposal-id": 1, + "voter": "cosmosaccaddr1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd", + "option": "no_with_veto" + } +} +``` + +## ICS23 - SlashingAPI + +The SlashingAPI exposes all functionalities needed to slash (*i.e* penalize) validators and delegators in Proof-of-Stake. The penalization is a fine of the staking coin and jail time, defined by governance parameters. During the jail period, the penalized validator is "jailed". + +### GET /slashing/validator/{validatorAddr}/signing-info + +- **URL**: `/slashing/validator/{validatorAddr}/signing-info` +- **Functionality**: Query the information from a single validator. +- Returns on success: + +```json +{ + "rest api":"2.3", + "code":200, + "error":"", + "result":{ + "transaction":"TODO" + } +} +``` + +### POST /slashing/validators/{validatorAddr}/unjail + +- **URL**: `/slashing/validators/{validatorAddr}/unjail` +- **Functionality**: Submit a message to unjail a validator after it has been penalized. +- POST Body: + +```js +{ + // Name of key to use + "name": "string", + // Password for that key + "password": "string", + "chain_id": "string", + "account_number": 64, + "sequence": 64, + "gas": 64, +} +``` + +- Returns on success: + +```json +{ + "rest api":"2.3", + "code":200, + "error":"", + "result":{ + "transaction":"TODO" + } } ``` diff --git a/docs/sdk/clients.md b/docs/sdk/clients.md index 5d02548a27..be42a46dba 100644 --- a/docs/sdk/clients.md +++ b/docs/sdk/clients.md @@ -12,27 +12,25 @@ `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 +### Keys + +#### Key Types 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` - - `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` -### Generate Keys +#### Generate Keys 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. @@ -66,10 +64,14 @@ gaiad tendermint show-validator 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 +### Account + +#### Get Tokens 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. +#### Query Account balance + After receiving tokens to your address, you can view your account's balance by typing: ```bash @@ -79,7 +81,6 @@ gaiacli account ::: warning 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. -We're working on improving our error messages! ::: ### Send Tokens @@ -87,7 +88,7 @@ We're working on improving our error messages! ```bash gaiacli send \ --amount=10faucetToken \ - --chain-id=gaia-7005 \ + --chain-id= \ --name= \ --to= ``` @@ -109,20 +110,40 @@ You can also check your balance at a given block by using the `--block` flag: gaiacli account --block= ``` -### Delegate +### Staking + +#### Set up a Validator + +Please refer to the [Validator Setup](https://cosmos.network/docs/validators/validator-setup.html) section for a more complete guide on how to set up a validator-candidate. + +#### Delegate to a Validator On the upcoming mainnet, you can delegate `atom` to a validator. These [delegators](/resources/delegators-faq) 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 +##### Query Validators -On the testnet, we delegate `steak` instead of `atom`. Here's how you can bond tokens to a testnet validator: +You can query the list of all validators of a specific chain: + +```bash +gaiacli stake validators +``` + +If you want to get the information of a single validator you can check it with: + +```bash +gaiacli stake validator +``` + +#### Bond Tokens + +On the testnet, we delegate `steak` instead of `atom`. Here's how you can bond tokens to a testnet validator (*i.e.* delegate): ```bash gaiacli stake delegate \ --amount=10steak \ - --address-validator=$(gaiad tendermint show-validator) \ + --validator=$(gaiad tendermint show-validator) \ --name= \ - --chain-id=gaia-7005 + --chain-id= ``` 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. @@ -131,33 +152,232 @@ While tokens are bonded, they are pooled with all the other bonded tokens in the Don't use more `steak` thank you have! You can always get more by using the [Faucet](https://faucetcosmos.network/)! ::: -### Unbond Tokens +##### Query Delegations -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`\). +Once submitted a delegation to a validator, you can see it's information by using the following command: + +```bash +gaiacli stake delegation \ + --address-delegator= \ + --address-validator=$(gaiad tendermint show-validator) +``` + +Or if you want to check all your current delegations with disctinct validators: + +```bash +gaiacli stake delegations +``` + +You can also get previous delegation(s) status by adding the `--height` flag. + +#### Unbond Tokens + +If for any reason the validator misbehaves, or you just want to unbond a certain amount of tokens, use this following command. You can unbond a specific `shares-amount` (eg:`12.1`\) or a `shares-percent` (eg:`25`) with the corresponding flags. ```bash gaiacli stake unbond begin \ --address-validator=$(gaiad tendermint show-validator) \ - --shares=MAX \ - --name= \ - --chain-id=gaia-7005 + --shares-percent=100 \ + --from= \ + --chain-id= ``` -Later you must use the `gaiacli stake unbond complete` command to finish -unbonding at which point you can can check your balance and your stake -delegation to see that the unbonding went through successfully. +Later you must complete the unbonding process by using the `gaiacli stake unbond complete` command: ```bash -gaiacli account - -gaiacli stake delegation \ - --address-delegator= \ +gaiacli stake unbond complete \ --address-validator=$(gaiad tendermint show-validator) \ - --chain-id=gaia-7005 + --from= \ + --chain-id= ``` -## Light Client Daemon +##### Query Unbonding-Delegations + +Once you begin an unbonding-delegation, you can see it's information by using the following command: + +```bash +gaiacli stake unbonding-delegation \ + --address-delegator= \ + --address-validator=$(gaiad tendermint show-validator) \ +``` + +Or if you want to check all your current unbonding-delegations with disctinct validators: + +```bash +gaiacli stake unbonding-delegations +``` + +You can also get previous unbonding-delegation(s) status by adding the `--height` flag. + +#### Redelegate Tokens + +A redelegation is a type delegation that allows you to bond illiquid tokens from one validator to another: + +```bash +gaiacli stake redelegate begin \ + --address-validator-source=$(gaiad tendermint show-validator) \ + --address-validator-dest= \ + --shares-percent=50 \ + --from= \ + --chain-id= +``` + +Here you can also redelegate a specific `shares-amount` or a `shares-percent` with the corresponding flags. + +Later you must complete the redelegation process by using the `gaiacli stake redelegate complete` command: + +```bash +gaiacli stake unbond complete \ + --address-validator=$(gaiad tendermint show-validator) \ + --from= \ + --chain-id= +``` + +##### Query Redelegations + +Once you begin an redelegation, you can see it's information by using the following command: + +```bash +gaiacli stake redelegation \ + --address-delegator= \ + --address-validator-source=$(gaiad tendermint show-validator) \ + --address-validator-dest= \ +``` + +Or if you want to check all your current unbonding-delegations with disctinct validators: + +```bash +gaiacli stake redelegations +``` + +You can also get previous redelegation(s) status by adding the `--height` flag. + +### 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=<chain_id> +``` + +##### Query proposals + +Once created, you can now query information of the proposal: + +```bash +gaiacli gov query-proposal \ + --proposal-id=<proposal_id> +``` + +Or query all available proposals: + +```bash +gaiacli gov query-proposals +``` + +You can also query proposals filtered by `voter` or `depositer` by using the corresponding flags. + +#### 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 \ + --proposal-id=<proposal_id> \ + --depositer=<account_cosmosaccaddr> \ + --deposit=<200steak> \ + --from=<name> \ + --chain-id=<chain_id> +``` + +> _NOTE_: Proposals that don't meet this requirement will be deleted after `MaxDepositPeriod` is reached. + +#### 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 \ + --proposal-id=<proposal_id> \ + --voter=<account_cosmosaccaddr> \ + --option=<Yes/No/NoWithVeto/Abstain> \ + --from=<name> \ + --chain-id=<chain_id> +``` + +##### Query vote + +Check the vote with the option you just submitted: + +```bash +gaiacli gov query-vote \ + --proposal-id=<proposal_id> \ + --voter=<account_cosmosaccaddr> +``` + +#### Query Parameters + +You can get the current parameters that define high level settings for staking: + +``` +gaiacli stake parameters +``` + +With the above command you will get the values for: + +- Maximum and minumum Inflation rate +- Maximum annual change in inflation rate, +- Goal of bonded tokens (%) +- Unbonding time +- Maximum numbers of validators +- Coin denomination for staking + +All this values can be updated though a `governance` process by submitting a parameter change `proposal`. + +#### Query Pool + +A staking `Pool` defines the dynamic parameters of the current state. You can query them with the following command: + +``` +gaiacli stake pool +``` + +With the `pool` command you will get the values for: + +- Loose and bonded tokens +- Token supply +- Current anual inflation and the block in which the last inflation was processed +- Last recorded bonded shares + + +## Gaia-Lite ::: tip Note -🚧 We are actively working on documentation for the LCD. +🚧 We are actively working on documentation for Gaia-lite. ::: diff --git a/docs/sdk/core/app1.md b/docs/sdk/core/app1.md index 54121d05bf..a2978ffb08 100644 --- a/docs/sdk/core/app1.md +++ b/docs/sdk/core/app1.md @@ -469,7 +469,7 @@ Tendermint consensus engine. It would be initialized by a Genesis file, and it would be driven by blocks of transactions committed by the underlying Tendermint consensus. We'll talk more about ABCI and how this all works a bit later, but feel free to check the -[specification](https://github.com/tendermint/tendermint/blob/master/docs/abci-spec.md). +[specification](https://github.com/tendermint/tendermint/blob/master/docs/app-dev/abci-spec.md). We'll also see how to connect our app to a complete suite of components for running and using a live blockchain application. diff --git a/docs/sdk/core/app4.md b/docs/sdk/core/app4.md index 0724e5e7a8..b6596ef0cf 100644 --- a/docs/sdk/core/app4.md +++ b/docs/sdk/core/app4.md @@ -16,7 +16,7 @@ here we will introduce the other ABCI requests sent by Tendermint, and how we can use them to build more advanced applications. For a more complete depiction of the ABCI and how its used, see [the -specification](https://github.com/tendermint/tendermint/blob/master/docs/abci-spec.md) +specification](https://github.com/tendermint/tendermint/blob/master/docs/app-dev/abci-spec.md) ## InitChain diff --git a/docs/sdk/modules.md b/docs/sdk/modules.md index b9249cf3e9..7df8fb2bb0 100644 --- a/docs/sdk/modules.md +++ b/docs/sdk/modules.md @@ -6,7 +6,7 @@ The Cosmos SDK has all the necessary pre-built modules to add functionality on top of a `BaseApp`, which is the template to build a blockchain dApp in Cosmos. In this context, a `module` is a fundamental unit in the Cosmos SDK. -Each module is an extension of the `BaseApp`'s functionalities that defines transactions, handles application state and manages the state transition logic. Each module also contains handlers for messages and transactions, as well as REST and CLI for secure user interactions. +Each module is an extension of the `BaseApp`'s functionalities that defines transactions, handles application state and manages the state transition logic. Each module also contains handlers for messages and transactions, queriers for handling query requests, as well as REST and CLI for secure user interactions. Some of the most important modules in the SDK are: diff --git a/docs/sdk/sdk-by-examples/simple-governance/submit-proposal.md b/docs/sdk/sdk-by-examples/simple-governance/submit-proposal.md index bb9eb289f4..57571c1511 100644 --- a/docs/sdk/sdk-by-examples/simple-governance/submit-proposal.md +++ b/docs/sdk/sdk-by-examples/simple-governance/submit-proposal.md @@ -6,6 +6,23 @@ Uuse the CLI to create a new proposal: simplegovcli propose --title="Voting Period update" --description="Should we change the proposal voting period to 3 weeks?" --deposit=300Atoms ``` +Or, via a json file: + +```bash +simplegovcli propose --proposal="path/to/proposal.json" +``` + +Where proposal.json contains: + +```json +{ + "title": "Voting Period Update", + "description": "Should we change the proposal voting period to 3 weeks?", + "type": "Text", + "deposit": "300Atoms" +} +``` + Get the details of your newly created proposal: ```bash diff --git a/docs/spec/auth/vesting.md b/docs/spec/auth/vesting.md new file mode 100644 index 0000000000..c5c25ecaed --- /dev/null +++ b/docs/spec/auth/vesting.md @@ -0,0 +1,159 @@ +## Vesting + +### Intro and Requirements + +This paper specifies vesting account implementation for the Cosmos Hub. +The requirements for this vesting account is that it should be initialized during genesis with +a starting balance X coins and a vesting endtime T. The owner of this account should be able to delegate to validators +and vote with locked coins, however they cannot send locked coins to other accounts until those coins have been unlocked. +The vesting account should also be able to spend any coins it receives from other users. +Thus, the bank module's `MsgSend` handler should error if a vesting account is trying to send an amount that exceeds their +unlocked coin amount. + +### Implementation + +##### Vesting Account implementation + +NOTE: `Now = ctx.BlockHeader().Time` + +```go +type VestingAccount interface { + Account + AssertIsVestingAccount() // existence implies that account is vesting. + + // Calculates amount of coins that can be sent to other accounts given the current time + SendableCoins(sdk.Context) sdk.Coins +} + +// Implements Vesting Account +// Continuously vests by unlocking coins linearly with respect to time +type ContinuousVestingAccount struct { + BaseAccount + OriginalVestingCoins sdk.Coins // Coins in account on Initialization + ReceivedCoins sdk.Coins // Coins received from other accounts + SentCoins sdk.Coins // Coins sent to other accounts + + // StartTime and EndTime used to calculate how much of OriginalCoins is unlocked at any given point + StartTime time.Time + EndTime time.Time +} + +// Uses time in context to calculate total unlocked coins +SendableCoins(vacc ContinuousVestingAccount, ctx sdk.Context) sdk.Coins: + + // Coins unlocked by vesting schedule + unlockedCoins := ReceivedCoins - SentCoins + OriginalVestingCoins * (Now - StartTime) / (EndTime - StartTime) + + // Must still check for currentCoins constraint since some unlocked coins may have been delegated. + currentCoins := vacc.BaseAccount.GetCoins() + + // min will return sdk.Coins with each denom having the minimum amount from unlockedCoins and currentCoins + return min(unlockedCoins, currentCoins) + +``` + +The `VestingAccount` interface is used to assert that an account is a vesting account like so: + +```go +vacc, ok := acc.(VestingAccount); ok +``` + +as well as to calculate the SendableCoins at any given moment. + +The `ContinuousVestingAccount` struct implements the Vesting account interface. It uses `OriginalVestingCoins`, `ReceivedCoins`, +`SentCoins`, `StartTime`, and `EndTime` to calculate how many coins are sendable at any given point. +Since the vesting restrictions need to be implemented on a per-module basis, the `ContinuousVestingAccount` implements +the `Account` interface exactly like `BaseAccount`. Thus, `ContinuousVestingAccount.GetCoins()` will return the total of +both locked coins and unlocked coins currently in the account. Delegated coins are deducted from `Account.GetCoins()`, but do not count against unlocked coins because they are still at stake and will be reinstated (partially if slashed) after waiting the full unbonding period. + +##### Changes to Keepers/Handler + +Since a vesting account should be capable of doing everything but sending with its locked coins, the restriction should be +handled at the `bank.Keeper` level. Specifically in methods that are explicitly used for sending like +`sendCoins` and `inputOutputCoins`. These methods must check that an account is a vesting account using the check described above. + +```go +if acc is VestingAccount and Now < vestingAccount.EndTime: + // Check if amount is less than currently allowed sendable coins + if msg.Amount > vestingAccount.SendableCoins(ctx) then fail + else: + vestingAccount.SentCoins += msg.Amount + +else: + // Account has fully vested, treat like regular account + if msg.Amount > account.GetCoins() then fail + +// All checks passed, send the coins +SendCoins(inputs, outputs) + +``` + +Coins that are sent to a vesting account after initialization by users sending them coins should be spendable +immediately after receiving them. Thus, handlers (like staking or bank) that send coins that a vesting account did not +originally own should increment `ReceivedCoins` by the amount sent. +Unlocked coins that are sent to other accounts will increment the vesting account's `SentCoins` attribute. + +CONTRACT: Handlers SHOULD NOT update `ReceivedCoins` if they were originally sent from the vesting account. For example, if a vesting account unbonds from a validator, their tokens should be added back to account but staking handlers SHOULD NOT update `ReceivedCoins`. +However when a user sends coins to vesting account, then `ReceivedCoins` SHOULD be incremented. + +### Initializing at Genesis + +To initialize both vesting accounts and base accounts, the `GenesisAccount` struct will include an EndTime. Accounts meant to be +BaseAccounts will have `EndTime = 0`. The `initChainer` method will parse the GenesisAccount into BaseAccounts and VestingAccounts +as appropriate. + +```go +type GenesisAccount struct { + Address sdk.AccAddress `json:"address"` + GenesisCoins sdk.Coins `json:"coins"` + EndTime int64 `json:"lock"` +} + +initChainer: + for gacc in GenesisAccounts: + baseAccount := BaseAccount{ + Address: gacc.Address, + Coins: gacc.GenesisCoins, + } + if gacc.EndTime != 0: + vestingAccount := ContinuouslyVestingAccount{ + BaseAccount: baseAccount, + OriginalVestingCoins: gacc.GenesisCoins, + StartTime: RequestInitChain.Time, + EndTime: gacc.EndTime, + } + AddAccountToState(vestingAccount) + else: + AddAccountToState(baseAccount) + +``` + +### Formulas + +`OriginalVestingCoins`: Amount of coins in account at Genesis + +`CurrentCoins`: Coins currently in the baseaccount (both locked and unlocked: `vestingAccount.GetCoins`) + +`ReceivedCoins`: Coins received from other accounts (always unlocked) + +`LockedCoins`: Coins that are currently locked + +`Delegated`: Coins that have been delegated (no longer in account; may be locked or unlocked) + +`Sent`: Coins sent to other accounts (MUST be unlocked) + +Maximum amount of coins vesting schedule allows to be sent: + +`ReceivedCoins - SentCoins + OriginalVestingCoins * (Now - StartTime) / (EndTime - StartTime)` + +`ReceivedCoins - SentCoins + OriginalVestingCoins - LockedCoins` + +Coins currently in Account: + +`CurrentCoins = OriginalVestingCoins + ReceivedCoins - Delegated - Sent` + +`CurrentCoins = vestingAccount.GetCoins()` + +**Maximum amount of coins spendable right now:** + +`min( ReceivedCoins - SentCoins + OriginalVestingCoins - LockedCoins, CurrentCoins )` diff --git a/docs/spec/slashing/state.md b/docs/spec/slashing/state.md index 1df9d5022d..8bbb22c76a 100644 --- a/docs/spec/slashing/state.md +++ b/docs/spec/slashing/state.md @@ -47,5 +47,5 @@ type ValidatorSigningInfo struct { Where: * `StartHeight` is set to the height that the candidate became an active validator (with non-zero voting power). * `IndexOffset` is incremented each time the candidate was a bonded validator in a block (and may have signed a precommit or not). -* `JailedUntil` is set whenever the candidate is revoked due to downtime +* `JailedUntil` is set whenever the candidate is jailed due to downtime * `SignedBlocksCounter` is a counter kept to avoid unnecessary array reads. `SignedBlocksBitArray.Sum() == SignedBlocksCounter` always. diff --git a/docs/spec/staking/end_block.md b/docs/spec/staking/end_block.md index 0eb557fecc..c2fe143baf 100644 --- a/docs/spec/staking/end_block.md +++ b/docs/spec/staking/end_block.md @@ -4,7 +4,7 @@ The Tendermint validator set may be updated by state transitions that run at the end of every block. The Tendermint validator set may be changed by -validators either being revoked due to inactivity/unexpected behaviour (covered +validators either being jailed due to inactivity/unexpected behaviour (covered in slashing) or changed in validator power. Determining which validator set changes must be made occurs during staking transactions (and slashing transactions) - during end-block the already accounted changes are applied and diff --git a/docs/spec/staking/state.md b/docs/spec/staking/state.md index 46f18ed786..58bd67cd5e 100644 --- a/docs/spec/staking/state.md +++ b/docs/spec/staking/state.md @@ -71,7 +71,7 @@ validator. ```golang type Validator struct { ConsensusPubKey crypto.PubKey // Tendermint consensus pubkey of validator - Revoked bool // has the validator been revoked? + Jailed bool // has the validator been jailed? Status sdk.BondStatus // validator status (bonded/unbonding/unbonded) Tokens sdk.Dec // delegated tokens (incl. self-delegation) diff --git a/docs/spec/staking/transactions.md b/docs/spec/staking/transactions.md index d1b6a3626b..ee2b976aec 100644 --- a/docs/spec/staking/transactions.md +++ b/docs/spec/staking/transactions.md @@ -1,7 +1,7 @@ ## Transaction Overview In this section we describe the processing of the transactions and the -corresponding updates to the state. Transactions: +corresponding updates to the state. Transactions: - TxCreateValidator - TxEditValidator - TxDelegation @@ -19,7 +19,7 @@ Other notes: - `getXxx`, `setXxx`, and `removeXxx` functions are used to retrieve and modify objects from the store - `sdk.Dec` refers to a decimal type specified by the SDK. - + ### TxCreateValidator - triggers: `distribution.CreateValidatorDistribution` @@ -28,39 +28,39 @@ A validator is created using the `TxCreateValidator` transaction. ```golang type TxCreateValidator struct { - OwnerAddr sdk.Address + Operator sdk.Address ConsensusPubKey crypto.PubKey GovernancePubKey crypto.PubKey - SelfDelegation coin.Coin + SelfDelegation coin.Coin Description Description Commission sdk.Dec CommissionMax sdk.Dec CommissionMaxChange sdk.Dec } - + createValidator(tx TxCreateValidator): - validator = getValidator(tx.OwnerAddr) + validator = getValidator(tx.Operator) if validator != nil return // only one validator per address - - validator = NewValidator(OwnerAddr, ConsensusPubKey, GovernancePubKey, Description) + + validator = NewValidator(operatorAddr, ConsensusPubKey, GovernancePubKey, Description) init validator poolShares, delegatorShares set to 0 init validator commision fields from tx validator.PoolShares = 0 - + setValidator(validator) - - txDelegate = TxDelegate(tx.OwnerAddr, tx.OwnerAddr, tx.SelfDelegation) + + txDelegate = TxDelegate(tx.Operator, tx.Operator, tx.SelfDelegation) delegate(txDelegate, validator) // see delegate function in [TxDelegate](TxDelegate) return -``` +``` ### TxEditValidator If either the `Description` (excluding `DateBonded` which is constant), `Commission`, or the `GovernancePubKey` need to be updated, the -`TxEditCandidacy` transaction should be sent from the owner account: +`TxEditCandidacy` transaction should be sent from the operator account: ```golang type TxEditCandidacy struct { @@ -68,34 +68,34 @@ type TxEditCandidacy struct { Commission sdk.Dec Description Description } - + editCandidacy(tx TxEditCandidacy): validator = getValidator(tx.ValidatorAddr) - - if tx.Commission > CommissionMax || tx.Commission < 0 then fail + + if tx.Commission > CommissionMax || tx.Commission < 0 then fail if rateChange(tx.Commission) > CommissionMaxChange then fail validator.Commission = tx.Commission if tx.GovernancePubKey != nil validator.GovernancePubKey = tx.GovernancePubKey if tx.Description != nil validator.Description = tx.Description - + setValidator(store, validator) return ``` - + ### TxDelegate - + - triggers: `distribution.CreateOrModDelegationDistribution` Within this transaction the delegator provides coins, and in return receives some amount of their validator's delegator-shares that are assigned to -`Delegation.Shares`. +`Delegation.Shares`. ```golang type TxDelegate struct { - DelegatorAddr sdk.Address - ValidatorAddr sdk.Address - Amount sdk.Coin + DelegatorAddr sdk.Address + ValidatorAddr sdk.Address + Amount sdk.Coin } delegate(tx TxDelegate): @@ -104,14 +104,14 @@ delegate(tx TxDelegate): delegation = getDelegatorBond(DelegatorAddr, ValidatorAddr) if delegation == nil then delegation = NewDelegation(DelegatorAddr, ValidatorAddr) - + validator, pool, issuedDelegatorShares = validator.addTokensFromDel(tx.Amount, pool) delegation.Shares += issuedDelegatorShares - + setDelegation(delegation) updateValidator(validator) setPool(pool) - return + return ``` ### TxStartUnbonding @@ -120,28 +120,28 @@ Delegator unbonding is defined with the following transaction: ```golang type TxStartUnbonding struct { - DelegatorAddr sdk.Address - ValidatorAddr sdk.Address - Shares string + DelegatorAddr sdk.Address + ValidatorAddr sdk.Address + Shares string } -startUnbonding(tx TxStartUnbonding): +startUnbonding(tx TxStartUnbonding): delegation, found = getDelegatorBond(store, sender, tx.PubKey) - if !found == nil return - + if !found == nil return + if bond.Shares < tx.Shares return ErrNotEnoughBondShares validator, found = GetValidator(tx.ValidatorAddr) if !found { - return err + return err bond.Shares -= tx.Shares revokeCandidacy = false if bond.Shares.IsZero() { - if bond.DelegatorAddr == validator.Owner && validator.Revoked == false + if bond.DelegatorAddr == validator.Operator && validator.Revoked == false revokeCandidacy = true removeDelegation( bond) @@ -162,7 +162,7 @@ startUnbonding(tx TxStartUnbonding): validator = updateValidator(validator) if validator.DelegatorShares == 0 { - removeValidator(validator.Owner) + removeValidator(validator.Operator) return ``` @@ -185,7 +185,7 @@ redelegationComplete(tx TxRedelegate): returnTokens = ExpectedTokens * tx.startSlashRatio/validator.SlashRatio AddCoins(unbonding.DelegatorAddr, returnTokens) removeUnbondingDelegation(unbonding) - return + return ``` ### TxRedelegation @@ -206,20 +206,20 @@ type TxRedelegate struct { redelegate(tx TxRedelegate): pool = getPool() - delegation = getDelegatorBond(tx.DelegatorAddr, tx.ValidatorFrom.Owner) + delegation = getDelegatorBond(tx.DelegatorAddr, tx.ValidatorFrom.Operator) if delegation == nil - return - - if delegation.Shares < tx.Shares - return + return + + if delegation.Shares < tx.Shares + return delegation.shares -= Tx.Shares validator, pool, createdCoins = validator.RemoveShares(pool, tx.Shares) setPool(pool) - - redelegation = newRedelegation(tx.DelegatorAddr, tx.validatorFrom, + + redelegation = newRedelegation(tx.DelegatorAddr, tx.validatorFrom, tx.validatorTo, tx.Shares, createdCoins, tx.CompletedTime) setRedelegation(redelegation) - return + return ``` ### TxCompleteRedelegation @@ -239,7 +239,7 @@ redelegationComplete(tx TxRedelegate): redelegation = getRedelegation(tx.DelegatorAddr, tx.validatorFrom, tx.validatorTo) if redelegation.CompleteTime >= CurrentBlockTime && redelegation.CompleteHeight >= CurrentBlockHeight removeRedelegation(redelegation) - return + return ``` ### Update Validators @@ -273,11 +273,11 @@ updateBondedValidators(newValidator Validator) (updatedVal Validator) // use the validator provided because it has not yet been updated // in the main validator store - ownerAddr = iterator.Value() - if bytes.Equal(ownerAddr, newValidator.Owner) { + operatorAddr = iterator.Value() + if bytes.Equal(operatorAddr, newValidator.Operator) { validator = newValidator else - validator = getValidator(ownerAddr) + validator = getValidator(operatorAddr) // if not previously a validator (and unrevoked), // kick the cliff validator / bond this new validator @@ -285,7 +285,7 @@ updateBondedValidators(newValidator Validator) (updatedVal Validator) kickCliffValidator = true validator = bondValidator(ctx, store, validator) - if bytes.Equal(ownerAddr, newValidator.Owner) { + if bytes.Equal(operatorAddr, newValidator.Operator) { updatedVal = validator bondedValidatorsCount++ @@ -316,7 +316,7 @@ unbondValidator(ctx Context, store KVStore, validator Validator) } // perform all the store operations for when a validator status becomes bonded -bondValidator(ctx Context, store KVStore, validator Validator) Validator +bondValidator(ctx Context, store KVStore, validator Validator) Validator pool = GetPool(ctx) // set the status diff --git a/docs/validators/validator-setup.md b/docs/validators/validator-setup.md index dc3bf147f0..6fa4fefd21 100644 --- a/docs/validators/validator-setup.md +++ b/docs/validators/validator-setup.md @@ -1,10 +1,10 @@ # Validator Setup ::: warning Current Testnet -The current testnet is `gaia-7005`. +The current testnet is `gaia-8000`. ::: -Before setting up your validator node, make sure you've already gone through the [Full Node Setup](/getting-started/full-node.md) guide. +Before setting up your validator node, make sure you've already gone through the [Full Node Setup](/docs/getting-started/full-node.md) guide. ## Running a Validator Node @@ -34,7 +34,7 @@ gaiacli stake create-validator \ --pubkey=$(gaiad tendermint show-validator) \ --address-validator=<account_cosmosaccaddr> --moniker="choose a moniker" \ - --chain-id=gaia-7005 \ + --chain-id=<chain_id> \ --name=<key_name> ``` @@ -46,12 +46,12 @@ The `--identity` can be used as to verify identity with systems like Keybase or ```bash gaiacli stake edit-validator - --address-validator=<account_cosmosaccaddr> + --validator=<account_cosmosaccaddr> --moniker="choose a moniker" \ --website="https://cosmos.network" \ --identity=6A0D65E29A4CBC8E --details="To infinity and beyond!" - --chain-id=gaia-7005 \ + --chain-id=<chain_id> \ --name=<key_name> ``` @@ -60,9 +60,28 @@ gaiacli stake edit-validator View the validator's information with this command: ```bash -gaiacli stake validator \ - --address-validator=<account_cosmosaccaddr> \ - --chain-id=gaia-7005 +gaiacli stake validator <account_cosmosaccaddr> +``` + +### Track Validator Signing Information + +In order to keep track of a validator's signatures in the past you can do so by using the `signing-info` command: + +```bash +gaiacli stake signing-information <validator-pubkey>\ + --chain-id=<chain_id> +``` + +### Unjail Validator + +When a validator is "jailed" for downtime, you must submit an `Unjail` transaction in order to be able to get block proposer rewards again (depends on the zone fee distribution). + +```bash +gaiacli stake unjail \ + --from=<key_name> \ + --chain-id=<chain_id> + --validator=<account_cosmosaccaddr> \ + --chain-id=gaia-6002 ``` ### Confirm Your Validator is Running @@ -70,12 +89,11 @@ gaiacli stake validator \ Your validator is active if the following command returns anything: ```bash -gaiacli advanced tendermint validator-set | grep "$(gaiad tendermint show-validator)" +gaiacli 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. - ::: warning Note To be in the validator set, you need to have more total voting power than the 100th validator. ::: @@ -84,7 +102,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-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. +Your validator has become auto-unbonded. In `gaia-8000`, 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: @@ -95,11 +113,11 @@ 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-7005 --name=<name> +gaiacli stake unjail <cosmosaccaddr> --chain-id=<chain_id> --name=<name> ``` ::: danger 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. +If you don't wait for `gaiad` to sync before running `unjail`, 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. diff --git a/examples/basecoin/cmd/basecli/main.go b/examples/basecoin/cmd/basecli/main.go index 82a2835157..23183c87a4 100644 --- a/examples/basecoin/cmd/basecli/main.go +++ b/examples/basecoin/cmd/basecli/main.go @@ -14,6 +14,7 @@ import ( authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" + slashingcmd "github.com/cosmos/cosmos-sdk/x/slashing/client/cli" stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" "github.com/spf13/cobra" "github.com/tendermint/tendermint/libs/cli" @@ -51,6 +52,13 @@ func main() { stakecmd.GetCmdQueryValidators("stake", cdc), stakecmd.GetCmdQueryDelegation("stake", cdc), stakecmd.GetCmdQueryDelegations("stake", cdc), + stakecmd.GetCmdQueryPool("stake", cdc), + stakecmd.GetCmdQueryParams("stake", cdc), + stakecmd.GetCmdQueryUnbondingDelegation("stake", cdc), + stakecmd.GetCmdQueryUnbondingDelegations("stake", cdc), + stakecmd.GetCmdQueryRedelegation("stake", cdc), + stakecmd.GetCmdQueryRedelegations("stake", cdc), + slashingcmd.GetCmdQuerySigningInfo("slashing", cdc), authcmd.GetAccountCmd("acc", cdc, types.GetAccountDecoder(cdc)), )...) @@ -63,6 +71,8 @@ func main() { stakecmd.GetCmdEditValidator(cdc), stakecmd.GetCmdDelegate(cdc), stakecmd.GetCmdUnbond("stake", cdc), + stakecmd.GetCmdRedelegate("stake", cdc), + slashingcmd.GetCmdUnjail(cdc), )...) // add proxy, version and key info diff --git a/examples/basecoin/types/account.go b/examples/basecoin/types/account.go index 671494311f..45774ae435 100644 --- a/examples/basecoin/types/account.go +++ b/examples/basecoin/types/account.go @@ -10,7 +10,7 @@ var _ auth.Account = (*AppAccount)(nil) // AppAccount is a custom extension for this application. It is an example of // extending auth.BaseAccount with custom fields. It is compatible with the -// stock auth.AccountStore, since auth.AccountStore uses the flexible go-amino +// stock auth.AccountMapper, since auth.AccountMapper uses the flexible go-amino // library. type AppAccount struct { auth.BaseAccount diff --git a/examples/democoin/mock/validator.go b/examples/democoin/mock/validator.go index 789a1cb6a7..bb936097cc 100644 --- a/examples/democoin/mock/validator.go +++ b/examples/democoin/mock/validator.go @@ -19,7 +19,7 @@ func (v Validator) GetStatus() sdk.BondStatus { } // Implements sdk.Validator -func (v Validator) GetOwner() sdk.AccAddress { +func (v Validator) GetOperator() sdk.AccAddress { return v.Address } @@ -44,7 +44,7 @@ func (v Validator) GetDelegatorShares() sdk.Dec { } // Implements sdk.Validator -func (v Validator) GetRevoked() bool { +func (v Validator) GetJailed() bool { return false } @@ -127,11 +127,11 @@ func (vs *ValidatorSet) Slash(ctx sdk.Context, pubkey crypto.PubKey, height int6 } // Implements sdk.ValidatorSet -func (vs *ValidatorSet) Revoke(ctx sdk.Context, pubkey crypto.PubKey) { +func (vs *ValidatorSet) Jail(ctx sdk.Context, pubkey crypto.PubKey) { panic("not implemented") } // Implements sdk.ValidatorSet -func (vs *ValidatorSet) Unrevoke(ctx sdk.Context, pubkey crypto.PubKey) { +func (vs *ValidatorSet) Unjail(ctx sdk.Context, pubkey crypto.PubKey) { panic("not implemented") } diff --git a/examples/democoin/x/assoc/validator_set.go b/examples/democoin/x/assoc/validator_set.go index 03ce506ea0..ad89aab192 100644 --- a/examples/democoin/x/assoc/validator_set.go +++ b/examples/democoin/x/assoc/validator_set.go @@ -93,6 +93,7 @@ func (valset ValidatorSet) Dissociate(ctx sdk.Context, base sdk.AccAddress, asso func (valset ValidatorSet) Associations(ctx sdk.Context, base sdk.AccAddress) (res []sdk.AccAddress) { res = make([]sdk.AccAddress, valset.maxAssoc) iter := sdk.KVStorePrefixIterator(valset.store, GetAssocPrefix(base)) + defer iter.Close() i := 0 for ; iter.Valid(); iter.Next() { key := iter.Key() diff --git a/examples/democoin/x/oracle/handler.go b/examples/democoin/x/oracle/handler.go index 3c78fc566b..1aaefc7e16 100644 --- a/examples/democoin/x/oracle/handler.go +++ b/examples/democoin/x/oracle/handler.go @@ -28,6 +28,7 @@ func (keeper Keeper) update(ctx sdk.Context, val sdk.Validator, valset sdk.Valid prefix := GetSignPrefix(p, keeper.cdc) store := ctx.KVStore(keeper.key) iter := sdk.KVStorePrefixIterator(store, prefix) + defer iter.Close() for ; iter.Valid(); iter.Next() { if valset.Validator(ctx, iter.Value()) != nil { store.Delete(iter.Key()) diff --git a/networks/local/README.md b/networks/local/README.md index 3a0f855be0..ef5e27803d 100644 --- a/networks/local/README.md +++ b/networks/local/README.md @@ -61,7 +61,7 @@ rm -rf ./build make build-linux # Create configuration -docker run -v `pwd`/build:/gaiad tendermint/gaiadnode testnet --o . --v 1 +docker run -v `pwd`/build:/gaiad tendermint/gaiadnode testnet -o . --v 1 #Run the node docker run -v `pwd`/build:/gaiad tendermint/gaiadnode diff --git a/networks/remote/ansible/roles/add-lcd/templates/gaiacli.service.j2 b/networks/remote/ansible/roles/add-lcd/templates/gaiacli.service.j2 index 4f189f8f5b..0d562163cc 100644 --- a/networks/remote/ansible/roles/add-lcd/templates/gaiacli.service.j2 +++ b/networks/remote/ansible/roles/add-lcd/templates/gaiacli.service.j2 @@ -8,7 +8,7 @@ Restart=on-failure User=gaiad Group=gaiad PermissionsStartOnly=true -ExecStart=/usr/bin/gaiacli advanced rest-server --laddr {{GAIAD_ADDRESS}} +ExecStart=/usr/bin/gaiacli rest-server --laddr {{GAIAD_ADDRESS}} ExecReload=/bin/kill -HUP $MAINPID KillSignal=SIGTERM diff --git a/scripts/localnet-blocks-test.sh b/scripts/localnet-blocks-test.sh new file mode 100755 index 0000000000..53df090ff7 --- /dev/null +++ b/scripts/localnet-blocks-test.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +CNT=0 +ITER=$1 +SLEEP=$2 +NUMBLOCKS=$3 +NODEADDR=$4 + +if [ -z "$1" ]; then + echo "Need to input number of iterations to run..." + exit 1 +fi + +if [ -z "$2" ]; then + echo "Need to input number of seconds to sleep between iterations" + exit 1 +fi + +if [ -z "$3" ]; then + echo "Need to input block height to declare completion..." + exit 1 +fi + +if [ -z "$4" ]; then + echo "Need to input node address to poll..." + exit 1 +fi + +while [ ${CNT} -lt $ITER ]; do + var=$(curl -s $NODEADDR:26657/status | jq -r '.result.sync_info.latest_block_height') + echo "Number of Blocks: ${var}" + if [ ! -z ${var} ] && [ ${var} -gt ${NUMBLOCKS} ]; then + echo "Number of blocks reached, exiting success..." + exit 0 + fi + let CNT=CNT+1 + sleep $SLEEP +done + +echo "Timeout reached, exiting failure..." +exit 1 diff --git a/server/testnet.go b/server/testnet.go index d7e4ec9ac7..93f563005f 100644 --- a/server/testnet.go +++ b/server/testnet.go @@ -20,7 +20,7 @@ import ( var ( nodeDirPrefix = "node-dir-prefix" nValidators = "v" - outputDir = "o" + outputDir = "output-dir" startingIPAddress = "starting-ip-address" ) @@ -49,7 +49,7 @@ Example: } cmd.Flags().Int(nValidators, 4, "Number of validators to initialize the testnet with") - cmd.Flags().String(outputDir, "./mytestnet", + cmd.Flags().StringP(outputDir, "o", "./mytestnet", "Directory to store initialization data for the testnet") cmd.Flags().String(nodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)") diff --git a/server/tm_cmds.go b/server/tm_cmds.go index f852b4029a..c2395e3996 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -69,7 +69,7 @@ func ShowValidatorCmd(ctx *Context) *cobra.Command { func UnsafeResetAllCmd(ctx *Context) *cobra.Command { return &cobra.Command{ Use: "unsafe-reset-all", - Short: "Reset blockchain database, priv_validator.json file, and the logger", + Short: "Resets the blockchain database, removes address book files, and resets priv_validator.json to the genesis state", RunE: func(cmd *cobra.Command, args []string) error { cfg := ctx.Config tcmd.ResetAll(cfg.DBDir(), cfg.P2P.AddrBookFile(), cfg.PrivValidatorFile(), ctx.Logger) diff --git a/store/iavlstore_test.go b/store/iavlstore_test.go index d081b4576f..38d85c6581 100644 --- a/store/iavlstore_test.go +++ b/store/iavlstore_test.go @@ -168,6 +168,7 @@ func TestIAVLSubspaceIterator(t *testing.T) { require.EqualValues(t, value, expectedKey) i++ } + iter.Close() require.Equal(t, len(expected), i) iter = sdk.KVStorePrefixIterator(iavlStore, []byte{byte(55), byte(255), byte(255)}) @@ -183,6 +184,7 @@ func TestIAVLSubspaceIterator(t *testing.T) { require.EqualValues(t, value, []byte("test4")) i++ } + iter.Close() require.Equal(t, len(expected), i) iter = sdk.KVStorePrefixIterator(iavlStore, []byte{byte(255), byte(255)}) @@ -198,6 +200,7 @@ func TestIAVLSubspaceIterator(t *testing.T) { require.EqualValues(t, value, []byte("test4")) i++ } + iter.Close() require.Equal(t, len(expected), i) } diff --git a/store/rootmultistore.go b/store/rootmultistore.go index 8eb1c33dd5..04f8e44e69 100644 --- a/store/rootmultistore.go +++ b/store/rootmultistore.go @@ -68,6 +68,9 @@ func (rs *rootMultiStore) MountStoreWithDB(key StoreKey, typ StoreType, db dbm.D if _, ok := rs.storesParams[key]; ok { panic(fmt.Sprintf("rootMultiStore duplicate store key %v", key)) } + if _, ok := rs.keysByName[key.Name()]; ok { + panic(fmt.Sprintf("rootMultiStore duplicate store key name %v", key)) + } rs.storesParams[key] = storeParams{ key: key, typ: typ, diff --git a/store/rootmultistore_test.go b/store/rootmultistore_test.go index 79760d8695..d6a714c66e 100644 --- a/store/rootmultistore_test.go +++ b/store/rootmultistore_test.go @@ -21,6 +21,21 @@ func TestStoreType(t *testing.T) { } +func TestStoreMount(t *testing.T) { + db := dbm.NewMemDB() + store := NewCommitMultiStore(db) + + key1 := sdk.NewKVStoreKey("store1") + key2 := sdk.NewKVStoreKey("store2") + dup1 := sdk.NewKVStoreKey("store1") + + require.NotPanics(t, func() { store.MountStoreWithDB(key1, sdk.StoreTypeIAVL, db) }) + require.NotPanics(t, func() { store.MountStoreWithDB(key2, sdk.StoreTypeIAVL, db) }) + + require.Panics(t, func() { store.MountStoreWithDB(key1, sdk.StoreTypeIAVL, db) }) + require.Panics(t, func() { store.MountStoreWithDB(dup1, sdk.StoreTypeIAVL, db) }) +} + func TestMultistoreCommitLoad(t *testing.T) { var db dbm.DB = dbm.NewMemDB() if useDebugDB { diff --git a/tests/test_cover.sh b/tests/test_cover.sh index be6215b5a1..3fb0ab69ca 100644 --- a/tests/test_cover.sh +++ b/tests/test_cover.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -e -PKGS=$(go list ./... | grep -v /vendor/ | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test) +PKGS=$(go list ./... | grep -v /vendor/ | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test | grep -v '/simulation') set -e echo "mode: atomic" > coverage.txt diff --git a/types/account.go b/types/account.go index 92e2988f24..00076b5299 100644 --- a/types/account.go +++ b/types/account.go @@ -1,6 +1,7 @@ package types import ( + "bytes" "encoding/hex" "encoding/json" "errors" @@ -108,6 +109,23 @@ func (bz AccAddress) Format(s fmt.State, verb rune) { } } +// Returns boolean for whether two AccAddresses are Equal +func (bz AccAddress) Equals(bz2 AccAddress) bool { + if bz.Empty() && bz2.Empty() { + return true + } + return bytes.Compare(bz.Bytes(), bz2.Bytes()) == 0 +} + +// Returns boolean for whether an AccAddress is empty +func (bz AccAddress) Empty() bool { + if bz == nil { + return true + } + bz2 := AccAddress{} + return bytes.Compare(bz.Bytes(), bz2.Bytes()) == 0 +} + //__________________________________________________________ // AccAddress a wrapper around bytes meant to represent a validator address @@ -192,6 +210,23 @@ func (bz ValAddress) Format(s fmt.State, verb rune) { } } +// Returns boolean for whether two ValAddresses are Equal +func (bz ValAddress) Equals(bz2 ValAddress) bool { + if bz.Empty() && bz2.Empty() { + return true + } + return bytes.Compare(bz.Bytes(), bz2.Bytes()) == 0 +} + +// Returns boolean for whether an AccAddress is empty +func (bz ValAddress) Empty() bool { + if bz == nil { + return true + } + bz2 := ValAddress{} + return bytes.Compare(bz.Bytes(), bz2.Bytes()) == 0 +} + // Bech32ifyAccPub takes AccountPubKey and returns the bech32 encoded string func Bech32ifyAccPub(pub crypto.PubKey) (string, error) { return bech32.ConvertAndEncode(Bech32PrefixAccPub, pub.Bytes()) diff --git a/types/queryable.go b/types/queryable.go new file mode 100644 index 0000000000..9223332bc8 --- /dev/null +++ b/types/queryable.go @@ -0,0 +1,6 @@ +package types + +import abci "github.com/tendermint/tendermint/abci/types" + +// Type for querier functions on keepers to implement to handle custom queries +type Querier = func(ctx Context, path []string, req abci.RequestQuery) (res []byte, err Error) diff --git a/types/stake.go b/types/stake.go index acd24a1541..d872277256 100644 --- a/types/stake.go +++ b/types/stake.go @@ -37,10 +37,10 @@ func (b BondStatus) Equal(b2 BondStatus) bool { // validator for a delegated proof of stake system type Validator interface { - GetRevoked() bool // whether the validator is revoked + GetJailed() bool // whether the validator is jailed GetMoniker() string // moniker of the validator GetStatus() BondStatus // status of the validator - GetOwner() AccAddress // owner AccAddress to receive/return validators coins + GetOperator() AccAddress // owner AccAddress to receive/return validators coins GetPubKey() crypto.PubKey // validation pubkey GetPower() Dec // validation power GetTokens() Dec // validation tokens @@ -51,8 +51,9 @@ type Validator interface { // validator which fulfills abci validator interface for use in Tendermint func ABCIValidator(v Validator) abci.Validator { return abci.Validator{ - PubKey: tmtypes.TM2PB.PubKey(v.GetPubKey()), - Power: v.GetPower().RoundInt64(), + PubKey: tmtypes.TM2PB.PubKey(v.GetPubKey()), + Address: v.GetPubKey().Address(), + Power: v.GetPower().RoundInt64(), } } @@ -72,8 +73,8 @@ type ValidatorSet interface { // slash the validator and delegators of the validator, specifying offence height, offence power, and slash fraction Slash(Context, crypto.PubKey, int64, int64, Dec) - Revoke(Context, crypto.PubKey) // revoke a validator - Unrevoke(Context, crypto.PubKey) // unrevoke a validator + Jail(Context, crypto.PubKey) // jail a validator + Unjail(Context, crypto.PubKey) // unjail a validator } //_______________________________________________________________________________ diff --git a/version/version.go b/version/version.go index 9b332353bc..707868ae0f 100644 --- a/version/version.go +++ b/version/version.go @@ -2,10 +2,10 @@ package version const Maj = "0" -const Min = "23" +const Min = "24" const Fix = "1" -const Version = "0.23.1" +const Version = "0.24.1" // GitCommit set by build flags var GitCommit = "" diff --git a/x/auth/ante.go b/x/auth/ante.go index 60aea8fc78..078f376e22 100644 --- a/x/auth/ante.go +++ b/x/auth/ante.go @@ -5,13 +5,17 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/secp256k1" ) const ( - deductFeesCost sdk.Gas = 10 - memoCostPerByte sdk.Gas = 1 - verifyCost = 100 - maxMemoCharacters = 100 + deductFeesCost sdk.Gas = 10 + memoCostPerByte sdk.Gas = 1 + ed25519VerifyCost = 59 + secp256k1VerifyCost = 100 + maxMemoCharacters = 100 ) // NewAnteHandler returns an AnteHandler that checks @@ -187,7 +191,7 @@ func processSig( } // Check sig. - ctx.GasMeter().ConsumeGas(verifyCost, "ante verify") + consumeSignatureVerificationGas(ctx.GasMeter(), pubKey) if !pubKey.VerifyBytes(signBytes, sig.Signature) { return nil, sdk.ErrUnauthorized("signature verification failed").Result() } @@ -195,6 +199,17 @@ func processSig( return } +func consumeSignatureVerificationGas(meter sdk.GasMeter, pubkey crypto.PubKey) { + switch pubkey.(type) { + case ed25519.PubKeyEd25519: + meter.ConsumeGas(ed25519VerifyCost, "ante verify: ed25519") + case secp256k1.PubKeySecp256k1: + meter.ConsumeGas(secp256k1VerifyCost, "ante verify: secp256k1") + default: + panic("Unrecognized signature type") + } +} + // Deduct the fee from the account. // We could use the CoinKeeper (in addition to the AccountMapper, // because the CoinKeeper doesn't give us accounts), but it seems easier to do this. diff --git a/x/auth/mapper.go b/x/auth/mapper.go index 244527af3f..c8bf94a21f 100644 --- a/x/auth/mapper.go +++ b/x/auth/mapper.go @@ -87,6 +87,7 @@ func (am AccountMapper) SetAccount(ctx sdk.Context, acc Account) { func (am AccountMapper) IterateAccounts(ctx sdk.Context, process func(Account) (stop bool)) { store := ctx.KVStore(am.key) iter := sdk.KVStorePrefixIterator(store, []byte("account:")) + defer iter.Close() for { if !iter.Valid() { return diff --git a/x/bank/simulation/msgs.go b/x/bank/simulation/msgs.go index 3a72488757..43d7e1fd70 100644 --- a/x/bank/simulation/msgs.go +++ b/x/bank/simulation/msgs.go @@ -35,6 +35,10 @@ func TestAndRunSingleInputMsgSend(mapper auth.AccountMapper) simulation.TestAndR toAddr := sdk.AccAddress(toKey.PubKey().Address()) initFromCoins := mapper.GetAccount(ctx, fromAddr).GetCoins() + if len(initFromCoins) == 0 { + return "skipping, no coins at all", nil + } + denomIndex := r.Intn(len(initFromCoins)) amt, goErr := randPositiveInt(r, initFromCoins[denomIndex].Amount) if goErr != nil { diff --git a/x/bank/simulation/sim_test.go b/x/bank/simulation/sim_test.go index 5d76dd0589..8fedeca795 100644 --- a/x/bank/simulation/sim_test.go +++ b/x/bank/simulation/sim_test.go @@ -5,6 +5,8 @@ import ( "math/rand" "testing" + "github.com/tendermint/tendermint/crypto" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/mock" @@ -24,7 +26,7 @@ func TestBankWithRandomMessages(t *testing.T) { panic(err) } - appStateFn := func(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage { + appStateFn := func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage { mock.RandomSetGenesis(r, mapp, accs, []string{"stake"}) return json.RawMessage("{}") } @@ -39,6 +41,7 @@ func TestBankWithRandomMessages(t *testing.T) { NonnegativeBalanceInvariant(mapper), TotalCoinsInvariant(mapper, func() sdk.Coins { return mapp.TotalCoinsSupply }), }, - 100, 30, 30, + 30, 30, + false, ) } diff --git a/x/gov/client/cli/tx.go b/x/gov/client/cli/tx.go index d19de9f07f..2a7e71aac8 100644 --- a/x/gov/client/cli/tx.go +++ b/x/gov/client/cli/tx.go @@ -12,9 +12,12 @@ import ( authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context" "github.com/cosmos/cosmos-sdk/x/gov" + "encoding/json" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" + "io/ioutil" + "strings" ) const ( @@ -28,18 +31,51 @@ const ( flagDepositer = "depositer" flagStatus = "status" flagLatestProposalIDs = "latest" + flagProposal = "proposal" ) +type proposal struct { + Title string + Description string + Type string + Deposit string +} + +var proposalFlags = []string{ + flagTitle, + flagDescription, + flagProposalType, + flagDeposit, +} + // GetCmdSubmitProposal implements submitting a proposal transaction command. func GetCmdSubmitProposal(cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "submit-proposal", Short: "Submit a proposal along with an initial deposit", + Long: strings.TrimSpace(` +Submit a proposal along with an initial deposit. Proposal title, description, type and deposit can be given directly or through a proposal JSON file. For example: + +$ gaiacli gov submit-proposal --proposal="path/to/proposal.json" + +where proposal.json contains: + +{ + "title": "Test Proposal", + "description": "My awesome proposal", + "type": "Text", + "deposit": "1000test" +} + +is equivalent to + +$ gaiacli gov submit-proposal --title="Test Proposal" --description="My awesome proposal" --type="Text" --deposit="1000test" +`), RunE: func(cmd *cobra.Command, args []string) error { - title := viper.GetString(flagTitle) - description := viper.GetString(flagDescription) - strProposalType := viper.GetString(flagProposalType) - initialDeposit := viper.GetString(flagDeposit) + proposal, err := parseSubmitProposalFlags() + if err != nil { + return err + } txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc) cliCtx := context.NewCLIContext(). @@ -52,17 +88,17 @@ func GetCmdSubmitProposal(cdc *wire.Codec) *cobra.Command { return err } - amount, err := sdk.ParseCoins(initialDeposit) + amount, err := sdk.ParseCoins(proposal.Deposit) if err != nil { return err } - proposalType, err := gov.ProposalTypeFromString(strProposalType) + proposalType, err := gov.ProposalTypeFromString(proposal.Type) if err != nil { return err } - msg := gov.NewMsgSubmitProposal(title, description, proposalType, fromAddr, amount) + msg := gov.NewMsgSubmitProposal(proposal.Title, proposal.Description, proposalType, fromAddr, amount) err = msg.ValidateBasic() if err != nil { @@ -80,10 +116,42 @@ func GetCmdSubmitProposal(cdc *wire.Codec) *cobra.Command { cmd.Flags().String(flagDescription, "", "description of proposal") cmd.Flags().String(flagProposalType, "", "proposalType of proposal") cmd.Flags().String(flagDeposit, "", "deposit of proposal") + cmd.Flags().String(flagProposal, "", "proposal file path (if this path is given, other proposal flags are ignored)") return cmd } +func parseSubmitProposalFlags() (*proposal, error) { + proposal := &proposal{} + proposalFile := viper.GetString(flagProposal) + + if proposalFile == "" { + proposal.Title = viper.GetString(flagTitle) + proposal.Description = viper.GetString(flagDescription) + proposal.Type = viper.GetString(flagProposalType) + proposal.Deposit = viper.GetString(flagDeposit) + return proposal, nil + } + + for _, flag := range proposalFlags { + if viper.GetString(flag) != "" { + return nil, fmt.Errorf("--%s flag provided alongside --proposal, which is a noop", flag) + } + } + + contents, err := ioutil.ReadFile(proposalFile) + if err != nil { + return nil, err + } + + err = json.Unmarshal(contents, proposal) + if err != nil { + return nil, err + } + + return proposal, nil +} + // GetCmdDeposit implements depositing tokens for an active proposal. func GetCmdDeposit(cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ diff --git a/x/gov/client/cli/tx_test.go b/x/gov/client/cli/tx_test.go new file mode 100644 index 0000000000..e3aed05ffa --- /dev/null +++ b/x/gov/client/cli/tx_test.go @@ -0,0 +1,70 @@ +package cli + +import ( + "github.com/spf13/viper" + "github.com/stretchr/testify/require" + "io/ioutil" + "testing" +) + +func TestParseSubmitProposalFlags(t *testing.T) { + okJSON, err := ioutil.TempFile("", "proposal") + require.Nil(t, err, "unexpected error") + okJSON.WriteString(` +{ + "title": "Test Proposal", + "description": "My awesome proposal", + "type": "Text", + "deposit": "1000test" +} +`) + + badJSON, err := ioutil.TempFile("", "proposal") + require.Nil(t, err, "unexpected error") + badJSON.WriteString("bad json") + + // nonexistent json + viper.Set(flagProposal, "fileDoesNotExist") + _, err = parseSubmitProposalFlags() + require.Error(t, err) + + // invalid json + viper.Set(flagProposal, badJSON.Name()) + _, err = parseSubmitProposalFlags() + require.Error(t, err) + + // ok json + viper.Set(flagProposal, okJSON.Name()) + proposal1, err := parseSubmitProposalFlags() + require.Nil(t, err, "unexpected error") + require.Equal(t, "Test Proposal", proposal1.Title) + require.Equal(t, "My awesome proposal", proposal1.Description) + require.Equal(t, "Text", proposal1.Type) + require.Equal(t, "1000test", proposal1.Deposit) + + // flags that can't be used with --proposal + for _, incompatibleFlag := range proposalFlags { + viper.Set(incompatibleFlag, "some value") + _, err := parseSubmitProposalFlags() + require.Error(t, err) + viper.Set(incompatibleFlag, "") + } + + // no --proposal, only flags + viper.Set(flagProposal, "") + viper.Set(flagTitle, proposal1.Title) + viper.Set(flagDescription, proposal1.Description) + viper.Set(flagProposalType, proposal1.Type) + viper.Set(flagDeposit, proposal1.Deposit) + proposal2, err := parseSubmitProposalFlags() + require.Nil(t, err, "unexpected error") + require.Equal(t, proposal1.Title, proposal2.Title) + require.Equal(t, proposal1.Description, proposal2.Description) + require.Equal(t, proposal1.Type, proposal2.Type) + require.Equal(t, proposal1.Deposit, proposal2.Deposit) + + err = okJSON.Close() + require.Nil(t, err, "unexpected error") + err = badJSON.Close() + require.Nil(t, err, "unexpected error") +} diff --git a/x/gov/client/rest/rest.go b/x/gov/client/rest/rest.go index a410c7791e..5cdc7bda2b 100644 --- a/x/gov/client/rest/rest.go +++ b/x/gov/client/rest/rest.go @@ -3,7 +3,6 @@ package rest import ( "fmt" "net/http" - "strconv" "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" @@ -17,10 +16,11 @@ import ( // REST Variable names // nolint const ( - RestProposalID = "proposalID" + RestProposalID = "proposal-id" RestDepositer = "depositer" RestVoter = "voter" RestProposalStatus = "status" + RestNumLatest = "latest" storeName = "gov" ) @@ -97,16 +97,13 @@ func depositHandlerFn(cdc *wire.Codec, cliCtx context.CLIContext) http.HandlerFu return } - proposalID, err := strconv.ParseInt(strProposalID, 10, 64) - if err != nil { - err := errors.Errorf("proposalID [%d] is not positive", proposalID) - w.Write([]byte(err.Error())) - + proposalID, ok := parseInt64OrReturnBadRequest(strProposalID, w) + if !ok { return } var req depositReq - err = buildReq(w, r, cdc, &req) + err := buildReq(w, r, cdc, &req) if err != nil { return } @@ -139,15 +136,13 @@ func voteHandlerFn(cdc *wire.Codec, cliCtx context.CLIContext) http.HandlerFunc return } - proposalID, err := strconv.ParseInt(strProposalID, 10, 64) - if err != nil { - err := errors.Errorf("proposalID [%d] is not positive", proposalID) - w.Write([]byte(err.Error())) + proposalID, ok := parseInt64OrReturnBadRequest(strProposalID, w) + if !ok { return } var req voteReq - err = buildReq(w, r, cdc, &req) + err := buildReq(w, r, cdc, &req) if err != nil { return } @@ -180,36 +175,33 @@ func queryProposalHandlerFn(cdc *wire.Codec) http.HandlerFunc { return } - proposalID, err := strconv.ParseInt(strProposalID, 10, 64) - if err != nil { - err := errors.Errorf("proposalID [%d] is not positive", proposalID) - w.Write([]byte(err.Error())) - + proposalID, ok := parseInt64OrReturnBadRequest(strProposalID, w) + if !ok { return } cliCtx := context.NewCLIContext().WithCodec(cdc) - res, err := cliCtx.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 + params := gov.QueryProposalParams{ + ProposalID: proposalID, } - var proposal gov.Proposal - cdc.MustUnmarshalBinary(res, &proposal) - - output, err := wire.MarshalJSONIndent(cdc, proposal) + bz, err := cdc.MarshalJSON(params) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) + return + } + + res, err := cliCtx.QueryWithData("custom/gov/proposal", bz) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) return } - w.Write(output) + w.Write(res) } } @@ -227,12 +219,8 @@ func queryDepositHandlerFn(cdc *wire.Codec) http.HandlerFunc { return } - proposalID, err := strconv.ParseInt(strProposalID, 10, 64) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - err := errors.Errorf("proposalID [%d] is not positive", proposalID) - w.Write([]byte(err.Error())) - + proposalID, ok := parseInt64OrReturnBadRequest(strProposalID, w) + if !ok { return } @@ -255,36 +243,43 @@ func queryDepositHandlerFn(cdc *wire.Codec) http.HandlerFunc { cliCtx := context.NewCLIContext().WithCodec(cdc) - res, err := cliCtx.QueryStore(gov.KeyDeposit(proposalID, depositerAddr), storeName) - if err != nil || len(res) == 0 { - res, err := cliCtx.QueryStore(gov.KeyProposal(proposalID), storeName) - if err != nil || len(res) == 0 { - w.WriteHeader(http.StatusNotFound) - err := errors.Errorf("proposalID [%d] does not exist", proposalID) - w.Write([]byte(err.Error())) + params := gov.QueryDepositParams{ + ProposalID: proposalID, + Depositer: depositerAddr, + } - return - } + bz, err := cdc.MarshalJSON(params) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return + } - w.WriteHeader(http.StatusNotFound) - err = errors.Errorf("depositer [%s] did not deposit on proposalID [%d]", bechDepositerAddr, proposalID) + res, err := cliCtx.QueryWithData("custom/gov/deposit", bz) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } var deposit gov.Deposit - cdc.MustUnmarshalBinary(res, &deposit) - - output, err := wire.MarshalJSONIndent(cdc, deposit) - if err != nil { - w.WriteHeader(http.StatusBadRequest) + cdc.UnmarshalJSON(res, &deposit) + if deposit.Empty() { + res, err := cliCtx.QueryWithData("custom/gov/proposal", cdc.MustMarshalBinary(gov.QueryProposalParams{params.ProposalID})) + if err != nil || len(res) == 0 { + w.WriteHeader(http.StatusNotFound) + err := errors.Errorf("proposalID [%d] does not exist", proposalID) + w.Write([]byte(err.Error())) + return + } + w.WriteHeader(http.StatusNotFound) + err = errors.Errorf("depositer [%s] did not deposit on proposalID [%d]", bechDepositerAddr, proposalID) w.Write([]byte(err.Error())) - return } - w.Write(output) + w.Write(res) } } @@ -301,12 +296,8 @@ func queryVoteHandlerFn(cdc *wire.Codec) http.HandlerFunc { 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())) - + proposalID, ok := parseInt64OrReturnBadRequest(strProposalID, w) + if !ok { return } @@ -328,36 +319,47 @@ func queryVoteHandlerFn(cdc *wire.Codec) http.HandlerFunc { cliCtx := context.NewCLIContext().WithCodec(cdc) - res, err := cliCtx.QueryStore(gov.KeyVote(proposalID, voterAddr), storeName) - if err != nil || len(res) == 0 { - res, err := cliCtx.QueryStore(gov.KeyProposal(proposalID), storeName) - if err != nil || len(res) == 0 { - w.WriteHeader(http.StatusNotFound) - err := errors.Errorf("proposalID [%d] does not exist", proposalID) - w.Write([]byte(err.Error())) + params := gov.QueryVoteParams{ + Voter: voterAddr, + ProposalID: proposalID, + } + bz, err := cdc.MarshalJSON(params) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return + } - return - } - - w.WriteHeader(http.StatusNotFound) - err = errors.Errorf("voter [%s] did not vote on proposalID [%d]", bechVoterAddr, proposalID) + res, err := cliCtx.QueryWithData("custom/gov/vote", bz) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } var vote gov.Vote - cdc.MustUnmarshalBinary(res, &vote) - - output, err := wire.MarshalJSONIndent(cdc, vote) - if err != nil { - w.WriteHeader(http.StatusBadRequest) + cdc.UnmarshalJSON(res, &vote) + if vote.Empty() { + bz, err := cdc.MarshalJSON(gov.QueryProposalParams{params.ProposalID}) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return + } + res, err := cliCtx.QueryWithData("custom/gov/proposal", bz) + if err != nil || len(res) == 0 { + w.WriteHeader(http.StatusNotFound) + err := errors.Errorf("proposalID [%d] does not exist", proposalID) + w.Write([]byte(err.Error())) + return + } + w.WriteHeader(http.StatusNotFound) + err = errors.Errorf("voter [%s] did not deposit on proposalID [%d]", bechVoterAddr, proposalID) w.Write([]byte(err.Error())) - return } - - w.Write(output) + w.Write(res) } } @@ -376,59 +378,31 @@ func queryVotesOnProposalHandlerFn(cdc *wire.Codec) http.HandlerFunc { 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())) - + proposalID, ok := parseInt64OrReturnBadRequest(strProposalID, w) + if !ok { return } cliCtx := context.NewCLIContext().WithCodec(cdc) - res, err := cliCtx.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 + params := gov.QueryVotesParams{ + ProposalID: proposalID, } - - 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 := cliCtx.QuerySubspace(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) + bz, err := cdc.MarshalJSON(params) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) - return } - w.Write(output) + res, err := cliCtx.QueryWithData("custom/gov/votes", bz) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return + } + + w.Write(res) } } @@ -439,24 +413,23 @@ func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc { bechVoterAddr := r.URL.Query().Get(RestVoter) bechDepositerAddr := r.URL.Query().Get(RestDepositer) strProposalStatus := r.URL.Query().Get(RestProposalStatus) + strNumLatest := r.URL.Query().Get(RestNumLatest) - var err error - var voterAddr sdk.AccAddress - var depositerAddr sdk.AccAddress - var proposalStatus gov.ProposalStatus + params := gov.QueryProposalsParams{} if len(bechVoterAddr) != 0 { - voterAddr, err = sdk.AccAddressFromBech32(bechVoterAddr) + voterAddr, err := sdk.AccAddressFromBech32(bechVoterAddr) if err != nil { w.WriteHeader(http.StatusBadRequest) err := errors.Errorf("'%s' needs to be bech32 encoded", RestVoter) w.Write([]byte(err.Error())) return } + params.Voter = voterAddr } if len(bechDepositerAddr) != 0 { - depositerAddr, err = sdk.AccAddressFromBech32(bechDepositerAddr) + depositerAddr, err := sdk.AccAddressFromBech32(bechDepositerAddr) if err != nil { w.WriteHeader(http.StatusBadRequest) err := errors.Errorf("'%s' needs to be bech32 encoded", RestDepositer) @@ -464,10 +437,11 @@ func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc { return } + params.Depositer = depositerAddr } if len(strProposalStatus) != 0 { - proposalStatus, err = gov.ProposalStatusFromString(strProposalStatus) + proposalStatus, err := gov.ProposalStatusFromString(strProposalStatus) if err != nil { w.WriteHeader(http.StatusBadRequest) err := errors.Errorf("'%s' is not a valid Proposal Status", strProposalStatus) @@ -475,63 +449,33 @@ func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc { return } + params.ProposalStatus = proposalStatus + } + if len(strNumLatest) != 0 { + numLatest, ok := parseInt64OrReturnBadRequest(strNumLatest, w) + if !ok { + return + } + params.NumLatestProposals = numLatest + } + + bz, err := cdc.MarshalJSON(params) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return } cliCtx := context.NewCLIContext().WithCodec(cdc) - res, err := cliCtx.QueryStore(gov.KeyNextProposalID, storeName) + res, err := cliCtx.QueryWithData("custom/gov/proposals", bz) if err != nil { - err = errors.New("no proposals exist yet and proposalID has not been set") + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } - var maxProposalID int64 - cdc.MustUnmarshalBinary(res, &maxProposalID) - - matchingProposals := []gov.Proposal{} - - for proposalID := int64(0); proposalID < maxProposalID; proposalID++ { - if voterAddr != nil { - res, err = cliCtx.QueryStore(gov.KeyVote(proposalID, voterAddr), storeName) - if err != nil || len(res) == 0 { - continue - } - } - - if depositerAddr != nil { - res, err = cliCtx.QueryStore(gov.KeyDeposit(proposalID, depositerAddr), storeName) - if err != nil || len(res) == 0 { - continue - } - } - - res, err = cliCtx.QueryStore(gov.KeyProposal(proposalID), storeName) - if err != nil || len(res) == 0 { - continue - } - - var proposal gov.Proposal - cdc.MustUnmarshalBinary(res, &proposal) - - if len(strProposalStatus) != 0 { - if proposal.GetStatus() != proposalStatus { - continue - } - } - - matchingProposals = append(matchingProposals, proposal) - } - - output, err := wire.MarshalJSONIndent(cdc, matchingProposals) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(err.Error())) - - return - } - - w.Write(output) + w.Write(res) } } diff --git a/x/gov/client/rest/util.go b/x/gov/client/rest/util.go index 58d96b591f..e6aa83cc4b 100644 --- a/x/gov/client/rest/util.go +++ b/x/gov/client/rest/util.go @@ -1,8 +1,10 @@ package rest import ( + "fmt" "io/ioutil" "net/http" + "strconv" "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" @@ -100,3 +102,15 @@ func signAndBuild(w http.ResponseWriter, cliCtx context.CLIContext, baseReq base w.Write(output) } + +func parseInt64OrReturnBadRequest(s string, w http.ResponseWriter) (n int64, ok bool) { + var err error + n, err = strconv.ParseInt(s, 10, 64) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + err := fmt.Errorf("'%s' is not a valid int64", s) + w.Write([]byte(err.Error())) + return 0, false + } + return n, true +} diff --git a/x/gov/depositsvotes.go b/x/gov/depositsvotes.go index 19ed97f69d..b5c65931fc 100644 --- a/x/gov/depositsvotes.go +++ b/x/gov/depositsvotes.go @@ -15,6 +15,17 @@ type Vote struct { Option VoteOption `json:"option"` // option from OptionSet chosen by the voter } +// Returns whether 2 votes are equal +func (voteA Vote) Equals(voteB Vote) bool { + return voteA.Voter.Equals(voteB.Voter) && voteA.ProposalID == voteB.ProposalID && voteA.Option == voteB.Option +} + +// Returns whether a vote is empty +func (voteA Vote) Empty() bool { + voteB := Vote{} + return voteA.Equals(voteB) +} + // Deposit type Deposit struct { Depositer sdk.AccAddress `json:"depositer"` // Address of the depositer @@ -22,6 +33,17 @@ type Deposit struct { Amount sdk.Coins `json:"amount"` // Deposit amount } +// Returns whether 2 deposits are equal +func (depositA Deposit) Equals(depositB Deposit) bool { + return depositA.Depositer.Equals(depositB.Depositer) && depositA.ProposalID == depositB.ProposalID && depositA.Amount.IsEqual(depositB.Amount) +} + +// Returns whether a deposit is empty +func (depositA Deposit) Empty() bool { + depositB := Deposit{} + return depositA.Equals(depositB) +} + // Type that represents VoteOption as a byte type VoteOption byte diff --git a/x/gov/handler.go b/x/gov/handler.go index a9fdfcb3cd..4fa3887296 100644 --- a/x/gov/handler.go +++ b/x/gov/handler.go @@ -1,6 +1,8 @@ package gov import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/gov/tags" ) @@ -96,6 +98,8 @@ func handleMsgVote(ctx sdk.Context, keeper Keeper, msg MsgVote) sdk.Result { // Called every block, process inflation, update validator set func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) { + logger := ctx.Logger().With("module", "x/gov") + resTags = sdk.NewTags() // Delete proposals that haven't met minDeposit @@ -109,6 +113,9 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) { keeper.DeleteProposal(ctx, inactiveProposal) resTags.AppendTag(tags.Action, tags.ActionProposalDropped) resTags.AppendTag(tags.ProposalID, proposalIDBytes) + + logger.Info("Proposal %d - \"%s\" - didn't mean minimum deposit (had only %s), deleted", + inactiveProposal.GetProposalID(), inactiveProposal.GetTitle(), inactiveProposal.GetTotalDeposit()) } // Check if earliest Active Proposal ended voting period yet @@ -136,6 +143,9 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) { activeProposal.SetTallyResult(tallyResults) keeper.SetProposal(ctx, activeProposal) + logger.Info("Proposal %d - \"%s\" - tallied, passed: %v", + activeProposal.GetProposalID(), activeProposal.GetTitle(), passes) + for _, valAddr := range nonVotingVals { val := keeper.ds.GetValidatorSet().Validator(ctx, valAddr) keeper.ds.GetValidatorSet().Slash(ctx, @@ -143,6 +153,9 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) { ctx.BlockHeight(), val.GetPower().RoundInt64(), keeper.GetTallyingProcedure(ctx).GovernancePenalty) + + logger.Info(fmt.Sprintf("Validator %s failed to vote on proposal %d, slashing", + val.GetOperator(), activeProposal.GetProposalID())) } resTags.AppendTag(tags.Action, action) diff --git a/x/gov/keeper.go b/x/gov/keeper.go index 0034e3d713..e8dbbc4a7f 100644 --- a/x/gov/keeper.go +++ b/x/gov/keeper.go @@ -108,6 +108,52 @@ func (keeper Keeper) DeleteProposal(ctx sdk.Context, proposal Proposal) { store.Delete(KeyProposal(proposal.GetProposalID())) } +// nolint: gocyclo +// Get Proposal from store by ProposalID +func (keeper Keeper) GetProposalsFiltered(ctx sdk.Context, voterAddr sdk.AccAddress, depositerAddr sdk.AccAddress, status ProposalStatus, numLatest int64) []Proposal { + + maxProposalID, err := keeper.peekCurrentProposalID(ctx) + if err != nil { + return nil + } + + matchingProposals := []Proposal{} + + if numLatest <= 0 { + numLatest = maxProposalID + } + + for proposalID := maxProposalID - numLatest; proposalID < maxProposalID; proposalID++ { + if voterAddr != nil && len(voterAddr) != 0 { + _, found := keeper.GetVote(ctx, proposalID, voterAddr) + if !found { + continue + } + } + + if depositerAddr != nil && len(depositerAddr) != 0 { + _, found := keeper.GetDeposit(ctx, proposalID, depositerAddr) + if !found { + continue + } + } + + proposal := keeper.GetProposal(ctx, proposalID) + if proposal == nil { + continue + } + + if validProposalStatus(status) { + if proposal.GetStatus() != status { + continue + } + } + + matchingProposals = append(matchingProposals, proposal) + } + return matchingProposals +} + func (keeper Keeper) setInitialProposalID(ctx sdk.Context, proposalID int64) sdk.Error { store := ctx.KVStore(keeper.storeKey) bz := store.Get(KeyNextProposalID) @@ -119,6 +165,17 @@ func (keeper Keeper) setInitialProposalID(ctx sdk.Context, proposalID int64) sdk return nil } +// Get the last used proposal ID +func (keeper Keeper) GetLastProposalID(ctx sdk.Context) (proposalID int64) { + proposalID, err := keeper.peekCurrentProposalID(ctx) + if err != nil { + return 0 + } + proposalID-- + return +} + +// Gets the next available ProposalID and increments it func (keeper Keeper) getNewProposalID(ctx sdk.Context) (proposalID int64, err sdk.Error) { store := ctx.KVStore(keeper.storeKey) bz := store.Get(KeyNextProposalID) @@ -131,6 +188,17 @@ func (keeper Keeper) getNewProposalID(ctx sdk.Context) (proposalID int64, err sd return proposalID, nil } +// Peeks the next available ProposalID without incrementing it +func (keeper Keeper) peekCurrentProposalID(ctx sdk.Context) (proposalID int64, err sdk.Error) { + store := ctx.KVStore(keeper.storeKey) + bz := store.Get(KeyNextProposalID) + if bz == nil { + return -1, ErrInvalidGenesis(keeper.codespace, "InitialProposalID never set") + } + keeper.cdc.MustUnmarshalBinary(bz, &proposalID) + return proposalID, nil +} + func (keeper Keeper) activateVotingPeriod(ctx sdk.Context, proposal Proposal) { proposal.SetVotingStartBlock(ctx.BlockHeight()) proposal.SetStatus(StatusVotingPeriod) diff --git a/x/gov/keeper_test.go b/x/gov/keeper_test.go index 442caee901..a61292b93e 100644 --- a/x/gov/keeper_test.go +++ b/x/gov/keeper_test.go @@ -130,6 +130,7 @@ func TestDeposits(t *testing.T) { require.Equal(t, fourSteak, deposit.Amount) depositsIterator.Next() require.False(t, depositsIterator.Valid()) + depositsIterator.Close() // Test Refund Deposits deposit, found = keeper.GetDeposit(ctx, proposalID, addrs[1]) @@ -196,6 +197,7 @@ func TestVotes(t *testing.T) { require.Equal(t, OptionNoWithVeto, vote.Option) votesIterator.Next() require.False(t, votesIterator.Valid()) + votesIterator.Close() } func TestProposalQueues(t *testing.T) { diff --git a/x/gov/proposals.go b/x/gov/proposals.go index f05dabd08d..c52ab1e875 100644 --- a/x/gov/proposals.go +++ b/x/gov/proposals.go @@ -110,6 +110,7 @@ type ProposalKind byte //nolint const ( + ProposalTypeNil ProposalKind = 0x00 ProposalTypeText ProposalKind = 0x01 ProposalTypeParameterChange ProposalKind = 0x02 ProposalTypeSoftwareUpgrade ProposalKind = 0x03 @@ -203,6 +204,7 @@ type ProposalStatus byte //nolint const ( + StatusNil ProposalStatus = 0x00 StatusDepositPeriod ProposalStatus = 0x01 StatusVotingPeriod ProposalStatus = 0x02 StatusPassed ProposalStatus = 0x03 @@ -220,6 +222,8 @@ func ProposalStatusFromString(str string) (ProposalStatus, error) { return StatusPassed, nil case "Rejected": return StatusRejected, nil + case "": + return StatusNil, nil default: return ProposalStatus(0xff), errors.Errorf("'%s' is not a valid proposal status", str) } diff --git a/x/gov/queryable.go b/x/gov/queryable.go new file mode 100644 index 0000000000..e64d506d1e --- /dev/null +++ b/x/gov/queryable.go @@ -0,0 +1,213 @@ +package gov + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + abci "github.com/tendermint/tendermint/abci/types" +) + +func NewQuerier(keeper Keeper) sdk.Querier { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { + switch path[0] { + case "proposal": + return queryProposal(ctx, path[1:], req, keeper) + case "deposit": + return queryDeposit(ctx, path[1:], req, keeper) + case "vote": + return queryVote(ctx, path[1:], req, keeper) + case "deposits": + return queryDeposits(ctx, path[1:], req, keeper) + case "votes": + return queryVotes(ctx, path[1:], req, keeper) + case "proposals": + return queryProposals(ctx, path[1:], req, keeper) + case "tally": + return queryTally(ctx, path[1:], req, keeper) + default: + return nil, sdk.ErrUnknownRequest("unknown gov query endpoint") + } + } +} + +// Params for query 'custom/gov/proposal' +type QueryProposalParams struct { + ProposalID int64 +} + +func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { + var params QueryProposalParams + err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if err2 != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + } + + proposal := keeper.GetProposal(ctx, params.ProposalID) + if proposal == nil { + return []byte{}, ErrUnknownProposal(DefaultCodespace, params.ProposalID) + } + + bz, err2 := wire.MarshalJSONIndent(keeper.cdc, proposal) + if err2 != nil { + panic("could not marshal result to JSON") + } + return bz, nil +} + +// Params for query 'custom/gov/deposit' +type QueryDepositParams struct { + ProposalID int64 + Depositer sdk.AccAddress +} + +func queryDeposit(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { + var params QueryDepositParams + err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if err2 != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + } + + deposit, _ := keeper.GetDeposit(ctx, params.ProposalID, params.Depositer) + bz, err2 := wire.MarshalJSONIndent(keeper.cdc, deposit) + if err2 != nil { + panic("could not marshal result to JSON") + } + return bz, nil +} + +// Params for query 'custom/gov/vote' +type QueryVoteParams struct { + ProposalID int64 + Voter sdk.AccAddress +} + +func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { + var params QueryVoteParams + err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if err2 != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + } + + vote, _ := keeper.GetVote(ctx, params.ProposalID, params.Voter) + bz, err2 := wire.MarshalJSONIndent(keeper.cdc, vote) + if err2 != nil { + panic("could not marshal result to JSON") + } + return bz, nil +} + +// Params for query 'custom/gov/deposits' +type QueryDepositsParams struct { + ProposalID int64 +} + +func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { + var params QueryDepositParams + err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if err2 != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + } + + var deposits []Deposit + depositsIterator := keeper.GetDeposits(ctx, params.ProposalID) + for ; depositsIterator.Valid(); depositsIterator.Next() { + deposit := Deposit{} + keeper.cdc.MustUnmarshalBinary(depositsIterator.Value(), &deposit) + deposits = append(deposits, deposit) + } + + bz, err2 := wire.MarshalJSONIndent(keeper.cdc, deposits) + if err2 != nil { + panic("could not marshal result to JSON") + } + return bz, nil +} + +// Params for query 'custom/gov/votes' +type QueryVotesParams struct { + ProposalID int64 +} + +func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { + var params QueryVotesParams + err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + + if err2 != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + } + + var votes []Vote + votesIterator := keeper.GetVotes(ctx, params.ProposalID) + for ; votesIterator.Valid(); votesIterator.Next() { + vote := Vote{} + keeper.cdc.MustUnmarshalBinary(votesIterator.Value(), &vote) + votes = append(votes, vote) + } + + bz, err2 := wire.MarshalJSONIndent(keeper.cdc, votes) + if err2 != nil { + panic("could not marshal result to JSON") + } + return bz, nil +} + +// Params for query 'custom/gov/proposals' +type QueryProposalsParams struct { + Voter sdk.AccAddress + Depositer sdk.AccAddress + ProposalStatus ProposalStatus + NumLatestProposals int64 +} + +func queryProposals(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { + var params QueryProposalsParams + err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if err2 != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + } + + proposals := keeper.GetProposalsFiltered(ctx, params.Voter, params.Depositer, params.ProposalStatus, params.NumLatestProposals) + + bz, err2 := wire.MarshalJSONIndent(keeper.cdc, proposals) + if err2 != nil { + panic("could not marshal result to JSON") + } + return bz, nil +} + +// Params for query 'custom/gov/tally' +type QueryTallyParams struct { + ProposalID int64 +} + +func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { + // TODO: Dependant on #1914 + + var proposalID int64 + err2 := keeper.cdc.UnmarshalJSON(req.Data, proposalID) + if err2 != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + } + + proposal := keeper.GetProposal(ctx, proposalID) + if proposal == nil { + return []byte{}, ErrUnknownProposal(DefaultCodespace, proposalID) + } + + var tallyResult TallyResult + + if proposal.GetStatus() == StatusDepositPeriod { + tallyResult = EmptyTallyResult() + } else if proposal.GetStatus() == StatusPassed || proposal.GetStatus() == StatusRejected { + tallyResult = proposal.GetTallyResult() + } else { + _, tallyResult, _ = tally(ctx, keeper, proposal) + } + + bz, err2 := wire.MarshalJSONIndent(keeper.cdc, tallyResult) + if err2 != nil { + panic("could not marshal result to JSON") + } + return bz, nil +} diff --git a/x/gov/simulation/invariants.go b/x/gov/simulation/invariants.go new file mode 100644 index 0000000000..e9275f3c1a --- /dev/null +++ b/x/gov/simulation/invariants.go @@ -0,0 +1,19 @@ +package simulation + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" +) + +// AllInvariants tests all governance invariants +func AllInvariants() simulation.Invariant { + return func(t *testing.T, app *baseapp.BaseApp, log string) { + // TODO Add some invariants! + // Checking proposal queues, no passed-but-unexecuted proposals, etc. + require.Nil(t, nil) + } +} diff --git a/x/gov/simulation/msgs.go b/x/gov/simulation/msgs.go new file mode 100644 index 0000000000..ed80ab4e63 --- /dev/null +++ b/x/gov/simulation/msgs.go @@ -0,0 +1,132 @@ +package simulation + +import ( + "fmt" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/tendermint/tendermint/crypto" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/gov" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" + "github.com/cosmos/cosmos-sdk/x/stake" +) + +const ( + denom = "steak" +) + +// SimulateMsgSubmitProposal +func SimulateMsgSubmitProposal(k gov.Keeper, sk stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { + key := simulation.RandomKey(r, keys) + addr := sdk.AccAddress(key.PubKey().Address()) + deposit := randomDeposit(r) + msg := gov.NewMsgSubmitProposal( + simulation.RandStringOfLength(r, 5), + simulation.RandStringOfLength(r, 5), + gov.ProposalTypeText, + addr, + deposit, + ) + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := gov.NewHandler(k)(ctx, msg) + if result.IsOK() { + // Update pool to keep invariants + pool := sk.GetPool(ctx) + pool.LooseTokens = pool.LooseTokens.Sub(sdk.NewDecFromInt(deposit.AmountOf(denom))) + sk.SetPool(ctx, pool) + write() + } + event(fmt.Sprintf("gov/MsgSubmitProposal/%v", result.IsOK())) + action = fmt.Sprintf("TestMsgSubmitProposal: ok %v, msg %s", result.IsOK(), msg.GetSignBytes()) + return action, nil + } +} + +// SimulateMsgDeposit +func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { + key := simulation.RandomKey(r, keys) + addr := sdk.AccAddress(key.PubKey().Address()) + proposalID, ok := randomProposalID(r, k, ctx) + if !ok { + return "no-operation", nil + } + deposit := randomDeposit(r) + msg := gov.NewMsgDeposit(addr, proposalID, deposit) + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := gov.NewHandler(k)(ctx, msg) + if result.IsOK() { + // Update pool to keep invariants + pool := sk.GetPool(ctx) + pool.LooseTokens = pool.LooseTokens.Sub(sdk.NewDecFromInt(deposit.AmountOf(denom))) + sk.SetPool(ctx, pool) + write() + } + event(fmt.Sprintf("gov/MsgDeposit/%v", result.IsOK())) + action = fmt.Sprintf("TestMsgDeposit: ok %v, msg %s", result.IsOK(), msg.GetSignBytes()) + return action, nil + } +} + +// SimulateMsgVote +func SimulateMsgVote(k gov.Keeper, sk stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { + key := simulation.RandomKey(r, keys) + addr := sdk.AccAddress(key.PubKey().Address()) + proposalID, ok := randomProposalID(r, k, ctx) + if !ok { + return "no-operation", nil + } + option := randomVotingOption(r) + msg := gov.NewMsgVote(addr, proposalID, option) + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := gov.NewHandler(k)(ctx, msg) + if result.IsOK() { + write() + } + event(fmt.Sprintf("gov/MsgVote/%v", result.IsOK())) + action = fmt.Sprintf("TestMsgVote: ok %v, msg %s", result.IsOK(), msg.GetSignBytes()) + return action, nil + } +} + +// Pick a random deposit +func randomDeposit(r *rand.Rand) sdk.Coins { + // TODO Choose based on account balance and min deposit + amount := int64(r.Intn(20)) + 1 + return sdk.Coins{sdk.NewInt64Coin(denom, amount)} +} + +// Pick a random proposal ID +func randomProposalID(r *rand.Rand, k gov.Keeper, ctx sdk.Context) (proposalID int64, ok bool) { + lastProposalID := k.GetLastProposalID(ctx) + if lastProposalID < 1 { + return 0, false + } + proposalID = int64(r.Intn(int(lastProposalID))) + return proposalID, true +} + +// Pick a random voting option +func randomVotingOption(r *rand.Rand) gov.VoteOption { + switch r.Intn(4) { + case 0: + return gov.OptionYes + case 1: + return gov.OptionAbstain + case 2: + return gov.OptionNo + case 3: + return gov.OptionNoWithVeto + } + panic("should not happen") +} diff --git a/x/gov/simulation/sim_test.go b/x/gov/simulation/sim_test.go new file mode 100644 index 0000000000..691aa1cd2d --- /dev/null +++ b/x/gov/simulation/sim_test.go @@ -0,0 +1,69 @@ +package simulation + +import ( + "encoding/json" + "math/rand" + "testing" + + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/gov" + "github.com/cosmos/cosmos-sdk/x/mock" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" + "github.com/cosmos/cosmos-sdk/x/params" + "github.com/cosmos/cosmos-sdk/x/stake" +) + +// TestGovWithRandomMessages +func TestGovWithRandomMessages(t *testing.T) { + mapp := mock.NewApp() + + bank.RegisterWire(mapp.Cdc) + gov.RegisterWire(mapp.Cdc) + mapper := mapp.AccountMapper + coinKeeper := bank.NewKeeper(mapper) + stakeKey := sdk.NewKVStoreKey("stake") + stakeKeeper := stake.NewKeeper(mapp.Cdc, stakeKey, coinKeeper, stake.DefaultCodespace) + paramKey := sdk.NewKVStoreKey("params") + paramKeeper := params.NewKeeper(mapp.Cdc, paramKey) + govKey := sdk.NewKVStoreKey("gov") + govKeeper := gov.NewKeeper(mapp.Cdc, govKey, paramKeeper.Setter(), coinKeeper, stakeKeeper, gov.DefaultCodespace) + mapp.Router().AddRoute("gov", gov.NewHandler(govKeeper)) + mapp.SetEndBlocker(func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + gov.EndBlocker(ctx, govKeeper) + return abci.ResponseEndBlock{} + }) + + err := mapp.CompleteSetup([]*sdk.KVStoreKey{stakeKey, paramKey, govKey}) + if err != nil { + panic(err) + } + + appStateFn := func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage { + mock.RandomSetGenesis(r, mapp, accs, []string{"stake"}) + return json.RawMessage("{}") + } + + setup := func(r *rand.Rand, privKeys []crypto.PrivKey) { + ctx := mapp.NewContext(false, abci.Header{}) + stake.InitGenesis(ctx, stakeKeeper, stake.DefaultGenesisState()) + gov.InitGenesis(ctx, govKeeper, gov.DefaultGenesisState()) + } + + simulation.Simulate( + t, mapp.BaseApp, appStateFn, + []simulation.TestAndRunTx{ + SimulateMsgSubmitProposal(govKeeper, stakeKeeper), + SimulateMsgDeposit(govKeeper, stakeKeeper), + SimulateMsgVote(govKeeper, stakeKeeper), + }, []simulation.RandSetup{ + setup, + }, []simulation.Invariant{ + AllInvariants(), + }, 10, 100, + false, + ) +} diff --git a/x/gov/tally.go b/x/gov/tally.go index fc5b4317b2..cfb113ae33 100644 --- a/x/gov/tally.go +++ b/x/gov/tally.go @@ -24,8 +24,8 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall currValidators := make(map[string]validatorGovInfo) keeper.vs.IterateValidatorsBonded(ctx, func(index int64, validator sdk.Validator) (stop bool) { - currValidators[validator.GetOwner().String()] = validatorGovInfo{ - Address: validator.GetOwner(), + currValidators[validator.GetOperator().String()] = validatorGovInfo{ + Address: validator.GetOperator(), Power: validator.GetPower(), DelegatorShares: validator.GetDelegatorShares(), Minus: sdk.ZeroDec(), @@ -36,6 +36,7 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall // iterate over all the votes votesIterator := keeper.GetVotes(ctx, proposal.GetProposalID()) + defer votesIterator.Close() for ; votesIterator.Valid(); votesIterator.Next() { vote := &Vote{} keeper.cdc.MustUnmarshalBinary(votesIterator.Value(), vote) @@ -64,7 +65,6 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall keeper.deleteVote(ctx, vote.ProposalID, vote.Voter) } - votesIterator.Close() // Iterate over the validators again to tally their voting power and see who didn't vote nonVoting = []sdk.AccAddress{} diff --git a/x/gov/tally_test.go b/x/gov/tally_test.go index 730885266f..157f594401 100644 --- a/x/gov/tally_test.go +++ b/x/gov/tally_test.go @@ -354,7 +354,7 @@ func TestTallyDelgatorMultipleInherit(t *testing.T) { require.False(t, tallyResults.Equals(EmptyTallyResult())) } -func TestTallyRevokedValidator(t *testing.T) { +func TestTallyJailedValidator(t *testing.T) { mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) mapp.BeginBlock(abci.RequestBeginBlock{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{}) @@ -368,7 +368,7 @@ func TestTallyRevokedValidator(t *testing.T) { val2, found := sk.GetValidator(ctx, addrs[1]) require.True(t, found) - sk.Revoke(ctx, val2.PubKey) + sk.Jail(ctx, val2.PubKey) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) proposalID := proposal.GetProposalID() diff --git a/x/mock/app.go b/x/mock/app.go index 53b6345b00..f472c5531c 100644 --- a/x/mock/app.go +++ b/x/mock/app.go @@ -11,6 +11,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/secp256k1" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" ) @@ -173,7 +174,32 @@ 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] = ed25519.GenPrivKey() + if rand.Int63()%2 == 0 { + keys[i] = secp256k1.GenPrivKey() + } else { + keys[i] = ed25519.GenPrivKey() + } + addrs[i] = sdk.AccAddress(keys[i].PubKey().Address()) + } + return +} + +// GeneratePrivKeyAddressPairsFromRand generates a total of n private key, address +// pairs using the provided randomness source. +func GeneratePrivKeyAddressPairsFromRand(rand *rand.Rand, n int) (keys []crypto.PrivKey, addrs []sdk.AccAddress) { + keys = make([]crypto.PrivKey, n, n) + addrs = make([]sdk.AccAddress, n, n) + for i := 0; i < n; i++ { + secret := make([]byte, 32) + _, err := rand.Read(secret) + if err != nil { + panic("Could not read randomness") + } + if rand.Int63()%2 == 0 { + keys[i] = secp256k1.GenPrivKeySecp256k1(secret) + } else { + keys[i] = ed25519.GenPrivKeyFromSecret(secret) + } addrs[i] = sdk.AccAddress(keys[i].PubKey().Address()) } return diff --git a/x/mock/simulation/constants.go b/x/mock/simulation/constants.go new file mode 100644 index 0000000000..985a22dcac --- /dev/null +++ b/x/mock/simulation/constants.go @@ -0,0 +1,31 @@ +package simulation + +const ( + // Fraction of double-signing evidence from a past height + pastEvidenceFraction float64 = 0.5 + + // Minimum time per block + minTimePerBlock int64 = 86400 / 2 + + // Maximum time per block + maxTimePerBlock int64 = 86400 + + // Number of keys + numKeys int = 250 + + // Chance that double-signing evidence is found on a given block + evidenceFraction float64 = 0.01 + + // TODO Remove in favor of binary search for invariant violation + onOperation bool = false +) + +var ( + // Currently there are 3 different liveness types, fully online, spotty connection, offline. + initialLivenessWeightings = []int{40, 5, 5} + livenessTransitionMatrix, _ = CreateTransitionMatrix([][]int{ + {90, 20, 1}, + {10, 50, 5}, + {0, 10, 1000}, + }) +) diff --git a/x/mock/simulation/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go index 5f507b89c1..c7e6166149 100644 --- a/x/mock/simulation/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -4,78 +4,232 @@ import ( "encoding/json" "fmt" "math/rand" + "sort" "testing" "time" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" + tmtypes "github.com/tendermint/tendermint/types" + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/mock" "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" ) // Simulate tests application by sending random messages. func Simulate( - t *testing.T, app *baseapp.BaseApp, appStateFn func(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage, ops []TestAndRunTx, setups []RandSetup, - invariants []Invariant, numKeys int, numBlocks int, blockSize int, + t *testing.T, app *baseapp.BaseApp, appStateFn func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage, ops []TestAndRunTx, setups []RandSetup, + invariants []Invariant, numBlocks int, blockSize int, commit bool, ) { time := time.Now().UnixNano() - SimulateFromSeed(t, app, appStateFn, time, ops, setups, invariants, numKeys, numBlocks, blockSize) + SimulateFromSeed(t, app, appStateFn, time, ops, setups, invariants, numBlocks, blockSize, commit) } // SimulateFromSeed tests an application by running the provided // operations, testing the provided invariants, but using the provided seed. func SimulateFromSeed( - t *testing.T, app *baseapp.BaseApp, appStateFn func(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage, seed int64, ops []TestAndRunTx, setups []RandSetup, - invariants []Invariant, numKeys int, numBlocks int, blockSize int, + t *testing.T, app *baseapp.BaseApp, appStateFn func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage, seed int64, ops []TestAndRunTx, setups []RandSetup, + invariants []Invariant, numBlocks int, blockSize int, commit bool, ) { log := fmt.Sprintf("Starting SimulateFromSeed with randomness created with seed %d", int(seed)) - keys, addrs := mock.GeneratePrivKeyAddressPairs(numKeys) + fmt.Printf("%s\n", log) r := rand.New(rand.NewSource(seed)) + keys, accs := mock.GeneratePrivKeyAddressPairsFromRand(r, numKeys) // Setup event stats events := make(map[string]uint) event := func(what string) { + log += "\nevent - " + what events[what]++ } - app.InitChain(abci.RequestInitChain{AppStateBytes: appStateFn(r, addrs)}) + timestamp := time.Unix(0, 0) + timeDiff := maxTimePerBlock - minTimePerBlock + + res := app.InitChain(abci.RequestInitChain{AppStateBytes: appStateFn(r, keys, accs)}) + validators := make(map[string]mockValidator) + for _, validator := range res.Validators { + validators[string(validator.Address)] = mockValidator{validator, GetMemberOfInitialState(r, initialLivenessWeightings)} + } + for i := 0; i < len(setups); i++ { setups[i](r, keys) } - app.Commit() - header := abci.Header{Height: 0} + header := abci.Header{Height: 0, Time: timestamp} + opCount := 0 + + request := abci.RequestBeginBlock{Header: header} + + var pastTimes []time.Time for i := 0; i < numBlocks; i++ { - app.BeginBlock(abci.RequestBeginBlock{}) - // Make sure invariants hold at beginning of block and when nothing was - // done. + // Log the header time for future lookup + pastTimes = append(pastTimes, header.Time) + + // Run the BeginBlock handler + app.BeginBlock(request) + + log += "\nBeginBlock" + + // Make sure invariants hold at beginning of block AssertAllInvariants(t, app, invariants, log) ctx := app.NewContext(false, header) - // TODO: Add modes to simulate "no load", "medium load", and - // "high load" blocks. - for j := 0; j < blockSize; j++ { + var thisBlockSize int + load := r.Float64() + switch { + case load < 0.33: + thisBlockSize = 0 + case load < 0.66: + thisBlockSize = r.Intn(blockSize * 2) + default: + thisBlockSize = r.Intn(blockSize * 4) + } + for j := 0; j < thisBlockSize; j++ { logUpdate, err := ops[r.Intn(len(ops))](t, r, app, ctx, keys, log, event) log += "\n" + logUpdate require.Nil(t, err, log) - AssertAllInvariants(t, app, invariants, log) + if onOperation { + AssertAllInvariants(t, app, invariants, log) + } + if opCount%200 == 0 { + fmt.Printf("\rSimulating... block %d/%d, operation %d.", header.Height, numBlocks, opCount) + } + opCount++ } - app.EndBlock(abci.RequestEndBlock{}) + res := app.EndBlock(abci.RequestEndBlock{}) header.Height++ + header.Time = header.Time.Add(time.Duration(minTimePerBlock) * time.Second).Add(time.Duration(int64(r.Intn(int(timeDiff)))) * time.Second) + + log += "\nEndBlock" + + // Make sure invariants hold at end of block + AssertAllInvariants(t, app, invariants, log) + + if commit { + app.Commit() + } + + // Generate a random RequestBeginBlock with the current validator set for the next block + request = RandomRequestBeginBlock(t, r, validators, livenessTransitionMatrix, evidenceFraction, pastTimes, event, header, log) + + // Update the validator set + validators = updateValidators(t, r, validators, res.ValidatorUpdates, event) } + fmt.Printf("\nSimulation complete. Final height (blocks): %d, final time (seconds): %v\n", header.Height, header.Time) DisplayEvents(events) } +func getKeys(validators map[string]mockValidator) []string { + keys := make([]string, len(validators)) + i := 0 + for key := range validators { + keys[i] = key + i++ + } + sort.Strings(keys) + return keys +} + +// RandomRequestBeginBlock generates a list of signing validators according to the provided list of validators, signing fraction, and evidence fraction +func RandomRequestBeginBlock(t *testing.T, r *rand.Rand, validators map[string]mockValidator, livenessTransitions TransitionMatrix, evidenceFraction float64, + pastTimes []time.Time, event func(string), header abci.Header, log string) abci.RequestBeginBlock { + if len(validators) == 0 { + return abci.RequestBeginBlock{Header: header} + } + signingValidators := make([]abci.SigningValidator, len(validators)) + i := 0 + + for _, key := range getKeys(validators) { + mVal := validators[key] + mVal.livenessState = livenessTransitions.NextState(r, mVal.livenessState) + signed := true + + if mVal.livenessState == 1 { + // spotty connection, 50% probability of success + // See https://github.com/golang/go/issues/23804#issuecomment-365370418 + // for reasoning behind computing like this + signed = r.Int63()%2 == 0 + } else if mVal.livenessState == 2 { + // offline + signed = false + } + if signed { + event("beginblock/signing/signed") + } else { + event("beginblock/signing/missed") + } + signingValidators[i] = abci.SigningValidator{ + Validator: mVal.val, + SignedLastBlock: signed, + } + i++ + } + evidence := make([]abci.Evidence, 0) + for r.Float64() < evidenceFraction { + height := header.Height + time := header.Time + if r.Float64() < pastEvidenceFraction { + height = int64(r.Intn(int(header.Height))) + time = pastTimes[height] + } + validator := signingValidators[r.Intn(len(signingValidators))].Validator + var currentTotalVotingPower int64 + for _, mVal := range validators { + currentTotalVotingPower += mVal.val.Power + } + evidence = append(evidence, abci.Evidence{ + Type: tmtypes.ABCIEvidenceTypeDuplicateVote, + Validator: validator, + Height: height, + Time: time, + TotalVotingPower: currentTotalVotingPower, + }) + event("beginblock/evidence") + } + return abci.RequestBeginBlock{ + Header: header, + LastCommitInfo: abci.LastCommitInfo{ + Validators: signingValidators, + }, + ByzantineValidators: evidence, + } +} + // AssertAllInvariants asserts a list of provided invariants against application state func AssertAllInvariants(t *testing.T, app *baseapp.BaseApp, tests []Invariant, log string) { for i := 0; i < len(tests); i++ { tests[i](t, app, log) } } + +// updateValidators mimicks Tendermint's update logic +func updateValidators(t *testing.T, r *rand.Rand, current map[string]mockValidator, updates []abci.Validator, event func(string)) map[string]mockValidator { + for _, update := range updates { + switch { + case update.Power == 0: + require.NotNil(t, current[string(update.PubKey.Data)], "tried to delete a nonexistent validator") + event("endblock/validatorupdates/kicked") + delete(current, string(update.PubKey.Data)) + default: + // Does validator already exist? + if mVal, ok := current[string(update.PubKey.Data)]; ok { + mVal.val = update + event("endblock/validatorupdates/updated") + } else { + // Set this new validator + current[string(update.PubKey.Data)] = mockValidator{update, GetMemberOfInitialState(r, initialLivenessWeightings)} + event("endblock/validatorupdates/added") + } + } + } + return current +} diff --git a/x/mock/simulation/transition_matrix.go b/x/mock/simulation/transition_matrix.go new file mode 100644 index 0000000000..39bdb1e4f9 --- /dev/null +++ b/x/mock/simulation/transition_matrix.go @@ -0,0 +1,70 @@ +package simulation + +import ( + "fmt" + "math/rand" +) + +// TransitionMatrix is _almost_ a left stochastic matrix. +// It is technically not one due to not normalizing the column values. +// In the future, if we want to find the steady state distribution, +// it will be quite easy to normalize these values to get a stochastic matrix. +// Floats aren't currently used as the default due to non-determinism across +// architectures +type TransitionMatrix struct { + weights [][]int + // total in each column + totals []int + n int +} + +// CreateTransitionMatrix creates a transition matrix from the provided weights. +// TODO: Provide example usage +func CreateTransitionMatrix(weights [][]int) (TransitionMatrix, error) { + n := len(weights) + for i := 0; i < n; i++ { + if len(weights[i]) != n { + return TransitionMatrix{}, fmt.Errorf("Transition Matrix: Non-square matrix provided, error on row %d", i) + } + } + totals := make([]int, n) + for row := 0; row < n; row++ { + for col := 0; col < n; col++ { + totals[col] += weights[row][col] + } + } + return TransitionMatrix{weights, totals, n}, nil +} + +// NextState returns the next state randomly chosen using r, and the weightings provided +// in the transition matrix. +func (t TransitionMatrix) NextState(r *rand.Rand, i int) int { + randNum := r.Intn(t.totals[i]) + for row := 0; row < t.n; row++ { + if randNum < t.weights[row][i] { + return row + } + randNum -= t.weights[row][i] + } + // This line should never get executed + return -1 +} + +// GetMemberOfInitialState takes an initial array of weights, of size n. +// It returns a weighted random number in [0,n). +func GetMemberOfInitialState(r *rand.Rand, weights []int) int { + n := len(weights) + total := 0 + for i := 0; i < n; i++ { + total += weights[i] + } + randNum := r.Intn(total) + for state := 0; state < n; state++ { + if randNum < weights[state] { + return state + } + randNum -= weights[state] + } + // This line should never get executed + return -1 +} diff --git a/x/mock/simulation/types.go b/x/mock/simulation/types.go index 6e1d9f198f..35769b0b25 100644 --- a/x/mock/simulation/types.go +++ b/x/mock/simulation/types.go @@ -6,6 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" + abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" ) @@ -25,6 +26,11 @@ type ( // If the invariant has been broken, the function should halt the // test and output the log. Invariant func(t *testing.T, app *baseapp.BaseApp, log string) + + mockValidator struct { + val abci.Validator + livenessState int + } ) // PeriodicInvariant returns an Invariant function closure that asserts diff --git a/x/mock/simulation/util.go b/x/mock/simulation/util.go index 14227a1aef..1d64ba30dd 100644 --- a/x/mock/simulation/util.go +++ b/x/mock/simulation/util.go @@ -3,8 +3,9 @@ package simulation import ( "fmt" "math/rand" + "sort" - crypto "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -39,8 +40,15 @@ func RandStringOfLength(r *rand.Rand, n int) string { // Pretty-print events as a table func DisplayEvents(events map[string]uint) { - // TODO - fmt.Printf("Events: %v\n", events) + var keys []string + for key := range events { + keys = append(keys, key) + } + sort.Strings(keys) + fmt.Printf("Event statistics: \n") + for _, key := range keys { + fmt.Printf(" % 60s => %d\n", key, events[key]) + } } // Pick a random key from an array diff --git a/x/slashing/app_test.go b/x/slashing/app_test.go index 1e6a4e89d4..86d350a84b 100644 --- a/x/slashing/app_test.go +++ b/x/slashing/app_test.go @@ -107,15 +107,15 @@ func TestSlashingMsgs(t *testing.T) { mapp.BeginBlock(abci.RequestBeginBlock{}) validator := checkValidator(t, mapp, stakeKeeper, addr1, true) - require.Equal(t, addr1, validator.Owner) + require.Equal(t, addr1, validator.Operator) require.Equal(t, sdk.Bonded, validator.Status) require.True(sdk.DecEq(t, sdk.NewDec(10), validator.BondedTokens())) - unrevokeMsg := MsgUnrevoke{ValidatorAddr: sdk.AccAddress(validator.PubKey.Address())} + unjailMsg := MsgUnjail{ValidatorAddr: sdk.AccAddress(validator.PubKey.Address())} // no signing info yet checkValidatorSigningInfo(t, mapp, keeper, sdk.ValAddress(addr1), false) - // unrevoke should fail with unknown validator - res := mock.SignCheckDeliver(t, mapp.BaseApp, []sdk.Msg{unrevokeMsg}, []int64{0}, []int64{1}, false, priv1) - require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotRevoked), res.Code) + // unjail should fail with unknown validator + res := mock.SignCheckDeliver(t, mapp.BaseApp, []sdk.Msg{unjailMsg}, []int64{0}, []int64{1}, false, priv1) + require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotJailed), res.Code) } diff --git a/x/slashing/client/cli/flags.go b/x/slashing/client/cli/flags.go index 43f8fa90a2..09db8e8258 100644 --- a/x/slashing/client/cli/flags.go +++ b/x/slashing/client/cli/flags.go @@ -2,5 +2,5 @@ package cli // nolint const ( - FlagAddressValidator = "address-validator" + FlagAddressValidator = "validator" ) diff --git a/x/slashing/client/cli/tx.go b/x/slashing/client/cli/tx.go index 5085f5aacc..5831ef3100 100644 --- a/x/slashing/client/cli/tx.go +++ b/x/slashing/client/cli/tx.go @@ -14,12 +14,12 @@ import ( "github.com/spf13/cobra" ) -// GetCmdUnrevoke implements the create unrevoke validator command. -func GetCmdUnrevoke(cdc *wire.Codec) *cobra.Command { +// GetCmdUnjail implements the create unjail validator command. +func GetCmdUnjail(cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "unrevoke", + Use: "unjail", Args: cobra.ExactArgs(0), - Short: "unrevoke validator previously revoked for downtime", + Short: "unjail validator previously jailed for downtime", RunE: func(cmd *cobra.Command, args []string) error { txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc) cliCtx := context.NewCLIContext(). @@ -32,7 +32,7 @@ func GetCmdUnrevoke(cdc *wire.Codec) *cobra.Command { return err } - msg := slashing.NewMsgUnrevoke(validatorAddr) + msg := slashing.NewMsgUnjail(validatorAddr) return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg}) }, diff --git a/x/slashing/client/rest/tx.go b/x/slashing/client/rest/tx.go index 2ecec51ea8..6e45230b01 100644 --- a/x/slashing/client/rest/tx.go +++ b/x/slashing/client/rest/tx.go @@ -19,13 +19,13 @@ import ( func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { r.HandleFunc( - "/slashing/unrevoke", - unrevokeRequestHandlerFn(cdc, kb, cliCtx), + "/slashing/unjail", + unjailRequestHandlerFn(cdc, kb, cliCtx), ).Methods("POST") } -// Unrevoke TX body -type UnrevokeBody struct { +// Unjail TX body +type UnjailBody struct { LocalAccountName string `json:"name"` Password string `json:"password"` ChainID string `json:"chain_id"` @@ -35,9 +35,9 @@ type UnrevokeBody struct { ValidatorAddr string `json:"validator_addr"` } -func unrevokeRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc { +func unjailRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var m UnrevokeBody + var m UnjailBody body, err := ioutil.ReadAll(r.Body) if err != nil { w.WriteHeader(http.StatusBadRequest) @@ -79,7 +79,7 @@ func unrevokeRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.C Gas: m.Gas, } - msg := slashing.NewMsgUnrevoke(validatorAddr) + msg := slashing.NewMsgUnjail(validatorAddr) txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg}) if err != nil { diff --git a/x/slashing/errors.go b/x/slashing/errors.go index 3139c1662f..4573d5e145 100644 --- a/x/slashing/errors.go +++ b/x/slashing/errors.go @@ -12,9 +12,9 @@ const ( // Default slashing codespace DefaultCodespace sdk.CodespaceType = 10 - CodeInvalidValidator CodeType = 101 - CodeValidatorJailed CodeType = 102 - CodeValidatorNotRevoked CodeType = 103 + CodeInvalidValidator CodeType = 101 + CodeValidatorJailed CodeType = 102 + CodeValidatorNotJailed CodeType = 103 ) func ErrNoValidatorForAddress(codespace sdk.CodespaceType) sdk.Error { @@ -24,8 +24,8 @@ func ErrBadValidatorAddr(codespace sdk.CodespaceType) sdk.Error { return sdk.NewError(codespace, CodeInvalidValidator, "validator does not exist for that address") } func ErrValidatorJailed(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeValidatorJailed, "validator jailed, cannot yet be unrevoked") + return sdk.NewError(codespace, CodeValidatorJailed, "validator still jailed, cannot yet be unjailed") } -func ErrValidatorNotRevoked(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeValidatorNotRevoked, "validator not revoked, cannot be unrevoked") +func ErrValidatorNotJailed(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeValidatorNotJailed, "validator not jailed, cannot be unjailed") } diff --git a/x/slashing/handler.go b/x/slashing/handler.go index 0cb64ab409..d79ea73c2d 100644 --- a/x/slashing/handler.go +++ b/x/slashing/handler.go @@ -8,17 +8,17 @@ func NewHandler(k Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { // NOTE msg already has validate basic run switch msg := msg.(type) { - case MsgUnrevoke: - return handleMsgUnrevoke(ctx, msg, k) + case MsgUnjail: + return handleMsgUnjail(ctx, msg, k) default: return sdk.ErrTxDecode("invalid message parse in staking module").Result() } } } -// Validators must submit a transaction to unrevoke itself after -// having been revoked (and thus unbonded) for downtime -func handleMsgUnrevoke(ctx sdk.Context, msg MsgUnrevoke, k Keeper) sdk.Result { +// Validators must submit a transaction to unjail itself after +// having been jailed (and thus unbonded) for downtime +func handleMsgUnjail(ctx sdk.Context, msg MsgUnjail, k Keeper) sdk.Result { // Validator must exist validator := k.validatorSet.Validator(ctx, msg.ValidatorAddr) @@ -26,8 +26,8 @@ func handleMsgUnrevoke(ctx sdk.Context, msg MsgUnrevoke, k Keeper) sdk.Result { return ErrNoValidatorForAddress(k.codespace).Result() } - if !validator.GetRevoked() { - return ErrValidatorNotRevoked(k.codespace).Result() + if !validator.GetJailed() { + return ErrValidatorNotJailed(k.codespace).Result() } addr := sdk.ValAddress(validator.GetPubKey().Address()) @@ -38,19 +38,19 @@ func handleMsgUnrevoke(ctx sdk.Context, msg MsgUnrevoke, k Keeper) sdk.Result { return ErrNoValidatorForAddress(k.codespace).Result() } - // Cannot be unrevoked until out of jail + // Cannot be unjailed until out of jail if ctx.BlockHeader().Time.Before(info.JailedUntil) { return ErrValidatorJailed(k.codespace).Result() } - // Update the starting height (so the validator can't be immediately revoked again) + // Update the starting height (so the validator can't be immediately jailed again) info.StartHeight = ctx.BlockHeight() k.setValidatorSigningInfo(ctx, addr, info) - // Unrevoke the validator - k.validatorSet.Unrevoke(ctx, validator.GetPubKey()) + // Unjail the validator + k.validatorSet.Unjail(ctx, validator.GetPubKey()) - tags := sdk.NewTags("action", []byte("unrevoke"), "validator", []byte(msg.ValidatorAddr.String())) + tags := sdk.NewTags("action", []byte("unjail"), "validator", []byte(msg.ValidatorAddr.String())) return sdk.Result{ Tags: tags, diff --git a/x/slashing/handler_test.go b/x/slashing/handler_test.go index 41cb5d1996..4408d3c09d 100644 --- a/x/slashing/handler_test.go +++ b/x/slashing/handler_test.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" ) -func TestCannotUnrevokeUnlessRevoked(t *testing.T) { +func TestCannotUnjailUnlessJailed(t *testing.T) { // initial setup ctx, ck, sk, _, keeper := createTestInput(t) slh := NewHandler(keeper) @@ -22,8 +22,8 @@ func TestCannotUnrevokeUnlessRevoked(t *testing.T) { require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}}) require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower())) - // assert non-revoked validator can't be unrevoked - got = slh(ctx, NewMsgUnrevoke(addr)) - require.False(t, got.IsOK(), "allowed unrevoke of non-revoked validator") - require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotRevoked), got.Code) + // assert non-jailed validator can't be unjailed + got = slh(ctx, NewMsgUnjail(addr)) + require.False(t, got.IsOK(), "allowed unjail of non-jailed validator") + require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotJailed), got.Code) } diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index 2f163e57a9..6d8e47cbe2 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -36,11 +36,15 @@ func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, vs sdk.ValidatorSet, params pa } // handle a validator signing two blocks at the same height -func (k Keeper) handleDoubleSign(ctx sdk.Context, pubkey crypto.PubKey, infractionHeight int64, timestamp time.Time, power int64) { +func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractionHeight int64, timestamp time.Time, power int64) { logger := ctx.Logger().With("module", "x/slashing") time := ctx.BlockHeader().Time age := time.Sub(timestamp) - address := sdk.ValAddress(pubkey.Address()) + address := sdk.ValAddress(addr) + pubkey, err := k.getPubkey(ctx, addr) + if err != nil { + panic(fmt.Sprintf("Validator address %v not found", addr)) + } // Double sign too old maxEvidenceAge := k.MaxEvidenceAge(ctx) @@ -55,10 +59,10 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, pubkey crypto.PubKey, infracti // Slash validator k.validatorSet.Slash(ctx, pubkey, infractionHeight, power, k.SlashFractionDoubleSign(ctx)) - // Revoke validator - k.validatorSet.Revoke(ctx, pubkey) - // Jail validator + k.validatorSet.Jail(ctx, pubkey) + + // Set validator jail duration signInfo, found := k.getValidatorSigningInfo(ctx, address) if !found { panic(fmt.Sprintf("Expected signing info for validator %s but not found", address)) @@ -109,16 +113,16 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p minHeight := signInfo.StartHeight + k.SignedBlocksWindow(ctx) if height > minHeight && signInfo.SignedBlocksCounter < k.MinSignedPerWindow(ctx) { validator := k.validatorSet.ValidatorByPubKey(ctx, pubkey) - if validator != nil && !validator.GetRevoked() { - // Downtime confirmed, slash, revoke, and jail the validator + if validator != nil && !validator.GetJailed() { + // Downtime confirmed: slash 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, k.MinSignedPerWindow(ctx))) k.validatorSet.Slash(ctx, pubkey, height, power, k.SlashFractionDowntime(ctx)) - k.validatorSet.Revoke(ctx, pubkey) + k.validatorSet.Jail(ctx, pubkey) signInfo.JailedUntil = ctx.BlockHeader().Time.Add(k.DowntimeUnbondDuration(ctx)) } 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", + // Validator was (a) not found or (b) already jailed, don't slash + logger.Info(fmt.Sprintf("Validator %s would have been slashed for downtime, but was either not found in store or already jailed", pubkey.Address())) } } diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index 68de7a43c5..808c82014e 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -37,18 +37,18 @@ func TestHandleDoubleSign(t *testing.T) { keeper.handleValidatorSignature(ctx, val.Address(), amtInt, true) // double sign less than max age - keeper.handleDoubleSign(ctx, val, 0, time.Unix(0, 0), amtInt) + keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), amtInt) - // should be revoked - require.True(t, sk.Validator(ctx, addr).GetRevoked()) - // unrevoke to measure power - sk.Unrevoke(ctx, val) + // should be jailed + require.True(t, sk.Validator(ctx, addr).GetJailed()) + // unjail to measure power + sk.Unjail(ctx, val) // power should be reduced require.Equal(t, sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20))), sk.Validator(ctx, addr).GetPower()) ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.MaxEvidenceAge(ctx))}) // double sign past max age - keeper.handleDoubleSign(ctx, val, 0, time.Unix(0, 0), amtInt) + keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), amtInt) require.Equal(t, sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20))), sk.Validator(ctx, addr).GetPower()) } @@ -112,17 +112,17 @@ func TestHandleAbsentValidator(t *testing.T) { require.Equal(t, int64(0), info.StartHeight) require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-1, info.SignedBlocksCounter) - // validator should have been revoked + // validator should have been jailed validator, _ = sk.GetValidatorByPubKey(ctx, val) require.Equal(t, sdk.Unbonded, validator.GetStatus()) // unrevocation should fail prior to jail expiration - got = slh(ctx, NewMsgUnrevoke(addr)) + got = slh(ctx, NewMsgUnjail(addr)) require.False(t, got.IsOK()) // unrevocation should succeed after jail expiration ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.DowntimeUnbondDuration(ctx))}) - got = slh(ctx, NewMsgUnrevoke(addr)) + got = slh(ctx, NewMsgUnjail(addr)) require.True(t, got.IsOK()) // validator should be rebonded now @@ -140,7 +140,7 @@ func TestHandleAbsentValidator(t *testing.T) { require.Equal(t, height, info.StartHeight) require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-1, info.SignedBlocksCounter) - // validator should not be immediately revoked again + // validator should not be immediately jailed again height++ ctx = ctx.WithBlockHeight(height) keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false) @@ -154,7 +154,7 @@ func TestHandleAbsentValidator(t *testing.T) { keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false) } - // validator should be revoked again after 500 unsigned blocks + // validator should be jailed again after 500 unsigned blocks nextHeight = height + keeper.MinSignedPerWindow(ctx) + 1 for ; height <= nextHeight; height++ { ctx = ctx.WithBlockHeight(height) @@ -166,7 +166,7 @@ func TestHandleAbsentValidator(t *testing.T) { // Test a new validator entering the validator set // Ensure that SigningInfo.StartHeight is set correctly -// and that they are not immediately revoked +// and that they are not immediately jailed func TestHandleNewValidator(t *testing.T) { // initial setup ctx, ck, sk, _, keeper := createTestInput(t) @@ -194,16 +194,16 @@ func TestHandleNewValidator(t *testing.T) { require.Equal(t, int64(1), info.SignedBlocksCounter) require.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil) - // validator should be bonded still, should not have been revoked or slashed + // validator should be bonded still, should not have been jailed or slashed validator, _ := sk.GetValidatorByPubKey(ctx, val) require.Equal(t, sdk.Bonded, validator.GetStatus()) pool := sk.GetPool(ctx) require.Equal(t, int64(100), pool.BondedTokens.RoundInt64()) } -// Test a revoked validator being "down" twice +// Test a jailed validator being "down" twice // Ensure that they're only slashed once -func TestHandleAlreadyRevoked(t *testing.T) { +func TestHandleAlreadyJailed(t *testing.T) { // initial setup ctx, _, sk, _, keeper := createTestInput(t) @@ -228,7 +228,7 @@ func TestHandleAlreadyRevoked(t *testing.T) { keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false) } - // validator should have been revoked and slashed + // validator should have been jailed and slashed validator, _ := sk.GetValidatorByPubKey(ctx, val) require.Equal(t, sdk.Unbonded, validator.GetStatus()) diff --git a/x/slashing/msg.go b/x/slashing/msg.go index 4b1483dce9..e22eca7bdd 100644 --- a/x/slashing/msg.go +++ b/x/slashing/msg.go @@ -11,25 +11,25 @@ var cdc = wire.NewCodec() const MsgType = "slashing" // verify interface at compile time -var _ sdk.Msg = &MsgUnrevoke{} +var _ sdk.Msg = &MsgUnjail{} -// MsgUnrevoke - struct for unrevoking revoked validator -type MsgUnrevoke struct { +// MsgUnjail - struct for unjailing jailed validator +type MsgUnjail struct { ValidatorAddr sdk.AccAddress `json:"address"` // address of the validator owner } -func NewMsgUnrevoke(validatorAddr sdk.AccAddress) MsgUnrevoke { - return MsgUnrevoke{ +func NewMsgUnjail(validatorAddr sdk.AccAddress) MsgUnjail { + return MsgUnjail{ ValidatorAddr: validatorAddr, } } //nolint -func (msg MsgUnrevoke) Type() string { return MsgType } -func (msg MsgUnrevoke) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.ValidatorAddr} } +func (msg MsgUnjail) Type() string { return MsgType } +func (msg MsgUnjail) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.ValidatorAddr} } // get the bytes for the message signer to sign on -func (msg MsgUnrevoke) GetSignBytes() []byte { +func (msg MsgUnjail) GetSignBytes() []byte { b, err := cdc.MarshalJSON(msg) if err != nil { panic(err) @@ -38,7 +38,7 @@ func (msg MsgUnrevoke) GetSignBytes() []byte { } // quick validity check -func (msg MsgUnrevoke) ValidateBasic() sdk.Error { +func (msg MsgUnjail) ValidateBasic() sdk.Error { if msg.ValidatorAddr == nil { return ErrBadValidatorAddr(DefaultCodespace) } diff --git a/x/slashing/msg_test.go b/x/slashing/msg_test.go index 287eb6c5c5..ef2e673c86 100644 --- a/x/slashing/msg_test.go +++ b/x/slashing/msg_test.go @@ -8,9 +8,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -func TestMsgUnrevokeGetSignBytes(t *testing.T) { +func TestMsgUnjailGetSignBytes(t *testing.T) { addr := sdk.AccAddress("abcd") - msg := NewMsgUnrevoke(addr) + msg := NewMsgUnjail(addr) bytes := msg.GetSignBytes() require.Equal(t, string(bytes), `{"address":"cosmosaccaddr1v93xxeqhyqz5v"}`) } diff --git a/x/slashing/params.go b/x/slashing/params.go index a25d121c94..6e18e5f481 100644 --- a/x/slashing/params.go +++ b/x/slashing/params.go @@ -66,8 +66,8 @@ var ( // TODO Temporarily set to five minutes for testnets defaultDoubleSignUnbondDuration int64 = 60 * 5 - // TODO Temporarily set to 100 blocks for testnets - defaultSignedBlocksWindow int64 = 100 + // TODO Temporarily set to 10000 blocks for testnets + defaultSignedBlocksWindow int64 = 10000 // TODO Temporarily set to 10 minutes for testnets defaultDowntimeUnbondDuration int64 = 60 * 10 diff --git a/x/slashing/signing_info.go b/x/slashing/signing_info.go index a21917e796..25a83e833d 100644 --- a/x/slashing/signing_info.go +++ b/x/slashing/signing_info.go @@ -60,9 +60,9 @@ func NewValidatorSigningInfo(startHeight int64, indexOffset int64, jailedUntil t // Signing info for a validator type ValidatorSigningInfo struct { - StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unrevoked + StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unjailed IndexOffset int64 `json:"index_offset"` // index offset into signed block bit array - JailedUntil time.Time `json:"jailed_until"` // timestamp validator cannot be unrevoked until + JailedUntil time.Time `json:"jailed_until"` // timestamp validator cannot be unjailed until SignedBlocksCounter int64 `json:"signed_blocks_counter"` // signed blocks counter (to avoid scanning the array every time) } diff --git a/x/slashing/simulation/invariants.go b/x/slashing/simulation/invariants.go new file mode 100644 index 0000000000..7352aa5032 --- /dev/null +++ b/x/slashing/simulation/invariants.go @@ -0,0 +1,18 @@ +package simulation + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" +) + +// AllInvariants tests all slashing invariants +func AllInvariants() simulation.Invariant { + return func(t *testing.T, app *baseapp.BaseApp, log string) { + // TODO Any invariants to check here? + require.Nil(t, nil) + } +} diff --git a/x/slashing/simulation/msgs.go b/x/slashing/simulation/msgs.go new file mode 100644 index 0000000000..8ef24493be --- /dev/null +++ b/x/slashing/simulation/msgs.go @@ -0,0 +1,34 @@ +package simulation + +import ( + "fmt" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/tendermint/tendermint/crypto" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" + "github.com/cosmos/cosmos-sdk/x/slashing" +) + +// SimulateMsgUnjail +func SimulateMsgUnjail(k slashing.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { + key := simulation.RandomKey(r, keys) + address := sdk.AccAddress(key.PubKey().Address()) + msg := slashing.NewMsgUnjail(address) + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := slashing.NewHandler(k)(ctx, msg) + if result.IsOK() { + write() + } + event(fmt.Sprintf("slashing/MsgUnjail/%v", result.IsOK())) + action = fmt.Sprintf("TestMsgUnjail: ok %v, msg %s", result.IsOK(), msg.GetSignBytes()) + return action, nil + } +} diff --git a/x/slashing/tick.go b/x/slashing/tick.go index 7478b511cf..253daa4128 100644 --- a/x/slashing/tick.go +++ b/x/slashing/tick.go @@ -29,13 +29,9 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags // Slash any validators (and since-unbonded stake within the unbonding period) // who contributed to valid infractions for _, evidence := range req.ByzantineValidators { - pk, err := tmtypes.PB2TM.PubKey(evidence.Validator.PubKey) - if err != nil { - panic(err) - } switch evidence.Type { case tmtypes.ABCIEvidenceTypeDuplicateVote: - sk.handleDoubleSign(ctx, pk, evidence.Height, evidence.Time, evidence.Validator.Power) + sk.handleDoubleSign(ctx, evidence.Validator.Address, evidence.Height, evidence.Time, evidence.Validator.Power) default: ctx.Logger().With("module", "x/slashing").Error(fmt.Sprintf("ignored unknown evidence type: %s", evidence.Type)) } diff --git a/x/slashing/tick_test.go b/x/slashing/tick_test.go index b230f9c940..78d2695494 100644 --- a/x/slashing/tick_test.go +++ b/x/slashing/tick_test.go @@ -77,7 +77,7 @@ func TestBeginBlocker(t *testing.T) { BeginBlocker(ctx, req, keeper) } - // validator should be revoked + // validator should be jailed validator, found := sk.GetValidatorByPubKey(ctx, pk) require.True(t, found) require.Equal(t, sdk.Unbonded, validator.GetStatus()) diff --git a/x/slashing/wire.go b/x/slashing/wire.go index 465a06587e..208acda06f 100644 --- a/x/slashing/wire.go +++ b/x/slashing/wire.go @@ -6,7 +6,7 @@ import ( // Register concrete types on wire codec func RegisterWire(cdc *wire.Codec) { - cdc.RegisterConcrete(MsgUnrevoke{}, "cosmos-sdk/MsgUnrevoke", nil) + cdc.RegisterConcrete(MsgUnjail{}, "cosmos-sdk/MsgUnjail", nil) } var cdcEmpty = wire.NewCodec() diff --git a/x/stake/app_test.go b/x/stake/app_test.go index 9847ed2904..65c64fdef2 100644 --- a/x/stake/app_test.go +++ b/x/stake/app_test.go @@ -136,7 +136,7 @@ func TestStakeMsgs(t *testing.T) { mApp.BeginBlock(abci.RequestBeginBlock{}) validator := checkValidator(t, mApp, keeper, addr1, true) - require.Equal(t, addr1, validator.Owner) + require.Equal(t, addr1, validator.Operator) require.Equal(t, sdk.Bonded, validator.Status) require.True(sdk.DecEq(t, sdk.NewDec(10), validator.BondedTokens())) @@ -148,7 +148,7 @@ func TestStakeMsgs(t *testing.T) { mApp.BeginBlock(abci.RequestBeginBlock{}) validator = checkValidator(t, mApp, keeper, addr2, true) - require.Equal(t, addr2, validator.Owner) + require.Equal(t, addr2, validator.Operator) require.Equal(t, sdk.Bonded, validator.Status) require.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens)) diff --git a/x/stake/client/cli/flags.go b/x/stake/client/cli/flags.go index 3d5e90b351..d0e83ab3c6 100644 --- a/x/stake/client/cli/flags.go +++ b/x/stake/client/cli/flags.go @@ -9,7 +9,7 @@ import ( // nolint const ( FlagAddressDelegator = "address-delegator" - FlagAddressValidator = "address-validator" + FlagAddressValidator = "validator" FlagAddressValidatorSrc = "addr-validator-source" FlagAddressValidatorDst = "addr-validator-dest" FlagPubKey = "pubkey" diff --git a/x/stake/client/cli/query.go b/x/stake/client/cli/query.go index dc2c8e30d2..4b8e99e7d2 100644 --- a/x/stake/client/cli/query.go +++ b/x/stake/client/cli/query.go @@ -315,11 +315,11 @@ func GetCmdQueryUnbondingDelegations(storeName string, cdc *wire.Codec) *cobra.C } // GetCmdQueryRedelegation implements the command to query a single -// unbonding-delegation record. +// redelegation record. func GetCmdQueryRedelegation(storeName string, cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "unbonding-delegation", - Short: "Query an unbonding-delegation record based on delegator and validator address", + Use: "redelegation", + Short: "Query a redelegation record based on delegator and a source and destination validator address", RunE: func(cmd *cobra.Command, args []string) error { valSrcAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressValidatorSrc)) if err != nil { @@ -376,11 +376,11 @@ func GetCmdQueryRedelegation(storeName string, cdc *wire.Codec) *cobra.Command { } // GetCmdQueryRedelegations implements the command to query all the -// unbonding-delegation records for a delegator. +// redelegation records for a delegator. func GetCmdQueryRedelegations(storeName string, cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "unbonding-delegations [delegator-addr]", - Short: "Query all unbonding-delegations records for one delegator", + Use: "redelegations [delegator-addr]", + Short: "Query all redelegations records for one delegator", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { delegatorAddr, err := sdk.AccAddressFromBech32(args[0]) @@ -417,3 +417,81 @@ func GetCmdQueryRedelegations(storeName string, cdc *wire.Codec) *cobra.Command return cmd } + +// GetCmdQueryPool implements the pool query command. +func GetCmdQueryPool(storeName string, cdc *wire.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "pool", + Short: "Query the current staking pool values", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + key := stake.PoolKey + cliCtx := context.NewCLIContext().WithCodec(cdc) + + res, err := cliCtx.QueryStore(key, storeName) + if err != nil { + return err + } + + pool := types.MustUnmarshalPool(cdc, res) + + switch viper.Get(cli.OutputFlag) { + case "text": + human := pool.HumanReadableString() + + fmt.Println(human) + + case "json": + // parse out the pool + output, err := wire.MarshalJSONIndent(cdc, pool) + if err != nil { + return err + } + + fmt.Println(string(output)) + } + return nil + }, + } + + return cmd +} + +// GetCmdQueryPool implements the params query command. +func GetCmdQueryParams(storeName string, cdc *wire.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "parameters", + Short: "Query the current staking parameters information", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + key := stake.ParamKey + cliCtx := context.NewCLIContext().WithCodec(cdc) + + res, err := cliCtx.QueryStore(key, storeName) + if err != nil { + return err + } + + params := types.MustUnmarshalParams(cdc, res) + + switch viper.Get(cli.OutputFlag) { + case "text": + human := params.HumanReadableString() + + fmt.Println(human) + + case "json": + // parse out the params + output, err := wire.MarshalJSONIndent(cdc, params) + if err != nil { + return err + } + + fmt.Println(string(output)) + } + return nil + }, + } + + return cmd +} diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 4dfaa0f7fa..a040c7541c 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -68,6 +68,18 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Cod validatorHandlerFn(cliCtx, cdc), ).Methods("GET") + // Get the current state of the staking pool + r.HandleFunc( + "/stake/pool", + poolHandlerFn(cliCtx, cdc), + ).Methods("GET") + + // Get the current staking parameter values + r.HandleFunc( + "/stake/parameters", + paramsHandlerFn(cliCtx, cdc), + ).Methods("GET") + } // already resolve the rational shares to not handle this in the client @@ -114,7 +126,7 @@ func delegatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handler } for _, validator := range validators { - validatorAddr = validator.Owner + validatorAddr = validator.Operator // Delegations delegations, statusCode, errMsg, err := getDelegatorDelegations(cliCtx, cdc, delegatorAddr, validatorAddr) @@ -400,7 +412,7 @@ func delegatorValidatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) ht for _, validator := range validators { // get all transactions from the delegator to val and append - validatorAccAddr = validator.Owner + validatorAccAddr = validator.Operator validator, statusCode, errMsg, errRes := getDelegatorValidator(cliCtx, cdc, delegatorAddr, validatorAccAddr) if errRes != nil { @@ -554,3 +566,63 @@ func validatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handler w.Write(output) } } + +// HTTP request handler to query the pool information +func poolHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + key := stake.PoolKey + + res, err := cliCtx.QueryStore(key, storeName) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(fmt.Sprintf("couldn't query pool. Error: %s", err.Error()))) + return + } + + pool, err := types.UnmarshalPool(cdc, res) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return + } + + output, err := cdc.MarshalJSON(pool) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return + } + + w.Write(output) + } +} + +// HTTP request handler to query the staking params values +func paramsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + key := stake.ParamKey + + res, err := cliCtx.QueryStore(key, storeName) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(fmt.Sprintf("couldn't query parameters. Error: %s", err.Error()))) + return + } + + params, err := types.UnmarshalParams(cdc, res) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return + } + + output, err := cdc.MarshalJSON(params) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return + } + + w.Write(output) + } +} diff --git a/x/stake/genesis.go b/x/stake/genesis.go index 46bda752d6..7a004bccd2 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -33,7 +33,6 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [ // Manually set indexes for the first time keeper.SetValidatorByPubKeyIndex(ctx, validator) - keeper.SetValidatorByPowerIndex(ctx, validator, data.Pool) if validator.Status == sdk.Bonded { diff --git a/x/stake/handler.go b/x/stake/handler.go index 8f7475de9b..c8be6a835a 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -136,8 +136,8 @@ func handleMsgDelegate(ctx sdk.Context, msg types.MsgDelegate, k keeper.Keeper) if msg.Delegation.Denom != k.GetParams(ctx).BondDenom { return ErrBadDenom(k.Codespace()).Result() } - if validator.Revoked == true { - return ErrValidatorRevoked(k.Codespace()).Result() + if validator.Jailed { + return ErrValidatorJailed(k.Codespace()).Result() } _, err := k.Delegate(ctx, msg.DelegatorAddr, msg.Delegation, validator, true) if err != nil { diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index a06be0f886..6ab54e48c2 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -80,9 +80,9 @@ func TestValidatorByPowerIndex(t *testing.T) { got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) - // slash and revoke the first validator + // slash and jail the first validator keeper.Slash(ctx, keep.PKs[0], 0, initBond, sdk.NewDecWithPrec(5, 1)) - keeper.Revoke(ctx, keep.PKs[0]) + keeper.Jail(ctx, keep.PKs[0]) validator, found = keeper.GetValidator(ctx, validatorAddr) require.True(t, found) require.Equal(t, sdk.Unbonded, validator.Status) // ensure is unbonded @@ -136,13 +136,13 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { require.True(t, found) assert.Equal(t, sdk.Bonded, validator.Status) - assert.Equal(t, addr1, validator.Owner) + assert.Equal(t, addr1, validator.Operator) assert.Equal(t, pk1, validator.PubKey) assert.Equal(t, sdk.NewDec(10), validator.BondedTokens()) assert.Equal(t, sdk.NewDec(10), validator.DelegatorShares) assert.Equal(t, Description{}, validator.Description) - // two validators can't have the same owner address + // two validators can't have the same operator address msgCreateValidator2 := newTestMsgCreateValidator(addr1, pk2, 10) got = handleMsgCreateValidator(ctx, msgCreateValidator2, keeper) require.False(t, got.IsOK(), "%v", got) @@ -152,7 +152,7 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { got = handleMsgCreateValidator(ctx, msgCreateValidator3, keeper) require.False(t, got.IsOK(), "%v", got) - // must have different pubkey and owner + // must have different pubkey and operator msgCreateValidator4 := newTestMsgCreateValidator(addr2, pk2, 10) got = handleMsgCreateValidator(ctx, msgCreateValidator4, keeper) require.True(t, got.IsOK(), "%v", got) @@ -160,7 +160,7 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { require.True(t, found) assert.Equal(t, sdk.Bonded, validator.Status) - assert.Equal(t, addr2, validator.Owner) + assert.Equal(t, addr2, validator.Operator) assert.Equal(t, pk2, validator.PubKey) assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens)) assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares)) @@ -180,7 +180,7 @@ func TestDuplicatesMsgCreateValidatorOnBehalfOf(t *testing.T) { require.True(t, found) assert.Equal(t, sdk.Bonded, validator.Status) - assert.Equal(t, validatorAddr, validator.Owner) + assert.Equal(t, validatorAddr, validator.Operator) assert.Equal(t, pk, validator.PubKey) assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens)) assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares)) @@ -387,7 +387,7 @@ func TestMultipleMsgCreateValidator(t *testing.T) { require.Equal(t, balanceExpd, balanceGot, "expected account to have %d, got %d", balanceExpd, balanceGot) } - // unbond them all by revoking delegation + // unbond them all by removing delegation for i, validatorAddr := range validatorAddrs { _, found := keeper.GetValidator(ctx, validatorAddr) require.True(t, found) @@ -449,7 +449,7 @@ func TestMultipleMsgDelegate(t *testing.T) { } } -func TestRevokeValidator(t *testing.T) { +func TestJailValidator(t *testing.T) { ctx, _, keeper := keep.CreateTestInput(t, false, 1000) validatorAddr, delegatorAddr := keep.Addrs[0], keep.Addrs[1] _ = setInstantUnbondPeriod(keeper, ctx) @@ -476,9 +476,9 @@ func TestRevokeValidator(t *testing.T) { validator, found := keeper.GetValidator(ctx, validatorAddr) require.True(t, found) - require.True(t, validator.Revoked, "%v", validator) + require.True(t, validator.Jailed, "%v", validator) - // test that this address cannot yet be bonded too because is revoked + // test that this address cannot yet be bonded too because is jailed got = handleMsgDelegate(ctx, msgDelegate, keeper) require.False(t, got.IsOK(), "expected error, got %v", got) diff --git a/x/stake/keeper/_store.md b/x/stake/keeper/_store.md index 1c95ffe876..818b17ac0c 100644 --- a/x/stake/keeper/_store.md +++ b/x/stake/keeper/_store.md @@ -4,18 +4,18 @@ This document provided a bit more insight as to the purpose of several related prefixed areas of the staking store which are accessed in `x/stake/keeper.go`. -## Validators +## Validators - Prefix Key Space: ValidatorsKey - - Key/Sort: Validator Owner Address + - Key/Sort: Validator Operator Address - Value: Validator Object - Contains: All Validator records independent of being bonded or not - - Used For: Retrieve validator from owner address, general validator retrieval + - Used For: Retrieve validator from operator address, general validator retrieval ## Validators By Power - Prefix Key Space: ValidatorsByPowerKey - Key/Sort: Validator Power (equivalent bonded shares) then Block Height then Transaction Order - - Value: Validator Owner Address + - Value: Validator Operator Address - Contains: All Validator records independent of being bonded or not - Used For: Determining who the top validators are whom should be bonded @@ -26,19 +26,19 @@ prefixed areas of the staking store which are accessed in `x/stake/keeper.go`. - Contains: The cliff validator (ex. 100th validator) power - Used For: Efficient updates to validator status -## Validators Bonded +## Validators Bonded - Prefix Key Space: ValidatorsBondedKey - Key/Sort: Validator PubKey Address (NOTE same as Tendermint) - - Value: Validator Owner Address + - Value: Validator Operator Address - Contains: Only currently bonded Validators - - Used For: Retrieving the list of all currently bonded validators when updating - for a new validator entering the validator set we may want to loop + - Used For: Retrieving the list of all currently bonded validators when updating + for a new validator entering the validator set we may want to loop through this set to determine who we've kicked out. retrieving validator by tendermint index ## Tendermint Updates - Prefix Key Space: TendermintUpdatesKey - - Key/Sort: Validator Owner Address + - Key/Sort: Validator Operator Address - Value: Tendermint ABCI Validator - Contains: Validators are queued to affect the consensus validation set in Tendermint - Used For: Informing Tendermint of the validator set updates, is used only intra-block, as the diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 4b4d267aa2..2bad79c20f 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -221,11 +221,11 @@ func (k Keeper) Delegate(ctx sdk.Context, delegatorAddr sdk.AccAddress, bondAmt validator types.Validator, subtractAccount bool) (newShares sdk.Dec, err sdk.Error) { // Get or create the delegator delegation - delegation, found := k.GetDelegation(ctx, delegatorAddr, validator.Owner) + delegation, found := k.GetDelegation(ctx, delegatorAddr, validator.Operator) if !found { delegation = types.Delegation{ DelegatorAddr: delegatorAddr, - ValidatorAddr: validator.Owner, + ValidatorAddr: validator.Operator, Shares: sdk.ZeroDec(), } } @@ -282,10 +282,10 @@ func (k Keeper) unbond(ctx sdk.Context, delegatorAddr, validatorAddr sdk.AccAddr // remove the delegation if delegation.Shares.IsZero() { - // if the delegation is the owner of the validator then - // trigger a revoke validator - if bytes.Equal(delegation.DelegatorAddr, validator.Owner) && validator.Revoked == false { - validator.Revoked = true + // if the delegation is the operator of the validator then + // trigger a jail validator + if bytes.Equal(delegation.DelegatorAddr, validator.Operator) && validator.Jailed == false { + validator.Jailed = true } k.RemoveDelegation(ctx, delegation) } else { @@ -303,7 +303,7 @@ func (k Keeper) unbond(ctx sdk.Context, delegatorAddr, validatorAddr sdk.AccAddr // update then remove validator if necessary validator = k.UpdateValidator(ctx, validator) if validator.DelegatorShares.IsZero() { - k.RemoveValidator(ctx, validator.Owner) + k.RemoveValidator(ctx, validator.Operator) } return diff --git a/x/stake/keeper/key.go b/x/stake/keeper/key.go index 502ec26544..958de62ed5 100644 --- a/x/stake/keeper/key.go +++ b/x/stake/keeper/key.go @@ -73,11 +73,11 @@ func getValidatorPowerRank(validator types.Validator, pool types.Pool) []byte { potentialPower := validator.Tokens powerBytes := []byte(potentialPower.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first) - revokedBytes := make([]byte, 1) - if validator.Revoked { - revokedBytes[0] = byte(0x00) + jailedBytes := make([]byte, 1) + if validator.Jailed { + jailedBytes[0] = byte(0x00) } else { - revokedBytes[0] = byte(0x01) + jailedBytes[0] = byte(0x01) } // heightBytes and counterBytes represent strings like powerBytes does @@ -88,7 +88,7 @@ func getValidatorPowerRank(validator types.Validator, pool types.Pool) []byte { return append(append(append(append( ValidatorsByPowerIndexKey, - revokedBytes...), + jailedBytes...), powerBytes...), heightBytes...), counterBytes...) diff --git a/x/stake/keeper/slash.go b/x/stake/keeper/slash.go index c1fabe4411..aa6fe974d8 100644 --- a/x/stake/keeper/slash.go +++ b/x/stake/keeper/slash.go @@ -43,7 +43,7 @@ func (k Keeper) Slash(ctx sdk.Context, pubkey crypto.PubKey, infractionHeight in pubkey.Address())) return } - ownerAddress := validator.GetOwner() + operatorAddress := validator.GetOperator() // Track remaining slash amount for the validator // This will decrease when we slash unbondings and @@ -68,7 +68,7 @@ func (k Keeper) Slash(ctx sdk.Context, pubkey crypto.PubKey, infractionHeight in case infractionHeight < ctx.BlockHeight(): // Iterate through unbonding delegations from slashed validator - unbondingDelegations := k.GetUnbondingDelegationsFromValidator(ctx, ownerAddress) + unbondingDelegations := k.GetUnbondingDelegationsFromValidator(ctx, operatorAddress) for _, unbondingDelegation := range unbondingDelegations { amountSlashed := k.slashUnbondingDelegation(ctx, unbondingDelegation, infractionHeight, slashFactor) if amountSlashed.IsZero() { @@ -78,7 +78,7 @@ func (k Keeper) Slash(ctx sdk.Context, pubkey crypto.PubKey, infractionHeight in } // Iterate through redelegations from slashed validator - redelegations := k.GetRedelegationsFromValidator(ctx, ownerAddress) + redelegations := k.GetRedelegationsFromValidator(ctx, operatorAddress) for _, redelegation := range redelegations { amountSlashed := k.slashRedelegation(ctx, validator, redelegation, infractionHeight, slashFactor) if amountSlashed.IsZero() { @@ -103,7 +103,7 @@ func (k Keeper) Slash(ctx sdk.Context, pubkey crypto.PubKey, infractionHeight in validator = k.UpdateValidator(ctx, validator) // remove validator if it has been reduced to zero shares if validator.Tokens.IsZero() { - k.RemoveValidator(ctx, validator.Owner) + k.RemoveValidator(ctx, validator.Operator) } // Log that a slash occurred! @@ -115,31 +115,31 @@ func (k Keeper) Slash(ctx sdk.Context, pubkey crypto.PubKey, infractionHeight in return } -// revoke a validator -func (k Keeper) Revoke(ctx sdk.Context, pubkey crypto.PubKey) { - k.setRevoked(ctx, pubkey, true) +// jail a validator +func (k Keeper) Jail(ctx sdk.Context, pubkey crypto.PubKey) { + k.setJailed(ctx, pubkey, true) logger := ctx.Logger().With("module", "x/stake") - logger.Info(fmt.Sprintf("Validator %s revoked", pubkey.Address())) + logger.Info(fmt.Sprintf("Validator %s jailed", pubkey.Address())) // TODO Return event(s), blocked on https://github.com/tendermint/tendermint/pull/1803 return } -// unrevoke a validator -func (k Keeper) Unrevoke(ctx sdk.Context, pubkey crypto.PubKey) { - k.setRevoked(ctx, pubkey, false) +// unjail a validator +func (k Keeper) Unjail(ctx sdk.Context, pubkey crypto.PubKey) { + k.setJailed(ctx, pubkey, false) logger := ctx.Logger().With("module", "x/stake") - logger.Info(fmt.Sprintf("Validator %s unrevoked", pubkey.Address())) + logger.Info(fmt.Sprintf("Validator %s unjailed", pubkey.Address())) // TODO Return event(s), blocked on https://github.com/tendermint/tendermint/pull/1803 return } -// set the revoked flag on a validator -func (k Keeper) setRevoked(ctx sdk.Context, pubkey crypto.PubKey, revoked bool) { +// set the jailed flag on a validator +func (k Keeper) setJailed(ctx sdk.Context, pubkey crypto.PubKey, jailed bool) { validator, found := k.GetValidatorByPubKey(ctx, pubkey) if !found { - panic(fmt.Errorf("Validator with pubkey %s not found, cannot set revoked to %v", pubkey, revoked)) + panic(fmt.Errorf("Validator with pubkey %s not found, cannot set jailed to %v", pubkey, jailed)) } - validator.Revoked = revoked + validator.Jailed = jailed k.UpdateValidator(ctx, validator) // update validator, possibly unbonding or bonding it return } diff --git a/x/stake/keeper/slash_test.go b/x/stake/keeper/slash_test.go index 444858f290..156f0602e9 100644 --- a/x/stake/keeper/slash_test.go +++ b/x/stake/keeper/slash_test.go @@ -34,7 +34,7 @@ func setupHelper(t *testing.T, amt int64) (sdk.Context, Keeper, types.Params) { return ctx, keeper, params } -// tests Revoke, Unrevoke +// tests Jail, Unjail func TestRevocation(t *testing.T) { // setup ctx, keeper, _ := setupHelper(t, 10) @@ -44,19 +44,19 @@ func TestRevocation(t *testing.T) { // initial state val, found := keeper.GetValidator(ctx, addr) require.True(t, found) - require.False(t, val.GetRevoked()) + require.False(t, val.GetJailed()) - // test revoke - keeper.Revoke(ctx, pk) + // test jail + keeper.Jail(ctx, pk) val, found = keeper.GetValidator(ctx, addr) require.True(t, found) - require.True(t, val.GetRevoked()) + require.True(t, val.GetJailed()) - // test unrevoke - keeper.Unrevoke(ctx, pk) + // test unjail + keeper.Unjail(ctx, pk) val, found = keeper.GetValidator(ctx, addr) require.True(t, found) - require.False(t, val.GetRevoked()) + require.False(t, val.GetJailed()) } diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index ce5a190613..e933a6d236 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -36,25 +36,25 @@ func (k Keeper) GetValidatorByPubKey(ctx sdk.Context, pubkey crypto.PubKey) (val func (k Keeper) SetValidator(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) bz := types.MustMarshalValidator(k.cdc, validator) - store.Set(GetValidatorKey(validator.Owner), bz) + store.Set(GetValidatorKey(validator.Operator), bz) } // validator index func (k Keeper) SetValidatorByPubKeyIndex(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) - store.Set(GetValidatorByPubKeyIndexKey(validator.PubKey), validator.Owner) + store.Set(GetValidatorByPubKeyIndexKey(validator.PubKey), validator.Operator) } // validator index func (k Keeper) SetValidatorByPowerIndex(ctx sdk.Context, validator types.Validator, pool types.Pool) { store := ctx.KVStore(k.storeKey) - store.Set(GetValidatorsByPowerIndexKey(validator, pool), validator.Owner) + store.Set(GetValidatorsByPowerIndexKey(validator, pool), validator.Operator) } // validator index func (k Keeper) SetValidatorBondedIndex(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) - store.Set(GetValidatorsBondedIndexKey(validator.Owner), []byte{}) + store.Set(GetValidatorsBondedIndexKey(validator.Operator), []byte{}) } // used in testing @@ -203,9 +203,9 @@ func (k Keeper) ClearTendermintUpdates(ctx sdk.Context) { func (k Keeper) UpdateValidator(ctx sdk.Context, validator types.Validator) types.Validator { store := ctx.KVStore(k.storeKey) pool := k.GetPool(ctx) - oldValidator, oldFound := k.GetValidator(ctx, validator.Owner) + oldValidator, oldFound := k.GetValidator(ctx, validator.Operator) - validator = k.updateForRevoking(ctx, oldFound, oldValidator, validator) + validator = k.updateForJailing(ctx, oldFound, oldValidator, validator) powerIncreasing := k.getPowerIncreasing(ctx, oldFound, oldValidator, validator) validator.BondHeight, validator.BondIntraTxCounter = k.bondIncrement(ctx, oldFound, oldValidator, validator) valPower := k.updateValidatorPower(ctx, oldFound, oldValidator, validator, pool) @@ -216,15 +216,15 @@ func (k Keeper) UpdateValidator(ctx sdk.Context, validator types.Validator) type // perform the following: // a) update Tendermint // b) check if the cliff validator needs to be updated - case powerIncreasing && !validator.Revoked && + case powerIncreasing && !validator.Jailed && (oldFound && oldValidator.Status == sdk.Bonded): bz := k.cdc.MustMarshalBinary(validator.ABCIValidator()) - store.Set(GetTendermintUpdatesKey(validator.Owner), bz) + store.Set(GetTendermintUpdatesKey(validator.Operator), bz) if cliffPower != nil { cliffAddr := sdk.AccAddress(k.GetCliffValidator(ctx)) - if bytes.Equal(cliffAddr, validator.Owner) { + if bytes.Equal(cliffAddr, validator.Operator) { k.updateCliffValidator(ctx, validator) } } @@ -255,7 +255,7 @@ func (k Keeper) UpdateValidator(ctx sdk.Context, validator types.Validator) type // if decreased in power but still bonded, update Tendermint validator if oldFound && oldValidator.BondedTokens().GT(validator.BondedTokens()) { bz := k.cdc.MustMarshalBinary(validator.ABCIValidator()) - store.Set(GetTendermintUpdatesKey(validator.Owner), bz) + store.Set(GetTendermintUpdatesKey(validator.Operator), bz) } } @@ -280,10 +280,6 @@ func (k Keeper) updateCliffValidator(ctx sdk.Context, affectedVal types.Validato panic(fmt.Sprintf("cliff validator record not found for address: %v\n", cliffAddr)) } - // NOTE: We get the power via affectedVal since the store (by power key) - // has yet to be updated. - affectedValPower := affectedVal.GetPower() - // Create a validator iterator ranging from smallest to largest by power // starting the current cliff validator's power. start := GetValidatorsByPowerIndexKey(oldCliffVal, pool) @@ -297,8 +293,8 @@ func (k Keeper) updateCliffValidator(ctx sdk.Context, affectedVal types.Validato panic(fmt.Sprintf("validator record not found for address: %v\n", ownerAddr)) } - if currVal.Status != sdk.Bonded || currVal.Revoked { - panic(fmt.Sprintf("unexpected revoked or unbonded validator for address: %s\n", ownerAddr)) + if currVal.Status != sdk.Bonded || currVal.Jailed { + panic(fmt.Sprintf("unexpected jailed or unbonded validator for address: %s\n", ownerAddr)) } newCliffVal = currVal @@ -307,24 +303,27 @@ func (k Keeper) updateCliffValidator(ctx sdk.Context, affectedVal types.Validato panic("failed to create valid validator power iterator") } - if bytes.Equal(affectedVal.Owner, newCliffVal.Owner) { + affectedValRank := GetValidatorsByPowerIndexKey(affectedVal, pool) + newCliffValRank := GetValidatorsByPowerIndexKey(newCliffVal, pool) + + if bytes.Equal(affectedVal.Operator, newCliffVal.Operator) { // The affected validator remains the cliff validator, however, since - // the store does not contain the new power, set the new cliff - // validator to the affected validator. - bz := GetValidatorsByPowerIndexKey(affectedVal, pool) - store.Set(ValidatorPowerCliffKey, bz) - } else if affectedValPower.GT(newCliffVal.GetPower()) { + // the store does not contain the new power, update the new power rank. + store.Set(ValidatorPowerCliffKey, affectedValRank) + } else if bytes.Compare(affectedValRank, newCliffValRank) > 0 { // The affected validator no longer remains the cliff validator as it's - // power is greater than the new current cliff validator. + // power is greater than the new cliff validator. k.setCliffValidator(ctx, newCliffVal, pool) + } else { + panic("invariant broken: the cliff validator should change or it should remain the same") } } -func (k Keeper) updateForRevoking(ctx sdk.Context, oldFound bool, oldValidator, newValidator types.Validator) types.Validator { - if newValidator.Revoked && oldFound && oldValidator.Status == sdk.Bonded { +func (k Keeper) updateForJailing(ctx sdk.Context, oldFound bool, oldValidator, newValidator types.Validator) types.Validator { + if newValidator.Jailed && oldFound && oldValidator.Status == sdk.Bonded { newValidator = k.unbondValidator(ctx, newValidator) - // need to also clear the cliff validator spot because the revoke has + // need to also clear the cliff validator spot because the jail has // opened up a new spot which will be filled when // updateValidatorsBonded is called k.clearCliffValidator(ctx) @@ -365,7 +364,7 @@ func (k Keeper) updateValidatorPower(ctx sdk.Context, oldFound bool, oldValidato store.Delete(GetValidatorsByPowerIndexKey(oldValidator, pool)) } valPower = GetValidatorsByPowerIndexKey(newValidator, pool) - store.Set(valPower, newValidator.Owner) + store.Set(valPower, newValidator.Operator) return valPower } @@ -407,7 +406,7 @@ func (k Keeper) UpdateBondedValidators( // situation that this is the "affected validator" just use the // validator provided because it has not yet been updated in the store ownerAddr := iterator.Value() - if bytes.Equal(ownerAddr, affectedValidator.Owner) { + if bytes.Equal(ownerAddr, affectedValidator.Operator) { validator = affectedValidator } else { var found bool @@ -417,13 +416,17 @@ func (k Keeper) UpdateBondedValidators( } } - if validator.Revoked { - // we should no longer consider jailed validators as they are ranked - // lower than any non-jailed/bonded validators - if validator.Status == sdk.Bonded { - panic(fmt.Sprintf("revoked validator cannot be bonded for address: %s\n", ownerAddr)) + // increment bondedValidatorsCount / get the validator to bond + if !validator.Jailed { + if validator.Status != sdk.Bonded { + validatorToBond = validator + if newValidatorBonded { + panic("already decided to bond a validator, can't bond another!") + } + newValidatorBonded = true } - + } else { + // TODO: document why we must break here. break } @@ -440,6 +443,10 @@ func (k Keeper) UpdateBondedValidators( iterator.Close() + if newValidatorBonded && bytes.Equal(oldCliffValidatorAddr, validator.Operator) { + panic("cliff validator has not been changed, yet we bonded a new validator") + } + // clear or set the cliff validator if bondedValidatorsCount == int(maxValidators) { k.setCliffValidator(ctx, validator, k.GetPool(ctx)) @@ -450,21 +457,29 @@ func (k Keeper) UpdateBondedValidators( // swap the cliff validator for a new validator if the affected validator // was bonded if newValidatorBonded { - // unbond the cliff validator if oldCliffValidatorAddr != nil { - cliffVal, found := k.GetValidator(ctx, oldCliffValidatorAddr) + oldCliffVal, found := k.GetValidator(ctx, oldCliffValidatorAddr) if !found { panic(fmt.Sprintf("validator record not found for address: %v\n", oldCliffValidatorAddr)) } - k.unbondValidator(ctx, cliffVal) + if bytes.Equal(validatorToBond.Operator, affectedValidator.Operator) { + // unbond the old cliff validator iff the affected validator was + // newly bonded and has greater power + k.unbondValidator(ctx, oldCliffVal) + } else { + // otherwise unbond the affected validator, which must have been + // kicked out + affectedValidator = k.unbondValidator(ctx, affectedValidator) + } } - // bond the new validator validator = k.bondValidator(ctx, validatorToBond) - if bytes.Equal(validator.Owner, affectedValidator.Owner) { + if bytes.Equal(validator.Operator, affectedValidator.Operator) { return validator, true } + + return affectedValidator, true } return types.Validator{}, false @@ -514,11 +529,11 @@ func (k Keeper) UpdateBondedValidatorsFull(ctx sdk.Context) { validator = k.bondValidator(ctx, validator) } - if validator.Revoked { + if validator.Jailed { // we should no longer consider jailed validators as they are ranked // lower than any non-jailed/bonded validators if validator.Status == sdk.Bonded { - panic(fmt.Sprintf("revoked validator cannot be bonded for address: %s\n", ownerAddr)) + panic(fmt.Sprintf("jailed validator cannot be bonded for address: %s\n", ownerAddr)) } break @@ -560,7 +575,7 @@ func (k Keeper) unbondValidator(ctx sdk.Context, validator types.Validator) type // sanity check if validator.Status == sdk.Unbonded { - panic(fmt.Sprintf("should not already be unbonded, validator: %v\n", validator)) + panic(fmt.Sprintf("should not already be unbonded, validator: %v\n", validator)) } // set the status @@ -572,10 +587,10 @@ func (k Keeper) unbondValidator(ctx sdk.Context, validator types.Validator) type // add to accumulated changes for tendermint bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidatorZero()) - store.Set(GetTendermintUpdatesKey(validator.Owner), bzABCI) + store.Set(GetTendermintUpdatesKey(validator.Operator), bzABCI) // also remove from the Bonded types.Validators Store - store.Delete(GetValidatorsBondedIndexKey(validator.Owner)) + store.Delete(GetValidatorsBondedIndexKey(validator.Operator)) return validator } @@ -596,11 +611,11 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types. // save the now bonded validator record to the three referenced stores k.SetValidator(ctx, validator) - store.Set(GetValidatorsBondedIndexKey(validator.Owner), []byte{}) + store.Set(GetValidatorsBondedIndexKey(validator.Operator), []byte{}) // add to accumulated changes for tendermint bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidator()) - store.Set(GetTendermintUpdatesKey(validator.Owner), bzABCI) + store.Set(GetTendermintUpdatesKey(validator.Operator), bzABCI) return validator } @@ -623,10 +638,10 @@ func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.AccAddress) { // delete from the current and power weighted validator groups if the validator // is bonded - and add validator with zero power to the validator updates - if store.Get(GetValidatorsBondedIndexKey(validator.Owner)) == nil { + if store.Get(GetValidatorsBondedIndexKey(validator.Operator)) == nil { return } - store.Delete(GetValidatorsBondedIndexKey(validator.Owner)) + store.Delete(GetValidatorsBondedIndexKey(validator.Operator)) bz := k.cdc.MustMarshalBinary(validator.ABCIValidatorZero()) store.Set(GetTendermintUpdatesKey(address), bz) @@ -651,7 +666,7 @@ func (k Keeper) setCliffValidator(ctx sdk.Context, validator types.Validator, po store := ctx.KVStore(k.storeKey) bz := GetValidatorsByPowerIndexKey(validator, pool) store.Set(ValidatorPowerCliffKey, bz) - store.Set(ValidatorCliffIndexKey, validator.Owner) + store.Set(ValidatorCliffIndexKey, validator.Operator) } // clear the current validator and power of the validator on the cliff diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index 7b15a9c7f1..54149707e8 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -48,7 +48,6 @@ func TestSetValidator(t *testing.T) { updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) require.Equal(t, validator.ABCIValidator(), updates[0]) - } func TestUpdateValidatorByPowerIndex(t *testing.T) { @@ -89,6 +88,69 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { require.True(t, keeper.validatorByPowerIndexExists(ctx, power)) } +func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { + numVals := 10 + maxVals := 5 + + // create context, keeper, and pool for tests + ctx, _, keeper := CreateTestInput(t, false, 0) + pool := keeper.GetPool(ctx) + + // create keeper parameters + params := keeper.GetParams(ctx) + params.MaxValidators = uint16(maxVals) + keeper.SetParams(ctx, params) + + // create a random pool + pool.LooseTokens = sdk.NewDec(10000) + pool.BondedTokens = sdk.NewDec(1234) + keeper.SetPool(ctx, pool) + + validators := make([]types.Validator, numVals) + for i := 0; i < len(validators); i++ { + moniker := fmt.Sprintf("val#%d", int64(i)) + val := types.NewValidator(Addrs[i], PKs[i], types.Description{Moniker: moniker}) + val.BondHeight = int64(i) + val.BondIntraTxCounter = int16(i) + val, pool, _ = val.AddTokensFromDel(pool, int64((i+1)*10)) + + keeper.SetPool(ctx, pool) + val = keeper.UpdateValidator(ctx, val) + validators[i] = val + } + + nextCliffVal := validators[numVals-maxVals+1] + + // remove enough tokens to kick out the validator below the current cliff + // validator and next in line cliff validator + nextCliffVal, pool, _ = nextCliffVal.RemoveDelShares(pool, sdk.NewDec(21)) + keeper.SetPool(ctx, pool) + nextCliffVal = keeper.UpdateValidator(ctx, nextCliffVal) + + // require the cliff validator has changed + cliffVal := validators[numVals-maxVals-1] + require.Equal(t, cliffVal.Operator, sdk.AccAddress(keeper.GetCliffValidator(ctx))) + + // require the cliff validator power has changed + cliffPower := keeper.GetCliffValidatorPower(ctx) + require.Equal(t, GetValidatorsByPowerIndexKey(cliffVal, pool), cliffPower) + + expectedValStatus := map[int]sdk.BondStatus{ + 9: sdk.Bonded, 8: sdk.Bonded, 7: sdk.Bonded, 5: sdk.Bonded, 4: sdk.Bonded, + 0: sdk.Unbonded, 1: sdk.Unbonded, 2: sdk.Unbonded, 3: sdk.Unbonded, 6: sdk.Unbonded, + } + + // require all the validators have their respective statuses + for valIdx, status := range expectedValStatus { + valAddr := validators[valIdx].Operator + val, _ := keeper.GetValidator(ctx, valAddr) + + require.Equal( + t, val.GetStatus(), status, + fmt.Sprintf("expected validator to have status: %s", sdk.BondStatusToString(status))) + } +} + func TestCliffValidatorChange(t *testing.T) { numVals := 10 maxVals := 5 @@ -128,7 +190,7 @@ func TestCliffValidatorChange(t *testing.T) { // assert new cliff validator to be set to the second lowest bonded validator by power newCliffVal := validators[numVals-maxVals+1] - require.Equal(t, newCliffVal.Owner, sdk.AccAddress(keeper.GetCliffValidator(ctx))) + require.Equal(t, newCliffVal.Operator, sdk.AccAddress(keeper.GetCliffValidator(ctx))) // assert cliff validator power should have been updated cliffPower := keeper.GetCliffValidatorPower(ctx) @@ -141,7 +203,20 @@ func TestCliffValidatorChange(t *testing.T) { // assert cliff validator has not change but increased in power cliffPower = keeper.GetCliffValidatorPower(ctx) - require.Equal(t, newCliffVal.Owner, sdk.AccAddress(keeper.GetCliffValidator(ctx))) + require.Equal(t, newCliffVal.Operator, sdk.AccAddress(keeper.GetCliffValidator(ctx))) + require.Equal(t, GetValidatorsByPowerIndexKey(newCliffVal, pool), cliffPower) + + // add enough power to cliff validator to be equal in rank to next validator + newCliffVal, pool, _ = newCliffVal.AddTokensFromDel(pool, 9) + keeper.SetPool(ctx, pool) + newCliffVal = keeper.UpdateValidator(ctx, newCliffVal) + + // assert new cliff validator due to power rank construction + newCliffVal = validators[numVals-maxVals+2] + require.Equal(t, newCliffVal.Operator, sdk.AccAddress(keeper.GetCliffValidator(ctx))) + + // assert cliff validator power should have been updated + cliffPower = keeper.GetCliffValidatorPower(ctx) require.Equal(t, GetValidatorsByPowerIndexKey(newCliffVal, pool), cliffPower) } @@ -240,7 +315,7 @@ func TestValidatorBasics(t *testing.T) { assert.True(ValEq(t, validators[2], resVals[2])) // remove a record - keeper.RemoveValidator(ctx, validators[1].Owner) + keeper.RemoveValidator(ctx, validators[1].Operator) _, found = keeper.GetValidator(ctx, addrVals[1]) require.False(t, found) } @@ -269,11 +344,11 @@ func GetValidatorSortingUnmixed(t *testing.T) { assert.Equal(t, sdk.NewDec(100), resValidators[2].BondedTokens(), "%v", resValidators) assert.Equal(t, sdk.NewDec(1), resValidators[3].BondedTokens(), "%v", resValidators) assert.Equal(t, sdk.NewDec(0), resValidators[4].BondedTokens(), "%v", resValidators) - assert.Equal(t, validators[3].Owner, resValidators[0].Owner, "%v", resValidators) - assert.Equal(t, validators[4].Owner, resValidators[1].Owner, "%v", resValidators) - assert.Equal(t, validators[1].Owner, resValidators[2].Owner, "%v", resValidators) - assert.Equal(t, validators[2].Owner, resValidators[3].Owner, "%v", resValidators) - assert.Equal(t, validators[0].Owner, resValidators[4].Owner, "%v", resValidators) + assert.Equal(t, validators[3].Operator, resValidators[0].Operator, "%v", resValidators) + assert.Equal(t, validators[4].Operator, resValidators[1].Operator, "%v", resValidators) + assert.Equal(t, validators[1].Operator, resValidators[2].Operator, "%v", resValidators) + assert.Equal(t, validators[2].Operator, resValidators[3].Operator, "%v", resValidators) + assert.Equal(t, validators[0].Operator, resValidators[4].Operator, "%v", resValidators) // test a basic increase in voting power validators[3].Tokens = sdk.NewDec(500) @@ -380,11 +455,11 @@ func GetValidatorSortingMixed(t *testing.T) { assert.Equal(t, sdk.NewDec(100), resValidators[2].BondedTokens(), "%v", resValidators) assert.Equal(t, sdk.NewDec(1), resValidators[3].BondedTokens(), "%v", resValidators) assert.Equal(t, sdk.NewDec(0), resValidators[4].BondedTokens(), "%v", resValidators) - assert.Equal(t, validators[3].Owner, resValidators[0].Owner, "%v", resValidators) - assert.Equal(t, validators[4].Owner, resValidators[1].Owner, "%v", resValidators) - assert.Equal(t, validators[1].Owner, resValidators[2].Owner, "%v", resValidators) - assert.Equal(t, validators[2].Owner, resValidators[3].Owner, "%v", resValidators) - assert.Equal(t, validators[0].Owner, resValidators[4].Owner, "%v", resValidators) + assert.Equal(t, validators[3].Operator, resValidators[0].Operator, "%v", resValidators) + assert.Equal(t, validators[4].Operator, resValidators[1].Operator, "%v", resValidators) + assert.Equal(t, validators[1].Operator, resValidators[2].Operator, "%v", resValidators) + assert.Equal(t, validators[2].Operator, resValidators[3].Operator, "%v", resValidators) + assert.Equal(t, validators[0].Operator, resValidators[4].Operator, "%v", resValidators) } // TODO separate out into multiple tests @@ -403,13 +478,15 @@ func TestGetValidatorsEdgeCases(t *testing.T) { var validators [4]types.Validator for i, amt := range amts { pool := keeper.GetPool(ctx) - validators[i] = types.NewValidator(Addrs[i], PKs[i], types.Description{}) + moniker := fmt.Sprintf("val#%d", int64(i)) + validators[i] = types.NewValidator(Addrs[i], PKs[i], types.Description{Moniker: moniker}) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, amt) keeper.SetPool(ctx, pool) validators[i] = keeper.UpdateValidator(ctx, validators[i]) } + for i := range amts { - validators[i], found = keeper.GetValidator(ctx, validators[i].Owner) + validators[i], found = keeper.GetValidator(ctx, validators[i].Operator) require.True(t, found) } resValidators := keeper.GetValidatorsByPower(ctx) @@ -433,7 +510,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { // validator 3 enters bonded validator set ctx = ctx.WithBlockHeight(40) - validators[3], found = keeper.GetValidator(ctx, validators[3].Owner) + validators[3], found = keeper.GetValidator(ctx, validators[3].Operator) require.True(t, found) validators[3], pool, _ = validators[3].AddTokensFromDel(pool, 1) keeper.SetPool(ctx, pool) @@ -460,7 +537,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[2], resValidators[1])) - validator, exists := keeper.GetValidator(ctx, validators[3].Owner) + validator, exists := keeper.GetValidator(ctx, validators[3].Operator) require.Equal(t, exists, true) require.Equal(t, int64(40), validator.BondHeight) } @@ -530,7 +607,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { } for i := range amts { var found bool - validators[i], found = keeper.GetValidator(ctx, validators[i].Owner) + validators[i], found = keeper.GetValidator(ctx, validators[i].Operator) require.True(t, found) } assert.Equal(t, sdk.Unbonded, validators[0].Status) @@ -603,8 +680,8 @@ func TestGetTendermintUpdatesAllNone(t *testing.T) { keeper.ClearTendermintUpdates(ctx) require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) - keeper.RemoveValidator(ctx, validators[0].Owner) - keeper.RemoveValidator(ctx, validators[1].Owner) + keeper.RemoveValidator(ctx, validators[0].Operator) + keeper.RemoveValidator(ctx, validators[1].Operator) updates = keeper.GetTendermintUpdates(ctx) assert.Equal(t, 2, len(updates)) diff --git a/x/stake/simulation/invariants.go b/x/stake/simulation/invariants.go index 654d5560b0..1e961d05de 100644 --- a/x/stake/simulation/invariants.go +++ b/x/stake/simulation/invariants.go @@ -28,7 +28,7 @@ func AllInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) simula func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) simulation.Invariant { return func(t *testing.T, app *baseapp.BaseApp, log string) { ctx := app.NewContext(false, abci.Header{}) - pool := k.GetPool(ctx) + //pool := k.GetPool(ctx) loose := sdk.ZeroInt() bonded := sdk.ZeroDec() @@ -52,11 +52,14 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) sim }) // Loose tokens should equal coin supply plus unbonding delegations plus tokens on unbonded validators - require.True(t, pool.LooseTokens.RoundInt64() == loose.Int64(), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s", - pool.LooseTokens.RoundInt64(), loose.Int64(), log) + // XXX TODO https://github.com/cosmos/cosmos-sdk/issues/2063#issuecomment-413720872 + // require.True(t, pool.LooseTokens.RoundInt64() == loose.Int64(), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s", + // pool.LooseTokens.RoundInt64(), loose.Int64(), log) // Bonded tokens should equal sum of tokens with bonded validators - require.True(t, pool.BondedTokens.Equal(bonded), "expected bonded tokens to equal total steak held by bonded validators\nlog: %s", log) + // XXX TODO https://github.com/cosmos/cosmos-sdk/issues/2063#issuecomment-413720872 + // require.True(t, pool.BondedTokens.RoundInt64() == bonded.RoundInt64(), "expected bonded tokens to equal total steak held by bonded validators - pool.BondedTokens: %v, sum of bonded validator tokens: %v\nlog: %s", + // pool.BondedTokens.RoundInt64(), bonded.RoundInt64(), log) // TODO Inflation check on total supply } diff --git a/x/stake/simulation/msgs.go b/x/stake/simulation/msgs.go index f402d765fc..17f9808931 100644 --- a/x/stake/simulation/msgs.go +++ b/x/stake/simulation/msgs.go @@ -235,7 +235,10 @@ func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.TestAndRunTx { func Setup(mapp *mock.App, k stake.Keeper) simulation.RandSetup { return func(r *rand.Rand, privKeys []crypto.PrivKey) { ctx := mapp.NewContext(false, abci.Header{}) - stake.InitGenesis(ctx, k, stake.DefaultGenesisState()) + gen := stake.DefaultGenesisState() + gen.Params.InflationMax = sdk.NewDec(0) + gen.Params.InflationMin = sdk.NewDec(0) + stake.InitGenesis(ctx, k, gen) params := k.GetParams(ctx) denom := params.BondDenom loose := sdk.ZeroInt() diff --git a/x/stake/simulation/sim_test.go b/x/stake/simulation/sim_test.go index 391ca1996e..84745cd1d4 100644 --- a/x/stake/simulation/sim_test.go +++ b/x/stake/simulation/sim_test.go @@ -5,12 +5,14 @@ import ( "math/rand" "testing" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/mock" "github.com/cosmos/cosmos-sdk/x/mock/simulation" "github.com/cosmos/cosmos-sdk/x/stake" - abci "github.com/tendermint/tendermint/abci/types" ) // TestStakeWithRandomMessages @@ -35,7 +37,7 @@ func TestStakeWithRandomMessages(t *testing.T) { panic(err) } - appStateFn := func(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage { + appStateFn := func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage { mock.RandomSetGenesis(r, mapp, accs, []string{"stake"}) return json.RawMessage("{}") } @@ -54,6 +56,7 @@ func TestStakeWithRandomMessages(t *testing.T) { Setup(mapp, stakeKeeper), }, []simulation.Invariant{ AllInvariants(coinKeeper, stakeKeeper, mapp.AccountMapper), - }, 10, 100, 100, + }, 10, 100, + false, ) } diff --git a/x/stake/stake.go b/x/stake/stake.go index c5185433dc..2782957ceb 100644 --- a/x/stake/stake.go +++ b/x/stake/stake.go @@ -94,7 +94,7 @@ var ( ErrNoValidatorFound = types.ErrNoValidatorFound ErrValidatorOwnerExists = types.ErrValidatorOwnerExists ErrValidatorPubKeyExists = types.ErrValidatorPubKeyExists - ErrValidatorRevoked = types.ErrValidatorRevoked + ErrValidatorJailed = types.ErrValidatorJailed ErrBadRemoveValidator = types.ErrBadRemoveValidator ErrDescriptionLength = types.ErrDescriptionLength ErrCommissionNegative = types.ErrCommissionNegative diff --git a/x/stake/types/errors.go b/x/stake/types/errors.go index d44ed411c5..0c1d9192d7 100644 --- a/x/stake/types/errors.go +++ b/x/stake/types/errors.go @@ -44,8 +44,8 @@ func ErrValidatorPubKeyExists(codespace sdk.CodespaceType) sdk.Error { return sdk.NewError(codespace, CodeInvalidValidator, "validator already exist for this pubkey, must use new validator pubkey") } -func ErrValidatorRevoked(codespace sdk.CodespaceType) sdk.Error { - return sdk.NewError(codespace, CodeInvalidValidator, "validator for this address is currently revoked") +func ErrValidatorJailed(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeInvalidValidator, "validator for this address is currently jailed") } func ErrBadRemoveValidator(codespace sdk.CodespaceType) sdk.Error { diff --git a/x/stake/types/params.go b/x/stake/types/params.go index f297f31059..bad4251cb3 100644 --- a/x/stake/types/params.go +++ b/x/stake/types/params.go @@ -2,9 +2,11 @@ package types import ( "bytes" + "fmt" "time" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" ) // defaultUnbondingTime reflects three weeks in seconds as the default @@ -43,3 +45,36 @@ func DefaultParams() Params { BondDenom: "steak", } } + +// HumanReadableString returns a human readable string representation of the +// parameters. +func (p Params) HumanReadableString() string { + + resp := "Pool \n" + resp += fmt.Sprintf("Maximum Annual Inflation Rate Change: %s\n", p.InflationRateChange) + resp += fmt.Sprintf("Max Inflation Rate: %s\n", p.InflationMax) + resp += fmt.Sprintf("Min Inflation Tate: %s\n", p.InflationMin) + resp += fmt.Sprintf("Bonded Token Goal (%s): %s\n", "s", p.GoalBonded) + resp += fmt.Sprintf("Unbonding Time: %s\n", p.UnbondingTime) + resp += fmt.Sprintf("Max Validators: %d: \n", p.MaxValidators) + resp += fmt.Sprintf("Bonded Coin Denomination: %s\n", p.BondDenom) + return resp +} + +// unmarshal the current staking params value from store key or panic +func MustUnmarshalParams(cdc *wire.Codec, value []byte) Params { + params, err := UnmarshalParams(cdc, value) + if err != nil { + panic(err) + } + return params +} + +// unmarshal the current staking params value from store key +func UnmarshalParams(cdc *wire.Codec, value []byte) (params Params, err error) { + err = cdc.UnmarshalBinary(value, ¶ms) + if err != nil { + return + } + return +} diff --git a/x/stake/types/pool.go b/x/stake/types/pool.go index d59c1ed251..b01ed8e9a9 100644 --- a/x/stake/types/pool.go +++ b/x/stake/types/pool.go @@ -6,13 +6,14 @@ import ( "time" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" ) // Pool - dynamic parameters of the current state type Pool struct { LooseTokens sdk.Dec `json:"loose_tokens"` // tokens which are not bonded in a validator BondedTokens sdk.Dec `json:"bonded_tokens"` // reserve of bonded tokens - InflationLastTime time.Time `json:"inflation_last_time"` // block which the last inflation was processed // TODO make time + InflationLastTime time.Time `json:"inflation_last_time"` // block which the last inflation was processed Inflation sdk.Dec `json:"inflation"` // current annual inflation rate DateLastCommissionReset int64 `json:"date_last_commission_reset"` // unix timestamp for last commission accounting reset (daily) @@ -123,3 +124,37 @@ func (p Pool) NextInflation(params Params) (inflation sdk.Dec) { return inflation } + +// HumanReadableString returns a human readable string representation of a +// pool. +func (p Pool) HumanReadableString() string { + + resp := "Pool \n" + resp += fmt.Sprintf("Loose Tokens: %s\n", p.LooseTokens) + resp += fmt.Sprintf("Bonded Tokens: %s\n", p.BondedTokens) + resp += fmt.Sprintf("Token Supply: %s\n", p.TokenSupply()) + resp += fmt.Sprintf("Bonded Ratio: %v\n", p.BondedRatio()) + resp += fmt.Sprintf("Previous Inflation Block: %s\n", p.InflationLastTime) + resp += fmt.Sprintf("Inflation: %v\n", p.Inflation) + resp += fmt.Sprintf("Date of Last Commission Reset: %d\n", p.DateLastCommissionReset) + resp += fmt.Sprintf("Previous Bonded Shares: %v\n", p.PrevBondedShares) + return resp +} + +// unmarshal the current pool value from store key or panics +func MustUnmarshalPool(cdc *wire.Codec, value []byte) Pool { + pool, err := UnmarshalPool(cdc, value) + if err != nil { + panic(err) + } + return pool +} + +// unmarshal the current pool value from store key +func UnmarshalPool(cdc *wire.Codec, value []byte) (pool Pool, err error) { + err = cdc.UnmarshalBinary(value, &pool) + if err != nil { + return + } + return +} diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index bd7d769932..f8404b5963 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -20,9 +20,9 @@ import ( // exchange rate. Voting power can be calculated as total bonds multiplied by // exchange rate. type Validator struct { - Owner sdk.AccAddress `json:"owner"` // sender of BondTx - UnbondTx returns here - PubKey crypto.PubKey `json:"pub_key"` // pubkey of validator - Revoked bool `json:"revoked"` // has the validator been revoked from bonded status? + Operator sdk.AccAddress `json:"operator"` // sender of BondTx - UnbondTx returns here + PubKey crypto.PubKey `json:"pub_key"` // pubkey of validator + Jailed bool `json:"jailed"` // has the validator been jailed from bonded status? Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded) Tokens sdk.Dec `json:"tokens"` // delegated tokens (incl. self-delegation) @@ -43,11 +43,11 @@ type Validator struct { } // NewValidator - initialize a new validator -func NewValidator(owner sdk.AccAddress, pubKey crypto.PubKey, description Description) Validator { +func NewValidator(operator sdk.AccAddress, pubKey crypto.PubKey, description Description) Validator { return Validator{ - Owner: owner, + Operator: operator, PubKey: pubKey, - Revoked: false, + Jailed: false, Status: sdk.Unbonded, Tokens: sdk.ZeroDec(), DelegatorShares: sdk.ZeroDec(), @@ -66,7 +66,7 @@ func NewValidator(owner sdk.AccAddress, pubKey crypto.PubKey, description Descri // what's kept in the store value type validatorValue struct { PubKey crypto.PubKey - Revoked bool + Jailed bool Status sdk.BondStatus Tokens sdk.Dec DelegatorShares sdk.Dec @@ -85,7 +85,7 @@ type validatorValue struct { func MustMarshalValidator(cdc *wire.Codec, validator Validator) []byte { val := validatorValue{ PubKey: validator.PubKey, - Revoked: validator.Revoked, + Jailed: validator.Jailed, Status: validator.Status, Tokens: validator.Tokens, DelegatorShares: validator.DelegatorShares, @@ -103,8 +103,8 @@ func MustMarshalValidator(cdc *wire.Codec, validator Validator) []byte { } // unmarshal a redelegation from a store key and value -func MustUnmarshalValidator(cdc *wire.Codec, ownerAddr, value []byte) Validator { - validator, err := UnmarshalValidator(cdc, ownerAddr, value) +func MustUnmarshalValidator(cdc *wire.Codec, operatorAddr, value []byte) Validator { + validator, err := UnmarshalValidator(cdc, operatorAddr, value) if err != nil { panic(err) } @@ -113,8 +113,8 @@ func MustUnmarshalValidator(cdc *wire.Codec, ownerAddr, value []byte) Validator } // unmarshal a redelegation from a store key and value -func UnmarshalValidator(cdc *wire.Codec, ownerAddr, value []byte) (validator Validator, err error) { - if len(ownerAddr) != sdk.AddrLen { +func UnmarshalValidator(cdc *wire.Codec, operatorAddr, value []byte) (validator Validator, err error) { + if len(operatorAddr) != sdk.AddrLen { err = fmt.Errorf("%v", ErrBadValidatorAddr(DefaultCodespace).Data()) return } @@ -125,9 +125,9 @@ func UnmarshalValidator(cdc *wire.Codec, ownerAddr, value []byte) (validator Val } return Validator{ - Owner: ownerAddr, + Operator: operatorAddr, PubKey: storeValue.PubKey, - Revoked: storeValue.Revoked, + Jailed: storeValue.Jailed, Tokens: storeValue.Tokens, Status: storeValue.Status, DelegatorShares: storeValue.DelegatorShares, @@ -144,7 +144,7 @@ func UnmarshalValidator(cdc *wire.Codec, ownerAddr, value []byte) (validator Val } // HumanReadableString returns a human readable string representation of a -// validator. An error is returned if the owner or the owner's public key +// validator. An error is returned if the operator or the operator's public key // cannot be converted to Bech32 format. func (v Validator) HumanReadableString() (string, error) { bechVal, err := sdk.Bech32ifyValPub(v.PubKey) @@ -153,9 +153,9 @@ func (v Validator) HumanReadableString() (string, error) { } resp := "Validator \n" - resp += fmt.Sprintf("Owner: %s\n", v.Owner) + resp += fmt.Sprintf("Operator: %s\n", v.Operator) resp += fmt.Sprintf("Validator: %s\n", bechVal) - resp += fmt.Sprintf("Revoked: %v\n", v.Revoked) + resp += fmt.Sprintf("Jailed: %v\n", v.Jailed) resp += fmt.Sprintf("Status: %s\n", sdk.BondStatusToString(v.Status)) resp += fmt.Sprintf("Tokens: %s\n", v.Tokens.String()) resp += fmt.Sprintf("Delegator Shares: %s\n", v.DelegatorShares.String()) @@ -175,9 +175,9 @@ func (v Validator) HumanReadableString() (string, error) { // validator struct for bech output type BechValidator struct { - Owner sdk.AccAddress `json:"owner"` // in bech32 - PubKey string `json:"pub_key"` // in bech32 - Revoked bool `json:"revoked"` // has the validator been revoked from bonded status? + Operator sdk.AccAddress `json:"operator"` // in bech32 + PubKey string `json:"pub_key"` // in bech32 + Jailed bool `json:"jailed"` // has the validator been jailed from bonded status? Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded) Tokens sdk.Dec `json:"tokens"` // delegated tokens (incl. self-delegation) @@ -205,9 +205,9 @@ func (v Validator) Bech32Validator() (BechValidator, error) { } return BechValidator{ - Owner: v.Owner, - PubKey: bechValPubkey, - Revoked: v.Revoked, + Operator: v.Operator, + PubKey: bechValPubkey, + Jailed: v.Jailed, Status: v.Status, Tokens: v.Tokens, @@ -233,7 +233,7 @@ func (v Validator) Bech32Validator() (BechValidator, error) { // nolint gocyclo - why dis fail? func (v Validator) Equal(c2 Validator) bool { return v.PubKey.Equals(c2.PubKey) && - bytes.Equal(v.Owner, c2.Owner) && + bytes.Equal(v.Operator, c2.Operator) && v.Status.Equal(c2.Status) && v.Tokens.Equal(c2.Tokens) && v.DelegatorShares.Equal(c2.DelegatorShares) && @@ -312,8 +312,9 @@ func (d Description) EnsureLength() (Description, sdk.Error) { // ABCIValidator returns an abci.Validator from a staked validator type. func (v Validator) ABCIValidator() abci.Validator { return abci.Validator{ - PubKey: tmtypes.TM2PB.PubKey(v.PubKey), - Power: v.BondedTokens().RoundInt64(), + PubKey: tmtypes.TM2PB.PubKey(v.PubKey), + Address: v.PubKey.Address(), + Power: v.BondedTokens().RoundInt64(), } } @@ -321,8 +322,9 @@ func (v Validator) ABCIValidator() abci.Validator { // with with zero power used for validator updates. func (v Validator) ABCIValidatorZero() abci.Validator { return abci.Validator{ - PubKey: tmtypes.TM2PB.PubKey(v.PubKey), - Power: 0, + PubKey: tmtypes.TM2PB.PubKey(v.PubKey), + Address: v.PubKey.Address(), + Power: 0, } } @@ -427,10 +429,10 @@ func (v Validator) BondedTokens() sdk.Dec { var _ sdk.Validator = Validator{} // nolint - for sdk.Validator -func (v Validator) GetRevoked() bool { return v.Revoked } +func (v Validator) GetJailed() bool { return v.Jailed } func (v Validator) GetMoniker() string { return v.Description.Moniker } func (v Validator) GetStatus() sdk.BondStatus { return v.Status } -func (v Validator) GetOwner() sdk.AccAddress { return v.Owner } +func (v Validator) GetOperator() sdk.AccAddress { return v.Operator } func (v Validator) GetPubKey() crypto.PubKey { return v.PubKey } func (v Validator) GetPower() sdk.Dec { return v.BondedTokens() } func (v Validator) GetTokens() sdk.Dec { return v.Tokens } diff --git a/x/stake/types/validator_test.go b/x/stake/types/validator_test.go index 3981f5754d..f4c874057f 100644 --- a/x/stake/types/validator_test.go +++ b/x/stake/types/validator_test.go @@ -72,7 +72,7 @@ func TestABCIValidatorZero(t *testing.T) { func TestRemoveTokens(t *testing.T) { validator := Validator{ - Owner: addr1, + Operator: addr1, PubKey: pk1, Status: sdk.Bonded, Tokens: sdk.NewDec(100), @@ -148,7 +148,7 @@ func TestAddTokensValidatorUnbonded(t *testing.T) { // TODO refactor to make simpler like the AddToken tests above func TestRemoveDelShares(t *testing.T) { valA := Validator{ - Owner: addr1, + Operator: addr1, PubKey: pk1, Status: sdk.Bonded, Tokens: sdk.NewDec(100), @@ -176,7 +176,7 @@ func TestRemoveDelShares(t *testing.T) { poolTokens := sdk.NewDec(5102) delShares := sdk.NewDec(115) validator := Validator{ - Owner: addr1, + Operator: addr1, PubKey: pk1, Status: sdk.Bonded, Tokens: poolTokens, @@ -229,7 +229,7 @@ func TestPossibleOverflow(t *testing.T) { poolTokens := sdk.NewDec(2159) delShares := sdk.NewDec(391432570689183511).Quo(sdk.NewDec(40113011844664)) validator := Validator{ - Owner: addr1, + Operator: addr1, PubKey: pk1, Status: sdk.Bonded, Tokens: poolTokens,