Merge branch 'master' into aaronc/6513-textual-json-proto
This commit is contained in:
commit
368efb0c7d
63
.github/PULL_REQUEST_TEMPLATE.md
vendored
63
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,29 +1,50 @@
|
||||
<!-- < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < ☺
|
||||
v ✰ Thanks for creating a PR! ✰
|
||||
v Before smashing the submit button please review the checkboxes.
|
||||
v If a checkbox is n/a - please still include it but + a little note why
|
||||
☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -->
|
||||
<!--
|
||||
The default pull request template is for types feat, fix, or refactor.
|
||||
For other templates, add one of the following parameters to the url:
|
||||
- template=docs.md
|
||||
- template=other.md
|
||||
-->
|
||||
|
||||
## Description
|
||||
|
||||
<!-- Add a description of the changes that this PR introduces and the files that
|
||||
are the most critical to review.
|
||||
-->
|
||||
Closes: #XXXX
|
||||
|
||||
closes: #XXXX
|
||||
<!-- Add a description of the changes that this PR introduces and the files that
|
||||
are the most critical to review. -->
|
||||
|
||||
---
|
||||
|
||||
Before we can merge this PR, please make sure that all the following items have been
|
||||
checked off. If any of the checklist items are not applicable, please leave them but
|
||||
write a little note why.
|
||||
### Author Checklist
|
||||
|
||||
- [ ] Targeted PR against correct branch (see [CONTRIBUTING.md](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting))
|
||||
- [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
|
||||
- [ ] Code follows the [module structure standards](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules/structure.md).
|
||||
- [ ] Wrote unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing)
|
||||
- [ ] Updated relevant documentation (`docs/`) or specification (`x/<module>/spec/`)
|
||||
- [ ] Added relevant `godoc` [comments](https://blog.golang.org/godoc-documenting-go-code).
|
||||
- [ ] Added a relevant changelog entry to the `Unreleased` section in `CHANGELOG.md`
|
||||
- [ ] Re-reviewed `Files changed` in the Github PR explorer
|
||||
- [ ] Review `Codecov Report` in the comment section below once CI passes
|
||||
*All items are required. Please add a note to the item if the item is not applicable and
|
||||
please add links to any relevant follow up issues.*
|
||||
|
||||
I have...
|
||||
|
||||
- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
|
||||
- [ ] added `!` to the type prefix if API or client breaking change
|
||||
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting))
|
||||
- [ ] provided a link to the relevant issue or specification
|
||||
- [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules)
|
||||
- [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing)
|
||||
- [ ] added a changelog entry to `CHANGELOG.md`
|
||||
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
|
||||
- [ ] updated the relevant documentation or specification
|
||||
- [ ] reviewed "Files changed" and left comments if necessary
|
||||
- [ ] confirmed all CI checks have passed
|
||||
|
||||
### Reviewers Checklist
|
||||
|
||||
*All items are required. Please add a note if the item is not applicable and please add
|
||||
your handle next to the items reviewed if you only reviewed selected items.*
|
||||
|
||||
I have...
|
||||
|
||||
- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
|
||||
- [ ] confirmed `!` in the type prefix if API or client breaking change
|
||||
- [ ] confirmed all author checklist items have been addressed
|
||||
- [ ] reviewed state machine logic
|
||||
- [ ] reviewed API design and naming
|
||||
- [ ] reviewed documentation is accurate
|
||||
- [ ] reviewed tests and test coverage
|
||||
- [ ] manually tested (if applicable)
|
||||
37
.github/PULL_REQUEST_TEMPLATE/docs.md
vendored
Normal file
37
.github/PULL_REQUEST_TEMPLATE/docs.md
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
## Description
|
||||
|
||||
Closes: #XXXX
|
||||
|
||||
<!-- Add a description of the changes that this PR introduces and the files that
|
||||
are the most critical to review. -->
|
||||
|
||||
---
|
||||
|
||||
### Author Checklist
|
||||
|
||||
*All items are required. Please add a note to the item if the item is not applicable and
|
||||
please add links to any relevant follow up issues.*
|
||||
|
||||
I have...
|
||||
|
||||
- [ ] included the correct `docs:` prefix in the PR title
|
||||
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting))
|
||||
- [ ] provided a link to the relevant issue or specification
|
||||
- [ ] followed the [documentation writing guidelines](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOC_WRITING_GUIDELINES.md)
|
||||
- [ ] reviewed "Files changed" and left comments if necessary
|
||||
- [ ] confirmed all CI checks have passed
|
||||
|
||||
### Reviewers Checklist
|
||||
|
||||
*All items are required. Please add a note if the item is not applicable and please add
|
||||
your handle next to the items reviewed if you only reviewed selected items.*
|
||||
|
||||
I have...
|
||||
|
||||
- [ ] confirmed the correct `docs:` prefix in the PR title
|
||||
- [ ] confirmed all author checklist items have been addressed
|
||||
- [ ] confirmed that this PR only changes documentation
|
||||
- [ ] reviewed content for consistency
|
||||
- [ ] reviewed content for thoroughness
|
||||
- [ ] reviewed content for spelling and grammar
|
||||
- [ ] tested instructions (if applicable)
|
||||
32
.github/PULL_REQUEST_TEMPLATE/other.md
vendored
Normal file
32
.github/PULL_REQUEST_TEMPLATE/other.md
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
## Description
|
||||
|
||||
Closes: #XXXX
|
||||
|
||||
<!-- Add a description of the changes that this PR introduces and the files that
|
||||
are the most critical to review. -->
|
||||
|
||||
---
|
||||
|
||||
### Author Checklist
|
||||
|
||||
*All items are required. Please add a note to the item if the item is not applicable and
|
||||
please add links to any relevant follow up issues.*
|
||||
|
||||
I have...
|
||||
|
||||
- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
|
||||
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting))
|
||||
- [ ] provided a link to the relevant issue or specification
|
||||
- [ ] reviewed "Files changed" and left comments if necessary
|
||||
- [ ] confirmed all CI checks have passed
|
||||
|
||||
### Reviewers Checklist
|
||||
|
||||
*All items are required. Please add a note if the item is not applicable and please add
|
||||
your handle next to the items reviewed if you only reviewed selected items.*
|
||||
|
||||
I have...
|
||||
|
||||
- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
|
||||
- [ ] confirmed all author checklist items have been addressed
|
||||
- [ ] confirmed that this PR does not change production code
|
||||
45
.github/labeler.yml
vendored
45
.github/labeler.yml
vendored
@ -1,41 +1,41 @@
|
||||
"Scope: x/auth":
|
||||
"C:x/auth":
|
||||
- x/auth/**/*
|
||||
"Scope: x/authz":
|
||||
"C:x/authz":
|
||||
- x/authz/**/*
|
||||
"Scope: x/bank":
|
||||
"C:x/bank":
|
||||
- x/bank/**/*
|
||||
"Scope: x/capability":
|
||||
"C:x/capability":
|
||||
- x/capability/**/*
|
||||
"Scope: x/crisis":
|
||||
"C:x/crisis":
|
||||
- x/crisis/**/*
|
||||
"Scope: x/distribution":
|
||||
"C:x/distribution":
|
||||
- x/distribution/**/*
|
||||
"Scope: x/evidence":
|
||||
"C:x/evidence":
|
||||
- x/evidence/**/*
|
||||
"Scope: x/feegrant":
|
||||
"C:x/feegrant":
|
||||
- x/feegrant/**/*
|
||||
"Scope: x/genutil":
|
||||
"C:x/genutil":
|
||||
- x/genutil/**/*
|
||||
"Scope: x/gov":
|
||||
"C:x/gov":
|
||||
- x/gov/**/*
|
||||
"Scope: x/mint":
|
||||
"C:x/mint":
|
||||
- x/mint/**/*
|
||||
"Scope: x/params":
|
||||
"C:x/params":
|
||||
- x/params/**/*
|
||||
"Scope: Simulations":
|
||||
"C:Simulations":
|
||||
- x/simulation/**/*
|
||||
- x/*/simulation/**/*
|
||||
"Scope: x/slashing":
|
||||
"C:x/slashing":
|
||||
- x/slashing/**/*
|
||||
"Scope: x/staking":
|
||||
"C:x/staking":
|
||||
- x/staking/**/*
|
||||
"Scope: x/upgrade":
|
||||
"C:x/upgrade":
|
||||
- x/upgrade/**/*
|
||||
"Scope: Cosmovisor":
|
||||
"C:Cosmovisor":
|
||||
- cosmovisor/**/*
|
||||
"Scope: Rosetta":
|
||||
"C:Rosetta":
|
||||
- contrib/rosetta/**/*
|
||||
"Scope: Keys":
|
||||
"C:Keys":
|
||||
- client/keys/**/*
|
||||
"Type: Build":
|
||||
- Makefile
|
||||
@ -47,11 +47,8 @@
|
||||
- buf.yaml
|
||||
- .mergify.yml
|
||||
- .golangci.yml
|
||||
"Scope: CLI":
|
||||
"C:CLI":
|
||||
- client/**/*
|
||||
- x/*/client/**/*
|
||||
"Type: Docs":
|
||||
- docs/**/*
|
||||
- x/*/spec/**/*
|
||||
"Type: ADR":
|
||||
- docs/architecture/**/*
|
||||
- docs/architecture/**/*
|
||||
|
||||
2
.github/workflows/linkchecker.yml
vendored
2
.github/workflows/linkchecker.yml
vendored
@ -7,6 +7,6 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: gaurav-nelson/github-action-markdown-link-check@1.0.12
|
||||
- uses: gaurav-nelson/github-action-markdown-link-check@1.0.13
|
||||
with:
|
||||
folder-path: "docs"
|
||||
|
||||
16
.github/workflows/lint-pr.yml
vendored
Normal file
16
.github/workflows/lint-pr.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
name: "Lint PR"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@v3.4.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
4
.github/workflows/release-sims.yml
vendored
4
.github/workflows/release-sims.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
- name: install runsim
|
||||
run: |
|
||||
export GO111MODULE="on" && go get github.com/cosmos/tools/cmd/runsim@v1.0.0
|
||||
- uses: actions/cache@v2.1.5
|
||||
- uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
@ -32,7 +32,7 @@ jobs:
|
||||
needs: [build, install-runsim]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2.1.5
|
||||
- uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
|
||||
10
.github/workflows/sims.yml
vendored
10
.github/workflows/sims.yml
vendored
@ -31,7 +31,7 @@ jobs:
|
||||
run: go version
|
||||
- name: Install runsim
|
||||
run: export GO111MODULE="on" && go get github.com/cosmos/tools/cmd/runsim@v1.0.0
|
||||
- uses: actions/cache@v2.1.5
|
||||
- uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
@ -52,7 +52,7 @@ jobs:
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- uses: actions/cache@v2.1.5
|
||||
- uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
@ -80,7 +80,7 @@ jobs:
|
||||
go.sum
|
||||
SET_ENV_NAME_INSERTIONS: 1
|
||||
SET_ENV_NAME_LINES: 1
|
||||
- uses: actions/cache@v2.1.5
|
||||
- uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
@ -108,7 +108,7 @@ jobs:
|
||||
go.sum
|
||||
SET_ENV_NAME_INSERTIONS: 1
|
||||
SET_ENV_NAME_LINES: 1
|
||||
- uses: actions/cache@v2.1.5
|
||||
- uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
@ -136,7 +136,7 @@ jobs:
|
||||
go.sum
|
||||
SET_ENV_NAME_INSERTIONS: 1
|
||||
SET_ENV_NAME_LINES: 1
|
||||
- uses: actions/cache@v2.1.5
|
||||
- uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
|
||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@ -7,7 +7,7 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
- uses: actions/stale@v4
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-pr-message: "This pull request has been automatically marked as stale because it has not had
|
||||
|
||||
2
.github/workflows/tag.yml
vendored
2
.github/workflows/tag.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
- name: Unshallow
|
||||
run: git fetch --prune --unshallow
|
||||
- name: Create release
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
uses: goreleaser/goreleaser-action@v2.6.1
|
||||
with:
|
||||
args: release --rm-dist --release-notes ./RELEASE_CHANGELOG.md
|
||||
env:
|
||||
|
||||
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
- name: install tparse
|
||||
run: |
|
||||
export GO111MODULE="on" && go get github.com/mfridman/tparse@v0.8.3
|
||||
- uses: actions/cache@v2.1.5
|
||||
- uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-tparse-binary
|
||||
@ -164,7 +164,7 @@ jobs:
|
||||
sed -i.bak "/$(echo $filename | sed 's/\//\\\//g')/d" coverage.txt
|
||||
done
|
||||
if: env.GIT_DIFF
|
||||
- uses: codecov/codecov-action@v1.4.1
|
||||
- uses: codecov/codecov-action@v1.5.2
|
||||
with:
|
||||
file: ./coverage.txt
|
||||
if: env.GIT_DIFF
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -26,7 +26,7 @@ artifacts
|
||||
# Data - ideally these don't exist
|
||||
baseapp/data/*
|
||||
client/lcd/keys/*
|
||||
mytestnet
|
||||
.testnets
|
||||
|
||||
# Testing
|
||||
coverage.txt
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
run:
|
||||
tests: false
|
||||
# # timeout for analysis, e.g. 30s, 5m, default is 1m
|
||||
# timeout: 5m
|
||||
# timeout for analysis, e.g. 30s, 5m, default is 1m
|
||||
timeout: 5m
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
@ -54,7 +54,7 @@ issues:
|
||||
- text: "ST1016:"
|
||||
linters:
|
||||
- stylecheck
|
||||
- path: "legacy"
|
||||
- path: "migrations"
|
||||
text: "SA1019:"
|
||||
linters:
|
||||
- staticcheck
|
||||
|
||||
17
.markdownlint.json
Normal file
17
.markdownlint.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"default": true,
|
||||
"MD001": false,
|
||||
"MD004": false,
|
||||
"MD007": { "indent": 4 },
|
||||
"MD013": false,
|
||||
"MD024": { "siblings_only": true },
|
||||
"MD025": false,
|
||||
"MD026": { "punctuation": ".,;:" },
|
||||
"MD029": false,
|
||||
"MD033": false,
|
||||
"MD034": false,
|
||||
"MD036": false,
|
||||
"MD040": false,
|
||||
"MD041": false,
|
||||
"no-hard-tabs": false
|
||||
}
|
||||
3
.markdownlintignore
Normal file
3
.markdownlintignore
Normal file
@ -0,0 +1,3 @@
|
||||
CHANGELOG.md
|
||||
docs/core/proto-docs.md
|
||||
docs/node_modules
|
||||
@ -8,6 +8,15 @@ pull_request_rules:
|
||||
merge:
|
||||
method: squash
|
||||
strict: true
|
||||
commit_message: title+body
|
||||
- name: backport patches to v0.43.x branch
|
||||
conditions:
|
||||
- base=master
|
||||
- label=backport/0.43.x
|
||||
actions:
|
||||
backport:
|
||||
branches:
|
||||
- release/v0.43.x
|
||||
- name: backport patches to v0.42.x branch
|
||||
conditions:
|
||||
- base=master
|
||||
|
||||
188
CHANGELOG.md
188
CHANGELOG.md
@ -26,7 +26,8 @@ Types of changes (Stanzas):
|
||||
"Improvements" for changes in existing functionality.
|
||||
"Deprecated" for soon-to-be removed features.
|
||||
"Bug Fixes" for any bug fixes.
|
||||
"Client Breaking" for breaking CLI commands and REST routes used by end-users.
|
||||
"Client Breaking" for breaking Protobuf, gRPC and REST routes used by end-users.
|
||||
"CLI Breaking" for breaking CLI commands.
|
||||
"API Breaking" for breaking exported APIs used by developers building on SDK.
|
||||
"State Machine Breaking" for any changes that result in a different AppState given same genesisState and txList.
|
||||
Ref: https://keepachangelog.com/en/1.0.0/
|
||||
@ -35,37 +36,96 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
* [\#9205](https://github.com/cosmos/cosmos-sdk/pull/9205) Improve readability in `abci` handleQueryP2P
|
||||
|
||||
### Features
|
||||
|
||||
* [\#9533](https://github.com/cosmos/cosmos-sdk/pull/9533) Added a new gRPC method, `DenomOwners`, in `x/bank` to query for all account holders of a specific denomination.
|
||||
* (bank) [\#9618](https://github.com/cosmos/cosmos-sdk/pull/9618) Update bank.Metadata: add URI and URIHash attributes.
|
||||
|
||||
### API Breaking Changes
|
||||
|
||||
* [\#9628](https://github.com/cosmos/cosmos-sdk/pull/9628) Rename `x/{mod}/legacy` to `x/{mod}/migrations`.
|
||||
* [\#9571](https://github.com/cosmos/cosmos-sdk/pull/9571) Implemented error handling for staking hooks, which now return an error on failure.
|
||||
* [\#9427](https://github.com/cosmos/cosmos-sdk/pull/9427) Move simapp `FundAccount` and `FundModuleAccount` to `x/bank/testutil`
|
||||
* (client/tx) [\#9421](https://github.com/cosmos/cosmos-sdk/pull/9421/) `BuildUnsignedTx`, `BuildSimTx`, `PrintUnsignedStdTx` functions are moved to
|
||||
the Tx Factory as methods.
|
||||
* (client/keys) [\#9407](https://github.com/cosmos/cosmos-sdk/pull/9601) Added `keys rename` CLI command and `Keyring.Rename` interface method to rename a key in the keyring.
|
||||
* (x/slashing) [\#9458](https://github.com/cosmos/cosmos-sdk/pull/9458) Coins burned from slashing is now returned from Slash function and included in Slash event.
|
||||
* [\#9246](https://github.com/cosmos/cosmos-sdk/pull/9246) The `New` method for the network package now returns an error.
|
||||
* (codec) [\#9521](https://github.com/cosmos/cosmos-sdk/pull/9521) Removed deprecated `clientCtx.JSONCodec` from `client.Context`.
|
||||
* (codec) [\#9521](https://github.com/cosmos/cosmos-sdk/pull/9521) Rename `EncodingConfig.Marshaler` to `Codec`.
|
||||
* [\#9418](https://github.com/cosmos/cosmos-sdk/pull/9418) `sdk.Msg`'s `GetSigners()` method updated to return `[]string`.
|
||||
* [\#9594](https://github.com/cosmos/cosmos-sdk/pull/9594) `RESTHandlerFn` argument is removed from the `gov/NewProposalHandler`.
|
||||
* [\#9594](https://github.com/cosmos/cosmos-sdk/pull/9594) `types/rest` package moved to `testutil/rest`.
|
||||
* [\#9432](https://github.com/cosmos/cosmos-sdk/pull/9432) `ConsensusParamsKeyTable` moved from `params/keeper` to `params/types`
|
||||
* [\#9576](https://github.com/cosmos/cosmos-sdk/pull/9576) Add debug error message to `sdkerrors.QueryResult` when enabled
|
||||
* [\#9650](https://github.com/cosmos/cosmos-sdk/pull/9650) Removed deprecated message handler implementation from the SDK modules.
|
||||
|
||||
### Client Breaking Changes
|
||||
|
||||
* [\#9594](https://github.com/cosmos/cosmos-sdk/pull/9594) Remove legacy REST API. Please see the [REST Endpoints Migration guide](https://docs.cosmos.network/master/migrations/rest.html) to migrate to the new REST endpoints.
|
||||
|
||||
|
||||
### CLI Breaking Changes
|
||||
|
||||
* [\#9246](https://github.com/cosmos/cosmos-sdk/pull/9246) Removed the CLI flag `--setup-config-only` from the `testnet` command and added the subcommand `init-files`.
|
||||
* [\#9371](https://github.com/cosmos/cosmos-sdk/pull/9371) Non-zero default fees/Server will error if there's an empty value for min-gas-price in app.toml
|
||||
|
||||
### Improvements
|
||||
|
||||
* (cli) [\#9593](https://github.com/cosmos/cosmos-sdk/pull/9593) Check if chain-id is blank before verifying signatures in multisign and error.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* [\#9720](https://github.com/cosmos/cosmos-sdk/pull/9720) Feegrant grant cli granter now accepts key name as well as address in general and accepts only address in --generate-only mode
|
||||
* [\#9651](https://github.com/cosmos/cosmos-sdk/pull/9651) Change inconsistent limit of `0` to `MaxUint64` on InfiniteGasMeter and add GasRemaining func to GasMeter.
|
||||
* [\#9639](https://github.com/cosmos/cosmos-sdk/pull/9639) Check store keys length before accessing them by making sure that `key` is of length `m+1` (for `key[n:m]`)
|
||||
* (types) [\#9627](https://github.com/cosmos/cosmos-sdk/pull/9627) Fix nil pointer panic on `NewBigIntFromInt`
|
||||
* (x/genutil) [\#9574](https://github.com/cosmos/cosmos-sdk/pull/9575) Actually use the `gentx` client tx flags (like `--keyring-dir`)
|
||||
* (x/distribution) [\#9599](https://github.com/cosmos/cosmos-sdk/pull/9599) Withdraw rewards event now includes a value attribute even if there are 0 rewards (due to situations like 100% commission).
|
||||
* (x/genutil) [\#9638](https://github.com/cosmos/cosmos-sdk/pull/9638) Added missing validator key save when recovering from mnemonic
|
||||
* (server) [#9704](https://github.com/cosmos/cosmos-sdk/pull/9704) Start GRPCWebServer in goroutine, avoid blocking other services from starting.
|
||||
|
||||
## [v0.43.0-rc0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.43.0-rc0) - 2021-06-25
|
||||
|
||||
### Features
|
||||
|
||||
* [\#6711](https://github.com/cosmos/cosmos-sdk/pull/6711) Make integration test suites reusable by apps, tests are exported in each module's `client/testutil` package.
|
||||
* [\#8077](https://github.com/cosmos/cosmos-sdk/pull/8077) Added support for grpc-web, enabling browsers to communicate with a chain's gRPC server
|
||||
* [\#8965](https://github.com/cosmos/cosmos-sdk/pull/8965) cosmos reflection now provides more information on the application such as: deliverable msgs, sdk.Config info etc (still in alpha stage).
|
||||
* [\#8520](https://github.com/cosmos/cosmos-sdk/pull/8520) Add support for permanently locked vesting accounts.
|
||||
* [\#8559](https://github.com/cosmos/cosmos-sdk/pull/8559) Added Protobuf compatible secp256r1 ECDSA signatures.
|
||||
* [\#8786](https://github.com/cosmos/cosmos-sdk/pull/8786) Enabled secp256r1 in x/auth.
|
||||
* (rosetta) [\#8729](https://github.com/cosmos/cosmos-sdk/pull/8729) Data API fully supports balance tracking. Construction API can now construct any message supported by the application.
|
||||
* [\#8754](https://github.com/cosmos/cosmos-sdk/pull/8875) Added support for reverse iteration to pagination.
|
||||
* (types) [\#9079](https://github.com/cosmos/cosmos-sdk/issues/9079) Add `AddAmount`/`SubAmount` methods to `sdk.Coin`.
|
||||
* [#9088](https://github.com/cosmos/cosmos-sdk/pull/9088) Added implementation to ADR-28 Derived Addresses.
|
||||
* [\#9133](https://github.com/cosmos/cosmos-sdk/pull/9133) Added hooks for governance actions.
|
||||
* (x/staking) [\#9214](https://github.com/cosmos/cosmos-sdk/pull/9214) Added `new_shares` attribute inside `EventTypeDelegate` event.
|
||||
* [\#9382](https://github.com/cosmos/cosmos-sdk/pull/9382) feat: add Dec.Float64() function.
|
||||
* [\#9457](https://github.com/cosmos/cosmos-sdk/pull/9457) Add amino support for x/authz and x/feegrant Msgs.
|
||||
* [\#9498](https://github.com/cosmos/cosmos-sdk/pull/9498) Added `Codec: codec.Codec` attribute to `client/Context` structure.
|
||||
* [\#9540](https://github.com/cosmos/cosmos-sdk/pull/9540) Add output flag for query txs command.
|
||||
* (errors) [\#8845](https://github.com/cosmos/cosmos-sdk/pull/8845) Add `Error.Wrap` handy method
|
||||
* [\#8518](https://github.com/cosmos/cosmos-sdk/pull/8518) Help users of multisig wallets debug signature issues.
|
||||
|
||||
|
||||
### Client Breaking Changes
|
||||
|
||||
* [\#8363](https://github.com/cosmos/cosmos-sdk/pull/8363) Addresses no longer have a fixed 20-byte length. From the SDK modules' point of view, any 1-255 bytes-long byte array is a valid address.
|
||||
* [\#8346](https://github.com/cosmos/cosmos-sdk/pull/8346) All CLI `tx` commands generate ServiceMsgs by default. Graceful Amino support has been added to ServiceMsgs to support signing legacy Msgs.
|
||||
* (crypto/ed25519) [\#8690] Adopt zip1215 ed2559 verification rules.
|
||||
* [\#8849](https://github.com/cosmos/cosmos-sdk/pull/8849) Upgrade module no longer supports time based upgrades.
|
||||
* [\#8880](https://github.com/cosmos/cosmos-sdk/pull/8880) The CLI `simd migrate v0.40 ...` command has been renamed to `simd migrate v0.42`.
|
||||
* [\#7477](https://github.com/cosmos/cosmos-sdk/pull/7477) Changed Bech32 Public Key serialization in the client facing functionality (CLI, MsgServer, QueryServer):
|
||||
* updated the keyring display structure (it uses protobuf JSON serialization) - the output is more verbose.
|
||||
* Renamed `MarshalAny` and `UnmarshalAny` to `MarshalInterface` and `UnmarshalInterface` respectively. These functions must take an interface as parameter (not a concrete type nor `Any` object). Underneath they use `Any` wrapping for correct protobuf serialization.
|
||||
* CLI: removed `--text` flag from `show-node-id` command; the text format for public keys is not used any more - instead we use ProtoJSON.
|
||||
* (types) [\#9079](https://github.com/cosmos/cosmos-sdk/issues/9079) Add `AddAmount`/`SubAmount` methods to `sdk.Coin`.
|
||||
* [\#8628](https://github.com/cosmos/cosmos-sdk/issues/8628) Commands no longer print outputs using `stderr` by default
|
||||
* (store) [\#8790](https://github.com/cosmos/cosmos-sdk/pull/8790) Reduce gas costs by 10x for transient store operations.
|
||||
* [\#9139](https://github.com/cosmos/cosmos-sdk/pull/9139) Querying events:
|
||||
* via `ServiceMsg` TypeURLs (e.g. `message.action='/cosmos.bank.v1beta1.Msg/Send'`) does not work anymore,
|
||||
* via legacy `msg.Type()` (e.g. `message.action='send'`) is being deprecated, new `Msg`s won't emit these events.
|
||||
* Please use concrete `Msg` TypeURLs instead (e.g. `message.action='/cosmos.bank.v1beta1.MsgSend'`).
|
||||
|
||||
|
||||
### API Breaking Changes
|
||||
|
||||
* (keyring) [#\8662](https://github.com/cosmos/cosmos-sdk/pull/8662) `NewMnemonic` now receives an additional `passphrase` argument to secure the key generated by the bip39 mnemonic.
|
||||
@ -74,8 +134,9 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
* (x/gov) [\#8473](https://github.com/cosmos/cosmos-sdk/pull/8473) On genesis init, if the gov module account balance, coming from bank module state, does not match the one in gov module state, the initialization will panic.
|
||||
* (x/distribution) [\#8473](https://github.com/cosmos/cosmos-sdk/pull/8473) On genesis init, if the distribution module account balance, coming from bank module state, does not match the one in distribution module state, the initialization will panic.
|
||||
* (client/keys) [\#8500](https://github.com/cosmos/cosmos-sdk/pull/8500) `InfoImporter` interface is removed from legacy keybase.
|
||||
* (x/staking) [\#8505](https://github.com/cosmos/cosmos-sdk/pull/8505) `sdk.PowerReduction` has been renamed to `sdk.DefaultPowerReduction`, and most staking functions relying on power reduction take a new function argument, instead of relying on that global variable.
|
||||
* [\#8629](https://github.com/cosmos/cosmos-sdk/pull/8629) Deprecated `SetFullFundraiserPath` from `Config` in favor of `SetPurpose` and `SetCoinType`.
|
||||
* (x/upgrade) [\#8673](https://github.com/cosmos/cosmos-sdk/pull/8673) Remove IBC logic from x/upgrade. Deprecates IBC fields in an Upgrade Plan. IBC upgrade logic moved to 02-client and an IBC UpgradeProposal is added.
|
||||
* (x/upgrade) [\#8673](https://github.com/cosmos/cosmos-sdk/pull/8673) Remove IBC logic from x/upgrade. Deprecates IBC fields in an Upgrade Plan, an error will be thrown if they are set. IBC upgrade logic moved to 02-client and an IBC UpgradeProposal is added.
|
||||
* (x/bank) [\#8517](https://github.com/cosmos/cosmos-sdk/pull/8517) `SupplyI` interface and `Supply` are removed and uses `sdk.Coins` for supply tracking
|
||||
* (x/upgrade) [\#8743](https://github.com/cosmos/cosmos-sdk/pull/8743) `UpgradeHandler` includes a new argument `VersionMap` which helps facilitate in-place migrations.
|
||||
* (x/auth) [\#8129](https://github.com/cosmos/cosmos-sdk/pull/8828) Updated `SigVerifiableTx.GetPubKeys` method signature to return error.
|
||||
@ -91,8 +152,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
* (client) [\#8926](https://github.com/cosmos/cosmos-sdk/pull/8926) `client/tx.PrepareFactory` has been converted to a private function, as it's only used internally.
|
||||
* (auth/tx) [\#8926](https://github.com/cosmos/cosmos-sdk/pull/8926) The `ProtoTxProvider` interface used as a workaround for transaction simulation has been removed.
|
||||
* (x/bank) [\#8798](https://github.com/cosmos/cosmos-sdk/pull/8798) `GetTotalSupply` is removed in favour of `GetPaginatedTotalSupply`
|
||||
* (keyring) [\#8739](https://github.com/cosmos/cosmos-sdk/pull/8739) Rename InfoImporter -> LegacyInfoImporter.
|
||||
* (x/bank/types) [\#9061](https://github.com/cosmos/cosmos-sdk/pull/9061) `AddressFromBalancesStore` now returns an error for invalid key instead of panic.
|
||||
* (codec) [\#9061](https://github.com/cosmos/cosmos-sdk/pull/9226) Rename codec interfaces and methods, to follow a general Go interfaces:
|
||||
* (x/auth) [\#9144](https://github.com/cosmos/cosmos-sdk/pull/9144) The `NewTxTimeoutHeightDecorator` antehandler has been converted from a struct to a function.
|
||||
* (codec) [\#9226](https://github.com/cosmos/cosmos-sdk/pull/9226) Rename codec interfaces and methods, to follow a general Go interfaces:
|
||||
* `codec.Marshaler` → `codec.Codec` (this defines objects which serialize other objects)
|
||||
* `codec.BinaryMarshaler` → `codec.BinaryCodec`
|
||||
* `codec.JSONMarshaler` → `codec.JSONCodec`
|
||||
@ -102,43 +165,137 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
* The `sdk.ServiceMsg` struct has been removed.
|
||||
* `sdk.Msg` now only contains `ValidateBasic` and `GetSigners` methods. The remaining methods `GetSignBytes`, `Route` and `Type` are moved to `legacytx.LegacyMsg`.
|
||||
* The `RegisterCustomTypeURL` function and the `cosmos.base.v1beta1.ServiceMsg` interface have been removed from the interface registry.
|
||||
|
||||
* (codec) [\#9251](https://github.com/cosmos/cosmos-sdk/pull/9251) Rename `clientCtx.JSONMarshaler` to `clientCtx.JSONCodec` as per #9226.
|
||||
* (x/bank) [\#9271](https://github.com/cosmos/cosmos-sdk/pull/9271) SendEnabledCoin(s) renamed to IsSendEnabledCoin(s) to better reflect its functionality.
|
||||
* (x/bank) [\#9550](https://github.com/cosmos/cosmos-sdk/pull/9550) `server.InterceptConfigsPreRunHandler` now takes 2 additional arguments: customAppConfigTemplate and customAppConfig. If you don't need to customize these, simply put `""` and `nil`.
|
||||
* [\#8245](https://github.com/cosmos/cosmos-sdk/pull/8245) Removed `simapp.MakeCodecs` and use `simapp.MakeTestEncodingConfig` instead.
|
||||
|
||||
|
||||
### State Machine Breaking
|
||||
|
||||
* (x/{bank,distrib,gov,slashing,staking}) [\#8363](https://github.com/cosmos/cosmos-sdk/issues/8363) Store keys have been modified to allow for variable-length addresses.
|
||||
* (x/evidence) [\#8502](https://github.com/cosmos/cosmos-sdk/pull/8502) `HandleEquivocationEvidence` persists the evidence to state.
|
||||
* (x/gov) [\#7733](https://github.com/cosmos/cosmos-sdk/pull/7733) ADR 037 Implementation: Governance Split Votes
|
||||
* (x/gov) [\#7733](https://github.com/cosmos/cosmos-sdk/pull/7733) ADR 037 Implementation: Governance Split Votes, use `MsgWeightedVote` to send a split vote. Sending a regular `MsgVote` will convert the underlying vote option into a weighted vote with weight 1.
|
||||
* (x/bank) [\#8656](https://github.com/cosmos/cosmos-sdk/pull/8656) balance and supply are now correctly tracked via `coin_spent`, `coin_received`, `coinbase` and `burn` events.
|
||||
* (x/bank) [\#8517](https://github.com/cosmos/cosmos-sdk/pull/8517) Supply is now stored and tracked as `sdk.Coins`
|
||||
* (store) [\#8790](https://github.com/cosmos/cosmos-sdk/pull/8790) Reduce gas costs by 10x for transient store operations.
|
||||
* (x/staking) [\#8505](https://github.com/cosmos/cosmos-sdk/pull/8505) Convert staking power reduction into an on-chain parameter rather than a hardcoded in-code variable.
|
||||
* (x/bank) [\#9051](https://github.com/cosmos/cosmos-sdk/pull/9051) Supply value is stored as `sdk.Int` rather than `string`.
|
||||
|
||||
|
||||
### CLI Breaking Changes
|
||||
|
||||
* [\#8880](https://github.com/cosmos/cosmos-sdk/pull/8880) The CLI `simd migrate v0.40 ...` command has been renamed to `simd migrate v0.42`.
|
||||
* [\#8628](https://github.com/cosmos/cosmos-sdk/issues/8628) Commands no longer print outputs using `stderr` by default
|
||||
* [\#9134](https://github.com/cosmos/cosmos-sdk/pull/9134) Renamed the CLI flag `--memo` to `--note`.
|
||||
* [\#9291](https://github.com/cosmos/cosmos-sdk/pull/9291) Migration scripts prior to v0.38 have been removed from the CLI `migrate` command. The oldest supported migration is v0.39->v0.42.
|
||||
|
||||
|
||||
### Improvements
|
||||
|
||||
* (store) [\#8012](https://github.com/cosmos/cosmos-sdk/pull/8012) Implementation of ADR-038 WriteListener and listen.KVStore
|
||||
* (x/bank) [\#8614](https://github.com/cosmos/cosmos-sdk/issues/8614) Add `Name` and `Symbol` fields to denom metadata
|
||||
* (x/auth) [\#8522](https://github.com/cosmos/cosmos-sdk/pull/8522) Allow to query all stored accounts
|
||||
* (crypto/types) [\#8600](https://github.com/cosmos/cosmos-sdk/pull/8600) `CompactBitArray`: optimize the `NumTrueBitsBefore` method and add an `Equal` method.
|
||||
* (x/upgrade) [\#8743](https://github.com/cosmos/cosmos-sdk/pull/8743) Add tracking module versions as per ADR-041
|
||||
* (types) [\#8962](https://github.com/cosmos/cosmos-sdk/issues/8962) Add `Abs()` method to `sdk.Int`.
|
||||
* (x/bank) [\#8950](https://github.com/cosmos/cosmos-sdk/pull/8950) Improve efficiency on supply updates.
|
||||
* (store) [\#8012](https://github.com/cosmos/cosmos-sdk/pull/8012) Implementation of ADR-038 WriteListener and listen.KVStore
|
||||
* (store) [\#8811](https://github.com/cosmos/cosmos-sdk/pull/8811) store/cachekv: use typed `types/kv.List` instead of `container/list.List`. The change brings time spent on the time assertion cummulatively to 580ms down from 6.88s.
|
||||
* (keyring) [\#8826](https://github.com/cosmos/cosmos-sdk/pull/8826) add trust to macOS Keychain for calling apps by default, avoiding repeating keychain popups that appears when dealing with keyring (key add, list, ...) operations.
|
||||
* (makefile) [\#7933](https://github.com/cosmos/cosmos-sdk/issues/7933) Use Docker to generate swagger files.
|
||||
* (crypto/types) [\#9196](https://github.com/cosmos/cosmos-sdk/pull/9196) Fix negative index accesses in CompactUnmarshal,GetIndex,SetIndex
|
||||
* (cli) [\#9201](https://github.com/cosmos/cosmos-sdk/pull/9201) Fix init --recover not working.
|
||||
* (makefile) [\#9192](https://github.com/cosmos/cosmos-sdk/pull/9192) Reuse proto containers in proto related jobs.
|
||||
* [\#9205](https://github.com/cosmos/cosmos-sdk/pull/9205) Improve readability in `abci` handleQueryP2P
|
||||
* [\#9231](https://github.com/cosmos/cosmos-sdk/pull/9231) Remove redundant staking errors.
|
||||
* [\#9314](https://github.com/cosmos/cosmos-sdk/pull/9314) Update Rosetta SDK to upstream's latest release.
|
||||
* (gRPC-Web) [\#9493](https://github.com/cosmos/cosmos-sdk/pull/9493) Add `EnableUnsafeCORS` flag to grpc-web config.
|
||||
* (x/params) [\#9481](https://github.com/cosmos/cosmos-sdk/issues/9481) Speedup simulator for parameter change proposals.
|
||||
* (x/staking) [\#9423](https://github.com/cosmos/cosmos-sdk/pull/9423) Staking delegations now returns empty list instead of rpc error when no records found.
|
||||
* (x/auth) [\#9553](https://github.com/cosmos/cosmos-sdk/pull/9553) The `--multisig` flag now accepts both a name and address.
|
||||
* [\#8549](https://github.com/cosmos/cosmos-sdk/pull/8549) Make gRPC requests go through tendermint Query
|
||||
* [\#8093](https://github.com/cosmos/cosmos-sdk/pull/8093) Limit usage of context.background.
|
||||
* [\#8460](https://github.com/cosmos/cosmos-sdk/pull/8460) Ensure b.ReportAllocs() in all the benchmarks
|
||||
* [\#8461](https://github.com/cosmos/cosmos-sdk/pull/8461) Fix upgrade tx commands not showing up in CLI
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* (x/gov) [\#8813](https://github.com/cosmos/cosmos-sdk/pull/8813) fix `{appd} q gov deposits [proposal-id]`, `GET /gov/proposals/{proposal_id}/deposits` to include initial deposit.
|
||||
* (gRPC) [\#8945](https://github.com/cosmos/cosmos-sdk/pull/8945) gRPC reflection now works correctly.
|
||||
* (keyring) [#\8635](https://github.com/cosmos/cosmos-sdk/issues/8635) Remove hardcoded default passphrase value on `NewMnemonic`
|
||||
* (x/bank) [\#8434](https://github.com/cosmos/cosmos-sdk/pull/8434) Fix legacy REST API `GET /bank/total` and `GET /bank/total/{denom}` in swagger
|
||||
* (x/slashing) [\#8427](https://github.com/cosmos/cosmos-sdk/pull/8427) Fix query signing infos command
|
||||
* (x/bank/types) [\#9112](https://github.com/cosmos/cosmos-sdk/pull/9112) fix AddressFromBalancesStore address length overflow
|
||||
* (x/bank) [\#9229](https://github.com/cosmos/cosmos-sdk/pull/9229) Now zero coin balances cannot be added to balances & supply stores. If any denom becomes zero corresponding key gets deleted from store. State migration: [\#9664](https://github.com/cosmos/cosmos-sdk/pull/9664).
|
||||
* [\#9363](https://github.com/cosmos/cosmos-sdk/pull/9363) Check store key uniqueness in app wiring.
|
||||
* [\#9460](https://github.com/cosmos/cosmos-sdk/pull/9460) Fix lint error in `MigratePrefixAddress`.
|
||||
* [\#9480](https://github.com/cosmos/cosmos-sdk/pull/9480) Fix added keys when using `--dry-run`.
|
||||
* (types) [\#9511](https://github.com/cosmos/cosmos-sdk/pull/9511) Change `maxBitLen` of `sdk.Int` and `sdk.Dec` to handle max ERC20 value.
|
||||
* [\#9454](https://github.com/cosmos/cosmos-sdk/pull/9454) Fix testnet command with --node-dir-prefix accepts `-` and change `node-dir-prefix token` to `testtoken`.
|
||||
* (keyring) [\#9583](https://github.com/cosmos/cosmos-sdk/pull/9583) Fix correct population of legacy `Vote.Option` field for votes with 1 VoteOption of weight 1.
|
||||
* (x/distinction) [\#8918](https://github.com/cosmos/cosmos-sdk/pull/8918) Fix module's parameters validation.
|
||||
* (x/gov/types) [\#8586](https://github.com/cosmos/cosmos-sdk/pull/8586) Fix bug caused by NewProposal that unnecessarily creates a Proposal object that’s discarded on any error.
|
||||
* [\#8580](https://github.com/cosmos/cosmos-sdk/pull/8580) Use more cheaper method from the math/big package that provides a way to trivially check if a value is zero with .BitLen() == 0
|
||||
* [\#8567](https://github.com/cosmos/cosmos-sdk/pull/8567) Fix bug by introducing pagination to GetValidatorSetByHeight response
|
||||
* (x/bank) [\#8531](https://github.com/cosmos/cosmos-sdk/pull/8531) Fix bug caused by ignoring errors returned by Balance.GetAddress()
|
||||
* (server) [\#8399](https://github.com/cosmos/cosmos-sdk/pull/8399) fix gRPC-web flag default value
|
||||
* (x/bank) [\#9229](https://github.com/cosmos/cosmos-sdk/pull/9229) Now zero coin balances cannot be added to balances & supply stores. If any denom becomes zero corresponding key gets deleted from store.
|
||||
* [\#8282](https://github.com/cosmos/cosmos-sdk/pull/8282) fix zero time checks
|
||||
|
||||
|
||||
### Deprecated
|
||||
|
||||
* (grpc) [\#8926](https://github.com/cosmos/cosmos-sdk/pull/8926) The `tx` field in `SimulateRequest` has been deprecated, prefer to pass `tx_bytes` instead.
|
||||
* (sdk types) [\#9498](https://github.com/cosmos/cosmos-sdk/pull/9498) `clientContext.JSONCodec` will be removed in the next version. use `clientContext.Codec` instead.
|
||||
|
||||
## [v0.42.7](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.7) - 2021-07-09
|
||||
|
||||
### Improvements
|
||||
|
||||
* (baseapp) [\#9578](https://github.com/cosmos/cosmos-sdk/pull/9578) Return `Baseapp`'s `trace` value for logging error stack traces.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* (x/ibc) [\#9640](https://github.com/cosmos/cosmos-sdk/pull/9640) Fix IBC Transfer Ack Success event as it was initially emitting opposite value.
|
||||
* [\#9645](https://github.com/cosmos/cosmos-sdk/pull/9645) Use correct Prometheus format for metric labels.
|
||||
* [\#9299](https://github.com/cosmos/cosmos-sdk/pull/9299) Fix `[appd] keys parse cosmos1...` freezing.
|
||||
* (keyring) [\#9563](https://github.com/cosmos/cosmos-sdk/pull/9563) fix keyring kwallet backend when using with empty wallet.
|
||||
* (x/capability) [\#9392](https://github.com/cosmos/cosmos-sdk/pull/9392) initialization fix, which fixes the consensus error when using statesync.
|
||||
|
||||
## [v0.42.6](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.6) - 2021-06-18
|
||||
|
||||
### Improvements
|
||||
|
||||
* [\#9428](https://github.com/cosmos/cosmos-sdk/pull/9428) Optimize bank InitGenesis. Added `k.initBalances`.
|
||||
* [\#9429](https://github.com/cosmos/cosmos-sdk/pull/9429) Add `cosmos_sdk_version` to node_info
|
||||
* [\#9541](https://github.com/cosmos/cosmos-sdk/pull/9541) Bump tendermint dependency to v0.34.11.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* [\#9385](https://github.com/cosmos/cosmos-sdk/pull/9385) Fix IBC `query ibc client header` cli command. Support historical queries for query header/node-state commands.
|
||||
* [\#9401](https://github.com/cosmos/cosmos-sdk/pull/9401) Fixes incorrect export of IBC identifier sequences. Previously, the next identifier sequence for clients/connections/channels was not set during genesis export. This resulted in the next identifiers being generated on the new chain to reuse old identifiers (the sequences began again from 0).
|
||||
* [\#9408](https://github.com/cosmos/cosmos-sdk/pull/9408) Update simapp to use correct default broadcast mode.
|
||||
* [\#9513](https://github.com/cosmos/cosmos-sdk/pull/9513) Fixes testnet CLI command. Testnet now updates the supply in genesis. Previously, when using add-genesis-account and testnet together, inconsistent genesis files would be produced, as only add-genesis-account was updating the supply.
|
||||
* (x/gov) [\#8813](https://github.com/cosmos/cosmos-sdk/pull/8813) fix `GET /cosmos/gov/v1beta1/proposals/{proposal_id}/deposits` to include initial deposit
|
||||
|
||||
### Features
|
||||
|
||||
* [\#9383](https://github.com/cosmos/cosmos-sdk/pull/9383) New CLI command `query ibc-transfer escrow-address <port> <channel id>` to get the escrow address for a channel; can be used to then query balance of escrowed tokens
|
||||
* (baseapp, types) [#\9390](https://github.com/cosmos/cosmos-sdk/pull/9390) Add current block header hash to `Context`
|
||||
* (store) [\#9403](https://github.com/cosmos/cosmos-sdk/pull/9403) Add `RefundGas` function to `GasMeter` interface
|
||||
|
||||
## [v0.42.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.5) - 2021-05-18
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* [\#9514](https://github.com/cosmos/cosmos-sdk/issues/9514) Fix panic when retrieving the `BlockGasMeter` on `(Re)CheckTx` mode.
|
||||
* [\#9235](https://github.com/cosmos/cosmos-sdk/pull/9235) CreateMembershipProof/CreateNonMembershipProof now returns an error
|
||||
if input key is empty, or input data contains empty key.
|
||||
* [\#9108](https://github.com/cosmos/cosmos-sdk/pull/9108) Fixed the bug with querying multisig account, which is not showing threshold and public_keys.
|
||||
* [\#9345](https://github.com/cosmos/cosmos-sdk/pull/9345) Fix ARM support.
|
||||
* [\#9040](https://github.com/cosmos/cosmos-sdk/pull/9040) Fix ENV variables binding to CLI flags for client config.
|
||||
|
||||
### Features
|
||||
|
||||
* [\#8953](https://github.com/cosmos/cosmos-sdk/pull/8953) Add the `config` CLI subcommand back to the SDK, which saves client-side configuration in a `client.toml` file.
|
||||
|
||||
## [v0.42.4](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.4) - 2021-04-08
|
||||
|
||||
@ -170,7 +327,7 @@ This release fixes a security vulnerability identified in x/bank.
|
||||
### Bug Fixes
|
||||
|
||||
* (crypto) [\#8841](https://github.com/cosmos/cosmos-sdk/pull/8841) Fix legacy multisig amino marshaling, allowing migrations to work between v0.39 and v0.40+.
|
||||
* (cli) [\#8873](https://github.com/cosmos/cosmos-sdk/pull/8873) add --output-document to multisign-batch.
|
||||
* (cli tx) [\8873](https://github.com/cosmos/cosmos-sdk/pull/8873) add missing `--output-document` option to `app tx multisign-batch`.
|
||||
|
||||
## [v0.42.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.42.1) - 2021-03-10
|
||||
|
||||
@ -250,6 +407,7 @@ he Cosmos Hub) should not use this release or any release in the v0.41.x series.
|
||||
* (x/ibc) [\#8404](https://github.com/cosmos/cosmos-sdk/pull/8404) Reorder IBC `ChanOpenAck` and `ChanOpenConfirm` handler execution to perform core handler first, followed by application callbacks.
|
||||
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* (simapp) [\#8418](https://github.com/cosmos/cosmos-sdk/pull/8418) Add balance coin to supply when adding a new genesis account
|
||||
|
||||
128
CONTRIBUTING.md
128
CONTRIBUTING.md
@ -1,21 +1,23 @@
|
||||
# Contributing
|
||||
|
||||
- [Contributing](#contributing)
|
||||
- [Architecture Decision Records (ADR)](#architecture-decision-records-adr)
|
||||
- [Pull Requests](#pull-requests)
|
||||
- [Process for reviewing PRs](#process-for-reviewing-prs)
|
||||
- [Updating Documentation](#updating-documentation)
|
||||
- [Forking](#forking)
|
||||
- [Dependencies](#dependencies)
|
||||
- [Protobuf](#protobuf)
|
||||
- [Testing](#testing)
|
||||
- [Branching Model and Release](#branching-model-and-release)
|
||||
- [PR Targeting](#pr-targeting)
|
||||
- [Development Procedure](#development-procedure)
|
||||
- [Pull Merge Procedure](#pull-merge-procedure)
|
||||
- [Release Procedure](#release-procedure)
|
||||
- [Point Release Procedure](#point-release-procedure)
|
||||
- [Code Owner Membership](#code-owner-membership)
|
||||
- [Architecture Decision Records (ADR)](#architecture-decision-records-adr)
|
||||
- [Pull Requests](#pull-requests)
|
||||
- [Pull Request Templates](#pull-request-templates)
|
||||
- [Requesting Reviews](#requesting-reviews)
|
||||
- [Reviewing Pull Requests](#reviewing-pull-requests)
|
||||
- [Updating Documentation](#updating-documentation)
|
||||
- [Forking](#forking)
|
||||
- [Dependencies](#dependencies)
|
||||
- [Protobuf](#protobuf)
|
||||
- [Testing](#testing)
|
||||
- [Branching Model and Release](#branching-model-and-release)
|
||||
- [PR Targeting](#pr-targeting)
|
||||
- [Development Procedure](#development-procedure)
|
||||
- [Pull Merge Procedure](#pull-merge-procedure)
|
||||
- [Release Procedure](#release-procedure)
|
||||
- [Point Release Procedure](#point-release-procedure)
|
||||
- [Code Owner Membership](#code-owner-membership)
|
||||
|
||||
Thank you for considering making contributions to Cosmos-SDK and related
|
||||
repositories!
|
||||
@ -34,7 +36,7 @@ contributors, the general procedure for contributing has been established:
|
||||
3. If nobody has been assigned for the issue and you would like to work on it,
|
||||
make a comment on the issue to inform the community of your intentions
|
||||
to begin work
|
||||
4. Follow standard Github best practices: fork the repo, branch from the
|
||||
4. Follow standard GitHub best practices: fork the repo, branch from the
|
||||
HEAD of `master`, make some commits, and submit a PR to `master`
|
||||
- For core developers working within the cosmos-sdk repo, to ensure a clear
|
||||
ownership of branches, branches must be named with the convention
|
||||
@ -49,7 +51,7 @@ contributors, the general procedure for contributing has been established:
|
||||
Note that for very small or blatantly obvious problems (such as typos) it is
|
||||
not required to an open issue to submit a PR, but be aware that for more complex
|
||||
problems/features, if a PR is opened before an adequate design discussion has
|
||||
taken place in a github issue, that PR runs a high likelihood of being rejected.
|
||||
taken place in a GitHub issue, that PR runs a high likelihood of being rejected.
|
||||
|
||||
Other notes:
|
||||
|
||||
@ -57,7 +59,7 @@ Other notes:
|
||||
[good first issues](https://github.com/cosmos/cosmos-sdk/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
|
||||
- Please make sure to run `make format` before every commit - the easiest way
|
||||
to do this is have your editor run it for you upon saving a file. Additionally
|
||||
please ensure that your code is lint compliant by running `golangci-lint run`.
|
||||
please ensure that your code is lint compliant by running `make lint-fix`.
|
||||
A convenience git `pre-commit` hook that runs the formatters automatically
|
||||
before each commit is available in the `contrib/githooks/` directory.
|
||||
|
||||
@ -66,37 +68,59 @@ Other notes:
|
||||
When proposing an architecture decision for the SDK, please create an [ADR](./docs/architecture/README.md)
|
||||
so further discussions can be made. We are following this process so all involved parties are in
|
||||
agreement before any party begins coding the proposed implementation. If you would like to see some examples
|
||||
of how these are written refer to the current [ADRs](https://github.com/cosmos/cosmos-sdk/tree/master/docs/architecture)
|
||||
of how these are written refer to the current [ADRs](https://github.com/cosmos/cosmos-sdk/tree/master/docs/architecture).
|
||||
|
||||
## Pull Requests
|
||||
|
||||
To accommodate review process we suggest that PRs are categorically broken up.
|
||||
Ideally each PR addresses only a single issue. Additionally, as much as possible
|
||||
code refactoring and cleanup should be submitted as a separate PRs from bugfixes/feature-additions.
|
||||
PRs should be categorically broken up based on the type of changes being made (i.e. `fix`, `feat`,
|
||||
`refactor`, `docs`, etc.). The *type* must be included in the PR title as a prefix (e.g.
|
||||
`fix: <description>`). This ensures that all changes committed to the base branch follow the
|
||||
[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification.
|
||||
Additionally, each PR should only address a single issue.
|
||||
|
||||
### Process for reviewing PRs
|
||||
### Pull Request Templates
|
||||
|
||||
All PRs require two Reviews before merge (except docs changes, or variable name-changes which only require one). When reviewing PRs please use the following review explanations:
|
||||
There are currently three PR templates. The [default template](./.github/PULL_REQUEST_TEMPLATE.md) is for types `fix`, `feat`, and `refactor`. We also have a [docs template](./.github/PULL_REQUEST_TEMPLATE/docs.md) for documentation changes and an [other template](./.github/PULL_REQUEST_TEMPLATE/other.md) for changes that do not affect production code. When previewing a PR before it has been opened, you can change the template by adding one of the following parameters to the url:
|
||||
|
||||
- `LGTM` without an explicit approval means that the changes look good, but you haven't pulled down the code, run tests locally and thoroughly reviewed it.
|
||||
- `Approval` through the GH UI means that you understand the code, documentation/spec is updated in the right places, you have pulled down and tested the code locally. In addition:
|
||||
- You must also think through anything which ought to be included but is not
|
||||
- You must think through whether any added code could be partially combined (DRYed) with existing code
|
||||
- You must think through any potential security issues or incentive-compatibility flaws introduced by the changes
|
||||
- Naming must be consistent with conventions and the rest of the codebase
|
||||
- Code must live in a reasonable location, considering dependency structures (e.g. not importing testing modules in production code, or including example code modules in production code).
|
||||
- if you approve of the PR, you are responsible for fixing any of the issues mentioned here and more
|
||||
- `template=docs.md`
|
||||
- `template=other.md`
|
||||
|
||||
### Requesting Reviews
|
||||
|
||||
In order to accomodate the review process, the author of the PR must complete the author checklist
|
||||
to the best of their abilities before marking the PR as "Ready for Review". If you would like to
|
||||
receive early feedback on the PR, open the PR as a "Draft" and leave a comment in the PR indicating
|
||||
that you would like early feedback and tagging whoever you would like to receive feedback from.
|
||||
|
||||
### Reviewing Pull Requests
|
||||
|
||||
All PRs require at least two reviews before they can be merged (one review might be acceptable in
|
||||
the case of minor changes to [docs](./.github/PULL_REQUEST_TEMPLATE/docs.md) or [other](./.github/PULL_REQUEST_TEMPLATE/other.md) changes that do not affect production code). Each PR template has a
|
||||
reviewers checklist that must be completed before the PR can be merged. Each reviewer is responsible
|
||||
for all checked items unless they have indicated otherwise by leaving their handle next to specific
|
||||
items. In addition, please use the following review explanations:
|
||||
|
||||
- `LGTM` without an explicit approval means that the changes look good, but you haven't thoroughly reviewed the reviewer checklist items.
|
||||
- `Approval` means that you have completed some or all of the reviewer checklist items. If you only reviewed selected items, you have added your handle next to the items that you have reviewed. In addition, please follow these guidelines:
|
||||
- You must also think through anything which ought to be included but is not
|
||||
- You must think through whether any added code could be partially combined (DRYed) with existing code
|
||||
- You must think through any potential security issues or incentive-compatibility flaws introduced by the changes
|
||||
- Naming must be consistent with conventions and the rest of the codebase
|
||||
- Code must live in a reasonable location, considering dependency structures (e.g. not importing testing modules in production code, or including example code modules in production code).
|
||||
- If you approve of the PR, you are responsible for any issues mentioned here and any issues that should have been addressed after thoroughly reviewing the reviewer checklist items in the pull request template.
|
||||
- If you sat down with the PR submitter and did a pairing review please note that in the `Approval`, or your PR comments.
|
||||
- If you are only making "surface level" reviews, submit any notes as `Comments` without adding a review.
|
||||
|
||||
### Updating Documentation
|
||||
|
||||
If you open a PR on the Cosmos SDK, it is mandatory to update the relevant documentation in /docs.
|
||||
If you open a PR on the Cosmos SDK, it is mandatory to update the relevant documentation in `/docs`.
|
||||
|
||||
- If your change relates to the core SDK (baseapp, store, ...), please update the `docs/basics/`, `docs/core/` and/or `docs/building-modules/` folders.
|
||||
- If your changes relate to the core of the CLI or Light-client (not specifically to module's CLI/Rest), please modify the `docs/interfaces/` folder.
|
||||
- If your changes relate to the core of the CLI (not specifically to module's CLI/Rest), please modify the `docs/run-node/` folder.
|
||||
- If your changes relate to a module, please update the module's spec in `x/moduleName/docs/spec/`.
|
||||
|
||||
When writing documentation, follow the [Documentation Writing Guidelines](./docs/DOC_WRITING_GUIDELINES.md).
|
||||
|
||||
## Forking
|
||||
|
||||
Please note that Go requires code to live under absolute paths, which complicates forking.
|
||||
@ -107,7 +131,7 @@ Instead, we use `git remote` to add the fork as a new remote for the original re
|
||||
|
||||
For instance, to create a fork and work on a branch of it, I would:
|
||||
|
||||
- Create the fork on github, using the fork button.
|
||||
- Create the fork on GitHub, using the fork button.
|
||||
- Go to the original repo checked out locally (i.e. `$GOPATH/src/github.com/cosmos/cosmos-sdk`)
|
||||
- `git remote rename origin upstream`
|
||||
- `git remote add origin git@github.com:rigeyrigerige/cosmos-sdk.git`
|
||||
@ -166,7 +190,7 @@ For example, in vscode your `.vscode/settings.json` should look like:
|
||||
|
||||
## Testing
|
||||
|
||||
Tests can be ran by running `make test` at the top level of the SDK repository.
|
||||
Tests can be ran by running `make test` at the top level of the SDK repository.
|
||||
|
||||
We expect tests to use `require` or `assert` rather than `t.Skip` or `t.Fail`,
|
||||
unless there is a reason to do otherwise.
|
||||
@ -204,7 +228,7 @@ The SDK utilizes [semantic versioning](https://semver.org/).
|
||||
Ensure that you base and target your PR on the `master` branch.
|
||||
|
||||
All feature additions should be targeted against `master`. Bug fixes for an outstanding release candidate
|
||||
should be targeted against the release candidate branch.
|
||||
should be targeted against the release candidate branch.
|
||||
|
||||
### Development Procedure
|
||||
|
||||
@ -227,17 +251,17 @@ should be targeted against the release candidate branch.
|
||||
- Create the release candidate branch `rc/v*` (going forward known as **RC**)
|
||||
and ensure it's protected against pushing from anyone except the release
|
||||
manager/coordinator
|
||||
- **no PRs targeting this branch should be merged unless exceptional circumstances arise**
|
||||
- **no PRs targeting this branch should be merged unless exceptional circumstances arise**
|
||||
- On the `RC` branch, prepare a new version section in the `CHANGELOG.md`
|
||||
- All links must be link-ified: `$ python ./scripts/linkify_changelog.py CHANGELOG.md`
|
||||
- Copy the entries into a `RELEASE_CHANGELOG.md`, this is needed so the bot knows which entries to add to the release page on github.
|
||||
- All links must be link-ified: `$ python ./scripts/linkify_changelog.py CHANGELOG.md`
|
||||
- Copy the entries into a `RELEASE_CHANGELOG.md`, this is needed so the bot knows which entries to add to the release page on GitHub.
|
||||
- Kick off a large round of simulation testing (e.g. 400 seeds for 2k blocks)
|
||||
- If errors are found during the simulation testing, commit the fixes to `master`
|
||||
and create a new `RC` branch (making sure to increment the `rcN`)
|
||||
- After simulation has successfully completed, create the release branch
|
||||
(`release/vX.XX.X`) from the `RC` branch
|
||||
- Create a PR to `master` to incorporate the `CHANGELOG.md` updates
|
||||
- Tag the release (use `git tag -a`) and create a release in Github
|
||||
- Tag the release (use `git tag -a`) and create a release in GitHub
|
||||
- Delete the `RC` branches
|
||||
|
||||
### Point Release Procedure
|
||||
@ -292,7 +316,7 @@ to developers who show an aptitude towards developing with this code base.
|
||||
|
||||
Several different kinds of privileges may be granted however most common
|
||||
privileges to be granted are merge rights to either part of, or the entirety of the
|
||||
code base (through the github `CODEOWNERS` file). The on-boarding process for
|
||||
code base (through the GitHub `CODEOWNERS` file). The on-boarding process for
|
||||
new code owners is as follows: On a bi-monthly basis (or more frequently if
|
||||
agreeable) all the existing code owners will privately convene to discuss
|
||||
potential new candidates as well as the potential for existing code-owners to
|
||||
@ -312,22 +336,21 @@ have had acted maliciously or grossly negligent, code-owner privileges may be
|
||||
stripped with no prior warning or consent from the member in question.
|
||||
|
||||
Other potential removal criteria:
|
||||
* Missing 3 scheduled meetings results in ICF evaluating whether the member should be
|
||||
|
||||
* Missing 3 scheduled meetings results in ICF evaluating whether the member should be
|
||||
removed / replaced
|
||||
* Violation of Code of Conduct
|
||||
* Violation of Code of Conduct
|
||||
|
||||
Earning this privilege should be considered to be no small feat and is by no
|
||||
means guaranteed by any quantifiable metric. It is a symbol of great trust of
|
||||
the community of this project.
|
||||
|
||||
|
||||
## Concept & Release Approval Process
|
||||
|
||||
The process for how Cosmos SDK maintainers take features and ADRs from concept to release
|
||||
is broken up into three distinct stages: **Strategy Discovery**, **Concept Approval**, and
|
||||
is broken up into three distinct stages: **Strategy Discovery**, **Concept Approval**, and
|
||||
**Implementation & Release Approval**
|
||||
|
||||
|
||||
### Strategy Discovery
|
||||
|
||||
* Develop long term priorities, strategy and roadmap for the SDK
|
||||
@ -352,8 +375,9 @@ If an individual Pull Request for an ADR needs more time than 2 weeks to reach r
|
||||
in current state (`Draft` or `Proposed`), with its contents updated to summarize
|
||||
the current state of its discussion.
|
||||
|
||||
If an ADR is taking longer than 4 weeks to reach a final conclusion, the **Concept Approval Committee**
|
||||
If an ADR is taking longer than 4 weeks to reach a final conclusion, the **Concept Approval Committee**
|
||||
should convene to rectify the situation by either:
|
||||
|
||||
- unanimously setting a new time bound period for this ADR
|
||||
- making changes to the Concept Approval Process (as outlined here)
|
||||
- making changes to the members of the Concept Approval Committee
|
||||
@ -371,13 +395,13 @@ of the **Concept Approval Committee**.
|
||||
|
||||
Members must:
|
||||
|
||||
* Participate in all or almost all ADR discussions, both on Github as well as in bi-weekly Architecture Review
|
||||
* Participate in all or almost all ADR discussions, both on GitHub as well as in bi-weekly Architecture Review
|
||||
meetings
|
||||
* Be active contributors to the SDK, and furthermore should be continuously making substantial contributions
|
||||
to the project's codebase, review process, documentation and ADRs
|
||||
* Have stake in the Cosmos SDK project, represented by:
|
||||
* Being a client / user of the Comsos SDK
|
||||
* "[giving back](https://www.debian.org/social_contract)" to the software
|
||||
* Being a client / user of the Comsos SDK
|
||||
* "[giving back](https://www.debian.org/social_contract)" to the software
|
||||
* Delegate representation in case of vacation or absence
|
||||
|
||||
Code owners need to maintain participation in the process, ideally as members of **Concept Approval Committee**
|
||||
@ -396,7 +420,7 @@ well as for PRs made as part of a release process:
|
||||
* Code reviewers should ensure the PR does exactly what the ADR said it should
|
||||
* Code reviewers should have more senior engineering capability
|
||||
* 1/2 approval is required from the **primary repo maintainers** in `CODEOWNERS`
|
||||
|
||||
|
||||
*Note: For any major or minor release series denoted as a "Stable Release" (e.g. v0.39 "Launchpad"), a separate release
|
||||
committee is often established. Stable Releases, and their corresponding release committees are documented
|
||||
separately in [STABLE_RELEASES.md](./STABLE_RELEASES.md)*
|
||||
|
||||
35
Makefile
35
Makefile
@ -144,15 +144,16 @@ cosmovisor:
|
||||
|
||||
.PHONY: build build-linux build-simd-all build-simd-linux cosmovisor
|
||||
|
||||
mockgen_cmd=go run github.com/golang/mock/mockgen
|
||||
|
||||
mocks: $(MOCKS_DIR)
|
||||
mockgen -source=client/account_retriever.go -package mocks -destination tests/mocks/account_retriever.go
|
||||
mockgen -package mocks -destination tests/mocks/tendermint_tm_db_DB.go github.com/tendermint/tm-db DB
|
||||
mockgen -source=types/module/module.go -package mocks -destination tests/mocks/types_module_module.go
|
||||
mockgen -source=types/invariant.go -package mocks -destination tests/mocks/types_invariant.go
|
||||
mockgen -source=types/router.go -package mocks -destination tests/mocks/types_router.go
|
||||
mockgen -source=types/handler.go -package mocks -destination tests/mocks/types_handler.go
|
||||
mockgen -package mocks -destination tests/mocks/grpc_server.go github.com/gogo/protobuf/grpc Server
|
||||
mockgen -package mocks -destination tests/mocks/tendermint_tendermint_libs_log_DB.go github.com/tendermint/tendermint/libs/log Logger
|
||||
$(mockgen_cmd) -source=client/account_retriever.go -package mocks -destination tests/mocks/account_retriever.go
|
||||
$(mockgen_cmd) -package mocks -destination tests/mocks/tendermint_tm_db_DB.go github.com/tendermint/tm-db DB
|
||||
$(mockgen_cmd) -source=types/module/module.go -package mocks -destination tests/mocks/types_module_module.go
|
||||
$(mockgen_cmd) -source=types/invariant.go -package mocks -destination tests/mocks/types_invariant.go
|
||||
$(mockgen_cmd) -source=types/router.go -package mocks -destination tests/mocks/types_router.go
|
||||
$(mockgen_cmd) -package mocks -destination tests/mocks/grpc_server.go github.com/gogo/protobuf/grpc Server
|
||||
$(mockgen_cmd) -package mocks -destination tests/mocks/tendermint_tendermint_libs_log_DB.go github.com/tendermint/tendermint/libs/log Logger
|
||||
.PHONY: mocks
|
||||
|
||||
$(MOCKS_DIR):
|
||||
@ -326,11 +327,18 @@ benchmark:
|
||||
### Linting ###
|
||||
###############################################################################
|
||||
|
||||
containerMarkdownLintImage=tmknom/markdownlint
|
||||
containerMarkdownLint=cosmos-sdk-markdownlint
|
||||
containerMarkdownLintFix=cosmos-sdk-markdownlint-fix
|
||||
|
||||
lint:
|
||||
golangci-lint run --out-format=tab
|
||||
@if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerMarkdownLint}$$"; then docker start -a $(containerMarkdownLint); else docker run --name $(containerMarkdownLint) -i -v "$(CURDIR):/work" $(containerMarkdownLintImage); fi
|
||||
|
||||
lint-fix:
|
||||
golangci-lint run --fix --out-format=tab --issues-exit-code=0
|
||||
@if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerMarkdownLintFix}$$"; then docker start -a $(containerMarkdownLintFix); else docker run --name $(containerMarkdownLintFix) -i -v "$(CURDIR):/work" $(containerMarkdownLintImage) . --fix; fi
|
||||
|
||||
.PHONY: lint lint-fix
|
||||
|
||||
format:
|
||||
@ -394,8 +402,9 @@ proto-swagger-gen:
|
||||
|
||||
proto-format:
|
||||
@echo "Formatting Protobuf files"
|
||||
@if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoFmt}$$"; then docker start -a $(containerProtoFmt); else docker run --name $(containerProtoFmt) -v $(CURDIR):/workspace --workdir /workspace $(containerProtoImage) \
|
||||
find ./ -not -path "./third_party/*" -name *.proto -exec clang-format -i {}; fi
|
||||
@if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoFmt}$$"; then docker start -a $(containerProtoFmt); else docker run --name $(containerProtoFmt) -v $(CURDIR):/workspace --workdir /workspace tendermintdev/docker-build-proto \
|
||||
find ./ -not -path "./third_party/*" -name "*.proto" -exec clang-format -i {} \; ; fi
|
||||
|
||||
|
||||
proto-lint:
|
||||
@$(DOCKER_BUF) lint --error-format=json
|
||||
@ -466,16 +475,16 @@ proto-update-deps:
|
||||
### Localnet ###
|
||||
###############################################################################
|
||||
|
||||
# Run a 4-node testnet locally
|
||||
# Run a 4-node testnet locally via docker compose
|
||||
localnet-start: build-linux localnet-stop
|
||||
$(if $(shell $(DOCKER) inspect -f '{{ .Id }}' cosmossdk/simd-env 2>/dev/null),$(info found image cosmossdk/simd-env),$(MAKE) -C contrib/images simd-env)
|
||||
if ! [ -f build/node0/simd/config/genesis.json ]; then $(DOCKER) run --rm \
|
||||
if ! test -f build/node0/simd/config/genesis.json; then $(DOCKER) run --rm \
|
||||
--user $(shell id -u):$(shell id -g) \
|
||||
-v $(BUILDDIR):/simd:Z \
|
||||
-v /etc/group:/etc/group:ro \
|
||||
-v /etc/passwd:/etc/passwd:ro \
|
||||
-v /etc/shadow:/etc/shadow:ro \
|
||||
cosmossdk/simd-env testnet --v 4 -o . --starting-ip-address 192.168.10.2 --keyring-backend=test ; fi
|
||||
cosmossdk/simd-env testnet init-files --v 4 -o . --starting-ip-address 192.168.10.2 --keyring-backend=test ; fi
|
||||
docker-compose up -d
|
||||
|
||||
localnet-stop:
|
||||
|
||||
@ -40,9 +40,6 @@ parent:
|
||||
<img alt="Lint Satus" src="https://github.com/cosmos/cosmos-sdk/workflows/Lint/badge.svg" />
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
The Cosmos-SDK is a framework for building blockchain applications in Golang.
|
||||
It is being used to build [`Gaia`](https://github.com/cosmos/gaia), the first implementation of the Cosmos Hub.
|
||||
|
||||
@ -65,7 +62,7 @@ The Cosmos Hub application, `gaia`, has moved to its [own repository](https://gi
|
||||
|
||||
## Interblockchain Communication (IBC)
|
||||
|
||||
The IBC module for the SDK has moved to its [own repository](https://github.com/cosmos/ibc-go). Go there to build and integrate with the IBC module.
|
||||
The IBC module for the SDK has moved to its [own repository](https://github.com/cosmos/ibc-go). Go there to build and integrate with the IBC module.
|
||||
|
||||
## Starport
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ the code.
|
||||
|
||||
- HD key derivation, local and Ledger, and all key-management functionality
|
||||
- Side-channel attack vectors with our implementations
|
||||
- e.g. key exfiltration based on time or memory-access patterns when decrypting privkey
|
||||
- e.g. key exfiltration based on time or memory-access patterns when decrypting privkey
|
||||
|
||||
## Disclosure Process
|
||||
|
||||
@ -73,6 +73,7 @@ This process can take some time. Every effort is made to handle the bug in as ti
|
||||
### Disclosure Communications
|
||||
|
||||
Communications to partners usually include the following details:
|
||||
|
||||
1. Affected version or versions
|
||||
1. New release version
|
||||
1. Impact on user funds
|
||||
@ -81,13 +82,14 @@ Communications to partners usually include the following details:
|
||||
1. Potential required actions if an adverse condition arises during the security release process
|
||||
|
||||
An example notice looks like:
|
||||
|
||||
```
|
||||
Dear Cosmos SDK partners,
|
||||
|
||||
A critical security vulnerability has been identified in Cosmos SDK vX.X.X.
|
||||
A critical security vulnerability has been identified in Cosmos SDK vX.X.X.
|
||||
User funds are NOT at risk; however, the vulnerability can result in a chain halt.
|
||||
|
||||
This notice is to inform you that on [[**March 1 at 1pm EST/6pm UTC**]], we will be releasing Cosmos SDK vX.X.Y to fix the security issue.
|
||||
This notice is to inform you that on [[**March 1 at 1pm EST/6pm UTC**]], we will be releasing Cosmos SDK vX.X.Y to fix the security issue.
|
||||
We ask all validators to upgrade their nodes ASAP.
|
||||
|
||||
If the chain halts, validators with sufficient voting power must upgrade and come online for the chain to resume.
|
||||
|
||||
@ -4,19 +4,16 @@
|
||||
|
||||
Only the following release series are currently supported and receive bug fixes:
|
||||
|
||||
The `0.37.x` release series will continue receiving bug fixes until the Cosmos Hub
|
||||
migrates to a newer release of the Cosmos-SDK.
|
||||
* **0.39 «Launchpad»** will be supported until 6 months after **0.42.0** is published. A fairly strict **bugfix-only** rule applies to pull requests that are requested to be included into a stable point-release.
|
||||
* **0.42 «Stargate»** is the latest stable release.
|
||||
|
||||
* **0.37** will continue receiving bug fixes until the Cosmos Hub migrates to a newer release series of the Cosmos-SDK.
|
||||
* **0.39 «Launchpad»** will be supported until 6 months after **0.40.0** is published. A fairly strict **bugfix-only** rule applies to pull requests that are requested to be included into a stable point-release.
|
||||
|
||||
The **0.39 «Launchpad»** release series is maintained in compliance with the **Stable Release Policy** as described in this document.
|
||||
The **0.42 «Stargate»** release series is maintained in compliance with the **Stable Release Policy** as described in this document.
|
||||
|
||||
## Stable Release Policy
|
||||
|
||||
This policy presently applies *only* to the following release series:
|
||||
|
||||
* **0.39 «Launchpad»**
|
||||
* **0.42 «Stargate»**
|
||||
|
||||
### Point Releases
|
||||
|
||||
@ -26,7 +23,7 @@ and must follow the [Point Release Procedure](CONTRIBUTING.md).
|
||||
### Rationale
|
||||
|
||||
Unlike in-development `master` branch snapshots, **Cosmos-SDK** releases are subject to much wider adoption,
|
||||
and by a significantly different demographic of users. During development, changes in the `master` branch
|
||||
and by a significantly different demographic of users. During development, changes in the `master` branch
|
||||
affect SDK users, application developers, early adopters, and other advanced users that elect to use
|
||||
unstable experimental software at their own risk.
|
||||
|
||||
@ -48,16 +45,20 @@ priority is to minimise the risk caused by changes that are not strictly require
|
||||
be correlated with minimising the size of such changes. As such, the same bug may need to be fixed in different
|
||||
ways in stable releases and `master` branch.
|
||||
|
||||
### Migrations
|
||||
|
||||
To smoothen the update to the latest stable release, the SDK includes a set of CLI commands for managing migrations between SDK versions, under the `migrate` subcommand. Only migration scripts between stable releases are included. For the current release, **0.39 «Launchpad»** and later migrations are supported.
|
||||
|
||||
### What qualifies as a Stable Release Update (SRU)
|
||||
|
||||
* **High-impact bugs**
|
||||
* Bugs that may directly cause a security vulnerability.
|
||||
* *Severe regressions* from a Cosmos-SDK's previous release. This includes all sort of issues
|
||||
* Bugs that may directly cause a security vulnerability.
|
||||
* *Severe regressions* from a Cosmos-SDK's previous release. This includes all sort of issues
|
||||
that may cause the core packages or the `x/` modules unusable.
|
||||
* Bugs that may cause **loss of user's data**.
|
||||
* Bugs that may cause **loss of user's data**.
|
||||
* Other safe cases:
|
||||
* Bugs which don't fit in the aforementioned categories for which an obvious safe patch is known.
|
||||
* Relatively small yet strictly non-breaking changes that introduce forward-compatible client
|
||||
* Bugs which don't fit in the aforementioned categories for which an obvious safe patch is known.
|
||||
* Relatively small yet strictly non-breaking changes that introduce forward-compatible client
|
||||
features to smoothen the migration to successive releases.
|
||||
|
||||
### What does not qualify as SRU
|
||||
@ -70,28 +71,30 @@ ways in stable releases and `master` branch.
|
||||
|
||||
Pull requests that fix bugs that fall in the following categories do not require a **Stable Release Exception** to be granted to be included in a stable point-release:
|
||||
|
||||
* **Severe regressions**.
|
||||
* Bugs that may cause **client applications** to be **largely unusable**.
|
||||
* Bugs that may cause **state corruption or data loss**.
|
||||
* Bugs that may directly or indirectly cause a **security vulnerability**.
|
||||
* **Severe regressions**.
|
||||
* Bugs that may cause **client applications** to be **largely unusable**.
|
||||
* Bugs that may cause **state corruption or data loss**.
|
||||
* Bugs that may directly or indirectly cause a **security vulnerability**.
|
||||
|
||||
## What pull requests will NOT be automatically included in stable point-releases
|
||||
|
||||
As rule of thumb, the following changes will **NOT** be automatically accepted into stable point-releases:
|
||||
|
||||
* **State machine changes**.
|
||||
* **Client application's code-breaking changes**, i.e. changes that prevent client applications to *build without modifications* to the client application's source code.
|
||||
|
||||
* **State machine changes**.
|
||||
* **Client application's code-breaking changes**, i.e. changes that prevent client applications to *build without modifications* to the client application's source code.
|
||||
|
||||
In some circumstances, PRs that don't meet the aforementioned criteria might be raised and asked to be granted a *Stable Release Exception*.
|
||||
|
||||
|
||||
## Stable Release Exception - Procedure
|
||||
|
||||
1. Check that the bug is either fixed or not reproducible in `master`. It is, in general, not appropriate to release bug fixes for stable releases without first testing them in `master`. Please apply the label [0.39 «Launchpad»](https://github.com/cosmos/cosmos-sdk/labels/0.39%20LTS%20%28Launchpad%29) to the issue.
|
||||
1. Check that the bug is either fixed or not reproducible in `master`. It is, in general, not appropriate to release bug fixes for stable releases without first testing them in `master`. Please apply the label [0.42 «Stargate»](https://github.com/cosmos/cosmos-sdk/labels/0.42%20LTS%20%28Stargate%29) to the issue.
|
||||
2. Add a comment to the issue and ensure it contains the following information (see the bug template below):
|
||||
* **[Impact]** An explanation of the bug on users and justification for backporting the fix to the stable release.
|
||||
* A **[Test Case]** section containing detailed instructions on how to reproduce the bug.
|
||||
* A **[Regression Potential]** section with a clear assessment on how regressions are most likely to manifest as a result of the pull request that aims to fix the bug in the target stable release.
|
||||
3. **Stable Release Managers** will review and discuss the PR. Once *consensus* surrounding the rationale has been reached and the technical review has successfully concluded, the pull request will be merged in the respective point-release target branch (e.g. `release/launchpad/0.39.X` being `X` the Launchpad's upcoming point-release) and the PR included in the point-release's respective milestone (e.g. `0.39.5`).
|
||||
|
||||
* **[Impact]** An explanation of the bug on users and justification for backporting the fix to the stable release.
|
||||
* A **[Test Case]** section containing detailed instructions on how to reproduce the bug.
|
||||
* A **[Regression Potential]** section with a clear assessment on how regressions are most likely to manifest as a result of the pull request that aims to fix the bug in the target stable release.
|
||||
|
||||
3. **Stable Release Managers** will review and discuss the PR. Once *consensus* surrounding the rationale has been reached and the technical review has successfully concluded, the pull request will be merged in the respective point-release target branch (e.g. `release/v0.42.x`) and the PR included in the point-release's respective milestone (e.g. `0.42.5`).
|
||||
|
||||
### Stable Release Exception - Bug template
|
||||
|
||||
@ -102,7 +105,7 @@ Brief xplanation of the effects of the bug on users and a justification for back
|
||||
|
||||
#### Test Case
|
||||
|
||||
Detailed instructions on how to reproduce the bug on Launchpad's most recently published point-release.
|
||||
Detailed instructions on how to reproduce the bug on Stargate's most recently published point-release.
|
||||
|
||||
#### Regression Potential
|
||||
|
||||
@ -118,14 +121,13 @@ according to the [stable release policy](#stable-release-policy) and [release pr
|
||||
Decisions are made by consensus.
|
||||
|
||||
Their responsibilites include:
|
||||
* Driving the Stable Release Exception process.
|
||||
* Approving/rejecting proposed changes to a stable release series.
|
||||
* Executing the release process of stable point-releases in compliance with the [Point Release Procedure](CONTRIBUTING.md).
|
||||
|
||||
The Stable Release Managers are appointed by the Interchain Foundation.
|
||||
* Driving the Stable Release Exception process.
|
||||
* Approving/rejecting proposed changes to a stable release series.
|
||||
* Executing the release process of stable point-releases in compliance with the [Point Release Procedure](CONTRIBUTING.md).
|
||||
|
||||
*Stable Release Managers* for the **0.39 «Launchpad»** release series follow:
|
||||
The Stable Release Managers are appointed by the Interchain Foundation. Currently residing Stable Release Managers:
|
||||
|
||||
* @alessio - Alessio Treglia
|
||||
* @clevinson - Cory Levinson-
|
||||
* @ethanfrey - Ethan Frey
|
||||
* @clevinson - Cory Levinson
|
||||
* @amaurym - Amaruy Martiny
|
||||
* @robert-zaremba - Robert Zaremba
|
||||
|
||||
@ -175,7 +175,19 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg
|
||||
gasMeter = sdk.NewInfiniteGasMeter()
|
||||
}
|
||||
|
||||
app.deliverState.ctx = app.deliverState.ctx.WithBlockGasMeter(gasMeter)
|
||||
// NOTE: header hash is not set in NewContext, so we manually set it here
|
||||
|
||||
app.deliverState.ctx = app.deliverState.ctx.
|
||||
WithBlockGasMeter(gasMeter).
|
||||
WithHeaderHash(req.Hash)
|
||||
|
||||
// we also set block gas meter to checkState in case the application needs to
|
||||
// verify gas consumption during (Re)CheckTx
|
||||
if app.checkState != nil {
|
||||
app.checkState.ctx = app.checkState.ctx.
|
||||
WithBlockGasMeter(gasMeter).
|
||||
WithHeaderHash(req.Hash)
|
||||
}
|
||||
|
||||
if app.beginBlocker != nil {
|
||||
res = app.beginBlocker(app.deliverState.ctx, req)
|
||||
@ -393,7 +405,7 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
||||
// ref: https://github.com/cosmos/cosmos-sdk/pull/8039
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
res = sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrPanic, "%v", r))
|
||||
res = sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrPanic, "%v", r), app.trace)
|
||||
}
|
||||
}()
|
||||
|
||||
@ -410,7 +422,7 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
||||
|
||||
path := splitPath(req.Path)
|
||||
if len(path) == 0 {
|
||||
sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "no query path provided"))
|
||||
sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "no query path provided"), app.trace)
|
||||
}
|
||||
|
||||
switch path[0] {
|
||||
@ -428,7 +440,7 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
||||
return handleQueryCustom(app, path, req)
|
||||
}
|
||||
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown query path"))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown query path"), app.trace)
|
||||
}
|
||||
|
||||
// ListSnapshots implements the ABCI interface. It delegates to app.snapshotManager if set.
|
||||
@ -558,12 +570,12 @@ func (app *BaseApp) ApplySnapshotChunk(req abci.RequestApplySnapshotChunk) abci.
|
||||
func (app *BaseApp) handleQueryGRPC(handler GRPCQueryHandler, req abci.RequestQuery) abci.ResponseQuery {
|
||||
ctx, err := app.createQueryContext(req.Height, req.Prove)
|
||||
if err != nil {
|
||||
return sdkerrors.QueryResult(err)
|
||||
return sdkerrors.QueryResult(err, app.trace)
|
||||
}
|
||||
|
||||
res, err := handler(ctx, req)
|
||||
if err != nil {
|
||||
res = sdkerrors.QueryResult(gRPCErrorToSDKError(err))
|
||||
res = sdkerrors.QueryResult(gRPCErrorToSDKError(err), app.trace)
|
||||
res.Height = req.Height
|
||||
return res
|
||||
}
|
||||
@ -734,7 +746,7 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.Res
|
||||
|
||||
gInfo, res, err := app.Simulate(txBytes)
|
||||
if err != nil {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to simulate tx"))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to simulate tx"), app.trace)
|
||||
}
|
||||
|
||||
simRes := &sdk.SimulationResponse{
|
||||
@ -744,7 +756,7 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.Res
|
||||
|
||||
bz, err := codec.ProtoMarshalJSON(simRes, app.interfaceRegistry)
|
||||
if err != nil {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to JSON encode simulation response"))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to JSON encode simulation response"), app.trace)
|
||||
}
|
||||
|
||||
return abci.ResponseQuery{
|
||||
@ -761,7 +773,7 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.Res
|
||||
}
|
||||
|
||||
default:
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query: %s", path))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query: %s", path), app.trace)
|
||||
}
|
||||
}
|
||||
|
||||
@ -769,15 +781,14 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.Res
|
||||
sdkerrors.Wrap(
|
||||
sdkerrors.ErrUnknownRequest,
|
||||
"expected second parameter to be either 'simulate' or 'version', neither was present",
|
||||
),
|
||||
)
|
||||
), app.trace)
|
||||
}
|
||||
|
||||
func handleQueryStore(app *BaseApp, path []string, req abci.RequestQuery) abci.ResponseQuery {
|
||||
// "/store" prefix for store queries
|
||||
queryable, ok := app.cms.(sdk.Queryable)
|
||||
if !ok {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "multistore doesn't support queries"))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "multistore doesn't support queries"), app.trace)
|
||||
}
|
||||
|
||||
req.Path = "/" + strings.Join(path[1:], "/")
|
||||
@ -787,8 +798,7 @@ func handleQueryStore(app *BaseApp, path []string, req abci.RequestQuery) abci.R
|
||||
sdkerrors.Wrap(
|
||||
sdkerrors.ErrInvalidRequest,
|
||||
"cannot query with proof when height <= 1; please provide a valid height",
|
||||
),
|
||||
)
|
||||
), app.trace)
|
||||
}
|
||||
|
||||
resp := queryable.Query(req)
|
||||
@ -803,8 +813,7 @@ func handleQueryP2P(app *BaseApp, path []string) abci.ResponseQuery {
|
||||
return sdkerrors.QueryResult(
|
||||
sdkerrors.Wrap(
|
||||
sdkerrors.ErrUnknownRequest, "path should be p2p filter <addr|id> <parameter>",
|
||||
),
|
||||
)
|
||||
), app.trace)
|
||||
}
|
||||
|
||||
var resp abci.ResponseQuery
|
||||
@ -821,7 +830,7 @@ func handleQueryP2P(app *BaseApp, path []string) abci.ResponseQuery {
|
||||
}
|
||||
|
||||
default:
|
||||
resp = sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "expected second parameter to be 'filter'"))
|
||||
resp = sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "expected second parameter to be 'filter'"), app.trace)
|
||||
}
|
||||
|
||||
return resp
|
||||
@ -834,17 +843,17 @@ func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) abci.
|
||||
// The QueryRouter routes using path[1]. For example, in the path
|
||||
// "custom/gov/proposal", QueryRouter routes using "gov".
|
||||
if len(path) < 2 || path[1] == "" {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "no route for custom query specified"))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "no route for custom query specified"), app.trace)
|
||||
}
|
||||
|
||||
querier := app.queryRouter.Route(path[1])
|
||||
if querier == nil {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "no custom querier found for route %s", path[1]))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "no custom querier found for route %s", path[1]), app.trace)
|
||||
}
|
||||
|
||||
ctx, err := app.createQueryContext(req.Height, req.Prove)
|
||||
if err != nil {
|
||||
return sdkerrors.QueryResult(err)
|
||||
return sdkerrors.QueryResult(err, app.trace)
|
||||
}
|
||||
|
||||
// Passes the rest of the path as an argument to the querier.
|
||||
@ -853,7 +862,7 @@ func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) abci.
|
||||
// []string{"proposal", "test"} as the path.
|
||||
resBytes, err := querier(ctx, path[2:], req)
|
||||
if err != nil {
|
||||
res := sdkerrors.QueryResult(err)
|
||||
res := sdkerrors.QueryResult(err, app.trace)
|
||||
res.Height = req.Height
|
||||
return res
|
||||
}
|
||||
|
||||
@ -19,7 +19,8 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/store/rootmulti"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
|
||||
sdktx "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -190,6 +191,11 @@ func (app *BaseApp) Logger() log.Logger {
|
||||
return app.logger
|
||||
}
|
||||
|
||||
// Trace returns the boolean value for logging error stack traces.
|
||||
func (app *BaseApp) Trace() bool {
|
||||
return app.trace
|
||||
}
|
||||
|
||||
// MsgServiceRouter returns the MsgServiceRouter of a BaseApp.
|
||||
func (app *BaseApp) MsgServiceRouter() *MsgServiceRouter { return app.msgServiceRouter }
|
||||
|
||||
@ -444,6 +450,8 @@ func (app *BaseApp) StoreConsensusParams(ctx sdk.Context, cp *abci.ConsensusPara
|
||||
app.paramStore.Set(ctx, ParamStoreKeyBlockParams, cp.Block)
|
||||
app.paramStore.Set(ctx, ParamStoreKeyEvidenceParams, cp.Evidence)
|
||||
app.paramStore.Set(ctx, ParamStoreKeyValidatorParams, cp.Validator)
|
||||
// We're explicitly not storing the Tendermint app_version in the param store. It's
|
||||
// stored instead in the x/upgrade store, with its own bump logic.
|
||||
}
|
||||
|
||||
// getMaximumBlockGas gets the maximum gas from the consensus params. It panics
|
||||
@ -503,7 +511,7 @@ func validateBasicTxMsgs(msgs []sdk.Msg) error {
|
||||
}
|
||||
|
||||
for _, msg := range msgs {
|
||||
err := msg.ValidateBasic()
|
||||
err := sdktx.ValidateMsg(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -717,10 +717,10 @@ func (msg msgCounter) String() string { return "TODO" }
|
||||
func (msg msgCounter) ProtoMessage() {}
|
||||
|
||||
// Implements Msg
|
||||
func (msg msgCounter) Route() string { return routeMsgCounter }
|
||||
func (msg msgCounter) Type() string { return "counter1" }
|
||||
func (msg msgCounter) GetSignBytes() []byte { return nil }
|
||||
func (msg msgCounter) GetSigners() []sdk.AccAddress { return nil }
|
||||
func (msg msgCounter) Route() string { return routeMsgCounter }
|
||||
func (msg msgCounter) Type() string { return "counter1" }
|
||||
func (msg msgCounter) GetSignBytes() []byte { return nil }
|
||||
func (msg msgCounter) GetSigners() []string { return nil }
|
||||
func (msg msgCounter) ValidateBasic() error {
|
||||
if msg.Counter >= 0 {
|
||||
return nil
|
||||
@ -762,10 +762,10 @@ func (msg msgCounter2) String() string { return "TODO" }
|
||||
func (msg msgCounter2) ProtoMessage() {}
|
||||
|
||||
// Implements Msg
|
||||
func (msg msgCounter2) Route() string { return routeMsgCounter2 }
|
||||
func (msg msgCounter2) Type() string { return "counter2" }
|
||||
func (msg msgCounter2) GetSignBytes() []byte { return nil }
|
||||
func (msg msgCounter2) GetSigners() []sdk.AccAddress { return nil }
|
||||
func (msg msgCounter2) Route() string { return routeMsgCounter2 }
|
||||
func (msg msgCounter2) Type() string { return "counter2" }
|
||||
func (msg msgCounter2) GetSignBytes() []byte { return nil }
|
||||
func (msg msgCounter2) GetSigners() []string { return nil }
|
||||
func (msg msgCounter2) ValidateBasic() error {
|
||||
if msg.Counter >= 0 {
|
||||
return nil
|
||||
@ -779,13 +779,13 @@ type msgKeyValue struct {
|
||||
Value []byte
|
||||
}
|
||||
|
||||
func (msg msgKeyValue) Reset() {}
|
||||
func (msg msgKeyValue) String() string { return "TODO" }
|
||||
func (msg msgKeyValue) ProtoMessage() {}
|
||||
func (msg msgKeyValue) Route() string { return routeMsgKeyValue }
|
||||
func (msg msgKeyValue) Type() string { return "keyValue" }
|
||||
func (msg msgKeyValue) GetSignBytes() []byte { return nil }
|
||||
func (msg msgKeyValue) GetSigners() []sdk.AccAddress { return nil }
|
||||
func (msg msgKeyValue) Reset() {}
|
||||
func (msg msgKeyValue) String() string { return "TODO" }
|
||||
func (msg msgKeyValue) ProtoMessage() {}
|
||||
func (msg msgKeyValue) Route() string { return routeMsgKeyValue }
|
||||
func (msg msgKeyValue) Type() string { return "keyValue" }
|
||||
func (msg msgKeyValue) GetSignBytes() []byte { return nil }
|
||||
func (msg msgKeyValue) GetSigners() []string { return nil }
|
||||
func (msg msgKeyValue) ValidateBasic() error {
|
||||
if msg.Key == nil {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "key cannot be nil")
|
||||
@ -950,7 +950,11 @@ func TestCheckTx(t *testing.T) {
|
||||
|
||||
// If a block is committed, CheckTx state should be reset.
|
||||
header := tmproto.Header{Height: 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header, Hash: []byte("hash")})
|
||||
|
||||
require.NotNil(t, app.checkState.ctx.BlockGasMeter(), "block gas meter should have been set to checkState")
|
||||
require.NotEmpty(t, app.checkState.ctx.HeaderHash())
|
||||
|
||||
app.EndBlock(abci.RequestEndBlock{})
|
||||
app.Commit()
|
||||
|
||||
|
||||
@ -36,9 +36,9 @@ func (msr *MsgServiceRouter) Handler(msg sdk.Msg) MsgServiceHandler {
|
||||
return msr.routes[sdk.MsgTypeURL(msg)]
|
||||
}
|
||||
|
||||
// HandlerbyTypeURL returns the MsgServiceHandler for a given query route path or nil
|
||||
// HandlerByTypeURL returns the MsgServiceHandler for a given query route path or nil
|
||||
// if not found.
|
||||
func (msr *MsgServiceRouter) HandlerbyTypeURL(typeURL string) MsgServiceHandler {
|
||||
func (msr *MsgServiceRouter) HandlerByTypeURL(typeURL string) MsgServiceHandler {
|
||||
return msr.routes[typeURL]
|
||||
}
|
||||
|
||||
|
||||
2
buf.yaml
2
buf.yaml
@ -26,8 +26,6 @@ lint:
|
||||
breaking:
|
||||
use:
|
||||
- FILE
|
||||
except:
|
||||
- FIELD_NO_DELETE
|
||||
ignore:
|
||||
- tendermint
|
||||
- gogoproto
|
||||
|
||||
@ -5,8 +5,8 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto/tmhash"
|
||||
"github.com/tendermint/tendermint/mempool"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
@ -46,13 +46,13 @@ func (ctx Context) BroadcastTx(txBytes []byte) (res *sdk.TxResponse, err error)
|
||||
// TODO: Avoid brittle string matching in favor of error matching. This requires
|
||||
// a change to Tendermint's RPCError type to allow retrieval or matching against
|
||||
// a concrete error type.
|
||||
func CheckTendermintError(err error, txBytes []byte) *sdk.TxResponse {
|
||||
func CheckTendermintError(err error, tx tmtypes.Tx) *sdk.TxResponse {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
errStr := strings.ToLower(err.Error())
|
||||
txHash := fmt.Sprintf("%X", tmhash.Sum(txBytes))
|
||||
txHash := fmt.Sprintf("%X", tx.Hash())
|
||||
|
||||
switch {
|
||||
case strings.Contains(errStr, strings.ToLower(mempool.ErrTxInCache.Error())):
|
||||
|
||||
@ -36,8 +36,11 @@ func runConfigCmd(cmd *cobra.Command, args []string) error {
|
||||
|
||||
switch len(args) {
|
||||
case 0:
|
||||
// print all client config fields to sdt out
|
||||
s, _ := json.MarshalIndent(conf, "", "\t")
|
||||
// print all client config fields to stdout
|
||||
s, err := json.MarshalIndent(conf, "", "\t")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.Println(string(s))
|
||||
|
||||
case 1:
|
||||
|
||||
@ -73,7 +73,8 @@ func ReadFromClientConfig(ctx client.Context) (client.Context, error) {
|
||||
}
|
||||
// we need to update KeyringDir field on Client Context first cause it is used in NewKeyringFromBackend
|
||||
ctx = ctx.WithOutputFormat(conf.Output).
|
||||
WithChainID(conf.ChainID)
|
||||
WithChainID(conf.ChainID).
|
||||
WithKeyringDir(ctx.HomeDir)
|
||||
|
||||
keyring, err := client.NewKeyringFromBackend(ctx, conf.KeyringBackend)
|
||||
if err != nil {
|
||||
|
||||
@ -25,7 +25,7 @@ type Context struct {
|
||||
FromAddress sdk.AccAddress
|
||||
Client rpcclient.Client
|
||||
ChainID string
|
||||
JSONMarshaler codec.JSONCodec
|
||||
Codec codec.Codec
|
||||
InterfaceRegistry codectypes.InterfaceRegistry
|
||||
Input io.Reader
|
||||
Keyring keyring.Keyring
|
||||
@ -72,9 +72,9 @@ func (ctx Context) WithInput(r io.Reader) Context {
|
||||
return ctx
|
||||
}
|
||||
|
||||
// WithJSONMarshaler returns a copy of the Context with an updated JSONMarshaler.
|
||||
func (ctx Context) WithJSONMarshaler(m codec.JSONCodec) Context {
|
||||
ctx.JSONMarshaler = m
|
||||
// WithCodec returns a copy of the Context with an updated Codec.
|
||||
func (ctx Context) WithCodec(m codec.Codec) Context {
|
||||
ctx.Codec = m
|
||||
return ctx
|
||||
}
|
||||
|
||||
@ -254,10 +254,10 @@ func (ctx Context) PrintBytes(o []byte) error {
|
||||
|
||||
// PrintProto outputs toPrint to the ctx.Output based on ctx.OutputFormat which is
|
||||
// either text or json. If text, toPrint will be YAML encoded. Otherwise, toPrint
|
||||
// will be JSON encoded using ctx.JSONMarshaler. An error is returned upon failure.
|
||||
// will be JSON encoded using ctx.Codec. An error is returned upon failure.
|
||||
func (ctx Context) PrintProto(toPrint proto.Message) error {
|
||||
// always serialize JSON initially because proto json can't be directly YAML encoded
|
||||
out, err := ctx.JSONMarshaler.MarshalJSON(toPrint)
|
||||
out, err := ctx.Codec.MarshalJSON(toPrint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ func TestContext_PrintObject(t *testing.T) {
|
||||
// proto
|
||||
//
|
||||
registry := testdata.NewTestInterfaceRegistry()
|
||||
ctx = ctx.WithJSONMarshaler(codec.NewProtoCodec(registry))
|
||||
ctx = ctx.WithCodec(codec.NewProtoCodec(registry))
|
||||
|
||||
// json
|
||||
buf := &bytes.Buffer{}
|
||||
@ -105,7 +105,8 @@ func TestCLIQueryConn(t *testing.T) {
|
||||
cfg := network.DefaultConfig()
|
||||
cfg.NumValidators = 1
|
||||
|
||||
n := network.New(t, cfg)
|
||||
n, err := network.New(t, t.TempDir(), cfg)
|
||||
require.NoError(t, err)
|
||||
defer n.Cleanup()
|
||||
|
||||
testClient := testdata.NewQueryClient(n.Validators[0].ClientCtx)
|
||||
|
||||
@ -32,7 +32,7 @@ func Cmd() *cobra.Command {
|
||||
// getPubKeyFromString decodes SDK PubKey using JSON marshaler.
|
||||
func getPubKeyFromString(ctx client.Context, pkstr string) (cryptotypes.PubKey, error) {
|
||||
var pk cryptotypes.PubKey
|
||||
err := ctx.JSONMarshaler.UnmarshalInterfaceJSON([]byte(pkstr), &pk)
|
||||
err := ctx.Codec.UnmarshalInterfaceJSON([]byte(pkstr), &pk)
|
||||
return pk, err
|
||||
}
|
||||
|
||||
|
||||
@ -1,17 +1,11 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "Cosmos SDK - Legacy REST and gRPC Gateway docs",
|
||||
"description": "A REST interface for state queries, legacy transactions",
|
||||
"title": "Cosmos SDK - gRPC Gateway docs",
|
||||
"description": "A REST interface for state queries",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"apis": [
|
||||
{
|
||||
"url": "./client/docs/swagger_legacy.yaml",
|
||||
"dereference": {
|
||||
"circular": "ignore"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "./tmp-swagger-gen/cosmos/auth/v1beta1/query.swagger.json",
|
||||
"operationIds": {
|
||||
@ -106,6 +100,22 @@
|
||||
"Params": "UpgradeParams"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "./tmp-swagger-gen/cosmos/authz/v1beta1/query.swagger.json",
|
||||
"operationIds": {
|
||||
"rename": {
|
||||
"Params": "AuthzParams"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "./tmp-swagger-gen/cosmos/feegrant/v1beta1/query.swagger.json",
|
||||
"operationIds": {
|
||||
"rename": {
|
||||
"Params": "FeegrantParams"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
8888
client/docs/swagger-ui/swagger.yaml
vendored
8888
client/docs/swagger-ui/swagger.yaml
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -50,7 +50,7 @@ const (
|
||||
FlagName = "name"
|
||||
FlagAccountNumber = "account-number"
|
||||
FlagSequence = "sequence"
|
||||
FlagMemo = "memo"
|
||||
FlagNote = "note"
|
||||
FlagFees = "fees"
|
||||
FlagGas = "gas"
|
||||
FlagGasPrices = "gas-prices"
|
||||
@ -97,7 +97,7 @@ func AddTxFlagsToCmd(cmd *cobra.Command) {
|
||||
cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign")
|
||||
cmd.Flags().Uint64P(FlagAccountNumber, "a", 0, "The account number of the signing account (offline mode only)")
|
||||
cmd.Flags().Uint64P(FlagSequence, "s", 0, "The sequence number of the signing account (offline mode only)")
|
||||
cmd.Flags().String(FlagMemo, "", "Memo to send along with transaction")
|
||||
cmd.Flags().String(FlagNote, "", "Note to add a description to the transaction (previously --memo)")
|
||||
cmd.Flags().String(FlagFees, "", "Fees to pay along with transaction; eg: 10uatom")
|
||||
cmd.Flags().String(FlagGasPrices, "", "Gas prices in decimal format to determine the transaction fee (e.g. 0.1uatom)")
|
||||
cmd.Flags().String(FlagNode, "tcp://localhost:26657", "<host>:<port> to tendermint rpc interface for this chain")
|
||||
@ -106,7 +106,7 @@ func AddTxFlagsToCmd(cmd *cobra.Command) {
|
||||
cmd.Flags().StringP(FlagBroadcastMode, "b", BroadcastSync, "Transaction broadcasting mode (sync|async|block)")
|
||||
cmd.Flags().Bool(FlagDryRun, false, "ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it")
|
||||
cmd.Flags().Bool(FlagGenerateOnly, false, "Build an unsigned transaction and write it to STDOUT (when enabled, the local Keybase is not accessible)")
|
||||
cmd.Flags().Bool(FlagOffline, false, "Offline mode (does not allow any online functionality")
|
||||
cmd.Flags().Bool(FlagOffline, false, "Offline mode (does not allow any online functionality)")
|
||||
cmd.Flags().BoolP(FlagSkipConfirmation, "y", false, "Skip tx broadcasting prompt confirmation")
|
||||
cmd.Flags().String(FlagKeyringBackend, DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test|memory)")
|
||||
cmd.Flags().String(FlagSignMode, "", "Choose sign mode (direct|amino-json), this is an advanced feature")
|
||||
|
||||
@ -688,13 +688,14 @@ func (m *GetNodeInfoResponse) GetApplicationVersion() *VersionInfo {
|
||||
|
||||
// VersionInfo is the type for the GetNodeInfoResponse message.
|
||||
type VersionInfo struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
AppName string `protobuf:"bytes,2,opt,name=app_name,json=appName,proto3" json:"app_name,omitempty"`
|
||||
Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"`
|
||||
GitCommit string `protobuf:"bytes,4,opt,name=git_commit,json=gitCommit,proto3" json:"git_commit,omitempty"`
|
||||
BuildTags string `protobuf:"bytes,5,opt,name=build_tags,json=buildTags,proto3" json:"build_tags,omitempty"`
|
||||
GoVersion string `protobuf:"bytes,6,opt,name=go_version,json=goVersion,proto3" json:"go_version,omitempty"`
|
||||
BuildDeps []*Module `protobuf:"bytes,7,rep,name=build_deps,json=buildDeps,proto3" json:"build_deps,omitempty"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
AppName string `protobuf:"bytes,2,opt,name=app_name,json=appName,proto3" json:"app_name,omitempty"`
|
||||
Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"`
|
||||
GitCommit string `protobuf:"bytes,4,opt,name=git_commit,json=gitCommit,proto3" json:"git_commit,omitempty"`
|
||||
BuildTags string `protobuf:"bytes,5,opt,name=build_tags,json=buildTags,proto3" json:"build_tags,omitempty"`
|
||||
GoVersion string `protobuf:"bytes,6,opt,name=go_version,json=goVersion,proto3" json:"go_version,omitempty"`
|
||||
BuildDeps []*Module `protobuf:"bytes,7,rep,name=build_deps,json=buildDeps,proto3" json:"build_deps,omitempty"`
|
||||
CosmosSdkVersion string `protobuf:"bytes,8,opt,name=cosmos_sdk_version,json=cosmosSdkVersion,proto3" json:"cosmos_sdk_version,omitempty"`
|
||||
}
|
||||
|
||||
func (m *VersionInfo) Reset() { *m = VersionInfo{} }
|
||||
@ -779,6 +780,13 @@ func (m *VersionInfo) GetBuildDeps() []*Module {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *VersionInfo) GetCosmosSdkVersion() string {
|
||||
if m != nil {
|
||||
return m.CosmosSdkVersion
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Module is the type for VersionInfo
|
||||
type Module struct {
|
||||
// module path
|
||||
@ -866,74 +874,75 @@ func init() {
|
||||
}
|
||||
|
||||
var fileDescriptor_40c93fb3ef485c5d = []byte{
|
||||
// 1060 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x6f, 0xdc, 0x44,
|
||||
0x14, 0xaf, 0xb3, 0x6d, 0x36, 0x79, 0x8b, 0x20, 0x99, 0x84, 0xc6, 0xb1, 0xd2, 0x6d, 0xf0, 0xa1,
|
||||
0x4d, 0x88, 0x62, 0x6b, 0xb7, 0x6d, 0xda, 0x43, 0x29, 0x22, 0x04, 0xd2, 0xa8, 0xa5, 0x8a, 0x1c,
|
||||
0xc4, 0x01, 0x21, 0x59, 0xde, 0xf5, 0xc4, 0x19, 0x65, 0xd7, 0x33, 0xf5, 0x8c, 0x83, 0x56, 0xa8,
|
||||
0x02, 0x71, 0xe2, 0x88, 0xc4, 0x57, 0xe8, 0x85, 0x2f, 0xc0, 0x11, 0x71, 0xe4, 0x58, 0x81, 0x84,
|
||||
0x2a, 0x4e, 0x28, 0xe1, 0x53, 0x70, 0x42, 0x9e, 0x19, 0xef, 0xda, 0x4d, 0xd2, 0xdd, 0xcd, 0x01,
|
||||
0x89, 0x93, 0x67, 0xde, 0xbf, 0xf9, 0xfd, 0xde, 0xbc, 0xf7, 0x3c, 0xf0, 0x6e, 0x9b, 0xf2, 0x2e,
|
||||
0xe5, 0x6e, 0x2b, 0xe0, 0xd8, 0x15, 0x38, 0x0e, 0x71, 0xd2, 0x25, 0xb1, 0x70, 0x8f, 0x1a, 0x2d,
|
||||
0x2c, 0x82, 0x86, 0xfb, 0x34, 0xc5, 0x49, 0xcf, 0x61, 0x09, 0x15, 0x14, 0xd5, 0x95, 0xad, 0x93,
|
||||
0xd9, 0x3a, 0x03, 0x5b, 0x47, 0xdb, 0x5a, 0xf3, 0x11, 0x8d, 0xa8, 0x34, 0x75, 0xb3, 0x95, 0xf2,
|
||||
0xb2, 0x16, 0x23, 0x4a, 0xa3, 0x0e, 0x76, 0xe5, 0xae, 0x95, 0xee, 0xbb, 0x41, 0xac, 0x03, 0x5a,
|
||||
0x4b, 0x5a, 0x15, 0x30, 0xe2, 0x06, 0x71, 0x4c, 0x45, 0x20, 0x08, 0x8d, 0xb9, 0xd6, 0x5a, 0x05,
|
||||
0x38, 0xac, 0xc9, 0x5c, 0xd1, 0x63, 0x38, 0xd7, 0x2d, 0x15, 0x74, 0x52, 0xee, 0xb6, 0x3a, 0xb4,
|
||||
0x7d, 0x78, 0xae, 0xb6, 0xe8, 0x5b, 0xa2, 0x2c, 0xf9, 0xf5, 0xd9, 0xb2, 0x20, 0x22, 0xb1, 0x04,
|
||||
0xa1, 0x6c, 0xed, 0x6f, 0x0c, 0xa8, 0x6f, 0x63, 0xf1, 0x59, 0xd0, 0x21, 0x61, 0x20, 0x68, 0xb2,
|
||||
0x87, 0xc5, 0x66, 0xef, 0x21, 0x26, 0xd1, 0x81, 0xf0, 0xf0, 0xd3, 0x14, 0x73, 0x81, 0xae, 0xc2,
|
||||
0xe4, 0x81, 0x14, 0x98, 0xc6, 0xb2, 0xb1, 0x52, 0xf1, 0xf4, 0x0e, 0x7d, 0x0c, 0x30, 0x08, 0x67,
|
||||
0x4e, 0x2c, 0x1b, 0x2b, 0xb5, 0xe6, 0x0d, 0xa7, 0x98, 0x42, 0x95, 0x5b, 0x7d, 0xb6, 0xb3, 0x1b,
|
||||
0x44, 0x58, 0xc7, 0xf4, 0x0a, 0x9e, 0xf6, 0x4b, 0x03, 0xae, 0x9f, 0x0b, 0x81, 0x33, 0x1a, 0x73,
|
||||
0x8c, 0xde, 0x81, 0x37, 0x24, 0x7f, 0xbf, 0x84, 0xa4, 0x26, 0x65, 0xca, 0x14, 0xed, 0x00, 0x1c,
|
||||
0xe5, 0x21, 0xb8, 0x39, 0xb1, 0x5c, 0x59, 0xa9, 0x35, 0x57, 0x9d, 0xd7, 0xdf, 0xa8, 0xd3, 0x3f,
|
||||
0xd4, 0x2b, 0x38, 0xa3, 0xed, 0x12, 0xb3, 0x8a, 0x64, 0x76, 0x73, 0x28, 0x33, 0x05, 0xb5, 0x44,
|
||||
0x6d, 0x1f, 0x96, 0xb6, 0xb1, 0x78, 0x1c, 0x08, 0xcc, 0x4b, 0xfc, 0xf2, 0xd4, 0x96, 0x53, 0x68,
|
||||
0x5c, 0x38, 0x85, 0x7f, 0x18, 0x70, 0xed, 0x9c, 0x83, 0xfe, 0xdf, 0x09, 0x7c, 0x6e, 0xc0, 0x74,
|
||||
0xff, 0x08, 0x64, 0x42, 0x35, 0x08, 0xc3, 0x04, 0x73, 0x2e, 0xf1, 0x4f, 0x7b, 0xf9, 0x16, 0xad,
|
||||
0x43, 0x95, 0xa5, 0x2d, 0xff, 0x10, 0xf7, 0x74, 0x21, 0xce, 0x3b, 0xaa, 0xf5, 0x9c, 0xbc, 0x2b,
|
||||
0x9d, 0x0f, 0xe2, 0x9e, 0x37, 0xc9, 0xd2, 0xd6, 0x23, 0xdc, 0xcb, 0xb2, 0x71, 0x44, 0x05, 0x89,
|
||||
0x23, 0x9f, 0xd1, 0x2f, 0x71, 0x22, 0x11, 0x56, 0xbc, 0x9a, 0x92, 0xed, 0x66, 0x22, 0xb4, 0x06,
|
||||
0xb3, 0x2c, 0xa1, 0x8c, 0x72, 0x9c, 0xf8, 0x2c, 0x21, 0x34, 0x21, 0xa2, 0x67, 0x5e, 0x96, 0x76,
|
||||
0x33, 0xb9, 0x62, 0x57, 0xcb, 0xed, 0x06, 0x2c, 0x6c, 0x63, 0xb1, 0x99, 0x25, 0x73, 0xc4, 0xee,
|
||||
0xb1, 0xbf, 0x06, 0xf3, 0xb4, 0x8b, 0xbe, 0xac, 0xdb, 0x30, 0xa5, 0x2e, 0x8b, 0x84, 0xba, 0x28,
|
||||
0x16, 0x8b, 0xb9, 0x57, 0xbd, 0x2e, 0x5d, 0x77, 0xb6, 0xbc, 0xaa, 0x34, 0xdd, 0x09, 0xd1, 0x3a,
|
||||
0x5c, 0x91, 0x4b, 0x9d, 0x81, 0x85, 0x73, 0x5c, 0x3c, 0x65, 0x65, 0x2f, 0xc0, 0xdb, 0xfd, 0x92,
|
||||
0x51, 0x0a, 0x85, 0xd8, 0x7e, 0x06, 0x57, 0x5f, 0x55, 0xfc, 0x97, 0xb8, 0xe6, 0x60, 0x76, 0x1b,
|
||||
0x8b, 0xbd, 0x5e, 0xdc, 0x26, 0x71, 0x94, 0x63, 0x72, 0x00, 0x15, 0x85, 0x1a, 0x8f, 0x09, 0x55,
|
||||
0xae, 0x44, 0x12, 0xce, 0x94, 0x97, 0x6f, 0xed, 0x79, 0x69, 0xff, 0x84, 0x86, 0x78, 0x27, 0xde,
|
||||
0xa7, 0x79, 0x94, 0x5f, 0x0c, 0x98, 0x2b, 0x89, 0x75, 0x9c, 0x47, 0x30, 0x1b, 0xe2, 0xfd, 0x20,
|
||||
0xed, 0x08, 0x3f, 0xa6, 0x21, 0xf6, 0x49, 0xbc, 0x4f, 0x35, 0xc1, 0xeb, 0x45, 0xb4, 0xac, 0xc9,
|
||||
0x9c, 0x2d, 0x65, 0xd8, 0x8f, 0xf1, 0x56, 0x58, 0x16, 0xa0, 0x2f, 0x60, 0x2e, 0x60, 0xac, 0x43,
|
||||
0xda, 0xb2, 0x82, 0xfd, 0x23, 0x9c, 0xf0, 0xc1, 0x7c, 0x5c, 0x1b, 0xda, 0x4f, 0xca, 0x5c, 0x86,
|
||||
0x46, 0x85, 0x38, 0x5a, 0x6e, 0xff, 0x63, 0x40, 0xad, 0x60, 0x83, 0x10, 0x5c, 0x8e, 0x83, 0x2e,
|
||||
0xd6, 0xfd, 0x20, 0xd7, 0x68, 0x11, 0xa6, 0x02, 0xc6, 0x7c, 0x29, 0x9f, 0xd0, 0x7d, 0xc2, 0xd8,
|
||||
0x93, 0x4c, 0x65, 0x42, 0x35, 0x07, 0x54, 0x51, 0x1a, 0xbd, 0x45, 0xd7, 0x00, 0x22, 0x22, 0xfc,
|
||||
0x36, 0xed, 0x76, 0x89, 0x90, 0x85, 0x3e, 0xed, 0x4d, 0x47, 0x44, 0x7c, 0x28, 0x05, 0x99, 0xba,
|
||||
0x95, 0x92, 0x4e, 0xe8, 0x8b, 0x20, 0xe2, 0xe6, 0x15, 0xa5, 0x96, 0x92, 0x4f, 0x83, 0x88, 0x4b,
|
||||
0x6f, 0xda, 0xe7, 0x3a, 0xa9, 0xbd, 0xa9, 0x46, 0x8a, 0x3e, 0xca, 0xbd, 0x43, 0xcc, 0xb8, 0x59,
|
||||
0x95, 0xa3, 0xe5, 0xc6, 0xb0, 0x54, 0x7c, 0x42, 0xc3, 0xb4, 0x83, 0xf5, 0x29, 0x5b, 0x98, 0x71,
|
||||
0xfb, 0x21, 0x4c, 0x2a, 0x61, 0x46, 0x9b, 0x05, 0xe2, 0x20, 0xa7, 0x9d, 0xad, 0x8b, 0xdc, 0x26,
|
||||
0xca, 0xdc, 0x66, 0xa0, 0xc2, 0xd3, 0xae, 0x66, 0x9c, 0x2d, 0x9b, 0xdf, 0x4d, 0x43, 0x75, 0x0f,
|
||||
0x27, 0x47, 0xa4, 0x8d, 0xd1, 0x8f, 0x06, 0xd4, 0x0a, 0x55, 0x81, 0x9a, 0xc3, 0x80, 0x9d, 0xae,
|
||||
0x2c, 0xeb, 0xd6, 0x58, 0x3e, 0xaa, 0xec, 0xec, 0xc6, 0xb7, 0xbf, 0xff, 0xfd, 0xc3, 0xc4, 0x1a,
|
||||
0x5a, 0x75, 0x87, 0xbc, 0x51, 0xfa, 0x45, 0x89, 0x9e, 0x1b, 0x00, 0x83, 0x46, 0x40, 0x8d, 0x11,
|
||||
0x8e, 0x2d, 0x77, 0x92, 0xd5, 0x1c, 0xc7, 0x45, 0x03, 0x75, 0x25, 0xd0, 0x55, 0x74, 0x73, 0x18,
|
||||
0x50, 0xdd, 0x7e, 0xe8, 0x27, 0x03, 0xde, 0x2c, 0xcf, 0x10, 0x74, 0x67, 0x84, 0x73, 0x4f, 0x0f,
|
||||
0x23, 0x6b, 0x63, 0x5c, 0x37, 0x0d, 0xf9, 0x8e, 0x84, 0xec, 0xa2, 0xf5, 0x61, 0x90, 0xe5, 0xd0,
|
||||
0xe1, 0x6e, 0x47, 0xc6, 0x40, 0x3f, 0x1b, 0x30, 0xf3, 0xea, 0x58, 0x46, 0x77, 0x47, 0xc0, 0x70,
|
||||
0xd6, 0xec, 0xb7, 0xee, 0x8d, 0xef, 0xa8, 0xe1, 0xdf, 0x95, 0xf0, 0x1b, 0xc8, 0x1d, 0x11, 0xfe,
|
||||
0x57, 0xea, 0xaf, 0xf2, 0x0c, 0xfd, 0x66, 0x14, 0xc6, 0x7a, 0xf1, 0x25, 0x80, 0xee, 0x8f, 0x9c,
|
||||
0xc9, 0x33, 0x5e, 0x2a, 0xd6, 0x7b, 0x17, 0xf4, 0xd6, 0x7c, 0xee, 0x4b, 0x3e, 0x1b, 0xe8, 0xf6,
|
||||
0x30, 0x3e, 0x83, 0x47, 0x04, 0x16, 0xfd, 0x5b, 0xf9, 0xd3, 0x90, 0xff, 0xd7, 0xb3, 0x5e, 0x88,
|
||||
0xe8, 0xc1, 0x08, 0xc0, 0x5e, 0xf3, 0xba, 0xb5, 0xde, 0xbf, 0xb0, 0xbf, 0xa6, 0xf6, 0x40, 0x52,
|
||||
0xbb, 0x87, 0x36, 0xc6, 0xa3, 0x96, 0xdf, 0xd8, 0xe6, 0xe3, 0x5f, 0x8f, 0xeb, 0xc6, 0x8b, 0xe3,
|
||||
0xba, 0xf1, 0xd7, 0x71, 0xdd, 0xf8, 0xfe, 0xa4, 0x7e, 0xe9, 0xc5, 0x49, 0xfd, 0xd2, 0xcb, 0x93,
|
||||
0xfa, 0xa5, 0xcf, 0x9b, 0x11, 0x11, 0x07, 0x69, 0xcb, 0x69, 0xd3, 0x6e, 0x1e, 0x5b, 0x7d, 0xd6,
|
||||
0x79, 0x78, 0xe8, 0xb6, 0x3b, 0x04, 0xc7, 0xc2, 0x8d, 0x12, 0xd6, 0x76, 0x45, 0x97, 0xab, 0x61,
|
||||
0xd6, 0x9a, 0x94, 0xef, 0x9d, 0x5b, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x08, 0x32, 0x9c, 0x36,
|
||||
0xf7, 0x0c, 0x00, 0x00,
|
||||
// 1081 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4d, 0x6f, 0xdc, 0x44,
|
||||
0x18, 0x8e, 0x77, 0xdb, 0x6c, 0xf2, 0x2e, 0x82, 0x64, 0x12, 0x1a, 0xc7, 0x4a, 0xb7, 0x61, 0x0f,
|
||||
0x6d, 0x42, 0x88, 0xad, 0xdd, 0xb6, 0x69, 0x0f, 0xa5, 0x88, 0x10, 0x48, 0xa3, 0x96, 0x2a, 0x72,
|
||||
0x10, 0x07, 0x84, 0x64, 0x79, 0xd7, 0x13, 0x67, 0x94, 0x5d, 0xcf, 0xd4, 0x33, 0x0e, 0x5a, 0xa1,
|
||||
0x0a, 0xc4, 0x89, 0x23, 0x12, 0x7f, 0xa1, 0x07, 0xf8, 0x03, 0x1c, 0x11, 0x47, 0x8e, 0x15, 0x48,
|
||||
0xa8, 0xe2, 0x84, 0x12, 0x7e, 0x08, 0xf2, 0xcc, 0x78, 0xd7, 0x6e, 0x92, 0xee, 0x6e, 0x0e, 0x48,
|
||||
0x3d, 0x79, 0xe6, 0xfd, 0x9a, 0xe7, 0x79, 0x66, 0xde, 0xf1, 0xc0, 0xbb, 0x6d, 0xca, 0xbb, 0x94,
|
||||
0x3b, 0x2d, 0x9f, 0x63, 0x47, 0xe0, 0x28, 0xc0, 0x71, 0x97, 0x44, 0xc2, 0x39, 0x6a, 0xb4, 0xb0,
|
||||
0xf0, 0x1b, 0xce, 0x93, 0x04, 0xc7, 0x3d, 0x9b, 0xc5, 0x54, 0x50, 0x54, 0x53, 0xb1, 0x76, 0x1a,
|
||||
0x6b, 0x0f, 0x62, 0x6d, 0x1d, 0x6b, 0xcd, 0x87, 0x34, 0xa4, 0x32, 0xd4, 0x49, 0x47, 0x2a, 0xcb,
|
||||
0x5a, 0x0c, 0x29, 0x0d, 0x3b, 0xd8, 0x91, 0xb3, 0x56, 0xb2, 0xef, 0xf8, 0x91, 0x2e, 0x68, 0x2d,
|
||||
0x69, 0x97, 0xcf, 0x88, 0xe3, 0x47, 0x11, 0x15, 0xbe, 0x20, 0x34, 0xe2, 0xda, 0x6b, 0xe5, 0xe0,
|
||||
0xb0, 0x26, 0x73, 0x44, 0x8f, 0xe1, 0xcc, 0xb7, 0x94, 0xf3, 0x49, 0xbb, 0xd3, 0xea, 0xd0, 0xf6,
|
||||
0xe1, 0xb9, 0xde, 0x7c, 0x6e, 0x81, 0xb2, 0xe4, 0xd7, 0x67, 0xcb, 0xfc, 0x90, 0x44, 0x12, 0x84,
|
||||
0x8a, 0xad, 0x7f, 0x6b, 0x40, 0x6d, 0x1b, 0x8b, 0xcf, 0xfd, 0x0e, 0x09, 0x7c, 0x41, 0xe3, 0x3d,
|
||||
0x2c, 0x36, 0x7b, 0x0f, 0x30, 0x09, 0x0f, 0x84, 0x8b, 0x9f, 0x24, 0x98, 0x0b, 0x74, 0x05, 0x26,
|
||||
0x0f, 0xa4, 0xc1, 0x34, 0x96, 0x8d, 0x95, 0xb2, 0xab, 0x67, 0xe8, 0x13, 0x80, 0x41, 0x39, 0xb3,
|
||||
0xb4, 0x6c, 0xac, 0x54, 0x9b, 0xd7, 0xed, 0xbc, 0x84, 0x4a, 0x5b, 0xbd, 0xb6, 0xbd, 0xeb, 0x87,
|
||||
0x58, 0xd7, 0x74, 0x73, 0x99, 0xf5, 0x17, 0x06, 0x5c, 0x3b, 0x17, 0x02, 0x67, 0x34, 0xe2, 0x18,
|
||||
0xbd, 0x03, 0x6f, 0x48, 0xfe, 0x5e, 0x01, 0x49, 0x55, 0xda, 0x54, 0x28, 0xda, 0x01, 0x38, 0xca,
|
||||
0x4a, 0x70, 0xb3, 0xb4, 0x5c, 0x5e, 0xa9, 0x36, 0x57, 0xed, 0x57, 0xef, 0xa8, 0xdd, 0x5f, 0xd4,
|
||||
0xcd, 0x25, 0xa3, 0xed, 0x02, 0xb3, 0xb2, 0x64, 0x76, 0x63, 0x28, 0x33, 0x05, 0xb5, 0x40, 0x6d,
|
||||
0x1f, 0x96, 0xb6, 0xb1, 0x78, 0xe4, 0x0b, 0xcc, 0x0b, 0xfc, 0x32, 0x69, 0x8b, 0x12, 0x1a, 0x17,
|
||||
0x96, 0xf0, 0x2f, 0x03, 0xae, 0x9e, 0xb3, 0xd0, 0xeb, 0x2d, 0xe0, 0x33, 0x03, 0xa6, 0xfb, 0x4b,
|
||||
0x20, 0x13, 0x2a, 0x7e, 0x10, 0xc4, 0x98, 0x73, 0x89, 0x7f, 0xda, 0xcd, 0xa6, 0x68, 0x1d, 0x2a,
|
||||
0x2c, 0x69, 0x79, 0x87, 0xb8, 0xa7, 0x0f, 0xe2, 0xbc, 0xad, 0x5a, 0xcf, 0xce, 0xba, 0xd2, 0xfe,
|
||||
0x30, 0xea, 0xb9, 0x93, 0x2c, 0x69, 0x3d, 0xc4, 0xbd, 0x54, 0x8d, 0x23, 0x2a, 0x48, 0x14, 0x7a,
|
||||
0x8c, 0x7e, 0x85, 0x63, 0x89, 0xb0, 0xec, 0x56, 0x95, 0x6d, 0x37, 0x35, 0xa1, 0x35, 0x98, 0x65,
|
||||
0x31, 0x65, 0x94, 0xe3, 0xd8, 0x63, 0x31, 0xa1, 0x31, 0x11, 0x3d, 0xf3, 0x92, 0x8c, 0x9b, 0xc9,
|
||||
0x1c, 0xbb, 0xda, 0x5e, 0x6f, 0xc0, 0xc2, 0x36, 0x16, 0x9b, 0xa9, 0x98, 0x23, 0x76, 0x4f, 0xfd,
|
||||
0x1b, 0x30, 0x4f, 0xa7, 0xe8, 0xcd, 0xba, 0x05, 0x53, 0x6a, 0xb3, 0x48, 0xa0, 0x0f, 0xc5, 0x62,
|
||||
0x5e, 0x7b, 0xd5, 0xeb, 0x32, 0x75, 0x67, 0xcb, 0xad, 0xc8, 0xd0, 0x9d, 0x00, 0xad, 0xc3, 0x65,
|
||||
0x39, 0xd4, 0x0a, 0x2c, 0x9c, 0x93, 0xe2, 0xaa, 0xa8, 0xfa, 0x02, 0xbc, 0xdd, 0x3f, 0x32, 0xca,
|
||||
0xa1, 0x10, 0xd7, 0x9f, 0xc2, 0x95, 0x97, 0x1d, 0xff, 0x27, 0xae, 0x39, 0x98, 0xdd, 0xc6, 0x62,
|
||||
0xaf, 0x17, 0xb5, 0x49, 0x14, 0x66, 0x98, 0x6c, 0x40, 0x79, 0xa3, 0xc6, 0x63, 0x42, 0x85, 0x2b,
|
||||
0x93, 0x84, 0x33, 0xe5, 0x66, 0xd3, 0xfa, 0xbc, 0x8c, 0x7f, 0x4c, 0x03, 0xbc, 0x13, 0xed, 0xd3,
|
||||
0xac, 0xca, 0x6f, 0x06, 0xcc, 0x15, 0xcc, 0xba, 0xce, 0x43, 0x98, 0x0d, 0xf0, 0xbe, 0x9f, 0x74,
|
||||
0x84, 0x17, 0xd1, 0x00, 0x7b, 0x24, 0xda, 0xa7, 0x9a, 0xe0, 0xb5, 0x3c, 0x5a, 0xd6, 0x64, 0xf6,
|
||||
0x96, 0x0a, 0xec, 0xd7, 0x78, 0x2b, 0x28, 0x1a, 0xd0, 0x97, 0x30, 0xe7, 0x33, 0xd6, 0x21, 0x6d,
|
||||
0x79, 0x82, 0xbd, 0x23, 0x1c, 0xf3, 0xc1, 0xfd, 0xb8, 0x36, 0xb4, 0x9f, 0x54, 0xb8, 0x2c, 0x8d,
|
||||
0x72, 0x75, 0xb4, 0xbd, 0xfe, 0x53, 0x09, 0xaa, 0xb9, 0x18, 0x84, 0xe0, 0x52, 0xe4, 0x77, 0xb1,
|
||||
0xee, 0x07, 0x39, 0x46, 0x8b, 0x30, 0xe5, 0x33, 0xe6, 0x49, 0x7b, 0x49, 0xf7, 0x09, 0x63, 0x8f,
|
||||
0x53, 0x97, 0x09, 0x95, 0x0c, 0x50, 0x59, 0x79, 0xf4, 0x14, 0x5d, 0x05, 0x08, 0x89, 0xf0, 0xda,
|
||||
0xb4, 0xdb, 0x25, 0x42, 0x1e, 0xf4, 0x69, 0x77, 0x3a, 0x24, 0xe2, 0x23, 0x69, 0x48, 0xdd, 0xad,
|
||||
0x84, 0x74, 0x02, 0x4f, 0xf8, 0x21, 0x37, 0x2f, 0x2b, 0xb7, 0xb4, 0x7c, 0xe6, 0x87, 0x5c, 0x66,
|
||||
0xd3, 0x3e, 0xd7, 0x49, 0x9d, 0x4d, 0x35, 0x52, 0xf4, 0x71, 0x96, 0x1d, 0x60, 0xc6, 0xcd, 0x8a,
|
||||
0xbc, 0x5a, 0xae, 0x0f, 0x93, 0xe2, 0x53, 0x1a, 0x24, 0x1d, 0xac, 0x57, 0xd9, 0xc2, 0x8c, 0xa3,
|
||||
0xf7, 0x00, 0xa9, 0x1c, 0x8f, 0x07, 0x87, 0xfd, 0xd5, 0xa6, 0xe4, 0x6a, 0x33, 0xca, 0xb3, 0x17,
|
||||
0x1c, 0x66, 0x52, 0x3d, 0x80, 0x49, 0x55, 0x22, 0x15, 0x89, 0xf9, 0xe2, 0x20, 0x13, 0x29, 0x1d,
|
||||
0xe7, 0x95, 0x28, 0x15, 0x95, 0x98, 0x81, 0x32, 0x4f, 0xba, 0x5a, 0x9f, 0x74, 0xd8, 0xfc, 0x7e,
|
||||
0x1a, 0x2a, 0x7b, 0x38, 0x3e, 0x22, 0x6d, 0x8c, 0x7e, 0x36, 0xa0, 0x9a, 0x3b, 0x43, 0xa8, 0x39,
|
||||
0x8c, 0xc6, 0xe9, 0x73, 0x68, 0xdd, 0x1c, 0x2b, 0x47, 0x1d, 0xd2, 0x7a, 0xe3, 0xbb, 0x3f, 0xff,
|
||||
0xfd, 0xb1, 0xb4, 0x86, 0x56, 0x9d, 0x21, 0x2f, 0x9a, 0xfe, 0x11, 0x46, 0xcf, 0x0c, 0x80, 0x41,
|
||||
0xdb, 0xa0, 0xc6, 0x08, 0xcb, 0x16, 0xfb, 0xce, 0x6a, 0x8e, 0x93, 0xa2, 0x81, 0x3a, 0x12, 0xe8,
|
||||
0x2a, 0xba, 0x31, 0x0c, 0xa8, 0x6e, 0x56, 0xf4, 0x8b, 0x01, 0x6f, 0x16, 0x6f, 0x1c, 0x74, 0x7b,
|
||||
0x84, 0x75, 0x4f, 0x5f, 0x5d, 0xd6, 0xc6, 0xb8, 0x69, 0x1a, 0xf2, 0x6d, 0x09, 0xd9, 0x41, 0xeb,
|
||||
0xc3, 0x20, 0xcb, 0x2b, 0x8a, 0x3b, 0x1d, 0x59, 0x03, 0xfd, 0x6a, 0xc0, 0xcc, 0xcb, 0x97, 0x38,
|
||||
0xba, 0x33, 0x02, 0x86, 0xb3, 0xfe, 0x14, 0xd6, 0xdd, 0xf1, 0x13, 0x35, 0xfc, 0x3b, 0x12, 0x7e,
|
||||
0x03, 0x39, 0x23, 0xc2, 0xff, 0x5a, 0xfd, 0x83, 0x9e, 0xa2, 0x3f, 0x8c, 0xdc, 0x4f, 0x20, 0xff,
|
||||
0x6e, 0x40, 0xf7, 0x46, 0x56, 0xf2, 0x8c, 0x77, 0x8d, 0xf5, 0xfe, 0x05, 0xb3, 0x35, 0x9f, 0x7b,
|
||||
0x92, 0xcf, 0x06, 0xba, 0x35, 0x8c, 0xcf, 0xe0, 0xc9, 0x81, 0x45, 0x7f, 0x57, 0xfe, 0x36, 0xe4,
|
||||
0xdf, 0xf8, 0xac, 0xf7, 0x24, 0xba, 0x3f, 0x02, 0xb0, 0x57, 0xbc, 0x85, 0xad, 0x0f, 0x2e, 0x9c,
|
||||
0xaf, 0xa9, 0xdd, 0x97, 0xd4, 0xee, 0xa2, 0x8d, 0xf1, 0xa8, 0x65, 0x3b, 0xb6, 0xf9, 0xe8, 0xf7,
|
||||
0xe3, 0x9a, 0xf1, 0xfc, 0xb8, 0x66, 0xfc, 0x73, 0x5c, 0x33, 0x7e, 0x38, 0xa9, 0x4d, 0x3c, 0x3f,
|
||||
0xa9, 0x4d, 0xbc, 0x38, 0xa9, 0x4d, 0x7c, 0xd1, 0x0c, 0x89, 0x38, 0x48, 0x5a, 0x76, 0x9b, 0x76,
|
||||
0xb3, 0xda, 0xea, 0xb3, 0xce, 0x83, 0x43, 0xa7, 0xdd, 0x21, 0x38, 0x12, 0x4e, 0x18, 0xb3, 0xb6,
|
||||
0x23, 0xba, 0x5c, 0x5d, 0x66, 0xad, 0x49, 0xf9, 0x3a, 0xba, 0xf9, 0x5f, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0x9d, 0x37, 0x87, 0xe4, 0x25, 0x0d, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@ -1734,6 +1743,13 @@ func (m *VersionInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.CosmosSdkVersion) > 0 {
|
||||
i -= len(m.CosmosSdkVersion)
|
||||
copy(dAtA[i:], m.CosmosSdkVersion)
|
||||
i = encodeVarintQuery(dAtA, i, uint64(len(m.CosmosSdkVersion)))
|
||||
i--
|
||||
dAtA[i] = 0x42
|
||||
}
|
||||
if len(m.BuildDeps) > 0 {
|
||||
for iNdEx := len(m.BuildDeps) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
@ -2082,6 +2098,10 @@ func (m *VersionInfo) Size() (n int) {
|
||||
n += 1 + l + sovQuery(uint64(l))
|
||||
}
|
||||
}
|
||||
l = len(m.CosmosSdkVersion)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovQuery(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
@ -3647,6 +3667,38 @@ func (m *VersionInfo) Unmarshal(dAtA []byte) error {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 8:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CosmosSdkVersion", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowQuery
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthQuery
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthQuery
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.CosmosSdkVersion = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipQuery(dAtA[iNdEx:])
|
||||
|
||||
@ -184,13 +184,14 @@ func (s queryServer) GetNodeInfo(ctx context.Context, req *GetNodeInfoRequest) (
|
||||
resp := GetNodeInfoResponse{
|
||||
DefaultNodeInfo: protoNodeInfo,
|
||||
ApplicationVersion: &VersionInfo{
|
||||
AppName: nodeInfo.AppName,
|
||||
Name: nodeInfo.Name,
|
||||
GitCommit: nodeInfo.GitCommit,
|
||||
GoVersion: nodeInfo.GoVersion,
|
||||
Version: nodeInfo.Version,
|
||||
BuildTags: nodeInfo.BuildTags,
|
||||
BuildDeps: deps,
|
||||
AppName: nodeInfo.AppName,
|
||||
Name: nodeInfo.Name,
|
||||
GitCommit: nodeInfo.GitCommit,
|
||||
GoVersion: nodeInfo.GoVersion,
|
||||
Version: nodeInfo.Version,
|
||||
BuildTags: nodeInfo.BuildTags,
|
||||
BuildDeps: deps,
|
||||
CosmosSdkVersion: nodeInfo.CosmosSdkVersion,
|
||||
},
|
||||
}
|
||||
return &resp, nil
|
||||
|
||||
@ -12,7 +12,7 @@ import (
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/network"
|
||||
qtypes "github.com/cosmos/cosmos-sdk/types/query"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/rest"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
)
|
||||
|
||||
@ -32,11 +32,12 @@ func (s *IntegrationTestSuite) SetupSuite() {
|
||||
cfg.NumValidators = 1
|
||||
|
||||
s.cfg = cfg
|
||||
s.network = network.New(s.T(), cfg)
|
||||
|
||||
s.Require().NotNil(s.network)
|
||||
var err error
|
||||
s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg)
|
||||
s.Require().NoError(err)
|
||||
|
||||
_, err := s.network.WaitForHeight(1)
|
||||
_, err = s.network.WaitForHeight(1)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.queryClient = tmservice.NewServiceClient(s.network.Validators[0].ClientCtx)
|
||||
@ -57,7 +58,7 @@ func (s IntegrationTestSuite) TestQueryNodeInfo() {
|
||||
restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/node_info", val.APIAddress))
|
||||
s.Require().NoError(err)
|
||||
var getInfoRes tmservice.GetNodeInfoResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &getInfoRes))
|
||||
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(restRes, &getInfoRes))
|
||||
s.Require().Equal(getInfoRes.ApplicationVersion.AppName, version.NewInfo().AppName)
|
||||
}
|
||||
|
||||
@ -70,7 +71,7 @@ func (s IntegrationTestSuite) TestQuerySyncing() {
|
||||
restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/syncing", val.APIAddress))
|
||||
s.Require().NoError(err)
|
||||
var syncingRes tmservice.GetSyncingResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &syncingRes))
|
||||
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(restRes, &syncingRes))
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestQueryLatestBlock() {
|
||||
@ -82,7 +83,7 @@ func (s IntegrationTestSuite) TestQueryLatestBlock() {
|
||||
restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/latest", val.APIAddress))
|
||||
s.Require().NoError(err)
|
||||
var blockInfoRes tmservice.GetLatestBlockResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &blockInfoRes))
|
||||
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(restRes, &blockInfoRes))
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestQueryBlockByHeight() {
|
||||
@ -93,7 +94,7 @@ func (s IntegrationTestSuite) TestQueryBlockByHeight() {
|
||||
restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/%d", val.APIAddress, 1))
|
||||
s.Require().NoError(err)
|
||||
var blockInfoRes tmservice.GetBlockByHeightResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &blockInfoRes))
|
||||
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(restRes, &blockInfoRes))
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestQueryLatestValidatorSet() {
|
||||
@ -124,7 +125,7 @@ func (s IntegrationTestSuite) TestQueryLatestValidatorSet() {
|
||||
restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=%d&pagination.limit=%d", val.APIAddress, 0, 1))
|
||||
s.Require().NoError(err)
|
||||
var validatorSetRes tmservice.GetLatestValidatorSetResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &validatorSetRes))
|
||||
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(restRes, &validatorSetRes))
|
||||
s.Require().Equal(1, len(validatorSetRes.Validators))
|
||||
anyPub, err := codectypes.NewAnyWithValue(val.PubKey)
|
||||
s.Require().NoError(err)
|
||||
@ -183,7 +184,7 @@ func (s IntegrationTestSuite) TestLatestValidatorSet_GRPCGateway() {
|
||||
s.Require().Contains(string(res), tc.expErrMsg)
|
||||
} else {
|
||||
var result tmservice.GetLatestValidatorSetResponse
|
||||
err = vals[0].ClientCtx.JSONMarshaler.UnmarshalJSON(res, &result)
|
||||
err = vals[0].ClientCtx.Codec.UnmarshalJSON(res, &result)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(uint64(len(vals)), result.Pagination.Total)
|
||||
anyPub, err := codectypes.NewAnyWithValue(vals[0].PubKey)
|
||||
@ -245,7 +246,7 @@ func (s IntegrationTestSuite) TestValidatorSetByHeight_GRPCGateway() {
|
||||
s.Require().Contains(string(res), tc.expErrMsg)
|
||||
} else {
|
||||
var result tmservice.GetValidatorSetByHeightResponse
|
||||
err = vals[0].ClientCtx.JSONMarshaler.UnmarshalJSON(res, &result)
|
||||
err = vals[0].ClientCtx.Codec.UnmarshalJSON(res, &result)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(uint64(len(vals)), result.Pagination.Total)
|
||||
}
|
||||
|
||||
@ -27,10 +27,11 @@ type IntegrationTestSuite struct {
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
s.T().Log("setting up integration test suite")
|
||||
|
||||
s.network = network.New(s.T(), network.DefaultConfig())
|
||||
s.Require().NotNil(s.network)
|
||||
var err error
|
||||
s.network, err = network.New(s.T(), s.T().TempDir(), network.DefaultConfig())
|
||||
s.Require().NoError(err)
|
||||
|
||||
_, err := s.network.WaitForHeight(2)
|
||||
_, err = s.network.WaitForHeight(2)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
|
||||
bip39 "github.com/cosmos/go-bip39"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
@ -89,7 +88,7 @@ func runAddCmdPrepare(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return RunAddCmd(clientCtx, cmd, args, buf)
|
||||
return runAddCmd(clientCtx, cmd, args, buf)
|
||||
}
|
||||
|
||||
/*
|
||||
@ -101,8 +100,7 @@ input
|
||||
output
|
||||
- armor encrypted private key (saved to file)
|
||||
*/
|
||||
func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *bufio.Reader) error {
|
||||
// func RunAddCmd(cmd *cobra.Command, args []string, kb keyring.Keyring, inBuf *bufio.Reader) error {
|
||||
func runAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *bufio.Reader) error {
|
||||
var err error
|
||||
|
||||
name := args[0]
|
||||
@ -110,6 +108,7 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
|
||||
noBackup, _ := cmd.Flags().GetBool(flagNoBackup)
|
||||
showMnemonic := !noBackup
|
||||
kb := ctx.Keyring
|
||||
outputFormat := ctx.OutputFormat
|
||||
|
||||
keyringAlgos, _ := kb.SupportedAlgorithms()
|
||||
algoStr, _ := cmd.Flags().GetString(flags.FlagKeyAlgorithm)
|
||||
@ -118,7 +117,10 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
|
||||
return err
|
||||
}
|
||||
|
||||
if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); !dryRun {
|
||||
if dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun); dryRun {
|
||||
// use in memory keybase
|
||||
kb = keyring.NewInMemory()
|
||||
} else {
|
||||
_, err = kb.Key(name)
|
||||
if err == nil {
|
||||
// account exists, ask for user confirmation
|
||||
@ -139,19 +141,19 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
|
||||
|
||||
multisigKeys, _ := cmd.Flags().GetStringSlice(flagMultisig)
|
||||
if len(multisigKeys) != 0 {
|
||||
var pks []cryptotypes.PubKey
|
||||
pks := make([]cryptotypes.PubKey, len(multisigKeys))
|
||||
multisigThreshold, _ := cmd.Flags().GetInt(flagMultiSigThreshold)
|
||||
if err := validateMultisigThreshold(multisigThreshold, len(multisigKeys)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, keyname := range multisigKeys {
|
||||
for i, keyname := range multisigKeys {
|
||||
k, err := kb.Key(keyname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pks = append(pks, k.GetPubKey())
|
||||
pks[i] = k.GetPubKey()
|
||||
}
|
||||
|
||||
if noSort, _ := cmd.Flags().GetBool(flagNoSort); !noSort {
|
||||
@ -161,24 +163,29 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
|
||||
}
|
||||
|
||||
pk := multisig.NewLegacyAminoPubKey(multisigThreshold, pks)
|
||||
if _, err := kb.SaveMultisig(name, pk); err != nil {
|
||||
info, err := kb.SaveMultisig(name, pk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PrintErrf("Key %q saved to disk.\n", name)
|
||||
return nil
|
||||
return printCreate(cmd, info, false, "", outputFormat)
|
||||
}
|
||||
}
|
||||
|
||||
pubKey, _ := cmd.Flags().GetString(FlagPublicKey)
|
||||
if pubKey != "" {
|
||||
var pk cryptotypes.PubKey
|
||||
err = ctx.JSONMarshaler.UnmarshalInterfaceJSON([]byte(pubKey), &pk)
|
||||
err = ctx.Codec.UnmarshalInterfaceJSON([]byte(pubKey), &pk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := kb.SavePubKey(name, pk, algo.Name())
|
||||
return err
|
||||
|
||||
info, err := kb.SavePubKey(name, pk, algo.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return printCreate(cmd, info, false, "", outputFormat)
|
||||
}
|
||||
|
||||
coinType, _ := cmd.Flags().GetUint32(flagCoinType)
|
||||
@ -202,7 +209,7 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
|
||||
return err
|
||||
}
|
||||
|
||||
return printCreate(cmd, info, false, "")
|
||||
return printCreate(cmd, info, false, "", outputFormat)
|
||||
}
|
||||
|
||||
// Get bip39 mnemonic
|
||||
@ -276,15 +283,14 @@ func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *buf
|
||||
mnemonic = ""
|
||||
}
|
||||
|
||||
return printCreate(cmd, info, showMnemonic, mnemonic)
|
||||
return printCreate(cmd, info, showMnemonic, mnemonic, outputFormat)
|
||||
}
|
||||
|
||||
func printCreate(cmd *cobra.Command, info keyring.Info, showMnemonic bool, mnemonic string) error {
|
||||
output, _ := cmd.Flags().GetString(cli.OutputFlag)
|
||||
switch output {
|
||||
func printCreate(cmd *cobra.Command, info keyring.Info, showMnemonic bool, mnemonic string, outputFormat string) error {
|
||||
switch outputFormat {
|
||||
case OutputFormatText:
|
||||
cmd.PrintErrln()
|
||||
printKeyInfo(cmd.OutOrStdout(), info, keyring.MkAccKeyOutput, output)
|
||||
printKeyInfo(cmd.OutOrStdout(), info, keyring.MkAccKeyOutput, outputFormat)
|
||||
|
||||
// print mnemonic unless requested not to.
|
||||
if showMnemonic {
|
||||
@ -311,7 +317,7 @@ func printCreate(cmd *cobra.Command, info keyring.Info, showMnemonic bool, mnemo
|
||||
cmd.Println(string(jsonString))
|
||||
|
||||
default:
|
||||
return fmt.Errorf("invalid output format %s", output)
|
||||
return fmt.Errorf("invalid output format %s", outputFormat)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -124,3 +126,66 @@ func Test_runAddCmdLedger(t *testing.T) {
|
||||
"PubKeySecp256k1{034FEF9CD7C4C63588D3B03FEB5281B9D232CBA34D6F3D71AEE59211FFBFE1FE87}",
|
||||
key1.GetPubKey().String())
|
||||
}
|
||||
|
||||
func Test_runAddCmdLedgerDryRun(t *testing.T) {
|
||||
testData := []struct {
|
||||
name string
|
||||
args []string
|
||||
added bool
|
||||
}{
|
||||
{
|
||||
name: "ledger account is added",
|
||||
args: []string{
|
||||
"testkey",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "false"),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagUseLedger, "true"),
|
||||
},
|
||||
added: true,
|
||||
},
|
||||
{
|
||||
name: "ledger account is not added with dry run",
|
||||
args: []string{
|
||||
"testkey",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "true"),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagUseLedger, "true"),
|
||||
},
|
||||
added: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range testData {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cmd := AddKeyCommand()
|
||||
cmd.Flags().AddFlagSet(Commands("home").PersistentFlags())
|
||||
|
||||
kbHome := t.TempDir()
|
||||
mockIn := testutil.ApplyMockIODiscardOutErr(cmd)
|
||||
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
|
||||
require.NoError(t, err)
|
||||
|
||||
clientCtx := client.Context{}.
|
||||
WithKeyringDir(kbHome).
|
||||
WithKeyring(kb)
|
||||
ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx)
|
||||
|
||||
b := bytes.NewBufferString("")
|
||||
cmd.SetOut(b)
|
||||
|
||||
cmd.SetArgs(tt.args)
|
||||
require.NoError(t, cmd.ExecuteContext(ctx))
|
||||
|
||||
if tt.added {
|
||||
_, err = kb.Key("testkey")
|
||||
require.NoError(t, err)
|
||||
|
||||
out, err := ioutil.ReadAll(b)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, string(out), "name: testkey")
|
||||
} else {
|
||||
_, err = kb.Key("testkey")
|
||||
require.Error(t, err)
|
||||
require.Equal(t, "testkey.info: key not found", err.Error())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -13,6 +15,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
@ -114,3 +117,113 @@ func Test_runAddCmdBasic(t *testing.T) {
|
||||
mockIn.Reset("\n" + password + "\n" + "fail" + "\n")
|
||||
require.Error(t, cmd.ExecuteContext(ctx))
|
||||
}
|
||||
|
||||
func Test_runAddCmdDryRun(t *testing.T) {
|
||||
pubkey1 := `{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AtObiFVE4s+9+RX5SP8TN9r2mxpoaT4eGj9CJfK7VRzN"}`
|
||||
pubkey2 := `{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A/se1vkqgdQ7VJQCM4mxN+L+ciGhnnJ4XYsQCRBMrdRi"}`
|
||||
|
||||
testData := []struct {
|
||||
name string
|
||||
args []string
|
||||
added bool
|
||||
}{
|
||||
{
|
||||
name: "account is added",
|
||||
args: []string{
|
||||
"testkey",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "false"),
|
||||
},
|
||||
added: true,
|
||||
},
|
||||
{
|
||||
name: "account is not added with dry run",
|
||||
args: []string{
|
||||
"testkey",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "true"),
|
||||
},
|
||||
added: false,
|
||||
},
|
||||
{
|
||||
name: "multisig account is added",
|
||||
args: []string{
|
||||
"testkey",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "false"),
|
||||
fmt.Sprintf("--%s=%s", flagMultisig, "subkey"),
|
||||
},
|
||||
added: true,
|
||||
},
|
||||
{
|
||||
name: "multisig account is not added with dry run",
|
||||
args: []string{
|
||||
"testkey",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "true"),
|
||||
fmt.Sprintf("--%s=%s", flagMultisig, "subkey"),
|
||||
},
|
||||
added: false,
|
||||
},
|
||||
{
|
||||
name: "pubkey account is added",
|
||||
args: []string{
|
||||
"testkey",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "false"),
|
||||
fmt.Sprintf("--%s=%s", FlagPublicKey, pubkey1),
|
||||
},
|
||||
added: true,
|
||||
},
|
||||
{
|
||||
name: "pubkey account is not added with dry run",
|
||||
args: []string{
|
||||
"testkey",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagDryRun, "true"),
|
||||
fmt.Sprintf("--%s=%s", FlagPublicKey, pubkey2),
|
||||
},
|
||||
added: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range testData {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cmd := AddKeyCommand()
|
||||
cmd.Flags().AddFlagSet(Commands("home").PersistentFlags())
|
||||
|
||||
kbHome := t.TempDir()
|
||||
mockIn := testutil.ApplyMockIODiscardOutErr(cmd)
|
||||
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
|
||||
require.NoError(t, err)
|
||||
|
||||
appCodec := simapp.MakeTestEncodingConfig().Codec
|
||||
clientCtx := client.Context{}.
|
||||
WithCodec(appCodec).
|
||||
WithKeyringDir(kbHome).
|
||||
WithKeyring(kb)
|
||||
ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx)
|
||||
|
||||
path := sdk.GetConfig().GetFullBIP44Path()
|
||||
_, err = kb.NewAccount("subkey", testutil.TestMnemonic, "", path, hd.Secp256k1)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
_ = kb.Delete("subkey")
|
||||
})
|
||||
|
||||
b := bytes.NewBufferString("")
|
||||
cmd.SetOut(b)
|
||||
|
||||
cmd.SetArgs(tt.args)
|
||||
require.NoError(t, cmd.ExecuteContext(ctx))
|
||||
|
||||
if tt.added {
|
||||
_, err = kb.Key("testkey")
|
||||
require.NoError(t, err)
|
||||
|
||||
out, err := ioutil.ReadAll(b)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, string(out), "name: testkey")
|
||||
} else {
|
||||
_, err = kb.Key("testkey")
|
||||
require.Error(t, err)
|
||||
require.Equal(t, "testkey.info: key not found", err.Error())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
67
client/keys/rename.go
Normal file
67
client/keys/rename.go
Normal file
@ -0,0 +1,67 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/input"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// RenameKeyCommand renames a key from the key store.
|
||||
func RenameKeyCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "rename <old_name> <new_name>",
|
||||
Short: "Rename an existing key",
|
||||
Long: `Rename a key from the Keybase backend.
|
||||
|
||||
Note that renaming offline or ledger keys will rename
|
||||
only the public key references stored locally, i.e.
|
||||
private keys stored in a ledger device cannot be renamed with the CLI.
|
||||
`,
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
buf := bufio.NewReader(cmd.InOrStdin())
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oldName, newName := args[0], args[1]
|
||||
|
||||
info, err := clientCtx.Keyring.Key(oldName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// confirm rename, unless -y is passed
|
||||
if skip, _ := cmd.Flags().GetBool(flagYes); !skip {
|
||||
prompt := fmt.Sprintf("Key reference will be renamed from %s to %s. Continue?", args[0], args[1])
|
||||
if yes, err := input.GetConfirmation(prompt, buf, cmd.ErrOrStderr()); err != nil {
|
||||
return err
|
||||
} else if !yes {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if err := clientCtx.Keyring.Rename(oldName, newName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.GetType() == keyring.TypeLedger || info.GetType() == keyring.TypeOffline {
|
||||
cmd.PrintErrln("Public key reference renamed")
|
||||
return nil
|
||||
}
|
||||
|
||||
cmd.PrintErrln(fmt.Sprintf("Key was successfully renamed from %s to %s", oldName, newName))
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().BoolP(flagYes, "y", false, "Skip confirmation prompt when renaming offline or ledger key references")
|
||||
|
||||
return cmd
|
||||
}
|
||||
98
client/keys/rename_test.go
Normal file
98
client/keys/rename_test.go
Normal file
@ -0,0 +1,98 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
func Test_runRenameCmd(t *testing.T) {
|
||||
// temp keybase
|
||||
kbHome := t.TempDir()
|
||||
cmd := RenameKeyCommand()
|
||||
cmd.Flags().AddFlagSet(Commands(kbHome).PersistentFlags())
|
||||
mockIn := testutil.ApplyMockIODiscardOutErr(cmd)
|
||||
|
||||
yesF, _ := cmd.Flags().GetBool(flagYes)
|
||||
require.False(t, yesF)
|
||||
|
||||
fakeKeyName1 := "runRenameCmd_Key1"
|
||||
fakeKeyName2 := "runRenameCmd_Key2"
|
||||
|
||||
path := sdk.GetConfig().GetFullBIP44Path()
|
||||
|
||||
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, kbHome, mockIn)
|
||||
require.NoError(t, err)
|
||||
|
||||
// put fakeKeyName1 in keyring
|
||||
_, err = kb.NewAccount(fakeKeyName1, testutil.TestMnemonic, "", path, hd.Secp256k1)
|
||||
require.NoError(t, err)
|
||||
|
||||
clientCtx := client.Context{}.
|
||||
WithKeyringDir(kbHome).
|
||||
WithKeyring(kb)
|
||||
|
||||
ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx)
|
||||
|
||||
// rename a key 'blah' which doesnt exist
|
||||
cmd.SetArgs([]string{"blah", "blaah", fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome)})
|
||||
err = cmd.ExecuteContext(ctx)
|
||||
require.Error(t, err)
|
||||
require.EqualError(t, err, "blah.info: key not found")
|
||||
|
||||
// User confirmation missing
|
||||
cmd.SetArgs([]string{
|
||||
fakeKeyName1,
|
||||
"nokey",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
|
||||
})
|
||||
err = cmd.Execute()
|
||||
require.Error(t, err)
|
||||
require.Equal(t, "EOF", err.Error())
|
||||
|
||||
oldKey, err := kb.Key(fakeKeyName1)
|
||||
require.NoError(t, err)
|
||||
|
||||
// add a confirmation
|
||||
cmd.SetArgs([]string{
|
||||
fakeKeyName1,
|
||||
fakeKeyName2,
|
||||
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
|
||||
fmt.Sprintf("--%s=true", flagYes),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
|
||||
})
|
||||
require.NoError(t, cmd.Execute())
|
||||
|
||||
// key1 is gone
|
||||
_, err = kb.Key(fakeKeyName1)
|
||||
require.Error(t, err)
|
||||
|
||||
// key2 exists now
|
||||
renamedKey, err := kb.Key(fakeKeyName2)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, oldKey.GetPubKey(), renamedKey.GetPubKey())
|
||||
require.Equal(t, oldKey.GetType(), renamedKey.GetType())
|
||||
require.Equal(t, oldKey.GetAddress(), renamedKey.GetAddress())
|
||||
require.Equal(t, oldKey.GetAlgo(), renamedKey.GetAlgo())
|
||||
|
||||
// try to rename key1 but it doesnt exist anymore so error
|
||||
cmd.SetArgs([]string{
|
||||
fakeKeyName1,
|
||||
fakeKeyName2,
|
||||
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
|
||||
fmt.Sprintf("--%s=true", flagYes),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
|
||||
})
|
||||
require.Error(t, cmd.Execute())
|
||||
}
|
||||
@ -44,8 +44,8 @@ The pass backend requires GnuPG: https://gnupg.org/
|
||||
ImportKeyCommand(),
|
||||
ListKeysCmd(),
|
||||
ShowKeysCmd(),
|
||||
flags.LineBreak,
|
||||
DeleteKeyCommand(),
|
||||
RenameKeyCommand(),
|
||||
ParseKeyStringCommand(),
|
||||
MigrateCommand(),
|
||||
)
|
||||
|
||||
@ -112,7 +112,9 @@ func runShowCmd(cmd *cobra.Command, args []string) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
output, _ := cmd.Flags().GetString(cli.OutputFlag)
|
||||
if isOutputSet {
|
||||
clientCtx.OutputFormat, _ = cmd.Flags().GetString(cli.OutputFlag)
|
||||
}
|
||||
|
||||
switch {
|
||||
case isShowAddr, isShowPubKey:
|
||||
@ -126,7 +128,7 @@ func runShowCmd(cmd *cobra.Command, args []string) (err error) {
|
||||
}
|
||||
fmt.Fprintln(cmd.OutOrStdout(), out)
|
||||
default:
|
||||
printKeyInfo(cmd.OutOrStdout(), info, bechKeyOut, output)
|
||||
printKeyInfo(cmd.OutOrStdout(), info, bechKeyOut, clientCtx.OutputFormat)
|
||||
}
|
||||
|
||||
if isShowDevice {
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// DeprecationURL is the URL for migrating deprecated REST endpoints to newer ones.
|
||||
// TODO Switch to `/` (not `/master`) once v0.40 docs are deployed.
|
||||
// https://github.com/cosmos/cosmos-sdk/issues/8019
|
||||
const DeprecationURL = "https://docs.cosmos.network/master/migrations/rest.html"
|
||||
|
||||
// addHTTPDeprecationHeaders is a mux middleware function for adding HTTP
|
||||
// Deprecation headers to a http handler
|
||||
func addHTTPDeprecationHeaders(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Deprecation", "true")
|
||||
w.Header().Set("Link", "<"+DeprecationURL+">; rel=\"deprecation\"")
|
||||
w.Header().Set("Warning", "199 - \"this endpoint is deprecated and may not work as before, see deprecation link for more info\"")
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// WithHTTPDeprecationHeaders returns a new *mux.Router, identical to its input
|
||||
// but with the addition of HTTP Deprecation headers. This is used to mark legacy
|
||||
// amino REST endpoints as deprecated in the REST API.
|
||||
// nolint: gocritic
|
||||
func WithHTTPDeprecationHeaders(r *mux.Router) *mux.Router {
|
||||
subRouter := r.NewRoute().Subrouter()
|
||||
subRouter.Use(addHTTPDeprecationHeaders)
|
||||
return subRouter
|
||||
}
|
||||
@ -3,16 +3,13 @@ package rpc
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
)
|
||||
|
||||
// BlockCommand returns the verified block data for a given heights
|
||||
@ -88,47 +85,3 @@ func GetChainHeight(clientCtx client.Context) (int64, error) {
|
||||
height := status.SyncInfo.LatestBlockHeight
|
||||
return height, nil
|
||||
}
|
||||
|
||||
// REST handler to get a block
|
||||
func BlockRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
|
||||
height, err := strconv.ParseInt(vars["height"], 10, 64)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest,
|
||||
"couldn't parse block height. Assumed format is '/block/{height}'.")
|
||||
return
|
||||
}
|
||||
|
||||
chainHeight, err := GetChainHeight(clientCtx)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, "failed to parse chain height")
|
||||
return
|
||||
}
|
||||
|
||||
if height > chainHeight {
|
||||
rest.WriteErrorResponse(w, http.StatusNotFound, "requested block height is bigger then the chain length")
|
||||
return
|
||||
}
|
||||
|
||||
output, err := getBlock(clientCtx, &height)
|
||||
if rest.CheckInternalServerError(w, err) {
|
||||
return
|
||||
}
|
||||
|
||||
rest.PostProcessResponseBare(w, clientCtx, output)
|
||||
}
|
||||
}
|
||||
|
||||
// REST handler to get the latest block
|
||||
func LatestBlockRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
output, err := getBlock(clientCtx, nil)
|
||||
if rest.CheckInternalServerError(w, err) {
|
||||
return
|
||||
}
|
||||
|
||||
rest.PostProcessResponseBare(w, clientCtx, output)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
)
|
||||
|
||||
// Register REST endpoints.
|
||||
func RegisterRoutes(clientCtx client.Context, r *mux.Router) {
|
||||
r.HandleFunc("/node_info", NodeInfoRequestHandlerFn(clientCtx)).Methods("GET")
|
||||
r.HandleFunc("/syncing", NodeSyncingRequestHandlerFn(clientCtx)).Methods("GET")
|
||||
r.HandleFunc("/blocks/latest", LatestBlockRequestHandlerFn(clientCtx)).Methods("GET")
|
||||
r.HandleFunc("/blocks/{height}", BlockRequestHandlerFn(clientCtx)).Methods("GET")
|
||||
r.HandleFunc("/validatorsets/latest", LatestValidatorSetRequestHandlerFn(clientCtx)).Methods("GET")
|
||||
r.HandleFunc("/validatorsets/{height}", ValidatorSetRequestHandlerFn(clientCtx)).Methods("GET")
|
||||
}
|
||||
@ -5,13 +5,10 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/rpc"
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/network"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
)
|
||||
|
||||
type IntegrationTestSuite struct {
|
||||
@ -23,8 +20,9 @@ type IntegrationTestSuite struct {
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
s.T().Log("setting up integration test suite")
|
||||
|
||||
s.network = network.New(s.T(), network.DefaultConfig())
|
||||
s.Require().NotNil(s.network)
|
||||
var err error
|
||||
s.network, err = network.New(s.T(), s.T().TempDir(), network.DefaultConfig())
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().NoError(s.network.WaitForNextBlock())
|
||||
}
|
||||
@ -45,17 +43,6 @@ func (s *IntegrationTestSuite) TestStatusCommand() {
|
||||
s.Require().Contains(out.String(), fmt.Sprintf("\"moniker\":\"%s\"", val0.Moniker))
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestLatestBlocks() {
|
||||
val0 := s.network.Validators[0]
|
||||
|
||||
res, err := rest.GetRequest(fmt.Sprintf("%s/blocks/latest", val0.APIAddress))
|
||||
s.Require().NoError(err)
|
||||
|
||||
var result ctypes.ResultBlock
|
||||
err = legacy.Cdc.UnmarshalJSON(res, &result)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func TestIntegrationTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(IntegrationTestSuite))
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
@ -14,8 +13,6 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
)
|
||||
|
||||
// ValidatorInfo is info about the node's validator, same as Tendermint,
|
||||
@ -88,45 +85,3 @@ func getNodeStatus(clientCtx client.Context) (*ctypes.ResultStatus, error) {
|
||||
|
||||
return node.Status(context.Background())
|
||||
}
|
||||
|
||||
// NodeInfoResponse defines a response type that contains node status and version
|
||||
// information.
|
||||
type NodeInfoResponse struct {
|
||||
p2p.DefaultNodeInfo `json:"node_info"`
|
||||
|
||||
ApplicationVersion version.Info `json:"application_version"`
|
||||
}
|
||||
|
||||
// REST handler for node info
|
||||
func NodeInfoRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
status, err := getNodeStatus(clientCtx)
|
||||
if rest.CheckInternalServerError(w, err) {
|
||||
return
|
||||
}
|
||||
|
||||
resp := NodeInfoResponse{
|
||||
DefaultNodeInfo: status.NodeInfo,
|
||||
ApplicationVersion: version.NewInfo(),
|
||||
}
|
||||
|
||||
rest.PostProcessResponseBare(w, clientCtx, resp)
|
||||
}
|
||||
}
|
||||
|
||||
// SyncingResponse defines a response type that contains node syncing information.
|
||||
type SyncingResponse struct {
|
||||
Syncing bool `json:"syncing"`
|
||||
}
|
||||
|
||||
// REST handler for node syncing
|
||||
func NodeSyncingRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
status, err := getNodeStatus(clientCtx)
|
||||
if rest.CheckInternalServerError(w, err) {
|
||||
return
|
||||
}
|
||||
|
||||
rest.PostProcessResponseBare(w, clientCtx, SyncingResponse{Syncing: status.SyncInfo.CatchingUp})
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,11 +3,9 @@ package rpc
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
@ -16,7 +14,7 @@ import (
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
"github.com/cosmos/cosmos-sdk/types/query"
|
||||
)
|
||||
|
||||
// TODO these next two functions feel kinda hacky based on their placement
|
||||
@ -60,7 +58,7 @@ func ValidatorCommand() *cobra.Command {
|
||||
|
||||
cmd.Flags().StringP(flags.FlagNode, "n", "tcp://localhost:26657", "Node to connect to")
|
||||
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
|
||||
cmd.Flags().Int(flags.FlagPage, rest.DefaultPage, "Query a specific page of paginated results")
|
||||
cmd.Flags().Int(flags.FlagPage, query.DefaultPage, "Query a specific page of paginated results")
|
||||
cmd.Flags().Int(flags.FlagLimit, 100, "Query number of results returned per page")
|
||||
|
||||
return cmd
|
||||
@ -148,57 +146,3 @@ func GetValidators(ctx context.Context, clientCtx client.Context, height *int64,
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// REST
|
||||
|
||||
// Validator Set at a height REST handler
|
||||
func ValidatorSetRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 100)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse pagination parameters")
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
height, err := strconv.ParseInt(vars["height"], 10, 64)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse block height")
|
||||
return
|
||||
}
|
||||
|
||||
chainHeight, err := GetChainHeight(clientCtx)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, "failed to parse chain height")
|
||||
return
|
||||
}
|
||||
if height > chainHeight {
|
||||
rest.WriteErrorResponse(w, http.StatusNotFound, "requested block height is bigger then the chain length")
|
||||
return
|
||||
}
|
||||
|
||||
output, err := GetValidators(r.Context(), clientCtx, &height, &page, &limit)
|
||||
if rest.CheckInternalServerError(w, err) {
|
||||
return
|
||||
}
|
||||
rest.PostProcessResponse(w, clientCtx, output)
|
||||
}
|
||||
}
|
||||
|
||||
// Latest Validator Set REST handler
|
||||
func LatestValidatorSetRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 100)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse pagination parameters")
|
||||
return
|
||||
}
|
||||
|
||||
output, err := GetValidators(r.Context(), clientCtx, nil, &page, &limit)
|
||||
if rest.CheckInternalServerError(w, err) {
|
||||
return
|
||||
}
|
||||
|
||||
rest.PostProcessResponse(w, clientCtx, output)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,16 @@
|
||||
package tx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
)
|
||||
@ -44,7 +49,7 @@ func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) Factory {
|
||||
accNum, _ := flagSet.GetUint64(flags.FlagAccountNumber)
|
||||
accSeq, _ := flagSet.GetUint64(flags.FlagSequence)
|
||||
gasAdj, _ := flagSet.GetFloat64(flags.FlagGasAdjustment)
|
||||
memo, _ := flagSet.GetString(flags.FlagMemo)
|
||||
memo, _ := flagSet.GetString(flags.FlagNote)
|
||||
timeoutHeight, _ := flagSet.GetUint64(flags.FlagTimeoutHeight)
|
||||
|
||||
gasStr, _ := flagSet.GetString(flags.FlagGas)
|
||||
@ -189,3 +194,132 @@ func (f Factory) WithTimeoutHeight(height uint64) Factory {
|
||||
f.timeoutHeight = height
|
||||
return f
|
||||
}
|
||||
|
||||
// BuildUnsignedTx builds a transaction to be signed given a set of messages.
|
||||
// Once created, the fee, memo, and messages are set.
|
||||
func (f Factory) BuildUnsignedTx(msgs ...sdk.Msg) (client.TxBuilder, error) {
|
||||
if f.chainID == "" {
|
||||
return nil, fmt.Errorf("chain ID required but not specified")
|
||||
}
|
||||
|
||||
fees := f.fees
|
||||
|
||||
if !f.gasPrices.IsZero() {
|
||||
if !fees.IsZero() {
|
||||
return nil, errors.New("cannot provide both fees and gas prices")
|
||||
}
|
||||
|
||||
glDec := sdk.NewDec(int64(f.gas))
|
||||
|
||||
// Derive the fees based on the provided gas prices, where
|
||||
// fee = ceil(gasPrice * gasLimit).
|
||||
fees = make(sdk.Coins, len(f.gasPrices))
|
||||
|
||||
for i, gp := range f.gasPrices {
|
||||
fee := gp.Amount.Mul(glDec)
|
||||
fees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt())
|
||||
}
|
||||
}
|
||||
|
||||
tx := f.txConfig.NewTxBuilder()
|
||||
|
||||
if err := tx.SetMsgs(msgs...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tx.SetMemo(f.memo)
|
||||
tx.SetFeeAmount(fees)
|
||||
tx.SetGasLimit(f.gas)
|
||||
tx.SetTimeoutHeight(f.TimeoutHeight())
|
||||
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// PrintUnsignedTx will generate an unsigned transaction and print it to the writer
|
||||
// specified by ctx.Output. If simulation was requested, the gas will be
|
||||
// simulated and also printed to the same writer before the transaction is
|
||||
// printed.
|
||||
func (f Factory) PrintUnsignedTx(clientCtx client.Context, msgs ...sdk.Msg) error {
|
||||
if f.SimulateAndExecute() {
|
||||
if clientCtx.Offline {
|
||||
return errors.New("cannot estimate gas in offline mode")
|
||||
}
|
||||
|
||||
_, adjusted, err := CalculateGas(clientCtx, f, msgs...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f = f.WithGas(adjusted)
|
||||
_, _ = fmt.Fprintf(os.Stderr, "%s\n", GasEstimateResponse{GasEstimate: f.Gas()})
|
||||
}
|
||||
|
||||
tx, err := f.BuildUnsignedTx(msgs...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
json, err := clientCtx.TxConfig.TxJSONEncoder()(tx.GetTx())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintString(fmt.Sprintf("%s\n", json))
|
||||
}
|
||||
|
||||
// BuildSimTx creates an unsigned tx with an empty single signature and returns
|
||||
// the encoded transaction or an error if the unsigned transaction cannot be
|
||||
// built.
|
||||
func (f Factory) BuildSimTx(msgs ...sdk.Msg) ([]byte, error) {
|
||||
txb, err := f.BuildUnsignedTx(msgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create an empty signature literal as the ante handler will populate with a
|
||||
// sentinel pubkey.
|
||||
sig := signing.SignatureV2{
|
||||
PubKey: &secp256k1.PubKey{},
|
||||
Data: &signing.SingleSignatureData{
|
||||
SignMode: f.signMode,
|
||||
},
|
||||
Sequence: f.Sequence(),
|
||||
}
|
||||
if err := txb.SetSignatures(sig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return f.txConfig.TxEncoder()(txb.GetTx())
|
||||
}
|
||||
|
||||
// Prepare ensures the account defined by ctx.GetFromAddress() exists and
|
||||
// if the account number and/or the account sequence number are zero (not set),
|
||||
// they will be queried for and set on the provided Factory. A new Factory with
|
||||
// the updated fields will be returned.
|
||||
func (f Factory) Prepare(clientCtx client.Context) (Factory, error) {
|
||||
fc := f
|
||||
|
||||
from := clientCtx.GetFromAddress()
|
||||
|
||||
if err := fc.accountRetriever.EnsureExists(clientCtx, from); err != nil {
|
||||
return fc, err
|
||||
}
|
||||
|
||||
initNum, initSeq := fc.accountNumber, fc.sequence
|
||||
if initNum == 0 || initSeq == 0 {
|
||||
num, seq, err := fc.accountRetriever.GetAccountNumberSequence(clientCtx, from)
|
||||
if err != nil {
|
||||
return fc, err
|
||||
}
|
||||
|
||||
if initNum == 0 {
|
||||
fc = fc.WithAccountNumber(num)
|
||||
}
|
||||
|
||||
if initSeq == 0 {
|
||||
fc = fc.WithSequence(seq)
|
||||
}
|
||||
}
|
||||
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
)
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
signing2 "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
@ -103,7 +103,7 @@ func (s *TestSuite) TestCopyTx() {
|
||||
s.Require().Equal(sigsV2_1, sigsV2_2)
|
||||
s.Require().Equal(aminoBuilder.GetTx().GetSigners(), aminoBuilder2.GetTx().GetSigners())
|
||||
s.Require().Equal(aminoBuilder.GetTx().GetMsgs()[0], aminoBuilder2.GetTx().GetMsgs()[0])
|
||||
s.Require().Equal(aminoBuilder.GetTx().GetMsgs()[1], aminoBuilder2.GetTx().GetMsgs()[1]) // We lose the "ServiceMsg" information
|
||||
s.Require().Equal(aminoBuilder.GetTx().GetMsgs()[1], aminoBuilder2.GetTx().GetMsgs()[1])
|
||||
}
|
||||
|
||||
func (s *TestSuite) TestConvertTxToStdTx() {
|
||||
|
||||
219
client/tx/tx.go
219
client/tx/tx.go
@ -5,20 +5,16 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
gogogrpc "github.com/gogo/protobuf/grpc"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/client/input"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
@ -34,50 +30,28 @@ func GenerateOrBroadcastTxCLI(clientCtx client.Context, flagSet *pflag.FlagSet,
|
||||
// GenerateOrBroadcastTxWithFactory will either generate and print and unsigned transaction
|
||||
// or sign it and broadcast it returning an error upon failure.
|
||||
func GenerateOrBroadcastTxWithFactory(clientCtx client.Context, txf Factory, msgs ...sdk.Msg) error {
|
||||
// Validate all msgs before generating or broadcasting the tx.
|
||||
// We were calling ValidateBasic separately in each CLI handler before.
|
||||
// Right now, we're factorizing that call inside this function.
|
||||
// ref: https://github.com/cosmos/cosmos-sdk/pull/9236#discussion_r623803504
|
||||
for _, msg := range msgs {
|
||||
if err := tx.ValidateMsg(msg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if clientCtx.GenerateOnly {
|
||||
return GenerateTx(clientCtx, txf, msgs...)
|
||||
return txf.PrintUnsignedTx(clientCtx, msgs...)
|
||||
}
|
||||
|
||||
return BroadcastTx(clientCtx, txf, msgs...)
|
||||
}
|
||||
|
||||
// GenerateTx will generate an unsigned transaction and print it to the writer
|
||||
// specified by ctx.Output. If simulation was requested, the gas will be
|
||||
// simulated and also printed to the same writer before the transaction is
|
||||
// printed.
|
||||
func GenerateTx(clientCtx client.Context, txf Factory, msgs ...sdk.Msg) error {
|
||||
if txf.SimulateAndExecute() {
|
||||
if clientCtx.Offline {
|
||||
return errors.New("cannot estimate gas in offline mode")
|
||||
}
|
||||
|
||||
_, adjusted, err := CalculateGas(clientCtx, txf, msgs...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txf = txf.WithGas(adjusted)
|
||||
_, _ = fmt.Fprintf(os.Stderr, "%s\n", GasEstimateResponse{GasEstimate: txf.Gas()})
|
||||
}
|
||||
|
||||
tx, err := BuildUnsignedTx(txf, msgs...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
json, err := clientCtx.TxConfig.TxJSONEncoder()(tx.GetTx())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintString(fmt.Sprintf("%s\n", json))
|
||||
}
|
||||
|
||||
// BroadcastTx attempts to generate, sign and broadcast a transaction with the
|
||||
// given set of messages. It will also simulate gas requirements if necessary.
|
||||
// It will return an error upon failure.
|
||||
func BroadcastTx(clientCtx client.Context, txf Factory, msgs ...sdk.Msg) error {
|
||||
txf, err := prepareFactory(clientCtx, txf)
|
||||
txf, err := txf.Prepare(clientCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -96,7 +70,7 @@ func BroadcastTx(clientCtx client.Context, txf Factory, msgs ...sdk.Msg) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
tx, err := BuildUnsignedTx(txf, msgs...)
|
||||
tx, err := txf.BuildUnsignedTx(msgs...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -138,147 +112,12 @@ func BroadcastTx(clientCtx client.Context, txf Factory, msgs ...sdk.Msg) error {
|
||||
return clientCtx.PrintProto(res)
|
||||
}
|
||||
|
||||
// WriteGeneratedTxResponse writes a generated unsigned transaction to the
|
||||
// provided http.ResponseWriter. It will simulate gas costs if requested by the
|
||||
// BaseReq. Upon any error, the error will be written to the http.ResponseWriter.
|
||||
// Note that this function returns the legacy StdTx Amino JSON format for compatibility
|
||||
// with legacy clients.
|
||||
// Deprecated: We are removing Amino soon.
|
||||
func WriteGeneratedTxResponse(
|
||||
clientCtx client.Context, w http.ResponseWriter, br rest.BaseReq, msgs ...sdk.Msg,
|
||||
) {
|
||||
gasAdj, ok := rest.ParseFloat64OrReturnBadRequest(w, br.GasAdjustment, flags.DefaultGasAdjustment)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
gasSetting, err := flags.ParseGasSetting(br.Gas)
|
||||
if rest.CheckBadRequestError(w, err) {
|
||||
return
|
||||
}
|
||||
|
||||
txf := Factory{fees: br.Fees, gasPrices: br.GasPrices}.
|
||||
WithAccountNumber(br.AccountNumber).
|
||||
WithSequence(br.Sequence).
|
||||
WithGas(gasSetting.Gas).
|
||||
WithGasAdjustment(gasAdj).
|
||||
WithMemo(br.Memo).
|
||||
WithChainID(br.ChainID).
|
||||
WithSimulateAndExecute(br.Simulate).
|
||||
WithTxConfig(clientCtx.TxConfig).
|
||||
WithTimeoutHeight(br.TimeoutHeight)
|
||||
|
||||
if br.Simulate || gasSetting.Simulate {
|
||||
if gasAdj < 0 {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, sdkerrors.ErrorInvalidGasAdjustment.Error())
|
||||
return
|
||||
}
|
||||
|
||||
_, adjusted, err := CalculateGas(clientCtx, txf, msgs...)
|
||||
if rest.CheckInternalServerError(w, err) {
|
||||
return
|
||||
}
|
||||
|
||||
txf = txf.WithGas(adjusted)
|
||||
|
||||
if br.Simulate {
|
||||
rest.WriteSimulationResponse(w, clientCtx.LegacyAmino, txf.Gas())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
tx, err := BuildUnsignedTx(txf, msgs...)
|
||||
if rest.CheckBadRequestError(w, err) {
|
||||
return
|
||||
}
|
||||
|
||||
stdTx, err := ConvertTxToStdTx(clientCtx.LegacyAmino, tx.GetTx())
|
||||
if rest.CheckInternalServerError(w, err) {
|
||||
return
|
||||
}
|
||||
|
||||
output, err := clientCtx.LegacyAmino.MarshalJSON(stdTx)
|
||||
if rest.CheckInternalServerError(w, err) {
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(output)
|
||||
}
|
||||
|
||||
// BuildUnsignedTx builds a transaction to be signed given a set of messages. The
|
||||
// transaction is initially created via the provided factory's generator. Once
|
||||
// created, the fee, memo, and messages are set.
|
||||
func BuildUnsignedTx(txf Factory, msgs ...sdk.Msg) (client.TxBuilder, error) {
|
||||
if txf.chainID == "" {
|
||||
return nil, fmt.Errorf("chain ID required but not specified")
|
||||
}
|
||||
|
||||
fees := txf.fees
|
||||
|
||||
if !txf.gasPrices.IsZero() {
|
||||
if !fees.IsZero() {
|
||||
return nil, errors.New("cannot provide both fees and gas prices")
|
||||
}
|
||||
|
||||
glDec := sdk.NewDec(int64(txf.gas))
|
||||
|
||||
// Derive the fees based on the provided gas prices, where
|
||||
// fee = ceil(gasPrice * gasLimit).
|
||||
fees = make(sdk.Coins, len(txf.gasPrices))
|
||||
|
||||
for i, gp := range txf.gasPrices {
|
||||
fee := gp.Amount.Mul(glDec)
|
||||
fees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt())
|
||||
}
|
||||
}
|
||||
|
||||
tx := txf.txConfig.NewTxBuilder()
|
||||
|
||||
if err := tx.SetMsgs(msgs...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tx.SetMemo(txf.memo)
|
||||
tx.SetFeeAmount(fees)
|
||||
tx.SetGasLimit(txf.gas)
|
||||
tx.SetTimeoutHeight(txf.TimeoutHeight())
|
||||
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// BuildSimTx creates an unsigned tx with an empty single signature and returns
|
||||
// the encoded transaction or an error if the unsigned transaction cannot be
|
||||
// built.
|
||||
func BuildSimTx(txf Factory, msgs ...sdk.Msg) ([]byte, error) {
|
||||
txb, err := BuildUnsignedTx(txf, msgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create an empty signature literal as the ante handler will populate with a
|
||||
// sentinel pubkey.
|
||||
sig := signing.SignatureV2{
|
||||
PubKey: &secp256k1.PubKey{},
|
||||
Data: &signing.SingleSignatureData{
|
||||
SignMode: txf.signMode,
|
||||
},
|
||||
Sequence: txf.Sequence(),
|
||||
}
|
||||
if err := txb.SetSignatures(sig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return txf.txConfig.TxEncoder()(txb.GetTx())
|
||||
}
|
||||
|
||||
// CalculateGas simulates the execution of a transaction and returns the
|
||||
// simulation response obtained by the query and the adjusted gas amount.
|
||||
func CalculateGas(
|
||||
clientCtx gogogrpc.ClientConn, txf Factory, msgs ...sdk.Msg,
|
||||
) (*tx.SimulateResponse, uint64, error) {
|
||||
txBytes, err := BuildSimTx(txf, msgs...)
|
||||
txBytes, err := txf.BuildSimTx(msgs...)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
@ -294,36 +133,6 @@ func CalculateGas(
|
||||
return simRes, uint64(txf.GasAdjustment() * float64(simRes.GasInfo.GasUsed)), nil
|
||||
}
|
||||
|
||||
// prepareFactory ensures the account defined by ctx.GetFromAddress() exists and
|
||||
// if the account number and/or the account sequence number are zero (not set),
|
||||
// they will be queried for and set on the provided Factory. A new Factory with
|
||||
// the updated fields will be returned.
|
||||
func prepareFactory(clientCtx client.Context, txf Factory) (Factory, error) {
|
||||
from := clientCtx.GetFromAddress()
|
||||
|
||||
if err := txf.accountRetriever.EnsureExists(clientCtx, from); err != nil {
|
||||
return txf, err
|
||||
}
|
||||
|
||||
initNum, initSeq := txf.accountNumber, txf.sequence
|
||||
if initNum == 0 || initSeq == 0 {
|
||||
num, seq, err := txf.accountRetriever.GetAccountNumberSequence(clientCtx, from)
|
||||
if err != nil {
|
||||
return txf, err
|
||||
}
|
||||
|
||||
if initNum == 0 {
|
||||
txf = txf.WithAccountNumber(num)
|
||||
}
|
||||
|
||||
if initSeq == 0 {
|
||||
txf = txf.WithSequence(seq)
|
||||
}
|
||||
}
|
||||
|
||||
return txf, nil
|
||||
}
|
||||
|
||||
// SignWithPrivKey signs a given tx with the given private key, and returns the
|
||||
// corresponding SignatureV2 if the signing is successful.
|
||||
func SignWithPrivKey(
|
||||
|
||||
@ -107,7 +107,7 @@ func TestBuildSimTx(t *testing.T) {
|
||||
WithSignMode(txCfg.SignModeHandler().DefaultMode())
|
||||
|
||||
msg := banktypes.NewMsgSend(sdk.AccAddress("from"), sdk.AccAddress("to"), nil)
|
||||
bz, err := tx.BuildSimTx(txf, msg)
|
||||
bz, err := txf.BuildSimTx(msg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, bz)
|
||||
}
|
||||
@ -122,7 +122,7 @@ func TestBuildUnsignedTx(t *testing.T) {
|
||||
WithChainID("test-chain")
|
||||
|
||||
msg := banktypes.NewMsgSend(sdk.AccAddress("from"), sdk.AccAddress("to"), nil)
|
||||
tx, err := tx.BuildUnsignedTx(txf, msg)
|
||||
tx, err := txf.BuildUnsignedTx(msg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, tx)
|
||||
|
||||
@ -169,11 +169,11 @@ func TestSign(t *testing.T) {
|
||||
WithSignMode(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
|
||||
msg1 := banktypes.NewMsgSend(info1.GetAddress(), sdk.AccAddress("to"), nil)
|
||||
msg2 := banktypes.NewMsgSend(info2.GetAddress(), sdk.AccAddress("to"), nil)
|
||||
txb, err := tx.BuildUnsignedTx(txfNoKeybase, msg1, msg2)
|
||||
txb, err := txfNoKeybase.BuildUnsignedTx(msg1, msg2)
|
||||
requireT.NoError(err)
|
||||
txb2, err := tx.BuildUnsignedTx(txfNoKeybase, msg1, msg2)
|
||||
txb2, err := txfNoKeybase.BuildUnsignedTx(msg1, msg2)
|
||||
requireT.NoError(err)
|
||||
txbSimple, err := tx.BuildUnsignedTx(txfNoKeybase, msg2)
|
||||
txbSimple, err := txfNoKeybase.BuildUnsignedTx(msg2)
|
||||
requireT.NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
|
||||
@ -57,25 +57,25 @@ func (ac *AminoCodec) MustUnmarshalLengthPrefixed(bz []byte, ptr ProtoMarshaler)
|
||||
ac.LegacyAmino.MustUnmarshalLengthPrefixed(bz, ptr)
|
||||
}
|
||||
|
||||
// MarshalJSON implements JSONMarshaler.MarshalJSON method,
|
||||
// MarshalJSON implements JSONCodec.MarshalJSON method,
|
||||
// it marshals to JSON using legacy amino codec.
|
||||
func (ac *AminoCodec) MarshalJSON(o proto.Message) ([]byte, error) {
|
||||
return ac.LegacyAmino.MarshalJSON(o)
|
||||
}
|
||||
|
||||
// MustMarshalJSON implements JSONMarshaler.MustMarshalJSON method,
|
||||
// MustMarshalJSON implements JSONCodec.MustMarshalJSON method,
|
||||
// it executes MarshalJSON except it panics upon failure.
|
||||
func (ac *AminoCodec) MustMarshalJSON(o proto.Message) []byte {
|
||||
return ac.LegacyAmino.MustMarshalJSON(o)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements JSONMarshaler.UnmarshalJSON method,
|
||||
// UnmarshalJSON implements JSONCodec.UnmarshalJSON method,
|
||||
// it unmarshals from JSON using legacy amino codec.
|
||||
func (ac *AminoCodec) UnmarshalJSON(bz []byte, ptr proto.Message) error {
|
||||
return ac.LegacyAmino.UnmarshalJSON(bz, ptr)
|
||||
}
|
||||
|
||||
// MustUnmarshalJSON implements JSONMarshaler.MustUnmarshalJSON method,
|
||||
// MustUnmarshalJSON implements JSONCodec.MustUnmarshalJSON method,
|
||||
// it executes UnmarshalJSON except it panics upon failure.
|
||||
func (ac *AminoCodec) MustUnmarshalJSON(bz []byte, ptr proto.Message) {
|
||||
ac.LegacyAmino.MustUnmarshalJSON(bz, ptr)
|
||||
|
||||
@ -11,8 +11,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
|
||||
)
|
||||
|
||||
func createTestCodec() *codec.LegacyAmino {
|
||||
@ -130,12 +129,4 @@ func TestAminoCodecFullDecodeAndEncode(t *testing.T) {
|
||||
marshaledTx, err := legacyCdc.MarshalJSON(tx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, string(marshaledTx), txSigned)
|
||||
|
||||
// Marshalling/unmarshalling the tx wrapped in a struct should work.
|
||||
txRequest := &rest.BroadcastReq{
|
||||
Mode: "block",
|
||||
Tx: tx,
|
||||
}
|
||||
_, err = legacyCdc.MarshalJSON(txRequest)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@ -68,11 +68,11 @@ func TestMarshalProtoPubKey(t *testing.T) {
|
||||
|
||||
pkAny, err := codectypes.NewAnyWithValue(pk)
|
||||
require.NoError(err)
|
||||
bz, err := ccfg.Marshaler.MarshalJSON(pkAny)
|
||||
bz, err := ccfg.Codec.MarshalJSON(pkAny)
|
||||
require.NoError(err)
|
||||
|
||||
var pkAny2 codectypes.Any
|
||||
err = ccfg.Marshaler.UnmarshalJSON(bz, &pkAny2)
|
||||
err = ccfg.Codec.UnmarshalJSON(bz, &pkAny2)
|
||||
require.NoError(err)
|
||||
// Before getting a cached value we need to unpack it.
|
||||
// Normally this happens in types which implement UnpackInterfaces
|
||||
@ -84,11 +84,11 @@ func TestMarshalProtoPubKey(t *testing.T) {
|
||||
|
||||
// **** test binary serialization ****
|
||||
|
||||
bz, err = ccfg.Marshaler.Marshal(pkAny)
|
||||
bz, err = ccfg.Codec.Marshal(pkAny)
|
||||
require.NoError(err)
|
||||
|
||||
var pkAny3 codectypes.Any
|
||||
err = ccfg.Marshaler.Unmarshal(bz, &pkAny3)
|
||||
err = ccfg.Codec.Unmarshal(bz, &pkAny3)
|
||||
require.NoError(err)
|
||||
err = ccfg.InterfaceRegistry.UnpackAny(&pkAny3, &pkI)
|
||||
require.NoError(err)
|
||||
@ -106,31 +106,31 @@ func TestMarshalProtoInterfacePubKey(t *testing.T) {
|
||||
|
||||
// **** test JSON serialization ****
|
||||
|
||||
bz, err := ccfg.Marshaler.MarshalInterfaceJSON(pk)
|
||||
bz, err := ccfg.Codec.MarshalInterfaceJSON(pk)
|
||||
require.NoError(err)
|
||||
|
||||
var pk3 cryptotypes.PubKey
|
||||
err = ccfg.Marshaler.UnmarshalInterfaceJSON(bz, &pk3)
|
||||
err = ccfg.Codec.UnmarshalInterfaceJSON(bz, &pk3)
|
||||
require.NoError(err)
|
||||
require.True(pk3.Equals(pk))
|
||||
|
||||
// ** Check unmarshal using JSONMarshaler **
|
||||
// ** Check unmarshal using JSONCodec **
|
||||
// Unpacking won't work straightforward s Any type
|
||||
// Any can't implement UnpackInterfacesMessage interface. So Any is not
|
||||
// automatically unpacked and we won't get a value.
|
||||
var pkAny codectypes.Any
|
||||
err = ccfg.Marshaler.UnmarshalJSON(bz, &pkAny)
|
||||
err = ccfg.Codec.UnmarshalJSON(bz, &pkAny)
|
||||
require.NoError(err)
|
||||
ifc := pkAny.GetCachedValue()
|
||||
require.Nil(ifc)
|
||||
|
||||
// **** test binary serialization ****
|
||||
|
||||
bz, err = ccfg.Marshaler.MarshalInterface(pk)
|
||||
bz, err = ccfg.Codec.MarshalInterface(pk)
|
||||
require.NoError(err)
|
||||
|
||||
var pk2 cryptotypes.PubKey
|
||||
err = ccfg.Marshaler.UnmarshalInterface(bz, &pk2)
|
||||
err = ccfg.Codec.UnmarshalInterface(bz, &pk2)
|
||||
require.NoError(err)
|
||||
require.True(pk2.Equals(pk))
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ func (pc *ProtoCodec) MustUnmarshalLengthPrefixed(bz []byte, ptr ProtoMarshaler)
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON implements JSONMarshaler.MarshalJSON method,
|
||||
// MarshalJSON implements JSONCodec.MarshalJSON method,
|
||||
// it marshals to JSON using proto codec.
|
||||
// NOTE: this function must be used with a concrete type which
|
||||
// implements proto.Message. For interface please use the codec.MarshalInterfaceJSON
|
||||
@ -135,7 +135,7 @@ func (pc *ProtoCodec) MarshalJSON(o proto.Message) ([]byte, error) {
|
||||
return ProtoMarshalJSON(m, pc.interfaceRegistry)
|
||||
}
|
||||
|
||||
// MustMarshalJSON implements JSONMarshaler.MustMarshalJSON method,
|
||||
// MustMarshalJSON implements JSONCodec.MustMarshalJSON method,
|
||||
// it executes MarshalJSON except it panics upon failure.
|
||||
// NOTE: this function must be used with a concrete type which
|
||||
// implements proto.Message. For interface please use the codec.MarshalInterfaceJSON
|
||||
@ -148,7 +148,7 @@ func (pc *ProtoCodec) MustMarshalJSON(o proto.Message) []byte {
|
||||
return bz
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements JSONMarshaler.UnmarshalJSON method,
|
||||
// UnmarshalJSON implements JSONCodec.UnmarshalJSON method,
|
||||
// it unmarshals from JSON using proto codec.
|
||||
// NOTE: this function must be used with a concrete type which
|
||||
// implements proto.Message. For interface please use the codec.UnmarshalInterfaceJSON
|
||||
@ -167,7 +167,7 @@ func (pc *ProtoCodec) UnmarshalJSON(bz []byte, ptr proto.Message) error {
|
||||
return types.UnpackInterfaces(ptr, pc.interfaceRegistry)
|
||||
}
|
||||
|
||||
// MustUnmarshalJSON implements JSONMarshaler.MustUnmarshalJSON method,
|
||||
// MustUnmarshalJSON implements JSONCodec.MustUnmarshalJSON method,
|
||||
// it executes UnmarshalJSON except it panics upon failure.
|
||||
// NOTE: this function must be used with a concrete type which
|
||||
// implements proto.Message. For interface please use the codec.UnmarshalInterfaceJSON
|
||||
|
||||
@ -7,13 +7,13 @@ import (
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// MarshalYAML marshals toPrint using jsonMarshaler to leverage specialized MarshalJSON methods
|
||||
// MarshalYAML marshals toPrint using JSONCodec to leverage specialized MarshalJSON methods
|
||||
// (usually related to serialize data with protobuf or amin depending on a configuration).
|
||||
// This involves additional roundtrip through JSON.
|
||||
func MarshalYAML(jsonMarshaler JSONCodec, toPrint proto.Message) ([]byte, error) {
|
||||
func MarshalYAML(cdc JSONCodec, toPrint proto.Message) ([]byte, error) {
|
||||
// We are OK with the performance hit of the additional JSON roundtip. MarshalYAML is not
|
||||
// used in any critical parts of the system.
|
||||
bz, err := jsonMarshaler.MarshalJSON(toPrint)
|
||||
bz, err := cdc.MarshalJSON(toPrint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
Installation:
|
||||
|
||||
```
|
||||
$ git config core.hooksPath contrib/githooks
|
||||
git config core.hooksPath contrib/githooks
|
||||
```
|
||||
|
||||
## pre-commit
|
||||
@ -14,8 +14,8 @@ that all the aforementioned commands are installed and available
|
||||
in the user's search `$PATH` environment variable:
|
||||
|
||||
```
|
||||
$ go get golang.org/x/tools/cmd/goimports
|
||||
$ go get github.com/golangci/misspell/cmd/misspell@master
|
||||
go get golang.org/x/tools/cmd/goimports
|
||||
go get github.com/golangci/misspell/cmd/misspell@master
|
||||
```
|
||||
|
||||
It also runs `go mod tidy` and `golangci-lint` if available.
|
||||
|
||||
@ -8,7 +8,7 @@ ARG UID=1000
|
||||
ARG GID=1000
|
||||
|
||||
USER ${UID}:${GID}
|
||||
VOLUME [ /simd ]
|
||||
VOLUME [ "/simd" ]
|
||||
WORKDIR /simd
|
||||
EXPOSE 26656 26657
|
||||
ENTRYPOINT ["/usr/bin/wrapper.sh"]
|
||||
|
||||
@ -5,6 +5,7 @@ This directory contains the files required to run the rosetta CI. It builds `sim
|
||||
## docker-compose.yaml
|
||||
|
||||
Builds:
|
||||
|
||||
- cosmos-sdk simapp node, with prefixed data directory, keys etc. This is required to test historical balances.
|
||||
- faucet is required so we can test construction API, it was literally impossible to put there a deterministic address to request funds for
|
||||
- rosetta is the rosetta node used by rosetta-cli to interact with the cosmos-sdk app
|
||||
|
||||
@ -32,7 +32,7 @@ services:
|
||||
- 8080
|
||||
|
||||
test_rosetta:
|
||||
image: tendermintdev/rosetta-cli:v0.6.6
|
||||
image: tendermintdev/rosetta-cli:v0.6.7
|
||||
volumes:
|
||||
- ./configuration:/rosetta/config:z
|
||||
command: ["./config/run_tests.sh"]
|
||||
|
||||
Binary file not shown.
@ -2,7 +2,7 @@ FROM golang:1.15-alpine as build
|
||||
|
||||
RUN apk add git gcc libc-dev --no-cache
|
||||
|
||||
ARG ROSETTA_VERSION="v0.5.23"
|
||||
ARG ROSETTA_VERSION="v0.6.7"
|
||||
|
||||
# build rosetta CLI
|
||||
WORKDIR /rosetta
|
||||
|
||||
@ -1,35 +1,31 @@
|
||||
# Cosmosvisor Quick Start
|
||||
|
||||
`cosmovisor` is a small process manager around Cosmos SDK binaries that monitors the governance module via stdout to see if there's a chain upgrade proposal coming in. If it see a proposal that gets approved it can be run manually or automatically to download the new code, stop the node, run the migration script, replace the node binary, and start with the new genesis file.
|
||||
`cosmovisor` is a small process manager for Cosmos SDK application binaries that monitors the governance module via stdout for incoming chain upgrade proposals. If it sees a proposal that gets approved, `cosmovisor` can automatically download the new binary, stop the current binary, switch from the old binary to the new one, and finally restart the node with the new binary.
|
||||
|
||||
*Note: If new versions of the application are not set up to run in-place store migrations, migrations will need to be run manually before restarting `cosmovisor` with the new binary. For this reason, we recommend applications adopt in-place store migrations.*
|
||||
|
||||
## Installation
|
||||
|
||||
Run:
|
||||
To install `cosmovisor`, run the following command:
|
||||
|
||||
`go get github.com/cosmos/cosmos-sdk/cosmovisor/cmd/cosmovisor`
|
||||
```
|
||||
go get github.com/cosmos/cosmos-sdk/cosmovisor/cmd/cosmovisor
|
||||
```
|
||||
|
||||
## Command Line Arguments And Environment Variables
|
||||
|
||||
All arguments passed to the `cosmovisor` program will be passed to the current daemon binary (as a subprocess).
|
||||
It will return `/dev/stdout` and `/dev/stderr` of the subprocess as its own. Because of that, it cannot accept
|
||||
any command line arguments, nor print anything to output (unless it terminates unexpectedly before executing a
|
||||
binary).
|
||||
All arguments passed to `cosmovisor` will be passed to the application binary (as a subprocess). `cosmovisor` will return `/dev/stdout` and `/dev/stderr` of the subprocess as its own. For this reason, `cosmovisor` cannot accept any command-line arguments other than those available to the application binary, nor will it print anything to output other than what is printed by the application binary.
|
||||
|
||||
`cosmovisor` reads its configuration from environment variables:
|
||||
|
||||
* `DAEMON_HOME` is the location where upgrade binaries should be kept (e.g. `$HOME/.gaiad` or `$HOME/.xrnd`).
|
||||
* `DAEMON_NAME` is the name of the binary itself (eg. `xrnd`, `gaiad`, `simd`, etc).
|
||||
* `DAEMON_ALLOW_DOWNLOAD_BINARIES` (*optional*) if set to `true` will enable auto-downloading of new binaries
|
||||
(for security reasons, this is intended for full nodes rather than validators).
|
||||
* `DAEMON_RESTART_AFTER_UPGRADE` (*optional*) if set to `true` it will restart the sub-process with the same
|
||||
command line arguments and flags (but new binary) after a successful upgrade. By default, `cosmovisor` dies
|
||||
afterwards and allows the supervisor to restart it if needed. Note that this will not auto-restart the child
|
||||
if there was an error.
|
||||
* `DAEMON_HOME` is the location where the `cosmovisor/` directory is kept that contains the genesis binary, the upgrade binaries, and any additional auxiliary files associated with each binary (e.g. `$HOME/.gaiad`, `$HOME/.regend`, `$HOME/.simd`, etc.).
|
||||
* `DAEMON_NAME` is the name of the binary itself (e.g. `gaiad`, `regend`, `simd`, etc.).
|
||||
* `DAEMON_ALLOW_DOWNLOAD_BINARIES` (*optional*), if set to `true`, will enable auto-downloading of new binaries (for security reasons, this is intended for full nodes rather than validators). By default, `cosmovisor` will not auto-download new binaries.
|
||||
* `DAEMON_RESTART_AFTER_UPGRADE` (*optional*), if set to `true`, will restart the subprocess with the same command-line arguments and flags (but with the new binary) after a successful upgrade. By default, `cosmovisor` stops running after an upgrade and requires the system administrator to manually restart it. Note that `cosmovisor` will not auto-restart the subprocess if there was an error.
|
||||
|
||||
## Data Folder Layout
|
||||
## Folder Layout
|
||||
|
||||
`$DAEMON_HOME/cosmovisor` is expected to belong completely to `cosmovisor` and
|
||||
subprocesses that are controlled by it. The folder content is organised as follows:
|
||||
`$DAEMON_HOME/cosmovisor` is expected to belong completely to `cosmovisor` and the subprocesses that are controlled by it. The folder content is organized as follows:
|
||||
|
||||
```
|
||||
.
|
||||
@ -43,18 +39,9 @@ subprocesses that are controlled by it. The folder content is organised as follo
|
||||
└── $DAEMON_NAME
|
||||
```
|
||||
|
||||
Each version of the Cosmos SDK application is stored under either `genesis` or `upgrades/<name>`, which holds `bin/$DAEMON_NAME`
|
||||
along with any other needed files such as auxiliary client programs or libraries. `current` is a symbolic link to the currently
|
||||
active folder (so `current/bin/$DAEMON_NAME` is the currently active binary).
|
||||
The `cosmovisor/` directory incudes a subdirectory for each version of the application (i.e. `genesis` or `upgrades/<name>`). Within each subdirectory is the application binary (i.e. `bin/$DAEMON_NAME`) and any additional auxiliary files associated with each binary. `current` is a symbolic link to the currently active directory (i.e `genesis` or `upgrades/<name>`). The `name` variable in `upgrades/<name>` is the URI-encoded name of the upgrade as specified in the upgrade module plan.
|
||||
|
||||
*Note: the `name` variable in `upgrades/<name>` holds the URI-encoded name of the upgrade as specified in the upgrade module plan.*
|
||||
|
||||
Please note that `$DAEMON_HOME/cosmovisor` just stores the *binaries* and associated *program code*.
|
||||
The `cosmovisor` binary can be stored in any typical location (eg `/usr/local/bin`). The actual blockchain
|
||||
program will store it's data under their default data directory (e.g. `$HOME/.gaiad`) which is independent of
|
||||
the `$DAEMON_HOME`. You can choose to set `$DAEMON_HOME` to the actual binary's home directory and then end up
|
||||
with a configuation like the following, but this is left as a choice to the system admininstrator for best
|
||||
directory layout:
|
||||
Please note that `$DAEMON_HOME/cosmovisor` only stores the *application binaries*. The `cosmovisor` binary itself can be stored in any typical location (e.g. `/usr/local/bin`). The application will continue to store its data in the default data directory (e.g. `$HOME/.gaiad`) or the data directory specified with the `--home` flag. `$DAEMON_HOME` is independent of the data directory and can be set to any location. If you set `$DAEMON_HOME` to the same directory as the data directory, you will end up with a configuation like the following:
|
||||
|
||||
```
|
||||
.gaiad
|
||||
@ -65,106 +52,179 @@ directory layout:
|
||||
|
||||
## Usage
|
||||
|
||||
The system administrator admin is responsible for:
|
||||
* installing the `cosmovisor` binary and configure the host's init system (e.g. `systemd`, `launchd`, etc) along with the environmental variables appropriately;
|
||||
* installing the `genesis` folder manually;
|
||||
* installing the `upgrades/<name>` folders manually.
|
||||
The system administrator is responsible for:
|
||||
|
||||
`cosmovisor` will set the `current` link to point to `genesis` at first start (when no `current` link exists) and handles
|
||||
binaries switch overs at the correct points in time, so that the system administrator can prepare days in advance and relax at upgrade time.
|
||||
- installing the `cosmovisor` binary
|
||||
- configuring the host's init system (e.g. `systemd`, `launchd`, etc.)
|
||||
- appropriately setting the environmental variables
|
||||
- manually installing the `genesis` folder
|
||||
- manually installing the `upgrades/<name>` folders
|
||||
|
||||
Note that blockchain applications that wish to support upgrades may package up a genesis `cosmovisor` tarball with this information,
|
||||
just as they prepare the genesis binary tarball. In fact, they may offer a tarball will all upgrades up to current point for easy download
|
||||
for those who wish to sync a fullnode from start.
|
||||
`cosmovisor` will set the `current` link to point to `genesis` at first start (i.e. when no `current` link exists) and then handle switching binaries at the correct points in time so that the system administrator can prepare days in advance and relax at upgrade time.
|
||||
|
||||
The `DAEMON` specific code and operations (e.g. tendermint config, the application db, syncing blocks, etc) are performed as normal.
|
||||
Application binaries' directives such as command-line flags and environment variables work normally.
|
||||
In order to support downloadable binaries, a tarball for each upgrade binary will need to be packaged up and made available through a canonical URL. Additionally, a tarball that includes the genesis binary and all available upgrade binaries can be packaged up and made available so that all the necessary binaries required to sync a fullnode from start can be easily downloaded.
|
||||
|
||||
## Example: simd
|
||||
The `DAEMON` specific code and operations (e.g. tendermint config, the application db, syncing blocks, etc.) all work as expected. The application binaries' directives such as command-line flags and environment variables also work as expected.
|
||||
|
||||
The following instructions provide a demonstration of `cosmovisor`'s integration with the `simd` application
|
||||
shipped along the Cosmos SDK's source code.
|
||||
## Auto-Download
|
||||
|
||||
First compile `simd`:
|
||||
Generally, `cosmovisor` requires that the system administrator place all relevant binaries on disk before the upgrade happens. However, for people who don't need such control and want an easier setup (maybe they are syncing a non-validating fullnode and want to do little maintenance), there is another option.
|
||||
|
||||
If `DAEMON_ALLOW_DOWNLOAD_BINARIES` is set to `true`, and no local binary can be found when an upgrade is triggered, `cosmovisor` will attempt to download and install the binary itself. The plan stored in the upgrade module has an info field for arbitrary JSON. This info is expected to be outputed on the halt log message. There are two valid formats to specify a download in such a message:
|
||||
|
||||
1. Store an os/architecture -> binary URI map in the upgrade plan info field as JSON under the `"binaries"` key. For example:
|
||||
|
||||
```json
|
||||
{
|
||||
"binaries": {
|
||||
"linux/amd64":"https://example.com/gaia.zip?checksum=sha256:aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. Store a link to a file that contains all information in the above format (e.g. if you want to specify lots of binaries, changelog info, etc. without filling up the blockchain). For example:
|
||||
|
||||
```
|
||||
https://example.com/testnet-1001-info.json?checksum=sha256:deaaa99fda9407c4dbe1d04bd49bab0cc3c1dd76fa392cd55a9425be074af01e
|
||||
```
|
||||
|
||||
When `cosmovisor` is triggered to download the new binary, `cosmovisor` will parse the `"binaries"` field, download the new binary with [go-getter](https://github.com/hashicorp/go-getter), and unpack the new binary in the `upgrades/<name>` folder so that it can be run as if it was installed manually.
|
||||
|
||||
Note that for this mechanism to provide strong security guarantees, all URLs should include a SHA 256/512 checksum. This ensures that no false binary is run, even if someone hacks the server or hijacks the DNS. `go-getter` will always ensure the downloaded file matches the checksum if it is provided.
|
||||
|
||||
To properly create a sha256 checksum on linux, you can use the `sha256sum` utility. For example:
|
||||
|
||||
```
|
||||
sha256sum ./testdata/repo/zip_directory/autod.zip
|
||||
```
|
||||
|
||||
The result will look something like the following: `29139e1381b8177aec909fab9a75d11381cab5adf7d3af0c05ff1c9c117743a7`.
|
||||
|
||||
You can also use `sha512sum` if you would prefer to use longer hashes, or `md5sum` if you would prefer to use broken hashes. Whichever you choose, make sure to set the hash algorithm properly in the checksum argument to the URL.
|
||||
|
||||
## Example: SimApp Upgrade
|
||||
|
||||
The following instructions provide a demonstration of `cosmovisor` using the simulation application (`simapp`) shipped with the Cosmos SDK's source code. The following commands are to be run from within the `cosmos-sdk` repository.
|
||||
|
||||
First compile the `simd` binary:
|
||||
|
||||
```
|
||||
cd cosmos-sdk/
|
||||
make build
|
||||
```
|
||||
|
||||
Create a new key and setup the `simd` node:
|
||||
Reset `~/.simapp` (never do this in a production environment):
|
||||
|
||||
```
|
||||
rm -rf $HOME/.simapp
|
||||
./build/simd keys --keyring-backend=test add validator
|
||||
./build/simd init testing --chain-id test
|
||||
./build/simd add-genesis-account --keyring-backend=test $(./build/simd keys --keyring-backend=test show validator -a) 1000000000stake,1000000000validatortoken
|
||||
./build/simd gentx --keyring-backend test --chain-id test validator 100000stake
|
||||
./build/simd unsafe-reset-all
|
||||
```
|
||||
|
||||
Configure the `simd` binary for testing:
|
||||
|
||||
```
|
||||
./build/simd config chain-id test
|
||||
./build/simd config keyring-backend test
|
||||
./build/simd config broadcast-mode block
|
||||
```
|
||||
|
||||
Initialize the node and overwrite any previous genesis file (never do this in a production environment):
|
||||
|
||||
<!-- TODO: init does not read chain-id from config -->
|
||||
|
||||
```
|
||||
./build/simd init test --chain-id test --overwrite
|
||||
```
|
||||
|
||||
Set the minimum gas price to `0stake` in `~/.simapp/config/app.toml`:
|
||||
|
||||
```
|
||||
minimum-gas-prices = "0stake"
|
||||
```
|
||||
|
||||
Create a new key for the validator, then add a genesis account and transaction:
|
||||
|
||||
<!-- TODO: add-genesis-account does not read keyring-backend from config -->
|
||||
<!-- TODO: gentx does not read chain-id from config -->
|
||||
|
||||
```
|
||||
./build/simd keys add validator
|
||||
./build/simd add-genesis-account validator 1000000000stake --keyring-backend test
|
||||
./build/simd gentx validator 1000000stake --chain-id test
|
||||
./build/simd collect-gentxs
|
||||
```
|
||||
|
||||
Set the required environment variables:
|
||||
|
||||
```
|
||||
export DAEMON_NAME=simd # binary name
|
||||
export DAEMON_HOME=$HOME/.simapp # daemon's home directory
|
||||
export DAEMON_NAME=simd
|
||||
export DAEMON_HOME=$HOME/.simapp
|
||||
```
|
||||
|
||||
Create the `cosmovisor`’s genesis folders and deploy the binary:
|
||||
Set the optional environment variable to trigger an automatic restart:
|
||||
|
||||
```
|
||||
export DAEMON_RESTART_AFTER_UPGRADE=true
|
||||
```
|
||||
|
||||
Create the folder for the genesis binary and copy the `simd` binary:
|
||||
|
||||
```
|
||||
mkdir -p $DAEMON_HOME/cosmovisor/genesis/bin
|
||||
cp ./build/simd $DAEMON_HOME/cosmovisor/genesis/bin
|
||||
```
|
||||
|
||||
For the sake of this demonstration, we would amend `voting_params.voting_period` in `.simapp/config/genesis.json` to a reduced time ~5 minutes (300s) and eventually launch `cosmosvisor`:
|
||||
For the sake of this demonstration, amend `voting_period` in `genesis.json` to a reduced time of 20 seconds (`20s`):
|
||||
|
||||
```
|
||||
cat <<< $(jq '.app_state.gov.voting_params.voting_period = "20s"' $HOME/.simapp/config/genesis.json) > $HOME/.simapp/config/genesis.json
|
||||
```
|
||||
|
||||
Next, we will hardcode a modification in `simapp` to simulate a code change. In `simapp/app.go`, find the line containing the `UpgradeKeeper` initialization. It should look like the following:
|
||||
|
||||
```go
|
||||
app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath)
|
||||
```
|
||||
|
||||
After that line, add the following:
|
||||
|
||||
```go
|
||||
app.UpgradeKeeper.SetUpgradeHandler("test1", func(ctx sdk.Context, plan upgradetypes.Plan) {
|
||||
// Add some coins to a random account
|
||||
addr, err := sdk.AccAddressFromBech32("cosmos18cgkqduwuh253twzmhedesw3l7v3fm37sppt58")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = app.BankKeeper.AddCoins(ctx, addr, sdk.Coins{sdk.Coin{Denom: "stake", Amount: sdk.NewInt(345600000)}})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Now recompile the `simd` binary with the added upgrade handler:
|
||||
|
||||
```
|
||||
make build
|
||||
```
|
||||
|
||||
Create the folder for the upgrade binary and copy the `simd` binary:
|
||||
|
||||
```
|
||||
mkdir -p $DAEMON_HOME/cosmovisor/upgrades/test1/bin
|
||||
cp ./build/simd $DAEMON_HOME/cosmovisor/upgrades/test1/bin
|
||||
```
|
||||
|
||||
Start `cosmosvisor`:
|
||||
|
||||
```
|
||||
cosmovisor start
|
||||
```
|
||||
|
||||
Submit a software upgrade proposal:
|
||||
Open a new terminal window and submit an upgrade proposal along with a deposit and a vote (these commands must be run within 20 seconds of each other):
|
||||
|
||||
```
|
||||
./build/simd tx gov submit-proposal software-upgrade test1 --title "upgrade-demo" --description "upgrade" --from validator --upgrade-height 100 --deposit 10000000stake --chain-id test --keyring-backend test -y
|
||||
```
|
||||
|
||||
Query the proposal to ensure it was correctly broadcast and added to a block:
|
||||
|
||||
```
|
||||
./build/simd query gov proposal 1
|
||||
```
|
||||
|
||||
Submit a `Yes` vote for the upgrade proposal:
|
||||
|
||||
```
|
||||
./build/simd tx gov vote 1 yes --from validator --keyring-backend test --chain-id test -y
|
||||
./build/simd tx gov submit-proposal software-upgrade test1 --title upgrade --description upgrade --upgrade-height 20 --from validator --yes
|
||||
./build/simd tx gov deposit 1 10000000stake --from validator --yes
|
||||
./build/simd tx gov vote 1 yes --from validator --yes
|
||||
```
|
||||
|
||||
For the sake of this demonstration, we will hardcode a modification in `simapp` to simulate a code change.
|
||||
In `simapp/app.go`, find the line containing the upgrade Keeper initialisation, it should look like
|
||||
`app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath)`.
|
||||
After that line, add the following snippet:
|
||||
|
||||
```
|
||||
app.UpgradeKeeper.SetUpgradeHandler("test1", func(ctx sdk.Context, plan upgradetypes.Plan) {
|
||||
// Add some coins to a random account
|
||||
addr, err := sdk.AccAddressFromBech32("cosmos18cgkqduwuh253twzmhedesw3l7v3fm37sppt58")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = app.BankKeeper.AddCoins(ctx, addr, sdk.Coins{sdk.Coin{Denom: "stake", Amount: sdk.NewInt(345600000)}})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Now recompile a new binary and place it in `$DAEMON_HOME/cosmosvisor/upgrades/test1/bin`:
|
||||
|
||||
```
|
||||
make build
|
||||
cp ./build/simd $DAEMON_HOME/cosmovisor/upgrades/test1/bin
|
||||
```
|
||||
|
||||
The upgrade will occur automatically at height 100.
|
||||
The upgrade will occur automatically at height 20.
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
package cosmovisor
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -21,6 +23,7 @@ type Config struct {
|
||||
Name string
|
||||
AllowDownloadBinaries bool
|
||||
RestartAfterUpgrade bool
|
||||
LogBufferSize int
|
||||
}
|
||||
|
||||
// Root returns the root directory where all info lives
|
||||
@ -99,6 +102,17 @@ func GetConfigFromEnv() (*Config, error) {
|
||||
cfg.RestartAfterUpgrade = true
|
||||
}
|
||||
|
||||
logBufferSizeStr := os.Getenv("DAEMON_LOG_BUFFER_SIZE")
|
||||
if logBufferSizeStr != "" {
|
||||
logBufferSize, err := strconv.Atoi(logBufferSizeStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg.LogBufferSize = logBufferSize * 1024
|
||||
} else {
|
||||
cfg.LogBufferSize = bufio.MaxScanTokenSize
|
||||
}
|
||||
|
||||
if err := cfg.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -38,6 +38,17 @@ func LaunchProcess(cfg *Config, args []string, stdout, stderr io.Writer) (bool,
|
||||
|
||||
scanOut := bufio.NewScanner(io.TeeReader(outpipe, stdout))
|
||||
scanErr := bufio.NewScanner(io.TeeReader(errpipe, stderr))
|
||||
// set scanner's buffer size to cfg.LogBufferSize, and ensure larger than bufio.MaxScanTokenSize otherwise fallback to bufio.MaxScanTokenSize
|
||||
var maxCapacity int
|
||||
if cfg.LogBufferSize < bufio.MaxScanTokenSize {
|
||||
maxCapacity = bufio.MaxScanTokenSize
|
||||
} else {
|
||||
maxCapacity = cfg.LogBufferSize
|
||||
}
|
||||
bufOut := make([]byte, maxCapacity)
|
||||
bufErr := make([]byte, maxCapacity)
|
||||
scanOut.Buffer(bufOut, maxCapacity)
|
||||
scanErr.Buffer(bufErr, maxCapacity)
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return false, fmt.Errorf("launching process %s %s: %w", bin, strings.Join(args, " "), err)
|
||||
|
||||
@ -41,6 +41,9 @@ const (
|
||||
keyringFileDirName = "keyring-file"
|
||||
keyringTestDirName = "keyring-test"
|
||||
passKeyringPrefix = "keyring-%s"
|
||||
|
||||
// temporary pass phrase for exporting a key during a key rename
|
||||
passPhrase = "temp"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -64,6 +67,9 @@ type Keyring interface {
|
||||
Delete(uid string) error
|
||||
DeleteByAddress(address sdk.Address) error
|
||||
|
||||
// Rename an existing key from the Keyring
|
||||
Rename(from string, to string) error
|
||||
|
||||
// NewMnemonic generates a new mnemonic, derives a hierarchical deterministic key from it, and
|
||||
// persists the key to storage. Returns the generated mnemonic and the key Info.
|
||||
// It returns an error if it fails to generate a key for the given algo type, or if
|
||||
@ -288,8 +294,10 @@ func (ks keystore) ExportPrivKeyArmorByAddress(address sdk.Address, encryptPassp
|
||||
}
|
||||
|
||||
func (ks keystore) ImportPrivKey(uid, armor, passphrase string) error {
|
||||
if _, err := ks.Key(uid); err == nil {
|
||||
return fmt.Errorf("cannot overwrite key: %s", uid)
|
||||
if k, err := ks.Key(uid); err == nil {
|
||||
if uid == k.GetName() {
|
||||
return fmt.Errorf("cannot overwrite key: %s", uid)
|
||||
}
|
||||
}
|
||||
|
||||
privKey, algo, err := crypto.UnarmorDecryptPrivKey(armor, passphrase)
|
||||
@ -426,6 +434,30 @@ func (ks keystore) DeleteByAddress(address sdk.Address) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ks keystore) Rename(oldName, newName string) error {
|
||||
_, err := ks.Key(newName)
|
||||
if err == nil {
|
||||
return fmt.Errorf("rename failed: %s already exists in the keyring", newName)
|
||||
}
|
||||
|
||||
armor, err := ks.ExportPrivKeyArmor(oldName, passPhrase)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ks.ImportPrivKey(newName, armor, passPhrase)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ks.Delete(oldName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ks keystore) Delete(uid string) error {
|
||||
info, err := ks.Key(uid)
|
||||
if err != nil {
|
||||
@ -760,7 +792,7 @@ func (ks keystore) writeInfo(info Info) error {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
return errors.New("public key already exist in keybase")
|
||||
return errors.New("public key already exists in keybase")
|
||||
}
|
||||
|
||||
err = ks.db.Set(keyring.Item{
|
||||
@ -783,16 +815,22 @@ func (ks keystore) writeInfo(info Info) error {
|
||||
}
|
||||
|
||||
// existsInDb returns true if key is in DB. Error is returned only when we have error
|
||||
// different thant ErrKeyNotFound
|
||||
// different than ErrKeyNotFound
|
||||
func (ks keystore) existsInDb(info Info) (bool, error) {
|
||||
if _, err := ks.db.Get(addrHexKeyAsString(info.GetAddress())); err == nil {
|
||||
return true, nil // address lookup succeeds - info exists
|
||||
if item, err := ks.db.Get(addrHexKeyAsString(info.GetAddress())); err == nil {
|
||||
if item.Key == info.GetName() {
|
||||
return true, nil // address lookup succeeds - info exists
|
||||
}
|
||||
return false, nil
|
||||
} else if err != keyring.ErrKeyNotFound {
|
||||
return false, err // received unexpected error - returns error
|
||||
}
|
||||
|
||||
if _, err := ks.db.Get(infoKey(info.GetName())); err == nil {
|
||||
return true, nil // uid lookup succeeds - info exists
|
||||
if item, err := ks.db.Get(infoKey(info.GetName())); err == nil {
|
||||
if item.Key == info.GetName() {
|
||||
return true, nil // uid lookup succeeds - info exists
|
||||
}
|
||||
return false, nil
|
||||
} else if err != keyring.ErrKeyNotFound {
|
||||
return false, err // received unexpected error - returns
|
||||
}
|
||||
|
||||
@ -1153,6 +1153,72 @@ func TestBackendConfigConstructors(t *testing.T) {
|
||||
require.Equal(t, "keyring-test", backend.PassPrefix)
|
||||
}
|
||||
|
||||
func TestRenameKey(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
run func(Keyring)
|
||||
}{
|
||||
{
|
||||
name: "rename a key",
|
||||
run: func(kr Keyring) {
|
||||
oldKeyUID, newKeyUID := "old", "new"
|
||||
oldKeyInfo := newKeyInfo(t, kr, oldKeyUID)
|
||||
err := kr.Rename(oldKeyUID, newKeyUID) // rename from "old" to "new"
|
||||
require.NoError(t, err)
|
||||
newInfo, err := kr.Key(newKeyUID) // new key should be in keyring
|
||||
require.NoError(t, err)
|
||||
requireEqualRenamedKey(t, newInfo, oldKeyInfo) // oldinfo and newinfo should be the same
|
||||
oldKeyInfo, err = kr.Key(oldKeyUID) // old key should be gone from keyring
|
||||
require.Error(t, err)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cant rename a key that doesnt exist",
|
||||
run: func(kr Keyring) {
|
||||
err := kr.Rename("bogus", "bogus2")
|
||||
require.Error(t, err)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cant rename a key to an already existing key name",
|
||||
run: func(kr Keyring) {
|
||||
key1, key2 := "existingKey", "existingKey2" // create 2 keys
|
||||
newKeyInfo(t, kr, key1)
|
||||
newKeyInfo(t, kr, key2)
|
||||
err := kr.Rename(key2, key1)
|
||||
require.Equal(t, fmt.Errorf("rename failed: %s already exists in the keyring", key1), err)
|
||||
assertKeysExist(t, kr, key1, key2) // keys should still exist after failed rename
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cant rename key to itself",
|
||||
run: func(kr Keyring) {
|
||||
keyName := "keyName"
|
||||
newKeyInfo(t, kr, keyName)
|
||||
err := kr.Rename(keyName, keyName)
|
||||
require.Equal(t, fmt.Errorf("rename failed: %s already exists in the keyring", keyName), err)
|
||||
assertKeysExist(t, kr, keyName)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
kr := newKeyring(t, "testKeyring")
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
tc.run(kr)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func requireEqualRenamedKey(t *testing.T, newKey, oldKey Info) {
|
||||
require.NotEqual(t, newKey.GetName(), oldKey.GetName())
|
||||
require.Equal(t, newKey.GetAddress(), oldKey.GetAddress())
|
||||
require.Equal(t, newKey.GetPubKey(), oldKey.GetPubKey())
|
||||
require.Equal(t, newKey.GetAlgo(), oldKey.GetAlgo())
|
||||
require.Equal(t, newKey.GetType(), oldKey.GetType())
|
||||
}
|
||||
|
||||
func requireEqualInfo(t *testing.T, key Info, mnemonic Info) {
|
||||
require.Equal(t, key.GetName(), mnemonic.GetName())
|
||||
require.Equal(t, key.GetAddress(), mnemonic.GetAddress())
|
||||
@ -1161,4 +1227,23 @@ func requireEqualInfo(t *testing.T, key Info, mnemonic Info) {
|
||||
require.Equal(t, key.GetType(), mnemonic.GetType())
|
||||
}
|
||||
|
||||
func newKeyring(t *testing.T, name string) Keyring {
|
||||
kr, err := New(name, "test", t.TempDir(), nil)
|
||||
require.NoError(t, err)
|
||||
return kr
|
||||
}
|
||||
|
||||
func newKeyInfo(t *testing.T, kr Keyring, name string) Info {
|
||||
keyInfo, _, err := kr.NewMnemonic(name, English, sdk.FullFundraiserPath, DefaultBIP39Passphrase, hd.Secp256k1)
|
||||
require.NoError(t, err)
|
||||
return keyInfo
|
||||
}
|
||||
|
||||
func assertKeysExist(t *testing.T, kr Keyring, names ...string) {
|
||||
for _, n := range names {
|
||||
_, err := kr.Key(n)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func accAddr(info Info) sdk.AccAddress { return info.GetAddress() }
|
||||
|
||||
@ -24,7 +24,7 @@ func (suite *SKSuite) TestPubKey() {
|
||||
suite.True(suite.sk.PublicKey.Equal(&pk.PublicKey))
|
||||
}
|
||||
|
||||
func (suite *SKSuite) Bytes() {
|
||||
func (suite *SKSuite) TestBytes() {
|
||||
bz := suite.sk.Bytes()
|
||||
suite.Len(bz, 32)
|
||||
var sk *PrivKey
|
||||
|
||||
@ -26,7 +26,9 @@ type PubKey struct {
|
||||
address tmcrypto.Address
|
||||
}
|
||||
|
||||
// Address creates an ADR-28 address for ECDSA keys. protoName is a concrete proto structure id.
|
||||
// Address gets the address associated with a pubkey. If no address exists, it returns a newly created ADR-28 address
|
||||
// for ECDSA keys.
|
||||
// protoName is a concrete proto structure id.
|
||||
func (pk *PubKey) Address(protoName string) tmcrypto.Address {
|
||||
if pk.address == nil {
|
||||
pk.address = address.Hash(protoName, pk.Bytes())
|
||||
|
||||
@ -48,9 +48,11 @@ func (suite *PKSuite) TestString() {
|
||||
}
|
||||
|
||||
func (suite *PKSuite) TestBytes() {
|
||||
require := suite.Require()
|
||||
bz := suite.sk.Bytes()
|
||||
fieldSize := (suite.sk.Curve.Params().BitSize + 7) / 8
|
||||
suite.Len(bz, fieldSize)
|
||||
var pk *PubKey
|
||||
require.Nil(pk.Bytes())
|
||||
suite.Nil(pk.Bytes())
|
||||
}
|
||||
|
||||
func (suite *PKSuite) TestMarshal() {
|
||||
|
||||
@ -18,7 +18,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
|
||||
)
|
||||
|
||||
func TestNewMultiSig(t *testing.T) {
|
||||
@ -352,7 +352,7 @@ func TestDisplay(t *testing.T) {
|
||||
func() { require.Empty(msig.String()) },
|
||||
)
|
||||
ccfg := simapp.MakeTestEncodingConfig()
|
||||
bz, err := ccfg.Marshaler.MarshalInterfaceJSON(msig)
|
||||
bz, err := ccfg.Codec.MarshalInterfaceJSON(msig)
|
||||
require.NoError(err)
|
||||
expectedPrefix := `{"@type":"/cosmos.crypto.multisig.LegacyAminoPubKey","threshold":2,"public_keys":[{"@type":"/cosmos.crypto.secp256k1.PubKey"`
|
||||
require.True(strings.HasPrefix(string(bz), expectedPrefix))
|
||||
|
||||
@ -8,6 +8,7 @@ Optimized C library for EC operations on curve secp256k1.
|
||||
This library is a work in progress and is being used to research best practices. Use at your own risk.
|
||||
|
||||
Features:
|
||||
|
||||
* secp256k1 ECDSA signing/verification and key generation.
|
||||
* Adding/multiplying private/public keys.
|
||||
* Serialization/parsing of private keys, public keys, signatures.
|
||||
@ -19,43 +20,43 @@ Implementation details
|
||||
----------------------
|
||||
|
||||
* General
|
||||
* No runtime heap allocation.
|
||||
* Extensive testing infrastructure.
|
||||
* Structured to facilitate review and analysis.
|
||||
* Intended to be portable to any system with a C89 compiler and uint64_t support.
|
||||
* Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.")
|
||||
* No runtime heap allocation.
|
||||
* Extensive testing infrastructure.
|
||||
* Structured to facilitate review and analysis.
|
||||
* Intended to be portable to any system with a C89 compiler and uint64_t support.
|
||||
* Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.")
|
||||
* Field operations
|
||||
* Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1).
|
||||
* Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys).
|
||||
* Using 10 26-bit limbs.
|
||||
* Field inverses and square roots using a sliding window over blocks of 1s (by Peter Dettman).
|
||||
* Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1).
|
||||
* Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys).
|
||||
* Using 10 26-bit limbs.
|
||||
* Field inverses and square roots using a sliding window over blocks of 1s (by Peter Dettman).
|
||||
* Scalar operations
|
||||
* Optimized implementation without data-dependent branches of arithmetic modulo the curve's order.
|
||||
* Using 4 64-bit limbs (relying on __int128 support in the compiler).
|
||||
* Using 8 32-bit limbs.
|
||||
* Optimized implementation without data-dependent branches of arithmetic modulo the curve's order.
|
||||
* Using 4 64-bit limbs (relying on __int128 support in the compiler).
|
||||
* Using 8 32-bit limbs.
|
||||
* Group operations
|
||||
* Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7).
|
||||
* Use addition between points in Jacobian and affine coordinates where possible.
|
||||
* Use a unified addition/doubling formula where necessary to avoid data-dependent branches.
|
||||
* Point/x comparison without a field inversion by comparison in the Jacobian coordinate space.
|
||||
* Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7).
|
||||
* Use addition between points in Jacobian and affine coordinates where possible.
|
||||
* Use a unified addition/doubling formula where necessary to avoid data-dependent branches.
|
||||
* Point/x comparison without a field inversion by comparison in the Jacobian coordinate space.
|
||||
* Point multiplication for verification (a*P + b*G).
|
||||
* Use wNAF notation for point multiplicands.
|
||||
* Use a much larger window for multiples of G, using precomputed multiples.
|
||||
* Use Shamir's trick to do the multiplication with the public key and the generator simultaneously.
|
||||
* Optionally (off by default) use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones.
|
||||
* Use wNAF notation for point multiplicands.
|
||||
* Use a much larger window for multiples of G, using precomputed multiples.
|
||||
* Use Shamir's trick to do the multiplication with the public key and the generator simultaneously.
|
||||
* Optionally (off by default) use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones.
|
||||
* Point multiplication for signing
|
||||
* Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions.
|
||||
* Access the table with branch-free conditional moves so memory access is uniform.
|
||||
* No data-dependent branches
|
||||
* The precomputed tables add and eventually subtract points for which no known scalar (private key) is known, preventing even an attacker with control over the private key used to control the data internally.
|
||||
* Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions.
|
||||
* Access the table with branch-free conditional moves so memory access is uniform.
|
||||
* No data-dependent branches
|
||||
* The precomputed tables add and eventually subtract points for which no known scalar (private key) is known, preventing even an attacker with control over the private key used to control the data internally.
|
||||
|
||||
Build steps
|
||||
-----------
|
||||
|
||||
libsecp256k1 is built using autotools:
|
||||
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ ./tests
|
||||
$ sudo make install # optional
|
||||
./autogen.sh
|
||||
./configure
|
||||
make
|
||||
./tests
|
||||
sudo make install # optional
|
||||
|
||||
@ -33,6 +33,9 @@ func (m *PrivKey) Sign(msg []byte) ([]byte, error) {
|
||||
|
||||
// Bytes serialize the private key.
|
||||
func (m *PrivKey) Bytes() []byte {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
return m.Secret.Bytes()
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ package secp256r1
|
||||
import (
|
||||
"testing"
|
||||
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
@ -41,7 +41,7 @@ func (suite *SKSuite) TestPubKey() {
|
||||
suite.True(suite.sk.(*PrivKey).Secret.PublicKey.Equal(&pk.(*PubKey).Key.PublicKey))
|
||||
}
|
||||
|
||||
func (suite *SKSuite) Bytes() {
|
||||
func (suite *SKSuite) TestBytes() {
|
||||
bz := suite.sk.Bytes()
|
||||
suite.Len(bz, fieldSize)
|
||||
var sk *PrivKey
|
||||
|
||||
@ -15,6 +15,9 @@ func (m *PubKey) String() string {
|
||||
|
||||
// Bytes implements SDK PubKey interface.
|
||||
func (m *PubKey) Bytes() []byte {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
return m.Key.Bytes()
|
||||
}
|
||||
|
||||
|
||||
@ -44,6 +44,13 @@ func (suite *PKSuite) TestType() {
|
||||
suite.Require().Equal(name, suite.pk.Type())
|
||||
}
|
||||
|
||||
func (suite *PKSuite) TestBytes() {
|
||||
bz := suite.pk.Bytes()
|
||||
suite.Len(bz, fieldSize+1)
|
||||
var pk *PubKey
|
||||
suite.Nil(pk.Bytes())
|
||||
}
|
||||
|
||||
func (suite *PKSuite) TestEquals() {
|
||||
require := suite.Require()
|
||||
|
||||
|
||||
@ -71,4 +71,4 @@ networks:
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 192.168.10.0/16
|
||||
- subnet: 192.168.10.0/25
|
||||
|
||||
@ -5,14 +5,14 @@ module.exports = {
|
||||
"/": {
|
||||
lang: "en-US"
|
||||
},
|
||||
kr: {
|
||||
lang: "kr"
|
||||
},
|
||||
cn: {
|
||||
lang: "cn"
|
||||
ko: {
|
||||
lang: "ko"
|
||||
},
|
||||
ru: {
|
||||
lang: "ru"
|
||||
},
|
||||
zh: {
|
||||
lang: "zh-CN"
|
||||
}
|
||||
},
|
||||
base: process.env.VUEPRESS_BASE || "/",
|
||||
@ -46,6 +46,10 @@ module.exports = {
|
||||
"label": "v0.42",
|
||||
"key": "v0.42"
|
||||
},
|
||||
{
|
||||
"label": "v0.43",
|
||||
"key": "v0.43"
|
||||
},
|
||||
{
|
||||
"label": "master",
|
||||
"key": "master"
|
||||
|
||||
@ -1,33 +1,33 @@
|
||||
# Updating the docs
|
||||
|
||||
If you want to open a PR on the Cosmos SDK to update the documentation, please follow the guidelines in the [`CONTRIBUTING.md`](https://github.com/cosmos/cosmos-sdk/tree/master/CONTRIBUTING.md#updating-documentation)
|
||||
If you want to open a PR in Cosmos SDK to update the documentation, please follow the guidelines in [`CONTRIBUTING.md`](https://github.com/cosmos/cosmos-sdk/tree/master/CONTRIBUTING.md#updating-documentation).
|
||||
|
||||
## Translating
|
||||
## Internationalization
|
||||
|
||||
- Docs translations live in a `docs/country-code/` folder, where `country-code` stands for the country code of the language used (`cn` for Chinese, `kr` for Korea, `fr` for France, ...).
|
||||
- Always translate content living on `master`.
|
||||
- Only content under `/docs/intro/`, `/docs/basics/`, `/docs/core/`, `/docs/building-modules/` and `docs/interfaces` needs to be translated, as well as `docs/README.md`. It is also nice (but not mandatory) to translate `/docs/spec/`.
|
||||
- Specify the release/tag of the translation in the README of your translation folder. Update the release/tag each time you update the translation.
|
||||
- Translations for documentation live in a `docs/<locale>/` folder, where `<locale>` is the language code for a specific language. For example, `zh` for Chinese, `ko` for Korean, `ru` for Russian, etc.
|
||||
- Each `docs/<locale>/` folder must follow the same folder structure within `docs/`, but only content in the following folders needs to be translated and included in the respective `docs/<locale>/` folder:
|
||||
- `docs/basics/`
|
||||
- `docs/building-modules/`
|
||||
- `docs/core/`
|
||||
- `docs/ibc/`
|
||||
- `docs/intro/`
|
||||
- `docs/migrations/`
|
||||
- `docs/run-node/`
|
||||
- Each `docs/<locale>/` folder must also have a `README.md` that includes a translated version of both the layout and content within the root-level [`README.md`](https://github.com/cosmos/cosmos-sdk/tree/master/docs/README.md). The layout defined in the `README.md` is used to build the homepage.
|
||||
- Always translate content living on `master` unless you are revising documentation for a specific release. Translated documentation like the root-level documentation is semantically versioned.
|
||||
- For additional configuration options, please see [VuePress Internationalization](https://vuepress.vuejs.org/guide/i18n.html).
|
||||
|
||||
## Docs Build Workflow
|
||||
|
||||
The documentation for the Cosmos SDK is hosted at https://cosmos.network/docs/
|
||||
|
||||
built from the files in this (`/docs`) directory for
|
||||
[master](https://github.com/cosmos/cosmos-sdk/tree/master/docs).
|
||||
The documentation for Cosmos SDK is hosted at https://docs.cosmos.network/ and built from the files in the `/docs` directory.
|
||||
|
||||
### How It Works
|
||||
|
||||
There is a CircleCI job listening for changes in the `/docs` directory, on
|
||||
the `master` branch. Any updates to files in this directory
|
||||
on that branch will automatically trigger a website deployment. Under the hood,
|
||||
the private website repository has a `make build-docs` target consumed by a CircleCI job in that repo.
|
||||
There is a CircleCI job listening for changes in the `/docs` directory for the `master` branch and each supported version tag (`v0.39` and `v0.42`). Any updates to files in the `/docs` directory will automatically trigger a website deployment. Under the hood, the private website repository has a `make build-docs` target consumed by a CircleCI job within that repository.
|
||||
|
||||
## README
|
||||
|
||||
The [README.md](./README.md) is also the landing page for the documentation
|
||||
on the website. During the Jenkins build, the current commit is added to the bottom
|
||||
of the README.
|
||||
The [README.md](./README.md) is both the README for the repository and the configuration for the layout of the landing page.
|
||||
|
||||
## Config.js
|
||||
|
||||
@ -108,14 +108,17 @@ much as possible with its [counterpart in the Tendermint Core repo](https://gith
|
||||
### Update and Build the RPC docs
|
||||
|
||||
1. Execute the following command at the root directory to install the swagger-ui generate tool.
|
||||
|
||||
```bash
|
||||
make tools
|
||||
```
|
||||
|
||||
2. Edit API docs
|
||||
1. Directly Edit API docs manually: `client/lcd/swagger-ui/swagger.yaml`.
|
||||
2. Edit API docs within the [Swagger Editor](https://editor.swagger.io/). Please refer to this [document](https://swagger.io/docs/specification/2-0/basic-structure/) for the correct structure in `.yaml`.
|
||||
3. Download `swagger.yaml` and replace the old `swagger.yaml` under fold `client/lcd/swagger-ui`.
|
||||
4. Compile gaiacli
|
||||
|
||||
```bash
|
||||
make install
|
||||
```
|
||||
|
||||
15
docs/DOC_WRITING_GUIDELINES.md
Normal file
15
docs/DOC_WRITING_GUIDELINES.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Documentation Writing Guidelines
|
||||
|
||||
## Best Practices
|
||||
|
||||
+ Check the spelling and grammar, even if you have to copy and paste from an external source.
|
||||
+ Use simple sentences. Easy-to-read sentences mean the reader can quickly use the guidance you share.
|
||||
+ Try to express your thoughts in a concise and clean way.
|
||||
+ Don't abuse `code` format when writing in plain English.
|
||||
+ Follow Google developer documentation [style guide](https://developers.google.com/style).
|
||||
+ Check the meaning of words in Microsoft's [A-Z word list and term collections](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/term-collections/accessibility-terms) (use the search input!).
|
||||
+ RFC keywords should be used in technical documents (uppercase) and we recommend to use them in user documentation (lowercase). The RFC keywords are: "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL. They are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
|
||||
|
||||
## Technical Writing Course
|
||||
|
||||
Google provides a free [course](https://developers.google.com/tech-writing/overview) for technical writing.
|
||||
@ -19,10 +19,10 @@ sections:
|
||||
desc: Discover how to build modules for the Cosmos SDK.
|
||||
icon: modules
|
||||
url: /building-modules/intro.html
|
||||
- title: Interfaces
|
||||
desc: Build interfaces for Cosmos SDK applications.
|
||||
- title: Running a Node
|
||||
desc: Running and interacting with nodes using the CLI and API.
|
||||
icon: interfaces
|
||||
url: /interfaces/interfaces-intro.html
|
||||
url: /run-node/
|
||||
- title: Modules
|
||||
desc: Explore existing modules to build your application with.
|
||||
icon: specifications
|
||||
@ -48,24 +48,24 @@ aside: false
|
||||
## Get Started
|
||||
|
||||
- **[SDK Intro](./intro/overview.md)**: High-level overview of the Cosmos SDK.
|
||||
- **[Starport](https://github.com/tendermint/starport/blob/develop/docs/README.md)**: A developer-friendly interface to the Cosmos SDK to scaffold a standard Cosmos SDK blockchain app.
|
||||
- **[SDK Application Tutorial](https://github.com/cosmos/sdk-application-tutorial)**: A tutorial that showcases how to build a Cosmos SDK-based blockchain from scratch and explains the basic principles of the SDK in the process.
|
||||
- **[Starport](https://docs.starport.network/)**: A developer-friendly interface to the Cosmos SDK to scaffold a standard Cosmos SDK blockchain app.
|
||||
- **[SDK Tutorials](https://tutorials.cosmos.network/)**: Tutorials that showcase how to build Cosmos SDK-based blockchains from scratch and explain the basic principles of the SDK in the process.
|
||||
|
||||
## Reference
|
||||
|
||||
- **[Basics](./basics/)**: Documentation on the basic concepts of the Cosmos SDK, like the standard anatomy of an application, the transaction lifecycle, and accounts management.
|
||||
- **[Core](./core/)**: Documentation on the core concepts of the Cosmos SDK, like `baseapp`, the `store`, or the `server`.
|
||||
- **[Building Modules](./building-modules/)**: Important concepts for module developers like `message`, `keeper`, `handler`, and `querier`.
|
||||
- **[Building Modules](./building-modules/)**: Important concepts for module developers like `message`, `keeper`, and `querier`.
|
||||
- **[IBC](./ibc/)**: Documentation for the IBC protocol integration and concepts.
|
||||
- **[Running a Node, API, CLI](./run-node/)**: Documentation on how to run a node and interact with the node using the CLI and the API.
|
||||
- **[Migrations](./migrations/)**: Migration guides for updating to Stargate.
|
||||
- **[Migrations](./migrations/)**: Migration guides for updating to newer versions of the SDK.
|
||||
|
||||
## Other Resources
|
||||
|
||||
- **[Module Directory](../x/)**: Cosmos SDK module implementations and their respective documentation.
|
||||
- **[Specifications](./spec/)**: Specifications of modules and other parts of the Cosmos SDK.
|
||||
- **[SDK API Reference](https://godoc.org/github.com/cosmos/cosmos-sdk)**: Godocs of the Cosmos SDK.
|
||||
- **[REST API spec](https://cosmos.network/rpc/)**: List of endpoints to interact with a `gaia` full-node through REST.
|
||||
- **[REST and RPC Endpoints](https://cosmos.network/rpc/)**: List of endpoints to interact with a `gaia` full-node.
|
||||
|
||||
## Cosmos Hub
|
||||
|
||||
@ -73,11 +73,8 @@ The Cosmos Hub (`gaia`) docs have moved to [github.com/cosmos/gaia](https://gith
|
||||
|
||||
## Languages
|
||||
|
||||
The Cosmos SDK is written in [Golang](https://golang.org/), though the
|
||||
framework could be implemented similarly in other languages.
|
||||
Contact us for information about funding an implementation in another language.
|
||||
The Cosmos SDK is written in [Golang](https://golang.org/), though the framework could be implemented similarly in other languages. Contact us for information about funding an implementation in another language.
|
||||
|
||||
## Contribute
|
||||
|
||||
See the [DOCS_README.md](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOCS_README.md) for details of the build process and
|
||||
considerations when making changes.
|
||||
See the [DOCS_README.md](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOCS_README.md) for details of the build process and considerations when making changes.
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
4. Add an entry to a list in the [README](./README.md) file.
|
||||
5. Create a Pull Request to propose a new ADR.
|
||||
|
||||
|
||||
## ADR life cycle
|
||||
|
||||
ADR creation is an **iterative** process. Instead of trying to solve all decisions in a single ADR pull request, we MUST firstly understand the problem and collect feedback through a GitHub Issue.
|
||||
@ -23,7 +22,6 @@ ADR creation is an **iterative** process. Instead of trying to solve all decisio
|
||||
|
||||
6. Merged ADRs SHOULD NOT be pruned.
|
||||
|
||||
|
||||
### ADR status
|
||||
|
||||
Status has two components:
|
||||
@ -44,7 +42,6 @@ DRAFT -> PROPOSED -> LAST CALL yyyy-mm-dd -> ACCEPTED | REJECTED -> SUPERSEEDED
|
||||
ABANDONED
|
||||
```
|
||||
|
||||
|
||||
+ `DRAFT`: [optional] an ADR which is work in progress, not being ready for a general review. This is to present an early work and get an early feedback in a Draft Pull Request form.
|
||||
+ `PROPOSED`: an ADR covering a full solution architecture and still in the review - project stakeholders haven't reached an agreed yet.
|
||||
+ `LAST CALL <date for the last call>`: [optional] clear notify that we are close to accept updates. Changing a status to `LAST CALL` means that social consensus (of Cosmos SDK maintainers) has been reached and we still want to give it a time to let the community react or analyze.
|
||||
@ -53,7 +50,6 @@ DRAFT -> PROPOSED -> LAST CALL yyyy-mm-dd -> ACCEPTED | REJECTED -> SUPERSEEDED
|
||||
+ `SUPERSEEDED by ADR-xxx`: ADR which has been superseded by a new ADR.
|
||||
+ `ABANDONED`: the ADR is no longer pursued by the original authors.
|
||||
|
||||
|
||||
## Language used in ADR
|
||||
|
||||
+ The context/background should be written in the present tense.
|
||||
|
||||
@ -32,11 +32,14 @@ it stands today.
|
||||
|
||||
If recorded decisions turned out to be lacking, convene a discussion, record the new decisions here, and then modify the code to match.
|
||||
|
||||
|
||||
## Creating new ADR
|
||||
|
||||
Read about the [PROCESS](./PROCESS.md).
|
||||
|
||||
#### Use RFC 2119 Keywords
|
||||
|
||||
When writing ADRs, follow the same best practices for writing RFCs. When writing RFCs, key words are used to signify the requirements in the specification. These words are often capitalized: "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL. They are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
|
||||
|
||||
## ADR Table of Contents
|
||||
|
||||
### Accepted
|
||||
@ -51,7 +54,7 @@ Read about the [PROCESS](./PROCESS.md).
|
||||
- [ADR 021: Protocol Buffer Query Encoding](./adr-021-protobuf-query-encoding.md)
|
||||
- [ADR 023: Protocol Buffer Naming and Versioning](./adr-023-protobuf-naming.md)
|
||||
- [ADR 029: Fee Grant Module](./adr-029-fee-grant-module.md)
|
||||
- [ADR 030: Message Authorization Module](architecture/adr-030-authz-module.md)
|
||||
- [ADR 030: Message Authorization Module](./adr-030-authz-module.md)
|
||||
- [ADR 031: Protobuf Msg Services](./adr-031-msg-service.md)
|
||||
|
||||
### Proposed
|
||||
@ -73,3 +76,4 @@ Read about the [PROCESS](./PROCESS.md).
|
||||
- [ADR 037: Governance Split Votes](./adr-037-gov-split-vote.md)
|
||||
- [ADR 038: State Listening](./adr-038-state-listening.md)
|
||||
- [ADR 039: Epoched Staking](./adr-039-epoched-staking.md)
|
||||
- [ADR 040: Storage and SMT State Commitments](./adr-040-storage-and-smt-state-commitments.md)
|
||||
|
||||
@ -33,7 +33,7 @@ past transactions and assigned to particular modes), and keep them in a memory-o
|
||||
chain is running.
|
||||
|
||||
The `CapabilityKeeper` will include a persistent `KVStore`, a `MemoryStore`, and an in-memory map.
|
||||
The persistent `KVStore` tracks which capability is owned by which modules.
|
||||
The persistent `KVStore` tracks which capability is owned by which modules.
|
||||
The `MemoryStore` stores a forward mapping that map from module name, capability tuples to capability names and
|
||||
a reverse mapping that map from module name, capability name to the capability index.
|
||||
Since we cannot marshal the capability into a `KVStore` and unmarshal without changing the memory location of the capability,
|
||||
|
||||
@ -7,12 +7,10 @@
|
||||
- 2020-01-14: Updates from review feedback
|
||||
- 2020-01-30: Updates from implementation
|
||||
|
||||
|
||||
### Glossary
|
||||
|
||||
* denom / denomination key -- unique token identifier.
|
||||
|
||||
|
||||
## Context
|
||||
|
||||
With permissionless IBC, anyone will be able to send arbitrary denominations to any other account. Currently, all non-zero balances are stored along with the account in an `sdk.Coins` struct, which creates a potential denial-of-service concern, as too many denominations will become expensive to load & store each time the account is modified. See issues [5467](https://github.com/cosmos/cosmos-sdk/issues/5467) and [4982](https://github.com/cosmos/cosmos-sdk/issues/4982) for additional context.
|
||||
|
||||
@ -9,23 +9,20 @@
|
||||
|
||||
## Context
|
||||
|
||||
Currently, an SDK application's CLI directory stores key material and metadata in a plain text database in the user’s home directory. Key material is encrypted by a passphrase, protected by bcrypt hashing algorithm. Metadata (e.g. addresses, public keys, key storage details) is available in plain text.
|
||||
Currently, an SDK application's CLI directory stores key material and metadata in a plain text database in the user’s home directory. Key material is encrypted by a passphrase, protected by bcrypt hashing algorithm. Metadata (e.g. addresses, public keys, key storage details) is available in plain text.
|
||||
|
||||
This is not desirable for a number of reasons. Perhaps the biggest reason is insufficient security protection of key material and metadata. Leaking the plain text allows an attacker to surveil what keys a given computer controls via a number of techniques, like compromised dependencies without any privilege execution. This could be followed by a more targeted attack on a particular user/computer.
|
||||
|
||||
All modern desktop computers OS (Ubuntu, Debian, MacOS, Windows) provide a built-in secret store that is designed to allow applications to store information that is isolated from all other applications and requires passphrase entry to access the data.
|
||||
All modern desktop computers OS (Ubuntu, Debian, MacOS, Windows) provide a built-in secret store that is designed to allow applications to store information that is isolated from all other applications and requires passphrase entry to access the data.
|
||||
|
||||
We are seeking solution that provides a common abstraction layer to the many different backends and reasonable fallback for minimal platforms that don’t provide a native secret store.
|
||||
|
||||
|
||||
## Decision
|
||||
|
||||
We recommend replacing the current Keybase backend based on LevelDB with [Keyring](https://github.com/99designs/keyring) by 99 designs. This application is designed to provide a common abstraction and uniform interface between many secret stores and is used by AWS Vault application by 99-designs application.
|
||||
|
||||
This appears to fulfill the requirement of protecting both key material and metadata from rouge software on a user’s machine.
|
||||
|
||||
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
@ -55,4 +52,3 @@ Running tests locally on a Mac require numerous repetitive password entries.
|
||||
- #5097 Add keys migrate command [__MERGED__]
|
||||
- #5180 Drop on-disk keybase in favor of keyring [_PENDING_REVIEW_]
|
||||
- cosmos/gaia#164 Drop on-disk keybase in favor of keyring (gaia's changes) [_PENDING_REVIEW_]
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ creation of a decentralized Computer Emergency Response Team (dCERT), whose
|
||||
members would be elected by a governing community and would fulfill the role of
|
||||
coordinating the community under emergency situations. This thinking
|
||||
can be further abstracted into the conception of "blockchain specialization
|
||||
groups".
|
||||
groups".
|
||||
|
||||
The creation of these groups are the beginning of specialization capabilities
|
||||
within a wider blockchain community which could be used to enable a certain
|
||||
@ -19,30 +19,29 @@ level of delegated responsibilities. Examples of specialization which could be
|
||||
beneficial to a blockchain community include: code auditing, emergency response,
|
||||
code development etc. This type of community organization paves the way for
|
||||
individual stakeholders to delegate votes by issue type, if in the future
|
||||
governance proposals include a field for issue type.
|
||||
|
||||
governance proposals include a field for issue type.
|
||||
|
||||
## Decision
|
||||
|
||||
A specialization group can be broadly broken down into the following functions
|
||||
(herein containing examples):
|
||||
|
||||
- Membership Admittance
|
||||
- Membership Acceptance
|
||||
- Membership Revocation
|
||||
- (probably) Without Penalty
|
||||
- member steps down (self-Revocation)
|
||||
- replaced by new member from governance
|
||||
- (probably) With Penalty
|
||||
- due to breach of soft-agreement (determined through governance)
|
||||
- due to breach of hard-agreement (determined by code)
|
||||
- Execution of Duties
|
||||
- Special transactions which only execute for members of a specialization
|
||||
- Membership Admittance
|
||||
- Membership Acceptance
|
||||
- Membership Revocation
|
||||
- (probably) Without Penalty
|
||||
- member steps down (self-Revocation)
|
||||
- replaced by new member from governance
|
||||
- (probably) With Penalty
|
||||
- due to breach of soft-agreement (determined through governance)
|
||||
- due to breach of hard-agreement (determined by code)
|
||||
- Execution of Duties
|
||||
- Special transactions which only execute for members of a specialization
|
||||
group (for example, dCERT members voting to turn off transaction routes in
|
||||
an emergency scenario)
|
||||
- Compensation
|
||||
- Group compensation (further distribution decided by the specialization group)
|
||||
- Individual compensation for all constituents of a group from the
|
||||
an emergency scenario)
|
||||
- Compensation
|
||||
- Group compensation (further distribution decided by the specialization group)
|
||||
- Individual compensation for all constituents of a group from the
|
||||
greater community
|
||||
|
||||
Membership admittance to a specialization group could take place over a wide
|
||||
@ -56,31 +55,31 @@ some of these possiblities in a common interface dubbed the `Electionator`. For
|
||||
its initial implementation as a part of this ADR we recommend that the general
|
||||
election abstraction (`Electionator`) is provided as well as a basic
|
||||
implementation of that abstraction which allows for a continuous election of
|
||||
members of a specialization group.
|
||||
members of a specialization group.
|
||||
|
||||
``` golang
|
||||
// The Electionator abstraction covers the concept space for
|
||||
// The Electionator abstraction covers the concept space for
|
||||
// a wide variety of election kinds.
|
||||
type Electionator interface {
|
||||
|
||||
|
||||
// is the election object accepting votes.
|
||||
Active() bool
|
||||
Active() bool
|
||||
|
||||
// functionality to execute for when a vote is cast in this election, here
|
||||
// the vote field is anticipated to be marshalled into a vote type used
|
||||
// by an election.
|
||||
//
|
||||
// the vote field is anticipated to be marshalled into a vote type used
|
||||
// by an election.
|
||||
//
|
||||
// NOTE There are no explicit ids here. Just votes which pertain specifically
|
||||
// to one electionator. Anyone can create and send a vote to the electionator item
|
||||
// which will presumably attempt to marshal those bytes into a particular struct
|
||||
// and apply the vote information in some arbitrary way. There can be multiple
|
||||
// Electionators within the Cosmos-Hub for multiple specialization groups, votes
|
||||
// would need to be routed to the Electionator upstream of here.
|
||||
Vote(addr sdk.AccAddress, vote []byte)
|
||||
Vote(addr sdk.AccAddress, vote []byte)
|
||||
|
||||
// here lies all functionality to authenticate and execute changes for
|
||||
// when a member accepts being elected
|
||||
AcceptElection(sdk.AccAddress)
|
||||
AcceptElection(sdk.AccAddress)
|
||||
|
||||
// Register a revoker object
|
||||
RegisterRevoker(Revoker)
|
||||
@ -89,25 +88,25 @@ type Electionator interface {
|
||||
SealRevokers()
|
||||
|
||||
// register hooks to call when an election actions occur
|
||||
RegisterHooks(ElectionatorHooks)
|
||||
RegisterHooks(ElectionatorHooks)
|
||||
|
||||
// query for the current winner(s) of this election based on arbitrary
|
||||
// election ruleset
|
||||
QueryElected() []sdk.AccAddress
|
||||
QueryElected() []sdk.AccAddress
|
||||
|
||||
// query metadata for an address in the election this
|
||||
// query metadata for an address in the election this
|
||||
// could include for example position that an address
|
||||
// is being elected for within a group
|
||||
//
|
||||
// this metadata may be directly related to
|
||||
// is being elected for within a group
|
||||
//
|
||||
// this metadata may be directly related to
|
||||
// voting information and/or privileges enabled
|
||||
// to members within a group.
|
||||
// to members within a group.
|
||||
QueryMetadata(sdk.AccAddress) []byte
|
||||
}
|
||||
|
||||
// ElectionatorHooks, once registered with an Electionator,
|
||||
// trigger execution of relevant interface functions when
|
||||
// Electionator events occur.
|
||||
// ElectionatorHooks, once registered with an Electionator,
|
||||
// trigger execution of relevant interface functions when
|
||||
// Electionator events occur.
|
||||
type ElectionatorHooks interface {
|
||||
AfterVoteCast(addr sdk.AccAddress, vote []byte)
|
||||
AfterMemberAccepted(addr sdk.AccAddress)
|
||||
@ -117,30 +116,30 @@ type ElectionatorHooks interface {
|
||||
// Revoker defines the function required for a membership revocation rule-set
|
||||
// used by a specialization group. This could be used to create self revoking,
|
||||
// and evidence based revoking, etc. Revokers types may be created and
|
||||
// reused for different election types.
|
||||
//
|
||||
// reused for different election types.
|
||||
//
|
||||
// When revoking the "cause" bytes may be arbitrarily marshalled into evidence,
|
||||
// memos, etc.
|
||||
type Revoker interface {
|
||||
RevokeName() string // identifier for this revoker type
|
||||
RevokeName() string // identifier for this revoker type
|
||||
RevokeMember(addr sdk.AccAddress, cause []byte) error
|
||||
}
|
||||
```
|
||||
|
||||
Certain level of commonality likely exists between the existing code within
|
||||
`x/governance` and required functionality of elections. This common
|
||||
functionality should be abstracted during implementation. Similarly for each
|
||||
functionality should be abstracted during implementation. Similarly for each
|
||||
vote implementation client CLI/REST functionality should be abstracted
|
||||
to be reused for multiple elections.
|
||||
to be reused for multiple elections.
|
||||
|
||||
The specialization group abstraction firstly extends the `Electionator`
|
||||
but also further defines traits of the group.
|
||||
but also further defines traits of the group.
|
||||
|
||||
``` golang
|
||||
type SpecializationGroup interface {
|
||||
Electionator
|
||||
Electionator
|
||||
GetName() string
|
||||
GetDescription() string
|
||||
GetDescription() string
|
||||
|
||||
// general soft contract the group is expected
|
||||
// to fulfill with the greater community
|
||||
@ -151,7 +150,7 @@ type SpecializationGroup interface {
|
||||
|
||||
// logic to be executed at endblock, this may for instance
|
||||
// include payment of a stipend to the group members
|
||||
// for participation in the security group.
|
||||
// for participation in the security group.
|
||||
EndBlocker(ctx sdk.Context)
|
||||
}
|
||||
```
|
||||
@ -164,16 +163,15 @@ type SpecializationGroup interface {
|
||||
|
||||
### Positive
|
||||
|
||||
- increases specialization capabilities of a blockchain
|
||||
- improve abstractions in `x/gov/` such that they can be used with specialization groups
|
||||
- increases specialization capabilities of a blockchain
|
||||
- improve abstractions in `x/gov/` such that they can be used with specialization groups
|
||||
|
||||
### Negative
|
||||
|
||||
- could be used to increase centralization within a community
|
||||
- could be used to increase centralization within a community
|
||||
|
||||
### Neutral
|
||||
|
||||
## References
|
||||
|
||||
- (dCERT ADR)[./adr-008-dCERT-group.md]
|
||||
|
||||
- [dCERT ADR](./adr-008-dCERT-group.md)
|
||||
|
||||
@ -15,13 +15,13 @@ bug-hunters, and developers. During a time of crisis, the dCERT group would
|
||||
aggregate and relay input from a variety of stakeholders to the developers who
|
||||
are actively devising a patch to the software, this way sensitive information
|
||||
does not need to be publicly disclosed while some input from the community can
|
||||
still be gained.
|
||||
still be gained.
|
||||
|
||||
Additionally, a special privilege is proposed for the dCERT group: the capacity
|
||||
to "circuit-break" (aka. temporarily disable) a particular message path. Note
|
||||
that this privilege should be enabled/disabled globally with a governance
|
||||
parameter such that this privilege could start disabled and later be enabled
|
||||
through a parameter change proposal, once a dCERT group has been established.
|
||||
through a parameter change proposal, once a dCERT group has been established.
|
||||
|
||||
In the future it is foreseeable that the community may wish to expand the roles
|
||||
of dCERT with further responsibilities such as the capacity to "pre-approve" a
|
||||
@ -32,52 +32,55 @@ vulnerability being patched on the live network.
|
||||
## Decision
|
||||
|
||||
The dCERT group is proposed to include an implementation of a `SpecializationGroup`
|
||||
as defined in [ADR 007](./adr-007-specialization-groups.md). This will include the
|
||||
implementation of:
|
||||
- continuous voting
|
||||
- slashing due to breach of soft contract
|
||||
- revoking a member due to breach of soft contract
|
||||
- emergency disband of the entire dCERT group (ex. for colluding maliciously)
|
||||
- compensation stipend from the community pool or other means decided by
|
||||
as defined in [ADR 007](./adr-007-specialization-groups.md). This will include the
|
||||
implementation of:
|
||||
|
||||
- continuous voting
|
||||
- slashing due to breach of soft contract
|
||||
- revoking a member due to breach of soft contract
|
||||
- emergency disband of the entire dCERT group (ex. for colluding maliciously)
|
||||
- compensation stipend from the community pool or other means decided by
|
||||
governance
|
||||
|
||||
This system necessitates the following new parameters:
|
||||
- blockly stipend allowance per dCERT member
|
||||
- maximum number of dCERT members
|
||||
- required staked slashable tokens for each dCERT member
|
||||
- quorum for suspending a particular member
|
||||
- proposal wager for disbanding the dCERT group
|
||||
- stabilization period for dCERT member transition
|
||||
- circuit break dCERT privileges enabled
|
||||
This system necessitates the following new parameters:
|
||||
|
||||
These parameters are expected to be implemented through the param keeper such
|
||||
that governance may change them at any given point.
|
||||
- blockly stipend allowance per dCERT member
|
||||
- maximum number of dCERT members
|
||||
- required staked slashable tokens for each dCERT member
|
||||
- quorum for suspending a particular member
|
||||
- proposal wager for disbanding the dCERT group
|
||||
- stabilization period for dCERT member transition
|
||||
- circuit break dCERT privileges enabled
|
||||
|
||||
These parameters are expected to be implemented through the param keeper such
|
||||
that governance may change them at any given point.
|
||||
|
||||
### Continuous Voting Electionator
|
||||
|
||||
An `Electionator` object is to be implemented as continuous voting and with the
|
||||
following specifications:
|
||||
- All delegation addresses may submit votes at any point which updates their
|
||||
preferred representation on the dCERT group.
|
||||
- Preferred representation may be arbitrarily split between addresses (ex. 50%
|
||||
to John, 25% to Sally, 25% to Carol)
|
||||
- In order for a new member to be added to the dCERT group they must
|
||||
|
||||
- All delegation addresses may submit votes at any point which updates their
|
||||
preferred representation on the dCERT group.
|
||||
- Preferred representation may be arbitrarily split between addresses (ex. 50%
|
||||
to John, 25% to Sally, 25% to Carol)
|
||||
- In order for a new member to be added to the dCERT group they must
|
||||
send a transaction accepting their admission at which point the validity of
|
||||
their admission is to be confirmed.
|
||||
- A sequence number is assigned when a member is added to dCERT group.
|
||||
their admission is to be confirmed.
|
||||
- A sequence number is assigned when a member is added to dCERT group.
|
||||
If a member leaves the dCERT group and then enters back, a new sequence number
|
||||
is assigned.
|
||||
- Addresses which control the greatest amount of preferred-representation are
|
||||
eligible to join the dCERT group (up the _maximum number of dCERT members_).
|
||||
- Addresses which control the greatest amount of preferred-representation are
|
||||
eligible to join the dCERT group (up the _maximum number of dCERT members_).
|
||||
If the dCERT group is already full and new member is admitted, the existing
|
||||
dCERT member with the lowest amount of votes is kicked from the dCERT group.
|
||||
- In the split situation where the dCERT group is full but a vying candidate
|
||||
has the same amount of vote as an existing dCERT member, the existing
|
||||
member should maintain its position.
|
||||
- In the split situation where somebody must be kicked out but the two
|
||||
- In the split situation where the dCERT group is full but a vying candidate
|
||||
has the same amount of vote as an existing dCERT member, the existing
|
||||
member should maintain its position.
|
||||
- In the split situation where somebody must be kicked out but the two
|
||||
addresses with the smallest number of votes have the same number of votes,
|
||||
the address with the smallest sequence number maintains its position.
|
||||
- A stabilization period can be optionally included to reduce the
|
||||
- A stabilization period can be optionally included to reduce the
|
||||
"flip-flopping" of the dCERT membership tail members. If a stabilization
|
||||
period is provided which is greater than 0, when members are kicked due to
|
||||
insufficient support, a queue entry is created which documents which member is
|
||||
@ -106,7 +109,7 @@ Membership suspension by the dCERT group takes place through a voting procedure
|
||||
by the dCERT group members. After this suspension has taken place, a governance
|
||||
proposal to slash the dCERT member must be submitted, if the proposal is not
|
||||
approved by the time the rescinding member has completed unbonding their
|
||||
tokens, then the tokens are no longer staked and unable to be slashed.
|
||||
tokens, then the tokens are no longer staked and unable to be slashed.
|
||||
|
||||
Additionally in the case of an emergency situation of a colluding and malicious
|
||||
dCERT group, the community needs the capability to disband the entire dCERT
|
||||
@ -119,24 +122,25 @@ wager should be required is because as soon as the proposal is made, the
|
||||
capability of the dCERT group to halt message routes is put on temporarily
|
||||
suspended, meaning that a malicious actor who created such a proposal could
|
||||
then potentially exploit a bug during this period of time, with no dCERT group
|
||||
capable of shutting down the exploitable message routes.
|
||||
capable of shutting down the exploitable message routes.
|
||||
|
||||
### dCERT membership transactions
|
||||
|
||||
Active dCERT members
|
||||
- change of the description of the dCERT group
|
||||
- circuit break a message route
|
||||
- vote to suspend a dCERT member.
|
||||
Active dCERT members
|
||||
|
||||
- change of the description of the dCERT group
|
||||
- circuit break a message route
|
||||
- vote to suspend a dCERT member.
|
||||
|
||||
Here circuit-breaking refers to the capability to disable a groups of messages,
|
||||
This could for instance mean: "disable all staking-delegation messages", or
|
||||
"disable all distribution messages". This could be accomplished by verifying
|
||||
that the message route has not been "circuit-broken" at CheckTx time (in
|
||||
`baseapp/baseapp.go`).
|
||||
`baseapp/baseapp.go`).
|
||||
|
||||
"unbreaking" a circuit is anticipated only to occur during a hard fork upgrade
|
||||
meaning that no capability to unbreak a message route on a live chain is
|
||||
required.
|
||||
required.
|
||||
|
||||
Note also, that if there was a problem with governance voting (for instance a
|
||||
capability to vote many times) then governance would be broken and should be
|
||||
@ -153,15 +157,15 @@ they should all be severely slashed.
|
||||
|
||||
### Positive
|
||||
|
||||
- Potential to reduces the number of parties to coordinate with during an emergency
|
||||
- Reduction in possibility of disclosing sensitive information to malicious parties
|
||||
- Potential to reduces the number of parties to coordinate with during an emergency
|
||||
- Reduction in possibility of disclosing sensitive information to malicious parties
|
||||
|
||||
### Negative
|
||||
|
||||
- Centralization risks
|
||||
- Centralization risks
|
||||
|
||||
### Neutral
|
||||
|
||||
## References
|
||||
|
||||
(Specialization Groups ADR)[./adr-007-specialization-groups.md]
|
||||
|
||||
[Specialization Groups ADR](./adr-007-specialization-groups.md)
|
||||
|
||||
@ -17,10 +17,12 @@ For example, let's say a user wants to implement some custom signature verificat
|
||||
One approach is to use the [ModuleManager](https://godoc.org/github.com/cosmos/cosmos-sdk/types/module) and have each module implement its own antehandler if it requires custom antehandler logic. The ModuleManager can then be passed in an AnteHandler order in the same way it has an order for BeginBlockers and EndBlockers. The ModuleManager returns a single AnteHandler function that will take in a tx and run each module's `AnteHandle` in the specified order. The module manager's AnteHandler is set as the baseapp's AnteHandler.
|
||||
|
||||
Pros:
|
||||
|
||||
1. Simple to implement
|
||||
2. Utilizes the existing ModuleManager architecture
|
||||
|
||||
Cons:
|
||||
|
||||
1. Improves granularity but still cannot get more granular than a per-module basis. e.g. If auth's `AnteHandle` function is in charge of validating memo and signatures, users cannot swap the signature-checking functionality while keeping the rest of auth's `AnteHandle` functionality.
|
||||
2. Module AnteHandler are run one after the other. There is no way for one AnteHandler to wrap or "decorate" another.
|
||||
|
||||
@ -53,10 +55,12 @@ func (example Decorator) Deliver(ctx Context, store KVStore, tx Tx, next Deliver
|
||||
```
|
||||
|
||||
Pros:
|
||||
|
||||
1. Weave Decorators can wrap over the next decorator/handler in the chain. The ability to both pre-process and post-process may be useful in certain settings.
|
||||
2. Provides a nested modular structure that isn't possible in the solution above, while also allowing for a linear one-after-the-other structure like the solution above.
|
||||
|
||||
Cons:
|
||||
|
||||
1. It is hard to understand at first glance the state updates that would occur after a Decorator runs given the `ctx`, `store`, and `tx`. A Decorator can have an arbitrary number of nested Decorators being called within its function body, each possibly doing some pre- and post-processing before calling the next decorator on the chain. Thus to understand what a Decorator is doing, one must also understand what every other decorator further along the chain is also doing. This can get quite complicated to understand. A linear, one-after-the-other approach while less powerful, may be much easier to reason about.
|
||||
|
||||
### Chained Micro-Functions
|
||||
@ -65,17 +69,17 @@ The benefit of Weave's approach is that the Decorators can be very concise, whic
|
||||
|
||||
Another approach is to split the AnteHandler functionality into tightly scoped "micro-functions", while preserving the one-after-the-other ordering that would come from the ModuleManager approach.
|
||||
|
||||
We can then have a way to chain these micro-functions so that they run one after the other. Modules may define multiple ante micro-functions and then also provide a default per-module AnteHandler that implements a default, suggested order for these micro-functions.
|
||||
We can then have a way to chain these micro-functions so that they run one after the other. Modules may define multiple ante micro-functions and then also provide a default per-module AnteHandler that implements a default, suggested order for these micro-functions.
|
||||
|
||||
Users can order the AnteHandlers easily by simply using the ModuleManager. The ModuleManager will take in a list of AnteHandlers and return a single AnteHandler that runs each AnteHandler in the order of the list provided. If the user is comfortable with the default ordering of each module, this is as simple as providing a list with each module's antehandler (exactly the same as BeginBlocker and EndBlocker).
|
||||
|
||||
If however, users wish to change the order or add, modify, or delete ante micro-functions in anyway; they can always define their own ante micro-functions and add them explicitly to the list that gets passed into module manager.
|
||||
|
||||
#### Default Workflow:
|
||||
#### Default Workflow
|
||||
|
||||
This is an example of a user's AnteHandler if they choose not to make any custom micro-functions.
|
||||
|
||||
##### SDK code:
|
||||
##### SDK code
|
||||
|
||||
```go
|
||||
// Chains together a list of AnteHandler micro-functions that get run one after the other.
|
||||
@ -137,7 +141,7 @@ func (mm ModuleManager) GetAnteHandler() AnteHandler {
|
||||
}
|
||||
```
|
||||
|
||||
##### User Code:
|
||||
##### User Code
|
||||
|
||||
```go
|
||||
// Note: Since user is not making any custom modifications, we can just SetAnteHandlerOrder with the default AnteHandlers provided by each module in our preferred order
|
||||
@ -166,11 +170,13 @@ moduleManager.SetAnteHandlerOrder([]AnteHandler(ValidateMemo, CustomSigVerify, D
|
||||
```
|
||||
|
||||
Pros:
|
||||
|
||||
1. Allows for ante functionality to be as modular as possible.
|
||||
2. For users that do not need custom ante-functionality, there is little difference between how antehandlers work and how BeginBlock and EndBlock work in ModuleManager.
|
||||
3. Still easy to understand
|
||||
|
||||
Cons:
|
||||
|
||||
1. Cannot wrap antehandlers with decorators like you can with Weave.
|
||||
|
||||
### Simple Decorators
|
||||
|
||||
@ -33,6 +33,7 @@ However in practice, we likely don't want a linear relation between amount of st
|
||||
#### Parameterization
|
||||
|
||||
This requires parameterizing a logistic function. It is very well understood how to parameterize this. It has four parameters:
|
||||
|
||||
1) A minimum slashing factor
|
||||
2) A maximum slashing factor
|
||||
3) The inflection point of the S-curve (essentially where do you want to center the S)
|
||||
@ -66,7 +67,6 @@ We then will iterate over all the SlashEvents in the queue, adding their `Valida
|
||||
|
||||
Once we have the `NewSlashPercent`, we then iterate over all the `SlashEvent`s in the queue once again, and if `NewSlashPercent > SlashedSoFar` for that SlashEvent, we call the `staking.Slash(slashEvent.Address, slashEvent.Power, Math.Min(Math.Max(minSlashPercent, NewSlashPercent - SlashedSoFar), maxSlashPercent)` (we pass in the power of the validator before any slashes occured, so that we slash the right amount of tokens). We then set `SlashEvent.SlashedSoFar` amount to `NewSlashPercent`.
|
||||
|
||||
|
||||
## Status
|
||||
|
||||
Proposed
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
## Context
|
||||
|
||||
Validator consensus key rotation feature has been discussed and requested for a long time, for the sake of safer validator key management policy (e.g. https://github.com/tendermint/tendermint/issues/1136). So, we suggest one of the simplest form of validator consensus key rotation implementation mostly onto Cosmos-SDK.
|
||||
Validator consensus key rotation feature has been discussed and requested for a long time, for the sake of safer validator key management policy (e.g. https://github.com/tendermint/tendermint/issues/1136). So, we suggest one of the simplest form of validator consensus key rotation implementation mostly onto Cosmos-SDK.
|
||||
|
||||
We don't need to make any update on consensus logic in Tendermint because Tendermint does not have any mapping information of consensus key and validator operator key, meaning that from Tendermint point of view, a consensus key rotation of a validator is simply a replacement of a consensus key to another.
|
||||
|
||||
@ -23,7 +23,6 @@ Also, it should be noted that this ADR includes only the simplest form of consen
|
||||
- start validating with new consensus key.
|
||||
- validators using HSM and KMS should update the consensus key in HSM to use the new rotated key after the height `h` when `MsgRotateConsPubKey` committed to the blockchain.
|
||||
|
||||
|
||||
### Considerations
|
||||
|
||||
- consensus key mapping information management strategy
|
||||
@ -33,13 +32,13 @@ Also, it should be noted that this ADR includes only the simplest form of consen
|
||||
- key rotation costs related to LCD and IBC
|
||||
- LCD and IBC will have traffic/computation burden when there exists frequent power changes
|
||||
- In current Tendermint design, consensus key rotations are seen as power changes from LCD or IBC perspective
|
||||
- Therefore, to minimize unnecessary frequent key rotation behavior, we limited maximum number of rotation in recent unbonding period and also applied exponentially increasing rotation fee
|
||||
- Therefore, to minimize unnecessary frequent key rotation behavior, we limited maximum number of rotation in recent unbonding period and also applied exponentially increasing rotation fee
|
||||
- limits
|
||||
- a validator cannot rotate its consensus key more than `MaxConsPubKeyRotations` time for any unbonding period, to prevent spam.
|
||||
- parameters can be decided by governance and stored in genesis file.
|
||||
- key rotation fee
|
||||
- a validator should pay `KeyRotationFee` to rotate the consensus key which is calculated as below
|
||||
- `KeyRotationFee` = (max(`VotingPowerPercentage` * 100, 1) * `InitialKeyRotationFee`) * 2^(number of rotations in `ConsPubKeyRotationHistory` in recent unbonding period)
|
||||
- `KeyRotationFee` = (max(`VotingPowerPercentage` *100, 1)* `InitialKeyRotationFee`) * 2^(number of rotations in `ConsPubKeyRotationHistory` in recent unbonding period)
|
||||
- evidence module
|
||||
- evidence module can search corresponding consensus key for any height from slashing keeper so that it can decide which consensus key is supposed to be used for given height.
|
||||
- abci.ValidatorUpdate
|
||||
@ -50,7 +49,6 @@ Also, it should be noted that this ADR includes only the simplest form of consen
|
||||
- `MaxConsPubKeyRotations` : maximum number of rotation can be executed by a validator in recent unbonding period. default value 10 is suggested(11th key rotation will be rejected)
|
||||
- `InitialKeyRotationFee` : the initial key rotation fee when no key rotation has happened in recent unbonding period. default value 1atom is suggested(1atom fee for the first key rotation in recent unbonding period)
|
||||
|
||||
|
||||
### Workflow
|
||||
|
||||
1. The validator generates a new consensus keypair.
|
||||
@ -64,7 +62,7 @@ Also, it should be noted that this ADR includes only the simplest form of consen
|
||||
```
|
||||
|
||||
3. `handleMsgRotateConsPubKey` gets `MsgRotateConsPubKey`, calls `RotateConsPubKey` with emits event
|
||||
4. `RotateConsPubKey`
|
||||
4. `RotateConsPubKey`
|
||||
- checks if `NewPubKey` is not duplicated on `ValidatorsByConsAddr`
|
||||
- checks if the validator is does not exceed parameter `MaxConsPubKeyRotations` by iterating `ConsPubKeyRotationHistory`
|
||||
- checks if the signing account has enough balance to pay `KeyRotationFee`
|
||||
@ -83,7 +81,7 @@ Also, it should be noted that this ADR includes only the simplest form of consen
|
||||
}
|
||||
```
|
||||
|
||||
5. `ApplyAndReturnValidatorSetUpdates` checks if there is `ConsPubKeyRotationHistory` with `ConsPubKeyRotationHistory.RotatedHeight == ctx.BlockHeight()` and if so, generates 2 `ValidatorUpdate` , one for a remove validator and one for create new validator
|
||||
5. `ApplyAndReturnValidatorSetUpdates` checks if there is `ConsPubKeyRotationHistory` with `ConsPubKeyRotationHistory.RotatedHeight == ctx.BlockHeight()` and if so, generates 2 `ValidatorUpdate` , one for a remove validator and one for create new validator
|
||||
|
||||
```go
|
||||
abci.ValidatorUpdate{
|
||||
@ -99,6 +97,7 @@ Also, it should be noted that this ADR includes only the simplest form of consen
|
||||
|
||||
6. at `previousVotes` Iteration logic of `AllocateTokens`, `previousVote` using `OldConsPubKey` match up with `ConsPubKeyRotationHistory`, and replace validator for token allocation
|
||||
7. Migrate `ValidatorSigningInfo` and `ValidatorMissedBlockBitArray` from `OldConsPubKey` to `NewConsPubKey`
|
||||
|
||||
- Note : All above features shall be implemented in `staking` module.
|
||||
|
||||
## Status
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user