Merge branch 'master' into sunny/change-pubkey-adr
This commit is contained in:
commit
2c58e1806c
|
@ -91,7 +91,8 @@ PenaltyExcessCharacter: 1000000
|
|||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Right
|
||||
RawStringFormats:
|
||||
- Delimiter: pb
|
||||
- Delimiters:
|
||||
- pb
|
||||
Language: TextProto
|
||||
BasedOnStyle: google
|
||||
ReflowComments: true
|
||||
|
|
|
@ -7,8 +7,6 @@ coverage:
|
|||
precision: 2
|
||||
round: down
|
||||
range: 70...100
|
||||
notify:
|
||||
after_n_builds: 4
|
||||
|
||||
status:
|
||||
# Learn more at https://docs.codecov.io/docs/commit-status
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
name: Nightly Builds
|
||||
# Nightly Builds rebuilds the simapp docker image Monday - Friday at midnight
|
||||
name: Build & Push
|
||||
# Build & Push builds the simapp docker image on every push to master and
|
||||
# and pushes the image to https://hub.docker.com/r/interchainio/simapp/tags
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * 1-5" # deploy at midnight Monday - Friday
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- "v[0-9]+.[0-9]+.[0-9]+" # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||
- "v[0-9]+.[0-9]+.[0-9]+-rc*" # Push events to matching v*, i.e. v1.0-rc1, v20.15.10-rc5
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
@ -12,9 +16,27 @@ jobs:
|
|||
- uses: actions/checkout@master
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Get current date
|
||||
id: date
|
||||
run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
|
||||
|
||||
- name: Prepare
|
||||
id: prep
|
||||
run: |
|
||||
DOCKER_IMAGE=interchainio/simapp
|
||||
VERSION=noop
|
||||
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
elif [[ $GITHUB_REF == refs/heads/* ]]; then
|
||||
VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
|
||||
if [ "${{ github.event.repository.default_branch }}" = "$VERSION" ]; then
|
||||
VERSION=latest
|
||||
fi
|
||||
fi
|
||||
TAGS="${DOCKER_IMAGE}:${VERSION}"
|
||||
if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||
TAGS="$TAGS,${DOCKER_IMAGE}:${VERSION}"
|
||||
fi
|
||||
echo ::set-output name=version::${VERSION}
|
||||
echo ::set-output name=tags::${TAGS}
|
||||
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
@ -28,5 +50,5 @@ jobs:
|
|||
- name: Publish to Docker Hub
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
push: true
|
||||
tags: interchainio/simapp:nightly-${{ steps.date.outputs.date }}
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.prep.outputs.tags }}
|
||||
|
|
|
@ -7,6 +7,6 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: gaurav-nelson/github-action-markdown-link-check@1.0.7
|
||||
- uses: gaurav-nelson/github-action-markdown-link-check@1.0.8
|
||||
with:
|
||||
folder-path: "docs"
|
||||
|
|
|
@ -14,16 +14,16 @@ jobs:
|
|||
timeout-minutes: 6
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- uses: golangci/golangci-lint-action@master
|
||||
with:
|
||||
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||
version: v1.28
|
||||
args: --timeout 10m
|
||||
github-token: ${{ secrets.github_token }}
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
|
|
|
@ -30,7 +30,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.1
|
||||
- uses: actions/cache@v2.1.2
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
|
@ -40,7 +40,7 @@ jobs:
|
|||
needs: [build, install-runsim]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2.1.1
|
||||
- uses: actions/cache@v2.1.2
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
|
|
|
@ -39,7 +39,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.1
|
||||
- uses: actions/cache@v2.1.2
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
|
@ -54,23 +54,21 @@ jobs:
|
|||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
SET_ENV_NAME_INSERTIONS: 1
|
||||
SET_ENV_NAME_LINES: 1
|
||||
- uses: actions/cache@v2.1.1
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- uses: actions/cache@v2.1.2
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
- name: test-sim-nondeterminism
|
||||
run: |
|
||||
make test-sim-nondeterminism
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
|
||||
test-sim-import-export:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -82,23 +80,23 @@ jobs:
|
|||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
SET_ENV_NAME_INSERTIONS: 1
|
||||
SET_ENV_NAME_LINES: 1
|
||||
- uses: actions/cache@v2.1.1
|
||||
- uses: actions/cache@v2.1.2
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
- name: test-sim-import-export
|
||||
run: |
|
||||
make test-sim-import-export
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
|
||||
test-sim-after-import:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -110,23 +108,23 @@ jobs:
|
|||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
SET_ENV_NAME_INSERTIONS: 1
|
||||
SET_ENV_NAME_LINES: 1
|
||||
- uses: actions/cache@v2.1.1
|
||||
- uses: actions/cache@v2.1.2
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
- name: test-sim-after-import
|
||||
run: |
|
||||
make test-sim-after-import
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
|
||||
test-sim-multi-seed-short:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -138,20 +136,20 @@ jobs:
|
|||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
SET_ENV_NAME_INSERTIONS: 1
|
||||
SET_ENV_NAME_LINES: 1
|
||||
- uses: actions/cache@v2.1.1
|
||||
- uses: actions/cache@v2.1.2
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
- name: test-sim-multi-seed-short
|
||||
run: |
|
||||
make test-sim-multi-seed-short
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
|
|
|
@ -26,7 +26,7 @@ jobs:
|
|||
- name: install tparse
|
||||
run: |
|
||||
export GO111MODULE="on" && go get github.com/mfridman/tparse@v0.8.3
|
||||
- uses: actions/cache@v2.1.1
|
||||
- uses: actions/cache@v2.1.2
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-tparse-binary
|
||||
|
@ -40,76 +40,106 @@ jobs:
|
|||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- uses: technote-space/get-diff-action@v1
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
id: git_diff
|
||||
with:
|
||||
PREFIX_FILTER: |
|
||||
cosmovisor
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- name: Run cosmovisor tests
|
||||
run: cd cosmovisor; make
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
|
||||
split-test-files:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2.1.3
|
||||
with:
|
||||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- name: Create a file with all the pkgs
|
||||
run: go list ./... > pkgs.txt
|
||||
- name: Split pkgs into 4 files
|
||||
run: split -n l/4 --additional-suffix=.txt ./pkgs.txt
|
||||
run: split -d -n l/4 pkgs.txt pkgs.txt.part.
|
||||
# cache multiple
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-aa"
|
||||
path: ./xaa.txt
|
||||
name: "${{ github.sha }}-00"
|
||||
path: ./pkgs.txt.part.00
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ab"
|
||||
path: ./xab.txt
|
||||
name: "${{ github.sha }}-01"
|
||||
path: ./pkgs.txt.part.01
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ac"
|
||||
path: ./xac.txt
|
||||
name: "${{ github.sha }}-02"
|
||||
path: ./pkgs.txt.part.02
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ad"
|
||||
path: ./xad.txt
|
||||
name: "${{ github.sha }}-03"
|
||||
path: ./pkgs.txt.part.03
|
||||
|
||||
test-coverage-run-1:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
needs: split-test-files
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
part: ["00", "01", "02", "03"]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2.1.3
|
||||
with:
|
||||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
id: git_diff
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-aa"
|
||||
if: "env.GIT_DIFF != ''"
|
||||
name: "${{ github.sha }}-${{ matrix.part }}"
|
||||
if: env.GIT_DIFF
|
||||
- name: test & coverage report creation
|
||||
run: |
|
||||
cat xaa.txt | xargs go test -mod=readonly -timeout 15m -coverprofile=coverage.txt -covermode=atomic -tags='norace ledger test_ledger_mock'
|
||||
if: "env.GIT_DIFF != ''"
|
||||
cat pkgs.txt.part.${{ matrix.part }} | xargs go test -mod=readonly -timeout 30m -coverprofile=${{ matrix.part }}profile.out -covermode=atomic -tags='norace ledger test_ledger_mock'
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-${{ matrix.part }}-coverage"
|
||||
path: ./${{ matrix.part }}profile.out
|
||||
|
||||
upload-coverage-report:
|
||||
runs-on: ubuntu-latest
|
||||
needs: tests
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-00-coverage"
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-01-coverage"
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-02-coverage"
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-03-coverage"
|
||||
if: env.GIT_DIFF
|
||||
- run: |
|
||||
cat ./*profile.out | grep -v "mode: atomic" >> coverage.txt
|
||||
if: env.GIT_DIFF
|
||||
- name: filter out DONTCOVER
|
||||
run: |
|
||||
excludelist="$(find ./ -type f -name '*.go' | xargs grep -l 'DONTCOVER')"
|
||||
|
@ -120,316 +150,101 @@ jobs:
|
|||
echo "Excluding ${filename} from coverage report..."
|
||||
sed -i.bak "/$(echo $filename | sed 's/\//\\\//g')/d" coverage.txt
|
||||
done
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
- uses: codecov/codecov-action@v1.0.13
|
||||
with:
|
||||
file: ./coverage.txt
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
|
||||
test-coverage-run-2:
|
||||
test-race:
|
||||
runs-on: ubuntu-latest
|
||||
needs: split-test-files
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
part: ["00", "01", "02", "03"]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2.1.3
|
||||
with:
|
||||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
id: git_diff
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ab"
|
||||
if: "env.GIT_DIFF != ''"
|
||||
name: "${{ github.sha }}-${{ matrix.part }}"
|
||||
if: env.GIT_DIFF
|
||||
- name: test & coverage report creation
|
||||
run: |
|
||||
cat xab.txt | xargs go test -mod=readonly -timeout 15m -coverprofile=coverage.txt -covermode=atomic -tags='norace ledger test_ledger_mock'
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- name: filter out DONTCOVER
|
||||
run: |
|
||||
excludelist="$(find ./ -type f -name '*.go' | xargs grep -l 'DONTCOVER')"
|
||||
excludelist+=" $(find ./ -type f -name '*.pb.go')"
|
||||
excludelist+=" $(find ./ -type f -path './tests/mocks/*.go')"
|
||||
for filename in ${excludelist}; do
|
||||
filename=$(echo $filename | sed 's/^./github.com\/cosmos\/cosmos-sdk/g')
|
||||
echo "Excluding ${filename} from coverage report..."
|
||||
sed -i.bak "/$(echo $filename | sed 's/\//\\\//g')/d" coverage.txt
|
||||
done
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- uses: codecov/codecov-action@v1.0.13
|
||||
with:
|
||||
file: ./coverage.txt
|
||||
if: "env.GIT_DIFF != ''"
|
||||
|
||||
test-coverage-run-3:
|
||||
runs-on: ubuntu-latest
|
||||
needs: split-test-files
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2.1.3
|
||||
with:
|
||||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
id: git_diff
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ac"
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- name: test & coverage report creation
|
||||
run: |
|
||||
cat xac.txt | xargs go test -mod=readonly -timeout 15m -coverprofile=coverage.txt -covermode=atomic -tags='norace ledger test_ledger_mock'
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- name: filter out DONTCOVER
|
||||
run: |
|
||||
excludelist="$(find ./ -type f -name '*.go' | xargs grep -l 'DONTCOVER')"
|
||||
excludelist+=" $(find ./ -type f -name '*.pb.go')"
|
||||
excludelist+=" $(find ./ -type f -path './tests/mocks/*.go')"
|
||||
for filename in ${excludelist}; do
|
||||
filename=$(echo $filename | sed 's/^./github.com\/cosmos\/cosmos-sdk/g')
|
||||
echo "Excluding ${filename} from coverage report..."
|
||||
sed -i.bak "/$(echo $filename | sed 's/\//\\\//g')/d" coverage.txt
|
||||
done
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- uses: codecov/codecov-action@v1.0.13
|
||||
with:
|
||||
file: ./coverage.txt
|
||||
if: "env.GIT_DIFF != ''"
|
||||
|
||||
test-coverage-run-4:
|
||||
runs-on: ubuntu-latest
|
||||
needs: split-test-files
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2.1.3
|
||||
with:
|
||||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
id: git_diff
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ad"
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- name: test & coverage report creation
|
||||
run: |
|
||||
cat xad.txt | xargs go test -mod=readonly -timeout 15m -coverprofile=coverage.txt -covermode=atomic -tags='norace ledger test_ledger_mock'
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- name: filter out DONTCOVER
|
||||
run: |
|
||||
excludelist="$(find ./ -type f -name '*.go' | xargs grep -l 'DONTCOVER')"
|
||||
excludelist+=" $(find ./ -type f -name '*.pb.go')"
|
||||
excludelist+=" $(find ./ -type f -path './tests/mocks/*.go')"
|
||||
for filename in ${excludelist}; do
|
||||
filename=$(echo $filename | sed 's/^./github.com\/cosmos\/cosmos-sdk/g')
|
||||
echo "Excluding ${filename} from coverage report..."
|
||||
sed -i.bak "/$(echo $filename | sed 's/\//\\\//g')/d" coverage.txt
|
||||
done
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- uses: codecov/codecov-action@v1.0.13
|
||||
with:
|
||||
file: ./coverage.txt
|
||||
if: "env.GIT_DIFF != ''"
|
||||
|
||||
test-race-1:
|
||||
runs-on: ubuntu-latest
|
||||
needs: split-test-files
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2.1.3
|
||||
with:
|
||||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
id: git_diff
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-aa"
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- name: Run tests with race detector
|
||||
run: cat xaa.txt | xargs go test -mod=readonly -json -timeout 30m -race -tags='cgo ledger test_ledger_mock' > xaa-race-output.txt
|
||||
if: "env.GIT_DIFF != ''"
|
||||
cat pkgs.txt.part.${{ matrix.part }} | xargs go test -mod=readonly -timeout 30m -race -tags='cgo ledger test_ledger_mock' > ${{ matrix.part }}-race-output.txt
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-aa-race-output"
|
||||
path: ./xaa-race-output.txt
|
||||
|
||||
test-race-2:
|
||||
runs-on: ubuntu-latest
|
||||
needs: split-test-files
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2.1.3
|
||||
with:
|
||||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
id: git_diff
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ab"
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- name: Run tests with race detector
|
||||
run: cat xab.txt | xargs go test -mod=readonly -json -timeout 30m -race -tags='cgo ledger test_ledger_mock' > xab-race-output.txt
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ab-race-output"
|
||||
path: ./xab-race-output.txt
|
||||
|
||||
test-race-3:
|
||||
runs-on: ubuntu-latest
|
||||
needs: split-test-files
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2.1.3
|
||||
with:
|
||||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
id: git_diff
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ac"
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- name: Run tests with race detector
|
||||
run: cat xac.txt | xargs go test -mod=readonly -json -timeout 30m -race -tags='cgo ledger test_ledger_mock' > xac-race-output.txt
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ac-race-output"
|
||||
path: ./xac-race-output.txt
|
||||
|
||||
test-race-4:
|
||||
runs-on: ubuntu-latest
|
||||
needs: split-test-files
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2.1.3
|
||||
with:
|
||||
go-version: 1.15
|
||||
- name: Display go version
|
||||
run: go version
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
id: git_diff
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ad"
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- name: Run tests with race detector
|
||||
run: cat xad.txt | xargs go test -mod=readonly -json -timeout 30m -race -tags='cgo ledger test_ledger_mock' > xad-race-output.txt
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ad-race-output"
|
||||
path: ./xad-race-output.txt
|
||||
name: "${{ github.sha }}-${{ matrix.part }}-race-output"
|
||||
path: ./${{ matrix.part }}-race-output.txt
|
||||
|
||||
race-detector-report:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test-race-1, test-race-2, test-race-3, test-race-4, install-tparse]
|
||||
needs: [test-race, install-tparse]
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v3
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
id: git_diff
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-aa-race-output"
|
||||
if: "env.GIT_DIFF != ''"
|
||||
name: "${{ github.sha }}-00-race-output"
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ab-race-output"
|
||||
if: "env.GIT_DIFF != ''"
|
||||
name: "${{ github.sha }}-01-race-output"
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ac-race-output"
|
||||
if: "env.GIT_DIFF != ''"
|
||||
name: "${{ github.sha }}-02-race-output"
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: "${{ github.sha }}-ad-race-output"
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- uses: actions/cache@v2.1.1
|
||||
name: "${{ github.sha }}-03-race-output"
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/cache@v2.1.2
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-tparse-binary
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
- name: Generate test report (go test -race)
|
||||
run: cat xa*-race-output.txt | ~/go/bin/tparse
|
||||
if: "env.GIT_DIFF != ''"
|
||||
run: cat ./*-race-output.txt | ~/go/bin/tparse
|
||||
if: env.GIT_DIFF
|
||||
|
||||
liveness-test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v1
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
id: git_diff
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- name: start localnet
|
||||
run: |
|
||||
make clean build-simd-linux localnet-start
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
- name: test liveness
|
||||
run: |
|
||||
./contrib/localnet_liveness.sh 100 5 50 localhost
|
||||
if: "env.GIT_DIFF != ''"
|
||||
if: env.GIT_DIFF
|
||||
|
||||
docker-build:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
*.swl
|
||||
*.swm
|
||||
*.swn
|
||||
.vscode
|
||||
.idea
|
||||
*.pyc
|
||||
|
||||
# private files
|
||||
private[.-]*
|
||||
private
|
||||
|
||||
# Build
|
||||
vendor
|
||||
build
|
||||
|
@ -39,8 +41,10 @@ sim_log_file
|
|||
vagrant
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.idea
|
||||
*.iml
|
||||
.dir-locals.el
|
||||
.vscode
|
||||
|
||||
# Graphviz
|
||||
dependency-graph.png
|
||||
|
|
586
CHANGELOG.md
586
CHANGELOG.md
|
@ -29,7 +29,6 @@ Types of changes (Stanzas):
|
|||
"Client Breaking" for breaking CLI commands and REST routes used by end-users.
|
||||
"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/
|
||||
-->
|
||||
|
||||
|
@ -39,298 +38,325 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||
|
||||
### Client Breaking
|
||||
|
||||
* (modules) [\#7243](https://github.com/cosmos/cosmos-sdk/pull/7243) Rename `RegisterCodec` to `RegisterLegacyAminoCodec` and `codec.New()` is now renamed to `codec.NewLegacyAmino()`
|
||||
* (cli) [\#6651](https://github.com/cosmos/cosmos-sdk/pull/6651) The `gentx` command has been improved. No longer are `--from` and `--name` flags required. Instead, a single argument, `name`, is required which refers to the key pair in the Keyring. In addition, an optional
|
||||
`--moniker` flag can be provided to override the moniker found in `config.toml`.
|
||||
* (api) [\#6426](https://github.com/cosmos/cosmos-sdk/pull/6426) The ability to start an out-of-process API REST server has now been removed. Instead, the API server is now started in-process along with the application and Tendermint. Configuration options have been added to `app.toml` to enable/disable the API server along with additional HTTP server options.
|
||||
* (baseapp) [\#6384](https://github.com/cosmos/cosmos-sdk/pull/6384) The `Result.Data` is now a Protocol Buffer encoded binary blob of type `TxData`. The `TxData` contains `Data` which contains a list of Protocol Buffer encoded message data and the corresponding message type.
|
||||
* (x/gov) [#6295](https://github.com/cosmos/cosmos-sdk/pull/6295) Fix typo in querying governance params.
|
||||
* (x/auth) [\#6054](https://github.com/cosmos/cosmos-sdk/pull/6054) Remove custom JSON marshaling for base accounts as multsigs cannot be bech32 decoded.
|
||||
* (modules) [\#5572](https://github.com/cosmos/cosmos-sdk/pull/5572) The `/bank/balances/{address}` endpoint now returns all account
|
||||
balances or a single balance by denom when the `denom` query parameter is present.
|
||||
* (client) [\#5640](https://github.com/cosmos/cosmos-sdk/pull/5640) The rest server endpoint `/swagger-ui/` is replaced by ´/´.
|
||||
* (x/auth) [\#5702](https://github.com/cosmos/cosmos-sdk/pull/5702) The `x/auth` querier route has changed from `"acc"` to `"auth"`.
|
||||
* (store/rootmulti) [\#6390](https://github.com/cosmos/cosmos-sdk/pull/6390) Proofs of empty stores are no longer supported.
|
||||
* (store/types) [\#5730](https://github.com/cosmos/cosmos-sdk/pull/5730) store.types.Cp() is removed in favour of types.CopyBytes().
|
||||
* (client) [\#5640](https://github.com/cosmos/cosmos-sdk/issues/5783) Unify all coins representations on JSON client requests for governance proposals.
|
||||
* [\#5785](https://github.com/cosmos/cosmos-sdk/issues/5785) JSON strings coerced to valid UTF-8 bytes at JSON marshalling time
|
||||
are now replaced by human-readable expressions. This change can potentially break compatibility with all those client side tools
|
||||
that parse log messages.
|
||||
* (client) [\#5799](https://github.com/cosmos/cosmos-sdk/pull/5799) The `tx encode/decode` commands, due to change on encoding break compatibility with
|
||||
older clients.
|
||||
* (x/auth) [\#5844](https://github.com/cosmos/cosmos-sdk/pull/5844) `tx sign` command now returns an error when signing is attempted with offline/multisig keys.
|
||||
* (x/auth) [\#6108](https://github.com/cosmos/cosmos-sdk/pull/6108) `tx sign` command's `--validate-signatures` flag is migrated into a `tx validate-signatures` standalone command.
|
||||
* (client/keys) [\#5889](https://github.com/cosmos/cosmos-sdk/pull/5889) Remove `keys update` command.
|
||||
* (x/evidence) [\#5952](https://github.com/cosmos/cosmos-sdk/pull/5952) Remove CLI and REST handlers for querying `x/evidence` parameters.
|
||||
* (server) [\#5982](https://github.com/cosmos/cosmos-sdk/pull/5982) `--pruning` now must be set to `custom` if you want to customise the granular options.
|
||||
* (x/gov) [\#7000](https://github.com/cosmos/cosmos-sdk/pull/7000) [\#6859](https://github.com/cosmos/cosmos-sdk/pull/6859) `ProposalStatus` and `VoteOption` are now JSON serialized using its protobuf name, so expect names like `PROPOSAL_STATUS_DEPOSIT_PERIOD` as opposed to `DepositPeriod`.
|
||||
* (x/auth/vesting) [\#6859](https://github.com/cosmos/cosmos-sdk/pull/6859) Custom JSON marshaling of vesting accounts was removed. Vesting accounts are now marshaled using their default proto or amino JSON representation.
|
||||
* (x/staking) [\#7499](https://github.com/cosmos/cosmos-sdk/pull/7499) `BondStatus` is now a protobuf `enum` instead of an `int32`, and JSON serialized using its protobuf name, so expect names like `BOND_STATUS_UNBONDING` as opposed to `Unbonding`.
|
||||
* (x/evidence) [\#7538](https://github.com/cosmos/cosmos-sdk/pull/7538) The ABCI's `Result.Data` field of `MsgSubmitEvidence` does not contain the raw evidence's hash, but the encoded `MsgSubmitEvidenceResponse` struct.
|
||||
|
||||
### API Breaking Changes
|
||||
### API Breaking
|
||||
|
||||
* (x/bank) [\#7327](https://github.com/cosmos/cosmos-sdk/pull/7327) AddCoins and SubtractCoins no longer return a resultingValue and will only return an error.
|
||||
* (x/evidence) [\#7251](https://github.com/cosmos/cosmos-sdk/pull/7251) New evidence types and light client evidence handling. The module function names changed.
|
||||
* (modules) [\#6564](https://github.com/cosmos/cosmos-sdk/pull/6564) Constant `DefaultParamspace` is removed from all modules, use ModuleName instead.
|
||||
* (client) [\#6525](https://github.com/cosmos/cosmos-sdk/pull/6525) Removed support for `indent` in JSON responses. Clients should consider piping to an external tool such as `jq`.
|
||||
* (x/staking) [\#6451](https://github.com/cosmos/cosmos-sdk/pull/6451) `DefaultParamspace` and `ParamKeyTable` in staking module are moved from keeper to types to enforce consistency.
|
||||
* [\#6409](https://github.com/cosmos/cosmos-sdk/pull/6409) Rename all IsEmpty methods to Empty across the codebase and enforce consistency.
|
||||
* [\#6231](https://github.com/cosmos/cosmos-sdk/pull/6231) Simplify `AppModule` interface, `Route` and `NewHandler` methods become only `Route`
|
||||
and returns a new `Route` type.
|
||||
* [\#6212](https://github.com/cosmos/cosmos-sdk/pull/6212) Remove `Get*` prefixes from key construction functions
|
||||
* [\#6079](https://github.com/cosmos/cosmos-sdk/pull/6079) Remove `UpgradeOldPrivValFile` (deprecated in Tendermint Core v0.28).
|
||||
* (modules) [\#5664](https://github.com/cosmos/cosmos-sdk/pull/5664) Remove amino `Codec` from simulation `StoreDecoder`, which now returns a function closure in order to unmarshal the key-value pairs.
|
||||
* (x/auth) [\#6029](https://github.com/cosmos/cosmos-sdk/pull/6029) Module accounts have been moved from `x/supply` to `x/auth`.
|
||||
* (x/supply) [\#6010](https://github.com/cosmos/cosmos-sdk/pull/6010) All `x/supply` types and APIs have been moved to `x/bank`.
|
||||
* (baseapp) [\#5865](https://github.com/cosmos/cosmos-sdk/pull/5865) The `SimulationResponse` returned from tx simulation is now JSON encoded instead of Amino binary.
|
||||
* [\#5719](https://github.com/cosmos/cosmos-sdk/pull/5719) Bump Go requirement to 1.14+
|
||||
* (x/params) [\#5619](https://github.com/cosmos/cosmos-sdk/pull/5619) The `x/params` keeper now accepts a `codec.Marshaller` instead of
|
||||
a reference to an amino codec. Amino is still used for JSON serialization.
|
||||
* (types) [\#5579](https://github.com/cosmos/cosmos-sdk/pull/5579) The `keepRecent` field has been removed from the `PruningOptions` type.
|
||||
The `PruningOptions` type now only includes fields `KeepEvery` and `SnapshotEvery`, where `KeepEvery`
|
||||
determines which committed heights are flushed to disk and `SnapshotEvery` determines which of these
|
||||
heights are kept after pruning. The `IsValid` method should be called whenever using these options. Methods
|
||||
`SnapshotVersion` and `FlushVersion` accept a version arugment and determine if the version should be
|
||||
flushed to disk or kept as a snapshot. Note, `KeepRecent` is automatically inferred from the options
|
||||
and provided directly the IAVL store.
|
||||
* (modules) [\#5555](https://github.com/cosmos/cosmos-sdk/pull/5555) Move `x/auth/client/utils/` types and functions to `x/auth/client/`.
|
||||
* (modules) [\#5572](https://github.com/cosmos/cosmos-sdk/pull/5572) Move account balance logic and APIs from `x/auth` to `x/bank`.
|
||||
* (types) [\#5533](https://github.com/cosmos/cosmos-sdk/pull/5533) Refactored `AppModuleBasic` and `AppModuleGenesis`
|
||||
to now accept a `codec.JSONMarshaler` for modular serialization of genesis state.
|
||||
* (types/rest) [\#5779](https://github.com/cosmos/cosmos-sdk/pull/5779) Drop unused Parse{Int64OrReturnBadRequest,QueryParamBool}() functions.
|
||||
* (keys) [\#5820](https://github.com/cosmos/cosmos-sdk/pull/5820/) Removed method CloseDB from Keybase interface.
|
||||
* (client/input) [\#5904](https://github.com/cosmos/cosmos-sdk/pull/5904) Removal of unnecessary `GetCheckPassword`, `PrintPrefixed` functions.
|
||||
* (client/keys) [\#5889](https://github.com/cosmos/cosmos-sdk/pull/5889) Rename `NewKeyBaseFromDir()` -> `NewLegacyKeyBaseFromDir()`.
|
||||
* (crypto) [\#5880](https://github.com/cosmos/cosmos-sdk/pull/5880) Merge `crypto/keys/mintkey` into `crypto`.
|
||||
* (crypto/hd) [\#5904](https://github.com/cosmos/cosmos-sdk/pull/5904) `crypto/keys/hd` moved to `crypto/hd`.
|
||||
* (crypto/keyring):
|
||||
* [\#5866](https://github.com/cosmos/cosmos-sdk/pull/5866) Rename `crypto/keys/` to `crypto/keyring/`.
|
||||
* [\#5904](https://github.com/cosmos/cosmos-sdk/pull/5904) `Keybase` -> `Keyring` interfaces migration. `LegacyKeybase` interface is added in order
|
||||
to guarantee limited backward compatibility with the old Keybase interface for the sole purpose of migrating keys across the new keyring backends. `NewLegacy`
|
||||
constructor is provided [\#5889](https://github.com/cosmos/cosmos-sdk/pull/5889) to allow for smooth migration of keys from the legacy LevelDB based implementation
|
||||
to new keyring backends. Plus, the package and the new keyring no longer depends on the sdk.Config singleton. Please consult the package documentation for more
|
||||
information on how to implement the new `Keyring` interface.
|
||||
* [\#5858](https://github.com/cosmos/cosmos-sdk/pull/5858) Make Keyring store keys by name and address's hexbytes representation.
|
||||
* (x/evidence) [\#5952](https://github.com/cosmos/cosmos-sdk/pull/5952) Remove APIs for getting and setting `x/evidence` parameters. `BaseApp` now uses a `ParamStore` to manage Tendermint consensus parameters which is managed via the `x/params` `Substore` type.
|
||||
* (export) [\#5952](https://github.com/cosmos/cosmos-sdk/pull/5952) `AppExporter` now returns ABCI consensus parameters to be included in marshaled exported state. These parameters must be returned from the application via the `BaseApp`.
|
||||
* (codec) `*codec.LegacyAmino` is now a wrapper around Amino which provides backwards compatibility with protobuf `Any`.
|
||||
ALL legacy code should use `*codec.LegacyAmino` instead of `*amino.Codec` directly
|
||||
* (x/gov) [\#6147](https://github.com/cosmos/cosmos-sdk/pull/6147) The `Content` field on `Proposal` and `MsgSubmitProposal`
|
||||
is now `Any` in concordance with [ADR 019](docs/architecture/adr-019-protobuf-state-encoding.md) and `GetContent` should now
|
||||
be used to retrieve the actual proposal `Content`. Also the `NewMsgSubmitProposal` constructor now may return an `error`
|
||||
* (modules) [\#5989](https://github.com/cosmos/cosmos-sdk/pull/5989) `AppModuleBasic.GetTxCmd` now takes a single `CLIContext` parameter.
|
||||
* (x/auth) [\#7006](https://github.com/cosmos/cosmos-sdk/pull/7006) All `AccountRetriever` methods now take `client.Context` as a parameter instead of as a struct member.
|
||||
* (x/auth) [\#6270](https://github.com/cosmos/cosmos-sdk/pull/6270) The passphrase argument has been removed from the signature of the following functions and methods:
|
||||
- BuildAndSign
|
||||
- MakeSignature
|
||||
- SignStdTx
|
||||
- TxBuilder.BuildAndSign
|
||||
- TxBuilder.Sign
|
||||
- TxBuilder.SignStdTx
|
||||
* (client) [\#6290](https://github.com/cosmos/cosmos-sdk/pull/6290) `CLIContext` is renamed to `Context`. `Context` and all related methods have been moved from package context to client.
|
||||
* (modules) [\#6326](https://github.com/cosmos/cosmos-sdk/pull/6326) `AppModuleBasic.GetQueryCmd` now takes a single `CLIContext` parameter.
|
||||
* (modules) [\#6336](https://github.com/cosmos/cosmos-sdk/pull/6336) `AppModuleBasic.RegisterQueryService` method was added to support gRPC queries, and `QuerierRoute` and `NewQuerierHandler` were deprecated.
|
||||
* (modules) [\#6311](https://github.com/cosmos/cosmos-sdk/issues/6311) Remove `alias.go` usage
|
||||
* (x/auth) [\#6443](https://github.com/cosmos/cosmos-sdk/issues/6443) Move `FeeTx` and `TxWithMemo` interfaces from `x/auth/ante` to `types`.
|
||||
* (modules) [\#6447](https://github.com/cosmos/cosmos-sdk/issues/6447) Rename `blacklistedAddrs` to `blockedAddrs`.
|
||||
|
||||
Migration guide:
|
||||
|
||||
```go
|
||||
cliCtx := context.CLIContext{}
|
||||
```
|
||||
|
||||
Now becomes:
|
||||
|
||||
```go
|
||||
clientCtx = client.Context{}
|
||||
```
|
||||
* (client/rpc) [\#6290](https://github.com/cosmos/cosmos-sdk/pull/6290) `RegisterRoutes` of rpc is moved from package client to client/rpc and client/rpc.RegisterRPCRoutes is removed.
|
||||
* (client/lcd) [\#6290](https://github.com/cosmos/cosmos-sdk/pull/6290) `CliCtx` of struct `RestServer` in package client/lcd has been renamed to `ClientCtx`.
|
||||
* (types) [\#6327](https://github.com/cosmos/cosmos-sdk/pull/6327) `sdk.Msg` now inherits `proto.Message`, as a result all `sdk.Msg` types now use pointer semantics.
|
||||
* (codec) [\#6330](https://github.com/cosmos/cosmos-sdk/pull/6330) `codec.RegisterCrypto` has been moved to the `crypto/codec` package and the global `codec.Cdc` Amino instance has been deprecated and moved to the `codec/legacy_global` package.
|
||||
* (x/ibc) [\#6374](https://github.com/cosmos/cosmos-sdk/pull/6374) `VerifyMembership` and `VerifyNonMembership` now take a `specs []string` argument to specify the proof format used for verification. Most SDK chains can simply use `commitmenttypes.GetSDKSpecs()` for this argument.
|
||||
* (crypto/types/multisig) [\#6373](https://github.com/cosmos/cosmos-sdk/pull/6373) `multisig.Multisignature` has been renamed to `AminoMultisignature`
|
||||
* (x/auth) [\#6428](https://github.com/cosmos/cosmos-sdk/issues/6428):
|
||||
* `NewAnteHandler` and `NewSigVerificationDecorator` both now take a `SignModeHandler` parameter.
|
||||
* `SignatureVerificationGasConsumer` now has the signature: `func(meter sdk.GasMeter, sig signing.SignatureV2, params types.Params) error`.
|
||||
* The `SigVerifiableTx` interface now has a `GetSignaturesV2() ([]signing.SignatureV2, error)` method and no longer has the `GetSignBytes` method.
|
||||
* (client/flags) [\#6632](https://github.com/cosmos/cosmos-sdk/pull/6632) Remove NewCompletionCmd(), the function is now available in tendermint.
|
||||
* (crypto) [\#6780](https://github.com/cosmos/cosmos-sdk/issues/6780) Move ledger code to its own package.
|
||||
* (modules) [\#6834](https://github.com/cosmos/cosmos-sdk/issues/6834) Add `RegisterInterfaces` method to `AppModuleBasic` to support registration of protobuf interface types.
|
||||
* (modules) [\#6734](https://github.com/cosmos/cosmos-sdk/issues/6834) Add `TxEncodingConfig` parameter to `AppModuleBasic.ValidateGenesis` command to support JSON tx decoding in `genutil`.
|
||||
* (genesis) [\#7000](https://github.com/cosmos/cosmos-sdk/pull/7000) The root `GenesisState` is now decoded using `encoding/json` instead of amino so `int64` and `uint64` types are now encoded as integers as opposed to strings.
|
||||
* (types) [\#7032](https://github.com/cosmos/cosmos-sdk/pull/7032) All types ending with `ID` (e.g. `ProposalID`) now end with `Id` (e.g. `ProposalId`), to match default Protobuf generated format. Also see [\#7033](https://github.com/cosmos/cosmos-sdk/pull/7033) for more details.
|
||||
* (store) [\#5803](https://github.com/cosmos/cosmos-sdk/pull/5803) The `store.CommitMultiStore` interface now includes the new `snapshots.Snapshotter` interface as well.
|
||||
* (AppModule) [\#7518](https://github.com/cosmos/cosmos-sdk/pull/7518) [\#7584](https://github.com/cosmos/cosmos-sdk/pull/7584) Rename `AppModule.RegisterQueryServices` to `AppModule.RegisterServices`, as this method now registers multiple services (the gRPC query service and the protobuf Msg service). A `Configurator` struct is used to hold the different services.
|
||||
* (x/staking/types) [\#7447](https://github.com/cosmos/cosmos-sdk/issues/7447) Remove bech32 PubKey support:
|
||||
* `ValidatorI` interface update. `GetConsPubKey` renamed to `TmConsPubKey` (consensus public key must be a tendermint key). `TmConsPubKey`, `GetConsAddr` methods return error.
|
||||
* `Validator` update. Methods changed in `ValidatorI` (as described above) and `ToTmValidator` return error.
|
||||
* `Validator.ConsensusPubkey` type changed from `string` to `codectypes.Any`.
|
||||
* `MsgCreateValidator.Pubkey` type changed from `string` to `codectypes.Any`.
|
||||
* Deprecating and renaming `MakeEncodingConfig` to `MakeTestEncodingConfig` (both in `simapp` and `simapp/params` packages).
|
||||
|
||||
### Features
|
||||
|
||||
* [\#7485](https://github.com/cosmos/cosmos-sdk/pull/7485) Introduce a new optional `--keyring-dir` flag that allows clients to specify a Keyring directory if it does not reside in the directory specified by `--home`.
|
||||
* [\#6755](https://github.com/cosmos/cosmos-sdk/pull/6755) Add custom regex validation for `Coin` denom by overwriting `CoinDenomRegex` when using `/types/coin.go`.
|
||||
* [\#7265](https://github.com/cosmos/cosmos-sdk/pull/7265) Support Tendermint block pruning through a new `min-retain-blocks` configuration that can be set in either `app.toml` or via the CLI. This parameter is used in conjunction with other criteria to determine the height at which Tendermint should prune blocks.
|
||||
* (vesting) [\#7209](https://github.com/cosmos/cosmos-sdk/pull/7209) Create new `MsgCreateVestingAccount` message type along with CLI handler that allows for the creation of delayed and continuous vesting types.
|
||||
* (events) [\#7121](https://github.com/cosmos/cosmos-sdk/pull/7121) The application now drives what events are indexed by Tendermint via the `index-events` configuration in `app.toml`, which is a list of events taking the form `{eventType}.{attributeKey}`.
|
||||
* [\#6089](https://github.com/cosmos/cosmos-sdk/pull/6089) Transactions can now have a `TimeoutHeight` set which allows the transaction to be rejected if it's committed at a height greater than the timeout.
|
||||
* (tests) [\#6489](https://github.com/cosmos/cosmos-sdk/pull/6489) Introduce package `testutil`, new in-process testing network framework for use in integration and unit tests.
|
||||
* (crypto/multisig) [\#6241](https://github.com/cosmos/cosmos-sdk/pull/6241) Add Multisig type directly to the repo. Previously this was in tendermint.
|
||||
* (rest) [\#6167](https://github.com/cosmos/cosmos-sdk/pull/6167) Support `max-body-bytes` CLI flag for the REST service.
|
||||
* (x/ibc) [\#5588](https://github.com/cosmos/cosmos-sdk/pull/5588) Add [ICS 024 - Host State Machine Requirements](https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements) subpackage to `x/ibc` module.
|
||||
* (baseapp) [\#5803](https://github.com/cosmos/cosmos-sdk/pull/5803) Added support for taking state snapshots at regular height intervals, via options `snapshot-interval` and `snapshot-keep-recent`.
|
||||
* (store) [\#5803](https://github.com/cosmos/cosmos-sdk/pull/5803) Added `rootmulti.Store` methods for taking and restoring snapshots, based on `iavl.Store` export/import.
|
||||
* (x/ibc) [\#5277](https://github.com/cosmos/cosmos-sdk/pull/5277) `x/ibc` changes from IBC alpha. For more details check the the [`x/ibc/core/spec`](https://github.com/cosmos/tree/master/x/ibc/core/spec) directory:
|
||||
* [ICS 002 - Client Semantics](https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics) subpackage
|
||||
* [ICS 003 - Connection Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-003-connection-semantics) subpackage
|
||||
* [ICS 004 - Channel and Packet Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-004-channel-and-packet-semantics) subpackage
|
||||
* [ICS 005 - Port Allocation](https://github.com/cosmos/ics/blob/master/spec/ics-005-port-allocation) subpackage
|
||||
* [ICS 007 - Tendermint Client](https://github.com/cosmos/ics/blob/master/spec/ics-007-tendermint-client) subpackage
|
||||
* [ICS 020 - Fungible Token Transfer](https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer) module
|
||||
* [ICS 023 - Vector Commitments](https://github.com/cosmos/ics/tree/master/spec/ics-023-vector-commitments) subpackage
|
||||
* (x/capability) [\#5828](https://github.com/cosmos/cosmos-sdk/pull/5828) Capability module integration as outlined in [ADR 3 - Dynamic Capability Store](https://github.com/cosmos/tree/master/docs/architecture/adr-003-dynamic-capability-store.md).
|
||||
* (x/params) [\#6005](https://github.com/cosmos/cosmos-sdk/pull/6005) Add new CLI command for querying raw x/params parameters by subspace and key.
|
||||
* (x/ibc) [\#5769](https://github.com/cosmos/cosmos-sdk/pull/5769) [ICS 009 - Loopback Client](https://github.com/cosmos/ics/tree/master/spec/ics-009-loopback-client) subpackage
|
||||
* (x/ibc) [\#6374](https://github.com/cosmos/cosmos-sdk/pull/6374) ICS-23 Verify functions will now accept and verify ics23 CommitmentProofs exclusively
|
||||
* (store) [\#6324](https://github.com/cosmos/cosmos-sdk/pull/6324) IAVL store query proofs now return CommitmentOp which wraps an ics23 CommitmentProof
|
||||
* (store) [\#6390](https://github.com/cosmos/cosmos-sdk/pull/6390) `RootMulti` store query proofs now return `CommitmentOp` which wraps `CommitmentProofs`
|
||||
* `store.Query` now only returns chained `ics23.CommitmentProof` wrapped in `merkle.Proof`
|
||||
* `ProofRuntime` only decodes and verifies `ics23.CommitmentProof`
|
||||
* (x/auth) [\6350](https://github.com/cosmos/cosmos-sdk/pull/6350) New sign-batch command to sign StdTx batch files.
|
||||
* (codec) [\#7519](https://github.com/cosmos/cosmos-sdk/pull/7519) `InterfaceRegistry` now inherits `jsonpb.AnyResolver`, and has a `RegisterCustomTypeURL` method to support ADR 031 packing of `Any`s. `AnyResolver` is now a required parameter to `RejectUnknownFields`.
|
||||
* (baseapp) [\#7519](https://github.com/cosmos/cosmos-sdk/pull/7519) Add `ServiceMsgRouter` to BaseApp to handle routing of protobuf service `Msg`s. The two new types defined in ADR 031, `sdk.ServiceMsg` and `sdk.MsgRequest` are introduced with this router.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* (types) [\#7038](https://github.com/cosmos/cosmos-sdk/issues/7038) Fix infinite looping of `ApproxRoot` by including a hard-coded maximum iterations limit of 100.
|
||||
* (simulation) [\#7129](https://github.com/cosmos/cosmos-sdk/issues/7129) Fix support for custom `Account` and key types on auth's simulation.
|
||||
* (types) [\#7084](https://github.com/cosmos/cosmos-sdk/pull/7084) Fix panic when calling `BigInt()` on an uninitialized `Int`.
|
||||
* (x/bank) [\#6536](https://github.com/cosmos/cosmos-sdk/pull/6536) Fix bug in `WriteGeneratedTxResponse` function used by multiple
|
||||
REST endpoints. Now it writes a Tx in StdTx format.
|
||||
* (x/staking) [\#6529](https://github.com/cosmos/cosmos-sdk/pull/6529) Export validator addresses (previously was empty).
|
||||
* (export) [\#6510](https://github.com/cosmos/cosmos-sdk/pull/6510/) Field TimeIotaMs now is included in genesis file while exporting.
|
||||
* (client) [\#6402](https://github.com/cosmos/cosmos-sdk/issues/6402) Fix `keys add` `--algo` flag which only worked for Tendermint's `secp256k1` default key signing algorithm.
|
||||
* (x/staking) [\#6061](https://github.com/cosmos/cosmos-sdk/pull/6061) Allow a validator to immediately unjail when no signing info is present due to
|
||||
falling below their minimum self-delegation and never having been bonded. The validator may immediately unjail once they've met their minimum self-delegation.
|
||||
* (modules) [\#5569](https://github.com/cosmos/cosmos-sdk/issues/5569) `InitGenesis`, for the relevant modules, now ensures module accounts exist.
|
||||
* (crypto/keyring) [\#5844](https://github.com/cosmos/cosmos-sdk/pull/5844) `Keyring.Sign()` methods no longer decode amino signatures when method receivers
|
||||
are offline/multisig keys.
|
||||
* (x/auth) [\#5892](https://github.com/cosmos/cosmos-sdk/pull/5892) Add `RegisterKeyTypeCodec` to register new
|
||||
types (eg. keys) to the `auth` module internal amino codec.
|
||||
* (rest) [\#5906](https://github.com/cosmos/cosmos-sdk/pull/5906) Fix an issue that make some REST calls panic when sending
|
||||
invalid or incomplete requests.
|
||||
* (x/genutil) [\#5938](https://github.com/cosmos/cosmos-sdk/pull/5938) Fix `InitializeNodeValidatorFiles` error handling.
|
||||
* (x/staking) [\#5949](https://github.com/cosmos/cosmos-sdk/pull/5949) Skip staking `HistoricalInfoKey` in simulations as headers are not exported.
|
||||
* (client) [\#5964](https://github.com/cosmos/cosmos-sdk/issues/5964) `--trust-node` is now false by default - for real. Users must ensure it is set to true if they don't want to enable the verifier.
|
||||
* (kvstore) [\#7415](https://github.com/cosmos/cosmos-sdk/pull/7415) Allow new stores to be registered during on-chain upgrades.
|
||||
|
||||
|
||||
## [v0.40.0-rc0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.40.0-rc0) - 2020-10-13
|
||||
|
||||
v0.40.0, known as the Stargate release of the Cosmos SDK, is one of the largest releases
|
||||
of the Cosmos SDK since launch. Please read through this changelog and [release notes](./RELEASE_NOTES.md) to make sure you are aware of any relevant breaking changes.
|
||||
|
||||
### Client Breaking Changes
|
||||
|
||||
* __CLI__
|
||||
* (client/keys) [\#5889](https://github.com/cosmos/cosmos-sdk/pull/5889) remove `keys update` command.
|
||||
* (x/auth) [\#5844](https://github.com/cosmos/cosmos-sdk/pull/5844) `tx sign` command now returns an error when signing is attempted with offline/multisig keys.
|
||||
* (x/auth) [\#6108](https://github.com/cosmos/cosmos-sdk/pull/6108) `tx sign` command's `--validate-signatures` flag is migrated into a `tx validate-signatures` standalone command.
|
||||
* (x/genutil) [\#6651](https://github.com/cosmos/cosmos-sdk/pull/6651) The `gentx` command has been improved. No longer are `--from` and `--name` flags required. Instead, a single argument, `name`, is required which refers to the key pair in the Keyring. In addition, an optional
|
||||
`--moniker` flag can be provided to override the moniker found in `config.toml`.
|
||||
* __REST / Queriers__
|
||||
* (api) [\#6426](https://github.com/cosmos/cosmos-sdk/pull/6426) The ability to start an out-of-process API REST server has now been removed. Instead, the API server is now started in-process along with the application and Tendermint. Configuration options have been added to `app.toml` to enable/disable the API server along with additional HTTP server options.
|
||||
* (client) [\#7246](https://github.com/cosmos/cosmos-sdk/pull/7246) The rest server endpoint `/swagger-ui/` is replaced by `/swagger/`, and contains swagger documentation for gRPC Gateway routes in addition to legacy REST routes. Swagger API is exposed only if set in `app.toml`.
|
||||
* (x/auth) [\#5702](https://github.com/cosmos/cosmos-sdk/pull/5702) The `x/auth` querier route has changed from `"acc"` to `"auth"`.
|
||||
* (x/bank) [\#5572](https://github.com/cosmos/cosmos-sdk/pull/5572) The `/bank/balances/{address}` endpoint now returns all account balances or a single balance by denom when the `denom` query parameter is present.
|
||||
* (x/evidence) [\#5952](https://github.com/cosmos/cosmos-sdk/pull/5952) Remove CLI and REST handlers for querying `x/evidence` parameters.
|
||||
* (x/gov) [#6295](https://github.com/cosmos/cosmos-sdk/pull/6295) Fix typo in querying governance params.
|
||||
* __General__
|
||||
* (baseapp) [\#6384](https://github.com/cosmos/cosmos-sdk/pull/6384) The `Result.Data` is now a Protocol Buffer encoded binary blob of type `TxData`. The `TxData` contains `Data` which contains a list of Protocol Buffer encoded message data and the corresponding message type.
|
||||
* (client) [\#5783](https://github.com/cosmos/cosmos-sdk/issues/5783) Unify all coins representations on JSON client requests for governance proposals.
|
||||
* (store/rootmulti) [\#6390](https://github.com/cosmos/cosmos-sdk/pull/6390) Proofs of empty stores are no longer supported.
|
||||
* (store/types) [\#5730](https://github.com/cosmos/cosmos-sdk/pull/5730) store.types.Cp() is removed in favour of types.CopyBytes().
|
||||
* (x/auth) [\#6054](https://github.com/cosmos/cosmos-sdk/pull/6054) Remove custom JSON marshaling for base accounts as multsigs cannot be bech32 decoded.
|
||||
* (x/auth/vesting) [\#6859](https://github.com/cosmos/cosmos-sdk/pull/6859) Custom JSON marshaling of vesting accounts was removed. Vesting accounts are now marshaled using their default proto or amino JSON representation.
|
||||
* (x/bank) [\#5785](https://github.com/cosmos/cosmos-sdk/issues/5785) In x/bank errors, JSON strings coerced to valid UTF-8 bytes at JSON marshalling time
|
||||
are now replaced by human-readable expressions. This change can potentially break compatibility with all those client side tools
|
||||
that parse log messages.
|
||||
* (x/gov) [\#6859](https://github.com/cosmos/cosmos-sdk/pull/6859) `ProposalStatus` and `VoteOption` are now JSON serialized using its protobuf name, so expect names like `PROPOSAL_STATUS_DEPOSIT_PERIOD` as opposed to `DepositPeriod`.
|
||||
|
||||
### API Breaking Changes
|
||||
|
||||
* __Baseapp / Client__
|
||||
* (baseapp) [\#5865](https://github.com/cosmos/cosmos-sdk/pull/5865) The `SimulationResponse` returned from tx simulation is now JSON encoded instead of Amino binary.
|
||||
* (client) [\#6290](https://github.com/cosmos/cosmos-sdk/pull/6290) `CLIContext` is renamed to `Context`. `Context` and all related methods have been moved from package context to client.
|
||||
* (client) [\#6525](https://github.com/cosmos/cosmos-sdk/pull/6525) Removed support for `indent` in JSON responses. Clients should consider piping to an external tool such as `jq`.
|
||||
* (client/flags) [\#6632](https://github.com/cosmos/cosmos-sdk/pull/6632) Remove NewCompletionCmd(), the function is now available in tendermint.
|
||||
* (client/input) [\#5904](https://github.com/cosmos/cosmos-sdk/pull/5904) Removal of unnecessary `GetCheckPassword`, `PrintPrefixed` functions.
|
||||
* (client/keys) [\#5889](https://github.com/cosmos/cosmos-sdk/pull/5889) Rename `NewKeyBaseFromDir()` -> `NewLegacyKeyBaseFromDir()`.
|
||||
* (client/keys) [\#5820](https://github.com/cosmos/cosmos-sdk/pull/5820/) Removed method CloseDB from Keybase interface.
|
||||
* (client/rpc) [\#6290](https://github.com/cosmos/cosmos-sdk/pull/6290) `client` package and subdirs reorganization.
|
||||
* (client/lcd) [\#6290](https://github.com/cosmos/cosmos-sdk/pull/6290) `CliCtx` of struct `RestServer` in package client/lcd has been renamed to `ClientCtx`.
|
||||
* (codec) [\#6330](https://github.com/cosmos/cosmos-sdk/pull/6330) `codec.RegisterCrypto` has been moved to the `crypto/codec` package and the global `codec.Cdc` Amino instance has been deprecated and moved to the `codec/legacy_global` package.
|
||||
* (crypto) [\#6780](https://github.com/cosmos/cosmos-sdk/issues/6780) Move ledger code to its own package.
|
||||
* (crypto/types/multisig) [\#6373](https://github.com/cosmos/cosmos-sdk/pull/6373) `multisig.Multisignature` has been renamed to `AminoMultisignature`
|
||||
* (codec) `*codec.LegacyAmino` is now a wrapper around Amino which provides backwards compatibility with protobuf `Any`. ALL legacy code should use `*codec.LegacyAmino` instead of `*amino.Codec` directly
|
||||
* (crypto) [\#5880](https://github.com/cosmos/cosmos-sdk/pull/5880) Merge `crypto/keys/mintkey` into `crypto`.
|
||||
* (crypto/hd) [\#5904](https://github.com/cosmos/cosmos-sdk/pull/5904) `crypto/keys/hd` moved to `crypto/hd`.
|
||||
* (crypto/keyring):
|
||||
* [\#5866](https://github.com/cosmos/cosmos-sdk/pull/5866) Rename `crypto/keys/` to `crypto/keyring/`.
|
||||
* [\#5904](https://github.com/cosmos/cosmos-sdk/pull/5904) `Keybase` -> `Keyring` interfaces migration. `LegacyKeybase` interface is added in order
|
||||
to guarantee limited backward compatibility with the old Keybase interface for the sole purpose of migrating keys across the new keyring backends. `NewLegacy`
|
||||
constructor is provided [\#5889](https://github.com/cosmos/cosmos-sdk/pull/5889) to allow for smooth migration of keys from the legacy LevelDB based implementation
|
||||
to new keyring backends. Plus, the package and the new keyring no longer depends on the sdk.Config singleton. Please consult the [package documentation](https://github.com/cosmos/cosmos-sdk/tree/master/crypto/keyring/doc.go) for more
|
||||
information on how to implement the new `Keyring` interface.
|
||||
* [\#5858](https://github.com/cosmos/cosmos-sdk/pull/5858) Make Keyring store keys by name and address's hexbytes representation.
|
||||
* (export) [\#5952](https://github.com/cosmos/cosmos-sdk/pull/5952) `AppExporter` now returns ABCI consensus parameters to be included in marshaled exported state. These parameters must be returned from the application via the `BaseApp`.
|
||||
* (store) [\#5803](https://github.com/cosmos/cosmos-sdk/pull/5803) The `store.CommitMultiStore` interface now includes the new `snapshots.Snapshotter` interface as well.
|
||||
* (types) [\#5579](https://github.com/cosmos/cosmos-sdk/pull/5579) The `keepRecent` field has been removed from the `PruningOptions` type.
|
||||
The `PruningOptions` type now only includes fields `KeepEvery` and `SnapshotEvery`, where `KeepEvery`
|
||||
determines which committed heights are flushed to disk and `SnapshotEvery` determines which of these
|
||||
heights are kept after pruning. The `IsValid` method should be called whenever using these options. Methods
|
||||
`SnapshotVersion` and `FlushVersion` accept a version arugment and determine if the version should be
|
||||
flushed to disk or kept as a snapshot. Note, `KeepRecent` is automatically inferred from the options
|
||||
and provided directly the IAVL store.
|
||||
* (types) [\#5533](https://github.com/cosmos/cosmos-sdk/pull/5533) Refactored `AppModuleBasic` and `AppModuleGenesis`
|
||||
to now accept a `codec.JSONMarshaler` for modular serialization of genesis state.
|
||||
* (types/rest) [\#5779](https://github.com/cosmos/cosmos-sdk/pull/5779) Drop unused Parse{Int64OrReturnBadRequest,QueryParamBool}() functions.
|
||||
* __Modules__
|
||||
* (modules) [\#7243](https://github.com/cosmos/cosmos-sdk/pull/7243) Rename `RegisterCodec` to `RegisterLegacyAminoCodec` and `codec.New()` is now renamed to `codec.NewLegacyAmino()`
|
||||
* (modules) [\#6564](https://github.com/cosmos/cosmos-sdk/pull/6564) Constant `DefaultParamspace` is removed from all modules, use ModuleName instead.
|
||||
* (modules) [\#5989](https://github.com/cosmos/cosmos-sdk/pull/5989) `AppModuleBasic.GetTxCmd` now takes a single `CLIContext` parameter.
|
||||
* (modules) [\#5664](https://github.com/cosmos/cosmos-sdk/pull/5664) Remove amino `Codec` from simulation `StoreDecoder`, which now returns a function closure in order to unmarshal the key-value pairs.
|
||||
* (modules) [\#5555](https://github.com/cosmos/cosmos-sdk/pull/5555) Move `x/auth/client/utils/` types and functions to `x/auth/client/`.
|
||||
* (modules) [\#5572](https://github.com/cosmos/cosmos-sdk/pull/5572) Move account balance logic and APIs from `x/auth` to `x/bank`.
|
||||
* (modules) [\#6326](https://github.com/cosmos/cosmos-sdk/pull/6326) `AppModuleBasic.GetQueryCmd` now takes a single `client.Context` parameter.
|
||||
* (modules) [\#6336](https://github.com/cosmos/cosmos-sdk/pull/6336) `AppModuleBasic.RegisterQueryService` method was added to support gRPC queries, and `QuerierRoute` and `NewQuerierHandler` were deprecated.
|
||||
* (modules) [\#6311](https://github.com/cosmos/cosmos-sdk/issues/6311) Remove `alias.go` usage
|
||||
* (modules) [\#6447](https://github.com/cosmos/cosmos-sdk/issues/6447) Rename `blacklistedAddrs` to `blockedAddrs`.
|
||||
* (modules) [\#6834](https://github.com/cosmos/cosmos-sdk/issues/6834) Add `RegisterInterfaces` method to `AppModuleBasic` to support registration of protobuf interface types.
|
||||
* (modules) [\#6734](https://github.com/cosmos/cosmos-sdk/issues/6834) Add `TxEncodingConfig` parameter to `AppModuleBasic.ValidateGenesis` command to support JSON tx decoding in `genutil`.
|
||||
* (types) [\#6327](https://github.com/cosmos/cosmos-sdk/pull/6327) `sdk.Msg` now inherits `proto.Message`, as a result all `sdk.Msg` types now use pointer semantics.
|
||||
* (types) [\#7032](https://github.com/cosmos/cosmos-sdk/pull/7032) All types ending with `ID` (e.g. `ProposalID`) now end with `Id` (e.g. `ProposalId`), to match default Protobuf generated format. Also see [\#7033](https://github.com/cosmos/cosmos-sdk/pull/7033) for more details.
|
||||
* (x/auth) [\#6029](https://github.com/cosmos/cosmos-sdk/pull/6029) Module accounts have been moved from `x/supply` to `x/auth`.
|
||||
* (x/auth) [\#6443](https://github.com/cosmos/cosmos-sdk/issues/6443) Move `FeeTx` and `TxWithMemo` interfaces from `x/auth/ante` to `types`.
|
||||
* (x/bank) [\#7327](https://github.com/cosmos/cosmos-sdk/pull/7327) AddCoins and SubtractCoins no longer return a resultingValue and will only return an error.
|
||||
* (x/evidence) [\#7251](https://github.com/cosmos/cosmos-sdk/pull/7251) New evidence types and light client evidence handling. The module function names changed.
|
||||
* (x/ibc) [\#6374](https://github.com/cosmos/cosmos-sdk/pull/6374) `VerifyMembership` and `VerifyNonMembership` now take a `specs []string` argument to specify the proof format used for verification. Most SDK chains can simply use `commitmenttypes.GetSDKSpecs()` for this argument.
|
||||
* (x/params) [\#5619](https://github.com/cosmos/cosmos-sdk/pull/5619) The `x/params` keeper now accepts a `codec.Marshaller` instead of
|
||||
a reference to an amino codec. Amino is still used for JSON serialization.
|
||||
* (x/staking) [\#6451](https://github.com/cosmos/cosmos-sdk/pull/6451) `DefaultParamspace` and `ParamKeyTable` in staking module are moved from keeper to types to enforce consistency.
|
||||
* (x/supply) [\#6010](https://github.com/cosmos/cosmos-sdk/pull/6010) All `x/supply` types and APIs have been moved to `x/bank`.
|
||||
* [\#6409](https://github.com/cosmos/cosmos-sdk/pull/6409) Rename all IsEmpty methods to Empty across the codebase and enforce consistency.
|
||||
* [\#6231](https://github.com/cosmos/cosmos-sdk/pull/6231) Simplify `AppModule` interface, `Route` and `NewHandler` methods become only `Route`
|
||||
and returns a new `Route` type.
|
||||
* (x/slashing) [\#6212](https://github.com/cosmos/cosmos-sdk/pull/6212) Remove `Get*` prefixes from key construction functions
|
||||
* (server) [\#6079](https://github.com/cosmos/cosmos-sdk/pull/6079) Remove `UpgradeOldPrivValFile` (deprecated in Tendermint Core v0.28).
|
||||
* [\#5719](https://github.com/cosmos/cosmos-sdk/pull/5719) Bump Go requirement to 1.14+
|
||||
* (x/evidence) [\#5952](https://github.com/cosmos/cosmos-sdk/pull/5952) Remove APIs for getting and setting `x/evidence` parameters. `BaseApp` now uses a `ParamStore` to manage Tendermint consensus parameters which is managed via the `x/params` `Substore` type.
|
||||
* (x/gov) [\#6147](https://github.com/cosmos/cosmos-sdk/pull/6147) The `Content` field on `Proposal` and `MsgSubmitProposal`
|
||||
is now `Any` in concordance with [ADR 019](docs/architecture/adr-019-protobuf-state-encoding.md) and `GetContent` should now
|
||||
be used to retrieve the actual proposal `Content`. Also the `NewMsgSubmitProposal` constructor now may return an `error`
|
||||
* (x/auth) [\#7006](https://github.com/cosmos/cosmos-sdk/pull/7006) All `AccountRetriever` methods now take `client.Context` as a parameter instead of as a struct member.
|
||||
* (x/auth) [\#6270](https://github.com/cosmos/cosmos-sdk/pull/6270) The passphrase argument has been removed from the signature of the following functions and methods: `BuildAndSign`, ` MakeSignature`, ` SignStdTx`, `TxBuilder.BuildAndSign`, `TxBuilder.Sign`, `TxBuilder.SignStdTx`
|
||||
* (x/auth) [\#6428](https://github.com/cosmos/cosmos-sdk/issues/6428):
|
||||
* `NewAnteHandler` and `NewSigVerificationDecorator` both now take a `SignModeHandler` parameter.
|
||||
* `SignatureVerificationGasConsumer` now has the signature: `func(meter sdk.GasMeter, sig signing.SignatureV2, params types.Params) error`.
|
||||
* The `SigVerifiableTx` interface now has a `GetSignaturesV2() ([]signing.SignatureV2, error)` method and no longer has the `GetSignBytes` method.
|
||||
|
||||
### State Machine Breaking
|
||||
|
||||
* (x/staking) [\#6844](https://github.com/cosmos/cosmos-sdk/pull/6844) Validators are now inserted into the unbonding queue based on their unbonding time and height. The relevant keeper APIs are modified to reflect these changes by now also requiring a height.
|
||||
* (x/bank) [\#6518](https://github.com/cosmos/cosmos-sdk/pull/6518) Support for global and per-denomination send enabled flags.
|
||||
* Existing send_enabled global flag has been moved into a Params structure as `default_send_enabled`.
|
||||
* An array of: `{denom: string, enabled: bool}` is added to bank Params to support per-denomination override of global default value.
|
||||
* (x/staking) [\#6061](https://github.com/cosmos/cosmos-sdk/pull/6061) Allow a validator to immediately unjail when no signing info is present due to
|
||||
* __General__
|
||||
* (client) [\#7268](https://github.com/cosmos/cosmos-sdk/pull/7268) / [\#7147](https://github.com/cosmos/cosmos-sdk/pull/7147) Introduce new protobuf based PubKeys, and migrate PubKey in BaseAccount to use this new protobuf based PubKey format
|
||||
|
||||
* __Modules__
|
||||
* (modules) [\#5572](https://github.com/cosmos/cosmos-sdk/pull/5572) Separate balance from accounts per ADR 004.
|
||||
* Account balances are now persisted and retrieved via the `x/bank` module.
|
||||
* Vesting account interface has been modified to account for changes.
|
||||
* Callers to `NewBaseVestingAccount` are responsible for verifying account balance in relation to
|
||||
the original vesting amount.
|
||||
* The `SendKeeper` and `ViewKeeper` interfaces in `x/bank` have been modified to account for changes.
|
||||
* (x/auth) [\#5533](https://github.com/cosmos/cosmos-sdk/pull/5533) Migrate the `x/auth` module to use Protocol Buffers for state
|
||||
serialization instead of Amino.
|
||||
* The `BaseAccount.PubKey` field is now represented as a Bech32 string instead of a `crypto.Pubkey`.
|
||||
* `NewBaseAccountWithAddress` now returns a reference to a `BaseAccount`.
|
||||
* The `x/auth` module now accepts a `Codec` interface which extends the `codec.Marshaler` interface by
|
||||
requiring a concrete codec to know how to serialize accounts.
|
||||
* The `AccountRetriever` type now accepts a `Codec` in its constructor in order to know how to
|
||||
serialize accounts.
|
||||
* (x/bank) [\#6518](https://github.com/cosmos/cosmos-sdk/pull/6518) Support for global and per-denomination send enabled flags.
|
||||
* Existing send_enabled global flag has been moved into a Params structure as `default_send_enabled`.
|
||||
* An array of: `{denom: string, enabled: bool}` is added to bank Params to support per-denomination override of global default value.
|
||||
* (x/distribution) [\#5610](https://github.com/cosmos/cosmos-sdk/pull/5610) Migrate the `x/distribution` module to use Protocol Buffers for state
|
||||
serialization instead of Amino. The exact codec used is `codec.HybridCodec` which utilizes Protobuf for binary encoding and Amino
|
||||
for JSON encoding.
|
||||
* `ValidatorHistoricalRewards.ReferenceCount` is now of types `uint32` instead of `uint16`.
|
||||
* `ValidatorSlashEvents` is now a struct with `slashevents`.
|
||||
* `ValidatorOutstandingRewards` is now a struct with `rewards`.
|
||||
* `ValidatorAccumulatedCommission` is now a struct with `commission`.
|
||||
* The `Keeper` constructor now takes a `codec.Marshaler` instead of a concrete Amino codec. This exact type
|
||||
provided is specified by `ModuleCdc`.
|
||||
* (x/evidence) [\#5634](https://github.com/cosmos/cosmos-sdk/pull/5634) Migrate the `x/evidence` module to use Protocol Buffers for state
|
||||
serialization instead of Amino.
|
||||
* The `internal` sub-package has been removed in order to expose the types proto file.
|
||||
* The module now accepts a `Codec` interface which extends the `codec.Marshaler` interface by
|
||||
requiring a concrete codec to know how to serialize `Evidence` types.
|
||||
* The `MsgSubmitEvidence` message has been removed in favor of `MsgSubmitEvidenceBase`. The application-level
|
||||
codec must now define the concrete `MsgSubmitEvidence` type which must implement the module's `MsgSubmitEvidence`
|
||||
interface.
|
||||
* (x/evidence) [\#5952](https://github.com/cosmos/cosmos-sdk/pull/5952) Remove parameters from `x/evidence` genesis and module state. The `x/evidence` module now solely uses Tendermint consensus parameters to determine of evidence is valid or not.
|
||||
* (x/gov) [\#5737](https://github.com/cosmos/cosmos-sdk/pull/5737) Migrate the `x/gov` module to use Protocol
|
||||
Buffers for state serialization instead of Amino.
|
||||
* `MsgSubmitProposal` will be removed in favor of the application-level proto-defined `MsgSubmitProposal` which
|
||||
implements the `MsgSubmitProposalI` interface. Applications should extend the `NewMsgSubmitProposalBase` type
|
||||
to define their own concrete `MsgSubmitProposal` types.
|
||||
* The module now accepts a `Codec` interface which extends the `codec.Marshaler` interface by
|
||||
requiring a concrete codec to know how to serialize `Proposal` types.
|
||||
* (x/mint) [\#5634](https://github.com/cosmos/cosmos-sdk/pull/5634) Migrate the `x/mint` module to use Protocol Buffers for state
|
||||
serialization instead of Amino.
|
||||
* The `internal` sub-package has been removed in order to expose the types proto file.
|
||||
* (x/slashing) [\#5627](https://github.com/cosmos/cosmos-sdk/pull/5627) Migrate the `x/slashing` module to use Protocol Buffers for state
|
||||
serialization instead of Amino. The exact codec used is `codec.HybridCodec` which utilizes Protobuf for binary encoding and Amino
|
||||
for JSON encoding.
|
||||
* The `Keeper` constructor now takes a `codec.Marshaler` instead of a concrete Amino codec. This exact type
|
||||
provided is specified by `ModuleCdc`.
|
||||
* (x/staking) [\#6844](https://github.com/cosmos/cosmos-sdk/pull/6844) Validators are now inserted into the unbonding queue based on their unbonding time and height. The relevant keeper APIs are modified to reflect these changes by now also requiring a height.
|
||||
* (x/staking) [\#6061](https://github.com/cosmos/cosmos-sdk/pull/6061) Allow a validator to immediately unjail when no signing info is present due to
|
||||
falling below their minimum self-delegation and never having been bonded. The validator may immediately unjail once they've met their minimum self-delegation.
|
||||
* (x/staking) [\#5600](https://github.com/cosmos/cosmos-sdk/pull/5600) Migrate the `x/staking` module to use Protocol Buffers for state
|
||||
serialization instead of Amino. The exact codec used is `codec.HybridCodec` which utilizes Protobuf for binary encoding and Amino
|
||||
for JSON encoding.
|
||||
* `BondStatus` is now of type `int32` instead of `byte`.
|
||||
* Types of `int16` in the `Params` type are now of type `int32`.
|
||||
* Every reference of `crypto.Pubkey` in context of a `Validator` is now of type string. `GetPubKeyFromBech32` must be used to get the `crypto.Pubkey`.
|
||||
* The `Keeper` constructor now takes a `codec.Marshaler` instead of a concrete Amino codec. This exact type
|
||||
provided is specified by `ModuleCdc`.
|
||||
* (x/supply) [\#6010](https://github.com/cosmos/cosmos-sdk/pull/6010) Removed the `x/supply` module by merging the existing types and APIs into the `x/bank` module.
|
||||
* (x/supply) [\#5533](https://github.com/cosmos/cosmos-sdk/pull/5533) Migrate the `x/supply` module to use Protocol Buffers for state
|
||||
serialization instead of Amino.
|
||||
* The `internal` sub-package has been removed in order to expose the types proto file.
|
||||
* The `x/supply` module now accepts a `Codec` interface which extends the `codec.Marshaler` interface by
|
||||
requiring a concrete codec to know how to serialize `SupplyI` types.
|
||||
* The `SupplyI` interface has been modified to no longer return `SupplyI` on methods. Instead the
|
||||
concrete type's receiver should modify the type.
|
||||
* (x/upgrade) [\#5659](https://github.com/cosmos/cosmos-sdk/pull/5659) Migrate the `x/upgrade` module to use Protocol
|
||||
Buffers for state serialization instead of Amino.
|
||||
* The `internal` sub-package has been removed in order to expose the types proto file.
|
||||
* The `x/upgrade` module now accepts a `codec.Marshaler` interface.
|
||||
|
||||
### Features
|
||||
|
||||
* __Baseapp / Client / REST__
|
||||
* (x/auth) [\#6213](https://github.com/cosmos/cosmos-sdk/issues/6213) Introduce new protobuf based path for transaction signing, see [ADR020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md) for more details
|
||||
* (x/auth) [\#6350](https://github.com/cosmos/cosmos-sdk/pull/6350) New sign-batch command to sign StdTx batch files.
|
||||
* (baseapp) [\#5803](https://github.com/cosmos/cosmos-sdk/pull/5803) Added support for taking state snapshots at regular height intervals, via options `snapshot-interval` and `snapshot-keep-recent`.
|
||||
* (client) [\#5921](https://github.com/cosmos/cosmos-sdk/issues/5921) Introduce new gRPC and gRPC Gateway based APIs for querying app & module data. See [ADR021](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-021-protobuf-query-encoding.md) for more details
|
||||
* (cli) [\#7485](https://github.com/cosmos/cosmos-sdk/pull/7485) Introduce a new optional `--keyring-dir` flag that allows clients to specify a Keyring directory if it does not reside in the directory specified by `--home`.
|
||||
* (coin) [\#6755](https://github.com/cosmos/cosmos-sdk/pull/6755) Add custom regex validation for `Coin` denom by overwriting `CoinDenomRegex` when using `/types/coin.go`.
|
||||
* (config) [\#7265](https://github.com/cosmos/cosmos-sdk/pull/7265) Support Tendermint block pruning through a new `min-retain-blocks` configuration that can be set in either `app.toml` or via the CLI. This parameter is used in conjunction with other criteria to determine the height at which Tendermint should prune blocks.
|
||||
* (events) [\#7121](https://github.com/cosmos/cosmos-sdk/pull/7121) The application now derives what events are indexed by Tendermint via the `index-events` configuration in `app.toml`, which is a list of events taking the form `{eventType}.{attributeKey}`.
|
||||
* (tx) [\#6089](https://github.com/cosmos/cosmos-sdk/pull/6089) Transactions can now have a `TimeoutHeight` set which allows the transaction to be rejected if it's committed at a height greater than the timeout.
|
||||
* (rest) [\#6167](https://github.com/cosmos/cosmos-sdk/pull/6167) Support `max-body-bytes` CLI flag for the REST service.
|
||||
* (genesis) [\#7089](https://github.com/cosmos/cosmos-sdk/pull/7089) The `export` command now adds a `initial_height` field in the exported JSON. Baseapp's `CommitMultiStore` now also has a `SetInitialVersion` setter, so it can set the initial store version inside `InitChain` and start a new chain from a given height.
|
||||
* __General__
|
||||
* (crypto/multisig) [\#6241](https://github.com/cosmos/cosmos-sdk/pull/6241) Add Multisig type directly to the repo. Previously this was in tendermint.
|
||||
* (tests) [\#6489](https://github.com/cosmos/cosmos-sdk/pull/6489) Introduce package `testutil`, new in-process testing network framework for use in integration and unit tests.
|
||||
* (store) [\#5803](https://github.com/cosmos/cosmos-sdk/pull/5803) Added `rootmulti.Store` methods for taking and restoring snapshots, based on `iavl.Store` export/import.
|
||||
* (store) [\#6324](https://github.com/cosmos/cosmos-sdk/pull/6324) IAVL store query proofs now return CommitmentOp which wraps an ics23 CommitmentProof
|
||||
* (store) [\#6390](https://github.com/cosmos/cosmos-sdk/pull/6390) `RootMulti` store query proofs now return `CommitmentOp` which wraps `CommitmentProofs`
|
||||
* `store.Query` now only returns chained `ics23.CommitmentProof` wrapped in `merkle.Proof`
|
||||
* `ProofRuntime` only decodes and verifies `ics23.CommitmentProof`
|
||||
* __Modules__
|
||||
* (modules) [\#5921](https://github.com/cosmos/cosmos-sdk/issues/5921) Introduction of Query gRPC service definitions along with REST annotations for gRPC Gateway for each module
|
||||
* (x/auth/vesting) [\#7209](https://github.com/cosmos/cosmos-sdk/pull/7209) Create new `MsgCreateVestingAccount` message type along with CLI handler that allows for the creation of delayed and continuous vesting types.
|
||||
* (x/capability) [\#5828](https://github.com/cosmos/cosmos-sdk/pull/5828) Capability module integration as outlined in [ADR 3 - Dynamic Capability Store](https://github.com/cosmos/tree/master/docs/architecture/adr-003-dynamic-capability-store.md).
|
||||
* (x/ibc) [\#5277](https://github.com/cosmos/cosmos-sdk/pull/5277) `x/ibc` changes from IBC alpha. For more details check the the [`x/ibc/core/spec`](https://github.com/cosmos/cosmos-sdk/tree/master/x/ibc/core/spec) directory, or the ICS specs below:
|
||||
* [ICS 002 - Client Semantics](https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics) subpackage
|
||||
* [ICS 003 - Connection Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-003-connection-semantics) subpackage
|
||||
* [ICS 004 - Channel and Packet Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-004-channel-and-packet-semantics) subpackage
|
||||
* [ICS 005 - Port Allocation](https://github.com/cosmos/ics/blob/master/spec/ics-005-port-allocation) subpackage
|
||||
* [ICS 006 - Solo Machine Client](https://github.com/cosmos/ics/tree/master/spec/ics-006-solo-machine-client) subpackage
|
||||
* [ICS 007 - Tendermint Client](https://github.com/cosmos/ics/blob/master/spec/ics-007-tendermint-client) subpackage
|
||||
* [ICS 009 - Loopback Client](https://github.com/cosmos/ics/tree/master/spec/ics-009-loopback-client) subpackage
|
||||
* [ICS 020 - Fungible Token Transfer](https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer) subpackage
|
||||
* [ICS 023 - Vector Commitments](https://github.com/cosmos/ics/tree/master/spec/ics-023-vector-commitments) subpackage
|
||||
* [ICS 024 - Host State Machine Requirements](https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements) subpackage
|
||||
* (x/ibc) [\#6374](https://github.com/cosmos/cosmos-sdk/pull/6374) ICS-23 Verify functions will now accept and verify ics23 CommitmentProofs exclusively
|
||||
* (x/params) [\#6005](https://github.com/cosmos/cosmos-sdk/pull/6005) Add new CLI command for querying raw x/params parameters by subspace and key.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* __Baseapp / Client / REST__
|
||||
* (client) [\#5964](https://github.com/cosmos/cosmos-sdk/issues/5964) `--trust-node` is now false by default - for real. Users must ensure it is set to true if they don't want to enable the verifier.
|
||||
* (client) [\#6402](https://github.com/cosmos/cosmos-sdk/issues/6402) Fix `keys add` `--algo` flag which only worked for Tendermint's `secp256k1` default key signing algorithm.
|
||||
* (export) [\#6510](https://github.com/cosmos/cosmos-sdk/pull/6510/) Field TimeIotaMs now is included in genesis file while exporting.
|
||||
* (rest) [\#5906](https://github.com/cosmos/cosmos-sdk/pull/5906) Fix an issue that make some REST calls panic when sending invalid or incomplete requests.
|
||||
* (crypto/keyring) [\#5844](https://github.com/cosmos/cosmos-sdk/pull/5844) `Keyring.Sign()` methods no longer decode amino signatures when method receivers
|
||||
are offline/multisig keys.
|
||||
* __Modules__
|
||||
* (modules) [\#5569](https://github.com/cosmos/cosmos-sdk/issues/5569) `InitGenesis`, for the relevant modules, now ensures module accounts exist.
|
||||
* (x/auth) [\#5892](https://github.com/cosmos/cosmos-sdk/pull/5892) Add `RegisterKeyTypeCodec` to register new
|
||||
types (eg. keys) to the `auth` module internal amino codec.
|
||||
* (x/bank) [\#6536](https://github.com/cosmos/cosmos-sdk/pull/6536) Fix bug in `WriteGeneratedTxResponse` function used by multiple
|
||||
REST endpoints. Now it writes a Tx in StdTx format.
|
||||
* (x/genutil) [\#5938](https://github.com/cosmos/cosmos-sdk/pull/5938) Fix `InitializeNodeValidatorFiles` error handling.
|
||||
* (x/staking) [\#6529](https://github.com/cosmos/cosmos-sdk/pull/6529) Export validator addresses (previously was empty).
|
||||
* (x/staking) [\#5949](https://github.com/cosmos/cosmos-sdk/pull/5949) Skip staking `HistoricalInfoKey` in simulations as headers are not exported.
|
||||
* (x/staking) [\#6061](https://github.com/cosmos/cosmos-sdk/pull/6061) Allow a validator to immediately unjail when no signing info is present due to
|
||||
falling below their minimum self-delegation and never having been bonded. The validator may immediately unjail once they've met their minimum self-delegation.
|
||||
* (x/supply) [\#6010](https://github.com/cosmos/cosmos-sdk/pull/6010) Removed the `x/supply` module by merging the existing types and APIs into the `x/bank` module.
|
||||
* (modules) [\#5572](https://github.com/cosmos/cosmos-sdk/pull/5572) Separate balance from accounts per ADR 004.
|
||||
* Account balances are now persisted and retrieved via the `x/bank` module.
|
||||
* Vesting account interface has been modified to account for changes.
|
||||
* Callers to `NewBaseVestingAccount` are responsible for verifying account balance in relation to
|
||||
the original vesting amount.
|
||||
* The `SendKeeper` and `ViewKeeper` interfaces in `x/bank` have been modified to account for changes.
|
||||
* (x/staking) [\#5600](https://github.com/cosmos/cosmos-sdk/pull/5600) Migrate the `x/staking` module to use Protocol Buffers for state
|
||||
serialization instead of Amino. The exact codec used is `codec.HybridCodec` which utilizes Protobuf for binary encoding and Amino
|
||||
for JSON encoding.
|
||||
* `BondStatus` is now of type `int32` instead of `byte`.
|
||||
* Types of `int16` in the `Params` type are now of type `int32`.
|
||||
* Every reference of `crypto.Pubkey` in context of a `Validator` is now of type string. `GetPubKeyFromBech32` must be used to get the `crypto.Pubkey`.
|
||||
* The `Keeper` constructor now takes a `codec.Marshaler` instead of a concrete Amino codec. This exact type
|
||||
provided is specified by `ModuleCdc`.
|
||||
* (x/slashing) [\#5627](https://github.com/cosmos/cosmos-sdk/pull/5627) Migrate the `x/slashing` module to use Protocol Buffers for state
|
||||
serialization instead of Amino. The exact codec used is `codec.HybridCodec` which utilizes Protobuf for binary encoding and Amino
|
||||
for JSON encoding.
|
||||
* The `Keeper` constructor now takes a `codec.Marshaler` instead of a concrete Amino codec. This exact type
|
||||
provided is specified by `ModuleCdc`.
|
||||
* (x/distribution) [\#5610](https://github.com/cosmos/cosmos-sdk/pull/5610) Migrate the `x/distribution` module to use Protocol Buffers for state
|
||||
serialization instead of Amino. The exact codec used is `codec.HybridCodec` which utilizes Protobuf for binary encoding and Amino
|
||||
for JSON encoding.
|
||||
* `ValidatorHistoricalRewards.ReferenceCount` is now of types `uint32` instead of `uint16`.
|
||||
* `ValidatorSlashEvents` is now a struct with `slashevents`.
|
||||
* `ValidatorOutstandingRewards` is now a struct with `rewards`.
|
||||
* `ValidatorAccumulatedCommission` is now a struct with `commission`.
|
||||
* The `Keeper` constructor now takes a `codec.Marshaler` instead of a concrete Amino codec. This exact type
|
||||
provided is specified by `ModuleCdc`.
|
||||
* (x/auth) [\#5533](https://github.com/cosmos/cosmos-sdk/pull/5533) Migrate the `x/auth` module to use Protocol Buffers for state
|
||||
serialization instead of Amino.
|
||||
* The `BaseAccount.PubKey` field is now represented as a Bech32 string instead of a `crypto.Pubkey`.
|
||||
* `NewBaseAccountWithAddress` now returns a reference to a `BaseAccount`.
|
||||
* The `x/auth` module now accepts a `Codec` interface which extends the `codec.Marshaler` interface by
|
||||
requiring a concrete codec to know how to serialize accounts.
|
||||
* The `AccountRetriever` type now accepts a `Codec` in its constructor in order to know how to
|
||||
serialize accounts.
|
||||
* (x/supply) [\#5533](https://github.com/cosmos/cosmos-sdk/pull/5533) Migrate the `x/supply` module to use Protocol Buffers for state
|
||||
serialization instead of Amino.
|
||||
* The `internal` sub-package has been removed in order to expose the types proto file.
|
||||
* The `x/supply` module now accepts a `Codec` interface which extends the `codec.Marshaler` interface by
|
||||
requiring a concrete codec to know how to serialize `SupplyI` types.
|
||||
* The `SupplyI` interface has been modified to no longer return `SupplyI` on methods. Instead the
|
||||
concrete type's receiver should modify the type.
|
||||
* (x/mint) [\#5634](https://github.com/cosmos/cosmos-sdk/pull/5634) Migrate the `x/mint` module to use Protocol Buffers for state
|
||||
serialization instead of Amino.
|
||||
* The `internal` sub-package has been removed in order to expose the types proto file.
|
||||
* (x/evidence) [\#5634](https://github.com/cosmos/cosmos-sdk/pull/5634) Migrate the `x/evidence` module to use Protocol Buffers for state
|
||||
serialization instead of Amino.
|
||||
* The `internal` sub-package has been removed in order to expose the types proto file.
|
||||
* The module now accepts a `Codec` interface which extends the `codec.Marshaler` interface by
|
||||
requiring a concrete codec to know how to serialize `Evidence` types.
|
||||
* The `MsgSubmitEvidence` message has been removed in favor of `MsgSubmitEvidenceBase`. The application-level
|
||||
codec must now define the concrete `MsgSubmitEvidence` type which must implement the module's `MsgSubmitEvidence`
|
||||
interface.
|
||||
* (x/upgrade) [\#5659](https://github.com/cosmos/cosmos-sdk/pull/5659) Migrate the `x/upgrade` module to use Protocol
|
||||
Buffers for state serialization instead of Amino.
|
||||
* The `internal` sub-package has been removed in order to expose the types proto file.
|
||||
* The `x/upgrade` module now accepts a `codec.Marshaler` interface.
|
||||
* (x/gov) [\#5737](https://github.com/cosmos/cosmos-sdk/pull/5737) Migrate the `x/gov` module to use Protocol
|
||||
Buffers for state serialization instead of Amino.
|
||||
* `MsgSubmitProposal` will be removed in favor of the application-level proto-defined `MsgSubmitProposal` which
|
||||
implements the `MsgSubmitProposalI` interface. Applications should extend the `NewMsgSubmitProposalBase` type
|
||||
to define their own concrete `MsgSubmitProposal` types.
|
||||
* The module now accepts a `Codec` interface which extends the `codec.Marshaler` interface by
|
||||
requiring a concrete codec to know how to serialize `Proposal` types.
|
||||
* (codec) [\#5799](https://github.com/cosmos/cosmos-sdk/pull/5799) Now we favor the use of `(Un)MarshalBinaryBare` instead of `(Un)MarshalBinaryLengthPrefixed` in all cases that are not needed.
|
||||
* (x/evidence) [\#5952](https://github.com/cosmos/cosmos-sdk/pull/5952) Remove parameters from `x/evidence` genesis and module state. The `x/evidence` module now solely uses Tendermint consensus parameters to determine of evidence is valid or not.
|
||||
* __General__
|
||||
* (types) [\#7038](https://github.com/cosmos/cosmos-sdk/issues/7038) Fix infinite looping of `ApproxRoot` by including a hard-coded maximum iterations limit of 100.
|
||||
* (types) [\#7084](https://github.com/cosmos/cosmos-sdk/pull/7084) Fix panic when calling `BigInt()` on an uninitialized `Int`.
|
||||
* (simulation) [\#7129](https://github.com/cosmos/cosmos-sdk/issues/7129) Fix support for custom `Account` and key types on auth's simulation.
|
||||
|
||||
|
||||
### Improvements
|
||||
|
||||
* (x/ibc-transfer) [\#6871](https://github.com/cosmos/cosmos-sdk/pull/6871) Implement [ADR 001 - Coin Source Tracing](./docs/architecture/adr-001-coin-source-tracing.md).
|
||||
* (types) [\#7027](https://github.com/cosmos/cosmos-sdk/pull/7027) `Coin(s)` and `DecCoin(s)` updates:
|
||||
* Bump denomination max length to 128
|
||||
* Allow uppercase letters and numbers in denominations to support [ADR 001](./docs/architecture/adr-001-coin-source-tracing.md)
|
||||
* Added `Validate` function that returns a descriptive error
|
||||
* (baseapp) [\#6186](https://github.com/cosmos/cosmos-sdk/issues/6186) Support emitting events during `AnteHandler` execution.
|
||||
* (x/auth) [\#5702](https://github.com/cosmos/cosmos-sdk/pull/5702) Add parameter querying support for `x/auth`.
|
||||
* (types) [\#5581](https://github.com/cosmos/cosmos-sdk/pull/5581) Add convenience functions {,Must}Bech32ifyAddressBytes.
|
||||
* (staking) [\#5584](https://github.com/cosmos/cosmos-sdk/pull/5584) Add util function `ToTmValidator` that converts a `staking.Validator` type to `*tmtypes.Validator`.
|
||||
* (types) [\#5585](https://github.com/cosmos/cosmos-sdk/pull/5585) IBC additions:
|
||||
* `Coin` denomination max lenght has been increased to 32.
|
||||
* Added `CapabilityKey` alias for `StoreKey` to match IBC spec.
|
||||
* (client) [\#5810](https://github.com/cosmos/cosmos-sdk/pull/5810) Added a new `--offline` flag that allows commands to be executed without an
|
||||
internet connection. Previously, `--generate-only` served this purpose in addition to only allowing txs to be generated. Now, `--generate-only` solely
|
||||
allows txs to be generated without being broadcasted and disallows Keybase use and `--offline` allows the use of Keybase but does not allow any
|
||||
functionality that requires an online connection.
|
||||
* (types/module) [\#5724](https://github.com/cosmos/cosmos-sdk/issues/5724) The `types/module` package does no longer depend on `x/simulation`.
|
||||
* (client) [\#5856](https://github.com/cosmos/cosmos-sdk/pull/5856) Added the possibility to set `--offline` flag with config command.
|
||||
* (client) [\#5895](https://github.com/cosmos/cosmos-sdk/issues/5895) show config options in the config command's help screen.
|
||||
* (types/rest) [\#5900](https://github.com/cosmos/cosmos-sdk/pull/5900) Add Check*Error function family to spare developers from replicating tons of boilerplate code.
|
||||
* (x/evidence) [\#5952](https://github.com/cosmos/cosmos-sdk/pull/5952) Tendermint Consensus parameters can now be changed via parameter change proposals through `x/gov`.
|
||||
* (x/evidence) [\#5961](https://github.com/cosmos/cosmos-sdk/issues/5961) Add `StoreDecoder` simulation for evidence module.
|
||||
* (x/auth/ante) [\#6040](https://github.com/cosmos/cosmos-sdk/pull/6040) `AccountKeeper` interface used for `NewAnteHandler` and handler's decorators to add support of using custom `AccountKeeper` implementations.
|
||||
* (simulation) [\#6002](https://github.com/cosmos/cosmos-sdk/pull/6002) Add randomized consensus params into simulation.
|
||||
* (x/staking) [\#6059](https://github.com/cosmos/cosmos-sdk/pull/6059) Updated `HistoricalEntries` parameter default to 100.
|
||||
* (x/ibc) [\#5948](https://github.com/cosmos/cosmos-sdk/issues/5948) Add `InitGenesis` and `ExportGenesis` functions for `ibc` module.
|
||||
* (types) [\#6128](https://github.com/cosmos/cosmos-sdk/pull/6137) Add String() method to GasMeter
|
||||
* (x/staking) [\#6163](https://github.com/cosmos/cosmos-sdk/pull/6163) CLI and REST call to unbonding delegations and delegations now accept
|
||||
pagination.
|
||||
* (types) [\#6128](https://github.com/cosmos/cosmos-sdk/pull/6137) Add `String()` method to `GasMeter`.
|
||||
* (types) [\#6195](https://github.com/cosmos/cosmos-sdk/pull/6195) Add codespace to broadcast(sync/async) response.
|
||||
* (baseapp) [\#6053](https://github.com/cosmos/cosmos-sdk/pull/6053) Customizable panic recovery handling added for `app.runTx()` method (as proposed in the [ADR 22](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-022-custom-panic-handling.md)). Adds ability for developers to register custom panic handlers extending standard ones.
|
||||
* (store) [\#6481](https://github.com/cosmos/cosmos-sdk/pull/6481) Move `SimpleProofsFromMap` from Tendermint into the SDK.
|
||||
* (store) [\#6719](https://github.com/cosmos/cosmos-sdk/6754) Add validity checks to stores for nil and empty keys.
|
||||
* (types) \#6897 Add KV type from tendermint to `types` directory.
|
||||
* __Baseapp / Client / REST__
|
||||
* (baseapp) [\#6186](https://github.com/cosmos/cosmos-sdk/issues/6186) Support emitting events during `AnteHandler` execution.
|
||||
* (baseapp) [\#6053](https://github.com/cosmos/cosmos-sdk/pull/6053) Customizable panic recovery handling added for `app.runTx()` method (as proposed in the [ADR 22](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-022-custom-panic-handling.md)). Adds ability for developers to register custom panic handlers extending standard ones.
|
||||
* (client) [\#5810](https://github.com/cosmos/cosmos-sdk/pull/5810) Added a new `--offline` flag that allows commands to be executed without an
|
||||
internet connection. Previously, `--generate-only` served this purpose in addition to only allowing txs to be generated. Now, `--generate-only` solely
|
||||
allows txs to be generated without being broadcasted and disallows Keybase use and `--offline` allows the use of Keybase but does not allow any
|
||||
functionality that requires an online connection.
|
||||
* (client) [\#5856](https://github.com/cosmos/cosmos-sdk/pull/5856) Added the possibility to set `--offline` flag with config command.
|
||||
* (client) [\#5895](https://github.com/cosmos/cosmos-sdk/issues/5895) show config options in the config command's help screen.
|
||||
* __Modules__
|
||||
* (x/auth) [\#5702](https://github.com/cosmos/cosmos-sdk/pull/5702) Add parameter querying support for `x/auth`.
|
||||
* (x/auth/ante) [\#6040](https://github.com/cosmos/cosmos-sdk/pull/6040) `AccountKeeper` interface used for `NewAnteHandler` and handler's decorators to add support of using custom `AccountKeeper` implementations.
|
||||
* (x/evidence) [\#5952](https://github.com/cosmos/cosmos-sdk/pull/5952) Tendermint Consensus parameters can now be changed via parameter change proposals through `x/gov`.
|
||||
* (x/evidence) [\#5961](https://github.com/cosmos/cosmos-sdk/issues/5961) Add `StoreDecoder` simulation for evidence module.
|
||||
* (x/ibc) [\#5948](https://github.com/cosmos/cosmos-sdk/issues/5948) Add `InitGenesis` and `ExportGenesis` functions for `ibc` module.
|
||||
* (x/ibc-transfer) [\#6871](https://github.com/cosmos/cosmos-sdk/pull/6871) Implement [ADR 001 - Coin Source Tracing](./docs/architecture/adr-001-coin-source-tracing.md).
|
||||
* (x/staking) [\#6059](https://github.com/cosmos/cosmos-sdk/pull/6059) Updated `HistoricalEntries` parameter default to 100.
|
||||
* (x/staking) [\#5584](https://github.com/cosmos/cosmos-sdk/pull/5584) Add util function `ToTmValidator` that converts a `staking.Validator` type to `*tmtypes.Validator`.
|
||||
* (x/staking) [\#6163](https://github.com/cosmos/cosmos-sdk/pull/6163) CLI and REST call to unbonding delegations and delegations now accept
|
||||
pagination.
|
||||
* __General__
|
||||
* (tendermint) [\#6365](https://github.com/cosmos/cosmos-sdk/issues/6365) Update tendermint version to v0.34, and make necessary upgrades to the SDK
|
||||
* (simulation) [\#6002](https://github.com/cosmos/cosmos-sdk/pull/6002) Add randomized consensus params into simulation.
|
||||
* (store) [\#6481](https://github.com/cosmos/cosmos-sdk/pull/6481) Move `SimpleProofsFromMap` from Tendermint into the SDK.
|
||||
* (store) [\#6719](https://github.com/cosmos/cosmos-sdk/6754) Add validity checks to stores for nil and empty keys.
|
||||
* (types) [\#7027](https://github.com/cosmos/cosmos-sdk/pull/7027) `Coin(s)` and `DecCoin(s)` updates:
|
||||
* Bump denomination max length to 128
|
||||
* Allow uppercase letters and numbers in denominations to support [ADR 001](./docs/architecture/adr-001-coin-source-tracing.md)
|
||||
* Added `Validate` function that returns a descriptive error
|
||||
* (types) [\#5581](https://github.com/cosmos/cosmos-sdk/pull/5581) Add convenience functions {,Must}Bech32ifyAddressBytes.
|
||||
* (types/module) [\#5724](https://github.com/cosmos/cosmos-sdk/issues/5724) The `types/module` package does no longer depend on `x/simulation`.
|
||||
* (types) [\#5585](https://github.com/cosmos/cosmos-sdk/pull/5585) IBC additions:
|
||||
* `Coin` denomination max lenght has been increased to 32.
|
||||
* Added `CapabilityKey` alias for `StoreKey` to match IBC spec.
|
||||
* (types/rest) [\#5900](https://github.com/cosmos/cosmos-sdk/pull/5900) Add Check*Error function family to spare developers from replicating tons of boilerplate code.
|
||||
* (types) [\#6128](https://github.com/cosmos/cosmos-sdk/pull/6137) Add `String()` method to `GasMeter`.
|
||||
* (types) [\#6195](https://github.com/cosmos/cosmos-sdk/pull/6195) Add codespace to broadcast(sync/async) response.
|
||||
* (types) \#6897 Add KV type from tendermint to `types` directory.
|
||||
|
||||
## [v0.39.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.39.1) - 2020-08-11
|
||||
|
||||
|
@ -338,7 +364,7 @@ pagination.
|
|||
|
||||
* (x/auth) [\#6861](https://github.com/cosmos/cosmos-sdk/pull/6861) Remove public key Bech32 encoding for all account types for JSON serialization, instead relying on direct Amino encoding. In addition, JSON serialization utilizes Amino instead of the Go stdlib, so integers are treated as strings.
|
||||
|
||||
### Improvements
|
||||
### Improvements
|
||||
|
||||
* (client) [\#6853](https://github.com/cosmos/cosmos-sdk/pull/6853) Add --unsafe-cors flag.
|
||||
|
||||
|
|
|
@ -142,6 +142,8 @@ build, in which case we can fall back on `go mod tidy -v`.
|
|||
|
||||
We use [Protocol Buffers](https://developers.google.com/protocol-buffers) along with [gogoproto](https://github.com/gogo/protobuf) to generate code for use in Cosmos-SDK.
|
||||
|
||||
For formatting code in `.proto` files, you can run `make proto-format` command.
|
||||
|
||||
For linting and checking breaking changes, we use [buf](https://buf.build/). There are two options for linting and to check if your changes will cause a break. The first is that you can install [buf](https://buf.build/docs/installation) locally, the commands for running buf after installing are `make proto-lint` and the breaking changes check will be `make proto-check-breaking`. If you do not want to install buf and have docker installed already then you can use these commands `make proto-lint-docker` and `make proto-check-breaking-docker`.
|
||||
|
||||
To generate the protobuf stubs you must have `protoc` and `protoc-gen-gocosmos` installed. To install these tools run `make proto-tools`. After this step you will be able to run `make proto-gen` to generate the protobuf stubs.
|
||||
|
|
34
Makefile
34
Makefile
|
@ -70,10 +70,12 @@ endif
|
|||
ifeq (rocksdb,$(findstring rocksdb,$(COSMOS_BUILD_OPTIONS)))
|
||||
CGO_ENABLED=1
|
||||
BUILD_TAGS += rocksdb
|
||||
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=rocksdb
|
||||
endif
|
||||
# handle boltdb
|
||||
ifeq (boltdb,$(findstring boltdb,$(COSMOS_BUILD_OPTIONS)))
|
||||
BUILD_TAGS += boltdb
|
||||
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=boltdb
|
||||
endif
|
||||
|
||||
ifeq (,$(findstring nostrip,$(COSMOS_BUILD_OPTIONS)))
|
||||
|
@ -173,16 +175,6 @@ go.sum: go.mod
|
|||
### Documentation ###
|
||||
###############################################################################
|
||||
|
||||
update-swagger-docs: statik
|
||||
$(BINDIR)/statik -src=client/docs/swagger-ui -dest=client/docs -f -m
|
||||
@if [ -n "$(git status --porcelain)" ]; then \
|
||||
echo "\033[91mSwagger docs are out of sync!!!\033[0m";\
|
||||
exit 1;\
|
||||
else \
|
||||
echo "\033[92mSwagger docs are in sync\033[0m";\
|
||||
fi
|
||||
.PHONY: update-swagger-docs
|
||||
|
||||
godocs:
|
||||
@echo "--> Wait a few seconds and visit http://localhost:6060/pkg/github.com/cosmos/cosmos-sdk/types"
|
||||
godoc -http=:6060
|
||||
|
@ -220,21 +212,27 @@ TEST_TARGETS := test-unit test-unit-amino test-unit-proto test-ledger-mock test-
|
|||
# Test runs-specific rules. To add a new test target, just add
|
||||
# a new rule, customise ARGS or TEST_PACKAGES ad libitum, and
|
||||
# append the new rule to the TEST_TARGETS list.
|
||||
|
||||
test-unit: ARGS=-tags='cgo ledger test_ledger_mock norace'
|
||||
test-unit-amino: ARGS=-tags='ledger test_ledger_mock test_amino norace'
|
||||
test-ledger: ARGS=-tags='cgo ledger norace'
|
||||
test-ledger-mock: ARGS=-tags='ledger test_ledger_mock norace'
|
||||
test-race: ARGS=-race -tags='cgo ledger test_ledger_mock'
|
||||
test-race: TEST_PACKAGES=$(PACKAGES_NOSIMULATION)
|
||||
|
||||
$(TEST_TARGETS): run-tests
|
||||
|
||||
# check-* compiles and collects tests without running them
|
||||
# note: go test -c doesn't support multiple packages yet (https://github.com/golang/go/issues/15513)
|
||||
CHECK_TEST_TARGETS := check-test-unit check-test-unit-amino
|
||||
check-test-unit: ARGS=-tags='cgo ledger test_ledger_mock norace'
|
||||
check-test-unit-amino: ARGS=-tags='ledger test_ledger_mock test_amino norace'
|
||||
$(CHECK_TEST_TARGETS): EXTRA_ARGS=-run=none
|
||||
$(CHECK_TEST_TARGETS): run-tests
|
||||
|
||||
run-tests:
|
||||
ifneq (,$(shell which tparse 2>/dev/null))
|
||||
go test -mod=readonly -json $(ARGS) $(TEST_PACKAGES) | tparse
|
||||
go test -mod=readonly -json $(ARGS) $(EXTRA_ARGS) $(TEST_PACKAGES) | tparse
|
||||
else
|
||||
go test -mod=readonly $(ARGS) $(TEST_PACKAGES)
|
||||
go test -mod=readonly $(ARGS) $(EXTRA_ARGS) $(TEST_PACKAGES)
|
||||
endif
|
||||
|
||||
.PHONY: run-tests test test-all $(TEST_TARGETS)
|
||||
|
@ -364,7 +362,11 @@ proto-gen:
|
|||
@./scripts/protocgen.sh
|
||||
|
||||
proto-format:
|
||||
@echo "Formatting Protobuf files"
|
||||
docker run -v $(shell pwd):/workspace \
|
||||
--workdir /workspace tendermintdev/docker-build-proto \
|
||||
find ./ -not -path "./third_party/*" -name *.proto -exec clang-format -i {} \;
|
||||
.PHONY: proto-format
|
||||
|
||||
# This generates the SDK's custom wrapper for google.protobuf.Any. It should only be run manually when needed
|
||||
proto-gen-any:
|
||||
|
@ -387,10 +389,10 @@ proto-check-breaking-docker:
|
|||
@$(DOCKER_BUF) check breaking --against-input $(HTTPS_GIT)#branch=master
|
||||
.PHONY: proto-check-breaking-ci
|
||||
|
||||
TM_URL = https://raw.githubusercontent.com/tendermint/tendermint/3359e0bf2f8414d9687f9eecda67b899d64a9cd1/proto/tendermint
|
||||
TM_URL = https://raw.githubusercontent.com/tendermint/tendermint/v0.34.0-rc5/proto/tendermint
|
||||
GOGO_PROTO_URL = https://raw.githubusercontent.com/regen-network/protobuf/cosmos
|
||||
COSMOS_PROTO_URL = https://raw.githubusercontent.com/regen-network/cosmos-proto/master
|
||||
CONFIO_URL = https://raw.githubusercontent.com/confio/ics23/v0.6.2
|
||||
CONFIO_URL = https://raw.githubusercontent.com/confio/ics23/v0.6.3
|
||||
|
||||
TM_CRYPTO_TYPES = third_party/proto/tendermint/crypto
|
||||
TM_ABCI_TYPES = third_party/proto/tendermint/abci
|
||||
|
|
|
@ -63,9 +63,9 @@ For more, please go to the [Cosmos SDK Docs](./docs/).
|
|||
|
||||
The Cosmos Hub application, `gaia`, has moved to its [own repository](https://github.com/cosmos/gaia). Go there to join the Cosmos Hub mainnet and more.
|
||||
|
||||
## Scaffolding
|
||||
## Starport
|
||||
|
||||
If you are starting a new app or a new module we provide a [scaffolding tool](https://github.com/cosmos/scaffold) to help you get started and speed up development. If you have any questions or find a bug, feel free to open an issue in the repo.
|
||||
If you are starting a new app or a new module you can use [Starport](https://github.com/tendermint/starport) to help you get started and speed up development. If you have any questions or find a bug, feel free to open an issue in the repo.
|
||||
|
||||
## Disambiguation
|
||||
|
||||
|
|
|
@ -213,11 +213,6 @@ func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBloc
|
|||
func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
|
||||
defer telemetry.MeasureSince(time.Now(), "abci", "check_tx")
|
||||
|
||||
tx, err := app.txDecoder(req.Tx)
|
||||
if err != nil {
|
||||
return sdkerrors.ResponseCheckTx(err, 0, 0, app.trace)
|
||||
}
|
||||
|
||||
var mode runTxMode
|
||||
|
||||
switch {
|
||||
|
@ -231,7 +226,7 @@ func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
|
|||
panic(fmt.Sprintf("unknown RequestCheckTx type: %s", req.Type))
|
||||
}
|
||||
|
||||
gInfo, result, err := app.runTx(mode, req.Tx, tx)
|
||||
gInfo, result, err := app.runTx(mode, req.Tx)
|
||||
if err != nil {
|
||||
return sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace)
|
||||
}
|
||||
|
@ -253,11 +248,6 @@ func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
|
|||
func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx {
|
||||
defer telemetry.MeasureSince(time.Now(), "abci", "deliver_tx")
|
||||
|
||||
tx, err := app.txDecoder(req.Tx)
|
||||
if err != nil {
|
||||
return sdkerrors.ResponseDeliverTx(err, 0, 0, app.trace)
|
||||
}
|
||||
|
||||
gInfo := sdk.GasInfo{}
|
||||
resultStr := "successful"
|
||||
|
||||
|
@ -268,7 +258,7 @@ func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx
|
|||
telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted")
|
||||
}()
|
||||
|
||||
gInfo, result, err := app.runTx(runTxModeDeliver, req.Tx, tx)
|
||||
gInfo, result, err := app.runTx(runTxModeDeliver, req.Tx)
|
||||
if err != nil {
|
||||
resultStr = "failed"
|
||||
return sdkerrors.ResponseDeliverTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace)
|
||||
|
@ -673,12 +663,7 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.Res
|
|||
case "simulate":
|
||||
txBytes := req.Data
|
||||
|
||||
tx, err := app.txDecoder(txBytes)
|
||||
if err != nil {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to decode tx"))
|
||||
}
|
||||
|
||||
gInfo, res, err := app.Simulate(txBytes, tx)
|
||||
gInfo, res, err := app.Simulate(txBytes)
|
||||
if err != nil {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to simulate tx"))
|
||||
}
|
||||
|
@ -688,7 +673,7 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.Res
|
|||
Result: res,
|
||||
}
|
||||
|
||||
bz, err := codec.ProtoMarshalJSON(simRes)
|
||||
bz, err := codec.ProtoMarshalJSON(simRes, app.interfaceRegistry)
|
||||
if err != nil {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to JSON encode simulation response"))
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/snapshots"
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
"github.com/cosmos/cosmos-sdk/store/rootmulti"
|
||||
|
@ -45,15 +46,17 @@ type (
|
|||
// BaseApp reflects the ABCI application implementation.
|
||||
type BaseApp struct { // nolint: maligned
|
||||
// initialized on creation
|
||||
logger log.Logger
|
||||
name string // application name from abci.Info
|
||||
db dbm.DB // common DB backend
|
||||
cms sdk.CommitMultiStore // Main (uncached) state
|
||||
storeLoader StoreLoader // function to handle store loading, may be overridden with SetStoreLoader()
|
||||
router sdk.Router // handle any kind of message
|
||||
queryRouter sdk.QueryRouter // router for redirecting query calls
|
||||
grpcQueryRouter *GRPCQueryRouter // router for redirecting gRPC query calls
|
||||
txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx
|
||||
logger log.Logger
|
||||
name string // application name from abci.Info
|
||||
db dbm.DB // common DB backend
|
||||
cms sdk.CommitMultiStore // Main (uncached) state
|
||||
storeLoader StoreLoader // function to handle store loading, may be overridden with SetStoreLoader()
|
||||
router sdk.Router // handle any kind of message
|
||||
queryRouter sdk.QueryRouter // router for redirecting query calls
|
||||
grpcQueryRouter *GRPCQueryRouter // router for redirecting gRPC query calls
|
||||
msgServiceRouter *MsgServiceRouter // router for redirecting Msg service messages
|
||||
interfaceRegistry types.InterfaceRegistry
|
||||
txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx
|
||||
|
||||
anteHandler sdk.AnteHandler // ante handler for fee and auth
|
||||
initChainer sdk.InitChainer // initialize state with validators and state blob
|
||||
|
@ -136,16 +139,17 @@ func NewBaseApp(
|
|||
name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),
|
||||
) *BaseApp {
|
||||
app := &BaseApp{
|
||||
logger: logger,
|
||||
name: name,
|
||||
db: db,
|
||||
cms: store.NewCommitMultiStore(db),
|
||||
storeLoader: DefaultStoreLoader,
|
||||
router: NewRouter(),
|
||||
queryRouter: NewQueryRouter(),
|
||||
grpcQueryRouter: NewGRPCQueryRouter(),
|
||||
txDecoder: txDecoder,
|
||||
fauxMerkleMode: false,
|
||||
logger: logger,
|
||||
name: name,
|
||||
db: db,
|
||||
cms: store.NewCommitMultiStore(db),
|
||||
storeLoader: DefaultStoreLoader,
|
||||
router: NewRouter(),
|
||||
queryRouter: NewQueryRouter(),
|
||||
grpcQueryRouter: NewGRPCQueryRouter(),
|
||||
msgServiceRouter: NewMsgServiceRouter(),
|
||||
txDecoder: txDecoder,
|
||||
fauxMerkleMode: false,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
|
@ -176,6 +180,9 @@ func (app *BaseApp) Logger() log.Logger {
|
|||
return app.logger
|
||||
}
|
||||
|
||||
// MsgServiceRouter returns the MsgServiceRouter of a BaseApp.
|
||||
func (app *BaseApp) MsgServiceRouter() *MsgServiceRouter { return app.msgServiceRouter }
|
||||
|
||||
// MountStores mounts all IAVL or DB stores to the provided keys in the BaseApp
|
||||
// multistore.
|
||||
func (app *BaseApp) MountStores(keys ...sdk.StoreKey) {
|
||||
|
@ -550,7 +557,7 @@ func (app *BaseApp) cacheTxContext(ctx sdk.Context, txBytes []byte) (sdk.Context
|
|||
// Note, gas execution info is always returned. A reference to a Result is
|
||||
// returned if the tx does not run out of gas and if all the messages are valid
|
||||
// and execute successfully. An error is returned otherwise.
|
||||
func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (gInfo sdk.GasInfo, result *sdk.Result, err error) {
|
||||
func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, result *sdk.Result, err error) {
|
||||
// NOTE: GasWanted should be returned by the AnteHandler. GasUsed is
|
||||
// determined by the GasMeter. We need access to the context to get the gas
|
||||
// meter so we initialize upfront.
|
||||
|
@ -596,6 +603,11 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (gInfo sdk.
|
|||
}
|
||||
}()
|
||||
|
||||
tx, err := app.txDecoder(txBytes)
|
||||
if err != nil {
|
||||
return sdk.GasInfo{}, nil, err
|
||||
}
|
||||
|
||||
msgs := tx.GetMsgs()
|
||||
if err := validateBasicTxMsgs(msgs); err != nil {
|
||||
return sdk.GasInfo{}, nil, err
|
||||
|
@ -682,20 +694,38 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s
|
|||
break
|
||||
}
|
||||
|
||||
msgRoute := msg.Route()
|
||||
handler := app.router.Route(ctx, msgRoute)
|
||||
var (
|
||||
msgEvents sdk.Events
|
||||
msgResult *sdk.Result
|
||||
msgFqName string
|
||||
err error
|
||||
)
|
||||
|
||||
if handler == nil {
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message route: %s; message index: %d", msgRoute, i)
|
||||
if svcMsg, ok := msg.(sdk.ServiceMsg); ok {
|
||||
msgFqName = svcMsg.MethodName
|
||||
handler := app.msgServiceRouter.Handler(msgFqName)
|
||||
if handler == nil {
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message service method: %s; message index: %d", msgFqName, i)
|
||||
}
|
||||
msgResult, err = handler(ctx, svcMsg.Request)
|
||||
} else {
|
||||
// legacy sdk.Msg routing
|
||||
msgRoute := msg.Route()
|
||||
msgFqName = msg.Type()
|
||||
handler := app.router.Route(ctx, msgRoute)
|
||||
if handler == nil {
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message route: %s; message index: %d", msgRoute, i)
|
||||
}
|
||||
|
||||
msgResult, err = handler(ctx, msg)
|
||||
}
|
||||
|
||||
msgResult, err := handler(ctx, msg)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrapf(err, "failed to execute message; message index: %d", i)
|
||||
}
|
||||
|
||||
msgEvents := sdk.Events{
|
||||
sdk.NewEvent(sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyAction, msg.Type())),
|
||||
msgEvents = sdk.Events{
|
||||
sdk.NewEvent(sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyAction, msgFqName)),
|
||||
}
|
||||
msgEvents = msgEvents.AppendEvents(msgResult.GetEvents())
|
||||
|
||||
|
|
|
@ -29,6 +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"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -97,6 +98,14 @@ func registerTestCodec(cdc *codec.LegacyAmino) {
|
|||
cdc.RegisterConcrete(&msgNoRoute{}, "cosmos-sdk/baseapp/msgNoRoute", nil)
|
||||
}
|
||||
|
||||
// aminoTxEncoder creates a amino TxEncoder for testing purposes.
|
||||
func aminoTxEncoder() sdk.TxEncoder {
|
||||
cdc := codec.NewLegacyAmino()
|
||||
registerTestCodec(cdc)
|
||||
|
||||
return legacytx.StdTxConfig{Cdc: cdc}.TxEncoder()
|
||||
}
|
||||
|
||||
// simple one store baseapp
|
||||
func setupBaseApp(t *testing.T, options ...func(*BaseApp)) *BaseApp {
|
||||
app := newBaseApp(t.Name(), options...)
|
||||
|
@ -422,7 +431,7 @@ func TestLoadVersionPruning(t *testing.T) {
|
|||
|
||||
for _, v := range []int64{1, 2, 4} {
|
||||
_, err = app.cms.CacheMultiStoreWithVersion(v)
|
||||
require.Error(t, err)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
for _, v := range []int64{3, 5, 6, 7} {
|
||||
|
@ -1118,13 +1127,13 @@ func TestSimulateTx(t *testing.T) {
|
|||
require.Nil(t, err)
|
||||
|
||||
// simulate a message, check gas reported
|
||||
gInfo, result, err := app.Simulate(txBytes, tx)
|
||||
gInfo, result, err := app.Simulate(txBytes)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, result)
|
||||
require.Equal(t, gasConsumed, gInfo.GasUsed)
|
||||
|
||||
// simulate again, same result
|
||||
gInfo, result, err = app.Simulate(txBytes, tx)
|
||||
gInfo, result, err = app.Simulate(txBytes)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, result)
|
||||
require.Equal(t, gasConsumed, gInfo.GasUsed)
|
||||
|
@ -1171,7 +1180,7 @@ func TestRunInvalidTransaction(t *testing.T) {
|
|||
// transaction with no messages
|
||||
{
|
||||
emptyTx := &txTest{}
|
||||
_, result, err := app.Deliver(emptyTx)
|
||||
_, result, err := app.Deliver(aminoTxEncoder(), emptyTx)
|
||||
require.Error(t, err)
|
||||
require.Nil(t, result)
|
||||
|
||||
|
@ -1198,7 +1207,7 @@ func TestRunInvalidTransaction(t *testing.T) {
|
|||
|
||||
for _, testCase := range testCases {
|
||||
tx := testCase.tx
|
||||
_, result, err := app.Deliver(tx)
|
||||
_, result, err := app.Deliver(aminoTxEncoder(), tx)
|
||||
|
||||
if testCase.fail {
|
||||
require.Error(t, err)
|
||||
|
@ -1215,7 +1224,7 @@ func TestRunInvalidTransaction(t *testing.T) {
|
|||
// transaction with no known route
|
||||
{
|
||||
unknownRouteTx := txTest{[]sdk.Msg{msgNoRoute{}}, 0, false}
|
||||
_, result, err := app.Deliver(unknownRouteTx)
|
||||
_, result, err := app.Deliver(aminoTxEncoder(), unknownRouteTx)
|
||||
require.Error(t, err)
|
||||
require.Nil(t, result)
|
||||
|
||||
|
@ -1224,7 +1233,7 @@ func TestRunInvalidTransaction(t *testing.T) {
|
|||
require.EqualValues(t, sdkerrors.ErrUnknownRequest.ABCICode(), code, err)
|
||||
|
||||
unknownRouteTx = txTest{[]sdk.Msg{msgCounter{}, msgNoRoute{}}, 0, false}
|
||||
_, result, err = app.Deliver(unknownRouteTx)
|
||||
_, result, err = app.Deliver(aminoTxEncoder(), unknownRouteTx)
|
||||
require.Error(t, err)
|
||||
require.Nil(t, result)
|
||||
|
||||
|
@ -1274,7 +1283,7 @@ func TestTxGasLimits(t *testing.T) {
|
|||
}
|
||||
}()
|
||||
|
||||
count := tx.(*txTest).Counter
|
||||
count := tx.(txTest).Counter
|
||||
newCtx.GasMeter().ConsumeGas(uint64(count), "counter-ante")
|
||||
|
||||
return newCtx, nil
|
||||
|
@ -1284,7 +1293,7 @@ func TestTxGasLimits(t *testing.T) {
|
|||
|
||||
routerOpt := func(bapp *BaseApp) {
|
||||
r := sdk.NewRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
|
||||
count := msg.(msgCounter).Counter
|
||||
count := msg.(*msgCounter).Counter
|
||||
ctx.GasMeter().ConsumeGas(uint64(count), "counter-handler")
|
||||
return &sdk.Result{}, nil
|
||||
})
|
||||
|
@ -1322,7 +1331,7 @@ func TestTxGasLimits(t *testing.T) {
|
|||
|
||||
for i, tc := range testCases {
|
||||
tx := tc.tx
|
||||
gInfo, result, err := app.Deliver(tx)
|
||||
gInfo, result, err := app.Deliver(aminoTxEncoder(), tx)
|
||||
|
||||
// check gas used and wanted
|
||||
require.Equal(t, tc.gasUsed, gInfo.GasUsed, fmt.Sprintf("tc #%d; gas: %v, result: %v, err: %s", i, gInfo, result, err))
|
||||
|
@ -1359,7 +1368,7 @@ func TestMaxBlockGasLimits(t *testing.T) {
|
|||
}
|
||||
}()
|
||||
|
||||
count := tx.(*txTest).Counter
|
||||
count := tx.(txTest).Counter
|
||||
newCtx.GasMeter().ConsumeGas(uint64(count), "counter-ante")
|
||||
|
||||
return
|
||||
|
@ -1368,7 +1377,7 @@ func TestMaxBlockGasLimits(t *testing.T) {
|
|||
|
||||
routerOpt := func(bapp *BaseApp) {
|
||||
r := sdk.NewRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
|
||||
count := msg.(msgCounter).Counter
|
||||
count := msg.(*msgCounter).Counter
|
||||
ctx.GasMeter().ConsumeGas(uint64(count), "counter-handler")
|
||||
return &sdk.Result{}, nil
|
||||
})
|
||||
|
@ -1412,7 +1421,7 @@ func TestMaxBlockGasLimits(t *testing.T) {
|
|||
|
||||
// execute the transaction multiple times
|
||||
for j := 0; j < tc.numDelivers; j++ {
|
||||
_, result, err := app.Deliver(tx)
|
||||
_, result, err := app.Deliver(aminoTxEncoder(), tx)
|
||||
|
||||
ctx := app.getState(runTxModeDeliver).ctx
|
||||
|
||||
|
@ -1480,7 +1489,7 @@ func TestCustomRunTxPanicHandler(t *testing.T) {
|
|||
{
|
||||
tx := newTxCounter(0, 0)
|
||||
|
||||
require.PanicsWithValue(t, customPanicMsg, func() { app.Deliver(tx) })
|
||||
require.PanicsWithValue(t, customPanicMsg, func() { app.Deliver(aminoTxEncoder(), tx) })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1589,7 +1598,7 @@ func TestGasConsumptionBadTx(t *testing.T) {
|
|||
|
||||
routerOpt := func(bapp *BaseApp) {
|
||||
r := sdk.NewRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
|
||||
count := msg.(msgCounter).Counter
|
||||
count := msg.(*msgCounter).Counter
|
||||
ctx.GasMeter().ConsumeGas(uint64(count), "counter-handler")
|
||||
return &sdk.Result{}, nil
|
||||
})
|
||||
|
@ -1668,7 +1677,7 @@ func TestQuery(t *testing.T) {
|
|||
require.Equal(t, 0, len(res.Value))
|
||||
|
||||
// query is still empty after a CheckTx
|
||||
_, resTx, err := app.Check(tx)
|
||||
_, resTx, err := app.Check(aminoTxEncoder(), tx)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resTx)
|
||||
res = app.Query(query)
|
||||
|
@ -1678,7 +1687,7 @@ func TestQuery(t *testing.T) {
|
|||
header := tmproto.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
_, resTx, err = app.Deliver(tx)
|
||||
_, resTx, err = app.Deliver(aminoTxEncoder(), tx)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resTx)
|
||||
res = app.Query(query)
|
||||
|
@ -1692,9 +1701,9 @@ func TestQuery(t *testing.T) {
|
|||
|
||||
func TestGRPCQuery(t *testing.T) {
|
||||
grpcQueryOpt := func(bapp *BaseApp) {
|
||||
testdata.RegisterTestServiceServer(
|
||||
testdata.RegisterQueryServer(
|
||||
bapp.GRPCQueryRouter(),
|
||||
testdata.TestServiceImpl{},
|
||||
testdata.QueryImpl{},
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1711,7 +1720,7 @@ func TestGRPCQuery(t *testing.T) {
|
|||
|
||||
reqQuery := abci.RequestQuery{
|
||||
Data: reqBz,
|
||||
Path: "/testdata.TestService/SayHello",
|
||||
Path: "/testdata.Query/SayHello",
|
||||
}
|
||||
|
||||
resQuery := app.Query(reqQuery)
|
||||
|
|
|
@ -4,12 +4,11 @@ import (
|
|||
gocontext "context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
|
||||
gogogrpc "github.com/gogo/protobuf/grpc"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
|
@ -22,6 +21,11 @@ type QueryServiceTestHelper struct {
|
|||
ctx sdk.Context
|
||||
}
|
||||
|
||||
var (
|
||||
_ gogogrpc.Server = &QueryServiceTestHelper{}
|
||||
_ gogogrpc.ClientConn = &QueryServiceTestHelper{}
|
||||
)
|
||||
|
||||
// NewQueryServerTestHelper creates a new QueryServiceTestHelper that wraps
|
||||
// the provided sdk.Context
|
||||
func NewQueryServerTestHelper(ctx sdk.Context, interfaceRegistry types.InterfaceRegistry) *QueryServiceTestHelper {
|
||||
|
@ -62,6 +66,3 @@ func (q *QueryServiceTestHelper) Invoke(_ gocontext.Context, method string, args
|
|||
func (q *QueryServiceTestHelper) NewStream(gocontext.Context, *grpc.StreamDesc, string, ...grpc.CallOption) (grpc.ClientStream, error) {
|
||||
return nil, fmt.Errorf("not supported")
|
||||
}
|
||||
|
||||
var _ gogogrpc.Server = &QueryServiceTestHelper{}
|
||||
var _ gogogrpc.ClientConn = &QueryServiceTestHelper{}
|
||||
|
|
|
@ -15,12 +15,12 @@ func TestGRPCRouter(t *testing.T) {
|
|||
qr := NewGRPCQueryRouter()
|
||||
interfaceRegistry := testdata.NewTestInterfaceRegistry()
|
||||
qr.SetInterfaceRegistry(interfaceRegistry)
|
||||
testdata.RegisterTestServiceServer(qr, testdata.TestServiceImpl{})
|
||||
testdata.RegisterQueryServer(qr, testdata.QueryImpl{})
|
||||
helper := &QueryServiceTestHelper{
|
||||
GRPCQueryRouter: qr,
|
||||
ctx: sdk.Context{}.WithContext(context.Background()),
|
||||
}
|
||||
client := testdata.NewTestServiceClient(helper)
|
||||
client := testdata.NewQueryClient(helper)
|
||||
|
||||
res, err := client.Echo(context.Background(), &testdata.EchoRequest{Message: "hello"})
|
||||
require.Nil(t, err)
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
package baseapp
|
||||
|
||||
import (
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
func (app *BaseApp) Check(tx sdk.Tx) (sdk.GasInfo, *sdk.Result, error) {
|
||||
return app.runTx(runTxModeCheck, nil, tx)
|
||||
}
|
||||
|
||||
func (app *BaseApp) Simulate(txBytes []byte, tx sdk.Tx) (sdk.GasInfo, *sdk.Result, error) {
|
||||
return app.runTx(runTxModeSimulate, txBytes, tx)
|
||||
}
|
||||
|
||||
func (app *BaseApp) Deliver(tx sdk.Tx) (sdk.GasInfo, *sdk.Result, error) {
|
||||
return app.runTx(runTxModeDeliver, nil, tx)
|
||||
}
|
||||
|
||||
// Context with current {check, deliver}State of the app used by tests.
|
||||
func (app *BaseApp) NewContext(isCheckTx bool, header tmproto.Header) sdk.Context {
|
||||
if isCheckTx {
|
||||
return sdk.NewContext(app.checkState.ms, header, true, app.logger).
|
||||
WithMinGasPrices(app.minGasPrices)
|
||||
}
|
||||
|
||||
return sdk.NewContext(app.deliverState.ms, header, false, app.logger)
|
||||
}
|
||||
|
||||
func (app *BaseApp) NewUncachedContext(isCheckTx bool, header tmproto.Header) sdk.Context {
|
||||
return sdk.NewContext(app.cms, header, isCheckTx, app.logger)
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package baseapp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
gogogrpc "github.com/gogo/protobuf/grpc"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
// MsgServiceRouter routes fully-qualified Msg service methods to their handler.
|
||||
type MsgServiceRouter struct {
|
||||
interfaceRegistry codectypes.InterfaceRegistry
|
||||
routes map[string]MsgServiceHandler
|
||||
}
|
||||
|
||||
var _ gogogrpc.Server = &MsgServiceRouter{}
|
||||
|
||||
// NewMsgServiceRouter creates a new MsgServiceRouter.
|
||||
func NewMsgServiceRouter() *MsgServiceRouter {
|
||||
return &MsgServiceRouter{
|
||||
routes: map[string]MsgServiceHandler{},
|
||||
}
|
||||
}
|
||||
|
||||
// MsgServiceHandler defines a function type which handles Msg service message.
|
||||
type MsgServiceHandler = func(ctx sdk.Context, req sdk.MsgRequest) (*sdk.Result, error)
|
||||
|
||||
// Handler returns the MsgServiceHandler for a given query route path or nil
|
||||
// if not found.
|
||||
func (msr *MsgServiceRouter) Handler(methodName string) MsgServiceHandler {
|
||||
return msr.routes[methodName]
|
||||
}
|
||||
|
||||
// RegisterService implements the gRPC Server.RegisterService method. sd is a gRPC
|
||||
// service description, handler is an object which implements that gRPC service.
|
||||
func (msr *MsgServiceRouter) RegisterService(sd *grpc.ServiceDesc, handler interface{}) {
|
||||
// Adds a top-level query handler based on the gRPC service name.
|
||||
for _, method := range sd.Methods {
|
||||
fqMethod := fmt.Sprintf("/%s/%s", sd.ServiceName, method.MethodName)
|
||||
methodHandler := method.Handler
|
||||
|
||||
// NOTE: This is how we pull the concrete request type for each handler for registering in the InterfaceRegistry.
|
||||
// This approach is maybe a bit hacky, but less hacky than reflecting on the handler object itself.
|
||||
// We use a no-op interceptor to avoid actually calling into the handler itself.
|
||||
_, _ = methodHandler(nil, context.Background(), func(i interface{}) error {
|
||||
msg, ok := i.(proto.Message)
|
||||
if !ok {
|
||||
// We panic here because there is no other alternative and the app cannot be initialized correctly
|
||||
// this should only happen if there is a problem with code generation in which case the app won't
|
||||
// work correctly anyway.
|
||||
panic(fmt.Errorf("can't register request type %T for service method %s", i, fqMethod))
|
||||
}
|
||||
|
||||
msr.interfaceRegistry.RegisterCustomTypeURL((*sdk.MsgRequest)(nil), fqMethod, msg)
|
||||
return nil
|
||||
}, noopInterceptor)
|
||||
|
||||
msr.routes[fqMethod] = func(ctx sdk.Context, req sdk.MsgRequest) (*sdk.Result, error) {
|
||||
ctx = ctx.WithEventManager(sdk.NewEventManager())
|
||||
interceptor := func(goCtx context.Context, _ interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
goCtx = context.WithValue(goCtx, sdk.SdkContextKey, ctx)
|
||||
return handler(goCtx, req)
|
||||
}
|
||||
// Call the method handler from the service description with the handler object.
|
||||
// We don't do any decoding here because the decoding was already done.
|
||||
res, err := methodHandler(handler, sdk.WrapSDKContext(ctx), noopDecoder, interceptor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resMsg, ok := res.(proto.Message)
|
||||
if !ok {
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "Expecting proto.Message, got %T", resMsg)
|
||||
}
|
||||
|
||||
return sdk.WrapServiceResult(ctx, resMsg, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetInterfaceRegistry sets the interface registry for the router.
|
||||
func (msr *MsgServiceRouter) SetInterfaceRegistry(interfaceRegistry codectypes.InterfaceRegistry) {
|
||||
msr.interfaceRegistry = interfaceRegistry
|
||||
}
|
||||
|
||||
// gRPC NOOP interceptor
|
||||
func noopInterceptor(_ context.Context, _ interface{}, _ *grpc.UnaryServerInfo, _ grpc.UnaryHandler) (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func noopDecoder(_ interface{}) error { return nil }
|
|
@ -0,0 +1,74 @@
|
|||
package baseapp_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
)
|
||||
|
||||
func TestMsgService(t *testing.T) {
|
||||
priv, _, _ := testdata.KeyTestPubAddr()
|
||||
encCfg := simapp.MakeTestEncodingConfig()
|
||||
db := dbm.NewMemDB()
|
||||
app := baseapp.NewBaseApp("test", log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, encCfg.TxConfig.TxDecoder())
|
||||
app.SetInterfaceRegistry(encCfg.InterfaceRegistry)
|
||||
testdata.RegisterMsgServer(
|
||||
app.MsgServiceRouter(),
|
||||
testdata.MsgServerImpl{},
|
||||
)
|
||||
_ = app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: 1}})
|
||||
|
||||
msg := testdata.NewServiceMsgCreateDog(&testdata.MsgCreateDog{Dog: &testdata.Dog{Name: "Spot"}})
|
||||
txBuilder := encCfg.TxConfig.NewTxBuilder()
|
||||
txBuilder.SetFeeAmount(testdata.NewTestFeeAmount())
|
||||
txBuilder.SetGasLimit(testdata.NewTestGasLimit())
|
||||
err := txBuilder.SetMsgs(msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
// First round: we gather all the signer infos. We use the "set empty
|
||||
// signature" hack to do that.
|
||||
sigV2 := signing.SignatureV2{
|
||||
PubKey: priv.PubKey(),
|
||||
Data: &signing.SingleSignatureData{
|
||||
SignMode: encCfg.TxConfig.SignModeHandler().DefaultMode(),
|
||||
Signature: nil,
|
||||
},
|
||||
Sequence: 0,
|
||||
}
|
||||
|
||||
err = txBuilder.SetSignatures(sigV2)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Second round: all signer infos are set, so each signer can sign.
|
||||
signerData := authsigning.SignerData{
|
||||
ChainID: "test",
|
||||
AccountNumber: 0,
|
||||
Sequence: 0,
|
||||
}
|
||||
sigV2, err = tx.SignWithPrivKey(
|
||||
encCfg.TxConfig.SignModeHandler().DefaultMode(), signerData,
|
||||
txBuilder, priv, encCfg.TxConfig, 0)
|
||||
require.NoError(t, err)
|
||||
err = txBuilder.SetSignatures(sigV2)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Send the tx to the app
|
||||
txBytes, err := encCfg.TxConfig.TxEncoder()(txBuilder.GetTx())
|
||||
require.NoError(t, err)
|
||||
res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.Equal(t, abci.CodeTypeOK, res.Code, "res=%+v", res)
|
||||
}
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/snapshots"
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
@ -221,3 +222,10 @@ func (app *BaseApp) SetSnapshotKeepRecent(snapshotKeepRecent uint32) {
|
|||
}
|
||||
app.snapshotKeepRecent = snapshotKeepRecent
|
||||
}
|
||||
|
||||
// SetInterfaceRegistry sets the InterfaceRegistry.
|
||||
func (app *BaseApp) SetInterfaceRegistry(registry types.InterfaceRegistry) {
|
||||
app.interfaceRegistry = registry
|
||||
app.grpcQueryRouter.SetInterfaceRegistry(registry)
|
||||
app.msgServiceRouter.SetInterfaceRegistry(registry)
|
||||
}
|
||||
|
|
|
@ -63,8 +63,8 @@ func ValidateEvidenceParams(i interface{}) error {
|
|||
return fmt.Errorf("evidence maximum age time duration must be positive: %v", v.MaxAgeDuration)
|
||||
}
|
||||
|
||||
if v.MaxNum <= 0 {
|
||||
return fmt.Errorf("evidence maximum number of evidence must be positive: %v", v.MaxNum)
|
||||
if v.MaxBytes < 0 {
|
||||
return fmt.Errorf("maximum evidence bytes must be positive: %v", v.MaxBytes)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -36,8 +36,8 @@ func TestValidateEvidenceParams(t *testing.T) {
|
|||
{nil, true},
|
||||
{&tmproto.EvidenceParams{}, true},
|
||||
{tmproto.EvidenceParams{}, true},
|
||||
{tmproto.EvidenceParams{MaxAgeNumBlocks: -1, MaxAgeDuration: 18004000, MaxNum: 50}, true},
|
||||
{tmproto.EvidenceParams{MaxAgeNumBlocks: 360000, MaxAgeDuration: 18004000, MaxNum: 50}, false},
|
||||
{tmproto.EvidenceParams{MaxAgeNumBlocks: -1, MaxAgeDuration: 18004000, MaxBytes: 5000000}, true},
|
||||
{tmproto.EvidenceParams{MaxAgeNumBlocks: 360000, MaxAgeDuration: 18004000, MaxBytes: 5000000}, false},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package baseapp
|
||||
|
||||
import (
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
func (app *BaseApp) Check(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk.Result, error) {
|
||||
// runTx expects tx bytes as argument, so we encode the tx argument into
|
||||
// bytes. Note that runTx will actually decode those bytes again. But since
|
||||
// this helper is only used in tests/simulation, it's fine.
|
||||
bz, err := txEncoder(tx)
|
||||
if err != nil {
|
||||
return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err)
|
||||
}
|
||||
return app.runTx(runTxModeCheck, bz)
|
||||
}
|
||||
|
||||
func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) {
|
||||
return app.runTx(runTxModeSimulate, txBytes)
|
||||
}
|
||||
|
||||
func (app *BaseApp) Deliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk.Result, error) {
|
||||
// See comment for Check().
|
||||
bz, err := txEncoder(tx)
|
||||
if err != nil {
|
||||
return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err)
|
||||
}
|
||||
return app.runTx(runTxModeDeliver, bz)
|
||||
}
|
||||
|
||||
// Context with current {check, deliver}State of the app used by tests.
|
||||
func (app *BaseApp) NewContext(isCheckTx bool, header tmproto.Header) sdk.Context {
|
||||
if isCheckTx {
|
||||
return sdk.NewContext(app.checkState.ms, header, true, app.logger).
|
||||
WithMinGasPrices(app.minGasPrices)
|
||||
}
|
||||
|
||||
return sdk.NewContext(app.deliverState.ms, header, false, app.logger)
|
||||
}
|
||||
|
||||
func (app *BaseApp) NewUncachedContext(isCheckTx bool, header tmproto.Header) sdk.Context {
|
||||
return sdk.NewContext(app.cms, header, isCheckTx, app.logger)
|
||||
}
|
1
buf.yaml
1
buf.yaml
|
@ -14,6 +14,7 @@ lint:
|
|||
- COMMENT_FIELD
|
||||
- SERVICE_SUFFIX
|
||||
- PACKAGE_VERSION_SUFFIX
|
||||
- RPC_REQUEST_STANDARD_NAME
|
||||
ignore:
|
||||
- tendermint
|
||||
- gogoproto
|
||||
|
|
|
@ -1,11 +1,25 @@
|
|||
package client
|
||||
|
||||
import "github.com/cosmos/cosmos-sdk/types"
|
||||
import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Account defines a read-only version of the auth module's AccountI.
|
||||
type Account interface {
|
||||
GetAddress() sdk.AccAddress
|
||||
GetPubKey() crypto.PubKey // can return nil.
|
||||
GetAccountNumber() uint64
|
||||
GetSequence() uint64
|
||||
}
|
||||
|
||||
// AccountRetriever defines the interfaces required by transactions to
|
||||
// ensure an account exists and to be able to query for account fields necessary
|
||||
// for signing.
|
||||
type AccountRetriever interface {
|
||||
EnsureExists(clientCtx Context, addr types.AccAddress) error
|
||||
GetAccountNumberSequence(clientCtx Context, addr types.AccAddress) (accNum uint64, accSeq uint64, err error)
|
||||
GetAccount(clientCtx Context, addr sdk.AccAddress) (Account, error)
|
||||
GetAccountWithHeight(clientCtx Context, addr sdk.AccAddress) (Account, int64, error)
|
||||
EnsureExists(clientCtx Context, addr sdk.AccAddress) error
|
||||
GetAccountNumberSequence(clientCtx Context, addr sdk.AccAddress) (accNum uint64, accSeq uint64, err error)
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ func TestCLIQueryConn(t *testing.T) {
|
|||
n := network.New(t, cfg)
|
||||
defer n.Cleanup()
|
||||
|
||||
testClient := testdata.NewTestServiceClient(n.Validators[0].ClientCtx)
|
||||
testClient := testdata.NewQueryClient(n.Validators[0].ClientCtx)
|
||||
res, err := testClient.Echo(context.Background(), &testdata.EchoRequest{Message: "hello"})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "hello", res.Message)
|
||||
|
|
|
@ -8,11 +8,10 @@ import (
|
|||
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
)
|
||||
|
||||
// BaseAppSimulateFn is the signature of the Baseapp#Simulate function.
|
||||
type BaseAppSimulateFn func(txBytes []byte, txtypes sdk.Tx) (sdk.GasInfo, *sdk.Result, error)
|
||||
type BaseAppSimulateFn func(txBytes []byte) (sdk.GasInfo, *sdk.Result, error)
|
||||
|
||||
type simulateServer struct {
|
||||
simulate BaseAppSimulateFn
|
||||
|
@ -39,13 +38,12 @@ func (s simulateServer) Simulate(ctx context.Context, req *SimulateRequest) (*Si
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
txBuilder := authtx.WrapTx(req.Tx)
|
||||
txBytes, err := req.Tx.Marshal()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gasInfo, result, err := s.simulate(txBytes, txBuilder.GetTx())
|
||||
gasInfo, result, err := s.simulate(txBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
|
|||
app.BankKeeper.SetParams(sdkCtx, banktypes.DefaultParams())
|
||||
|
||||
// Set up TxConfig.
|
||||
encodingConfig := simapp.MakeEncodingConfig()
|
||||
encodingConfig := simapp.MakeTestEncodingConfig()
|
||||
clientCtx := client.Context{}.WithTxConfig(encodingConfig.TxConfig)
|
||||
|
||||
// Create new simulation server.
|
||||
|
|
|
@ -43,7 +43,7 @@ func (s *IntegrationTestSuite) TestGRPCQuery() {
|
|||
val0 := s.network.Validators[0]
|
||||
|
||||
// gRPC query to test service should work
|
||||
testClient := testdata.NewTestServiceClient(val0.ClientCtx)
|
||||
testClient := testdata.NewQueryClient(val0.ClientCtx)
|
||||
testRes, err := testClient.Echo(context.Background(), &testdata.EchoRequest{Message: "hello"})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal("hello", testRes.Message)
|
||||
|
|
|
@ -306,7 +306,6 @@ func printCreate(cmd *cobra.Command, info keyring.Info, showMnemonic bool, mnemo
|
|||
|
||||
// print mnemonic unless requested not to.
|
||||
if showMnemonic {
|
||||
fmt.Fprintln(cmd.ErrOrStderr(), "\n**Important** write this mnemonic phrase in a safe place.")
|
||||
fmt.Fprintln(cmd.ErrOrStderr(), "\n**Important** write this mnemonic phrase in a safe place.")
|
||||
fmt.Fprintln(cmd.ErrOrStderr(), "It is the only way to recover your account if you ever forget your password.")
|
||||
fmt.Fprintln(cmd.ErrOrStderr(), "")
|
||||
|
|
|
@ -52,19 +52,6 @@ func (ctx Context) QueryABCI(req abci.RequestQuery) (abci.ResponseQuery, error)
|
|||
return ctx.queryABCI(req)
|
||||
}
|
||||
|
||||
// QuerySubspace performs a query to a Tendermint node with the provided
|
||||
// store name and subspace. It returns key value pair and height of the query
|
||||
// upon success or an error if the query fails.
|
||||
func (ctx Context) QuerySubspace(subspace []byte, storeName string) (res []sdk.KVPair, height int64, err error) {
|
||||
resRaw, height, err := ctx.queryStore(subspace, storeName, "subspace")
|
||||
if err != nil {
|
||||
return res, height, err
|
||||
}
|
||||
|
||||
ctx.LegacyAmino.MustUnmarshalBinaryBare(resRaw, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetFromAddress returns the from address from the context's name.
|
||||
func (ctx Context) GetFromAddress() sdk.AccAddress {
|
||||
return ctx.FromAddress
|
||||
|
|
|
@ -3,19 +3,67 @@ package client
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// TestAccountRetriever is an AccountRetriever that can be used in unit tests
|
||||
type TestAccountRetriever struct {
|
||||
Accounts map[string]struct {
|
||||
Address sdk.AccAddress
|
||||
Num uint64
|
||||
Seq uint64
|
||||
}
|
||||
var (
|
||||
_ AccountRetriever = TestAccountRetriever{}
|
||||
_ Account = TestAccount{}
|
||||
)
|
||||
|
||||
// TestAccount represents a client Account that can be used in unit tests
|
||||
type TestAccount struct {
|
||||
Address sdk.AccAddress
|
||||
Num uint64
|
||||
Seq uint64
|
||||
}
|
||||
|
||||
var _ AccountRetriever = TestAccountRetriever{}
|
||||
// GetAddress implements client Account.GetAddress
|
||||
func (t TestAccount) GetAddress() sdk.AccAddress {
|
||||
return t.Address
|
||||
}
|
||||
|
||||
// GetPubKey implements client Account.GetPubKey
|
||||
func (t TestAccount) GetPubKey() crypto.PubKey {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAccountNumber implements client Account.GetAccountNumber
|
||||
func (t TestAccount) GetAccountNumber() uint64 {
|
||||
return t.Num
|
||||
}
|
||||
|
||||
// GetSequence implements client Account.GetSequence
|
||||
func (t TestAccount) GetSequence() uint64 {
|
||||
return t.Seq
|
||||
}
|
||||
|
||||
// TestAccountRetriever is an AccountRetriever that can be used in unit tests
|
||||
type TestAccountRetriever struct {
|
||||
Accounts map[string]TestAccount
|
||||
}
|
||||
|
||||
// GetAccount implements AccountRetriever.GetAccount
|
||||
func (t TestAccountRetriever) GetAccount(_ Context, addr sdk.AccAddress) (Account, error) {
|
||||
acc, ok := t.Accounts[addr.String()]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("account %s not found", addr)
|
||||
}
|
||||
|
||||
return acc, nil
|
||||
}
|
||||
|
||||
// GetAccountWithHeight implements AccountRetriever.GetAccountWithHeight
|
||||
func (t TestAccountRetriever) GetAccountWithHeight(clientCtx Context, addr sdk.AccAddress) (Account, int64, error) {
|
||||
acc, err := t.GetAccount(clientCtx, addr)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return acc, 0, nil
|
||||
}
|
||||
|
||||
// EnsureExists implements AccountRetriever.EnsureExists
|
||||
func (t TestAccountRetriever) EnsureExists(_ Context, addr sdk.AccAddress) error {
|
||||
|
|
|
@ -19,7 +19,7 @@ func ConvertTxToStdTx(codec *codec.LegacyAmino, tx signing.Tx) (legacytx.StdTx,
|
|||
aminoTxConfig := legacytx.StdTxConfig{Cdc: codec}
|
||||
builder := aminoTxConfig.NewTxBuilder()
|
||||
|
||||
err := CopyTx(tx, builder)
|
||||
err := CopyTx(tx, builder, true)
|
||||
if err != nil {
|
||||
|
||||
return legacytx.StdTx{}, err
|
||||
|
@ -34,8 +34,9 @@ func ConvertTxToStdTx(codec *codec.LegacyAmino, tx signing.Tx) (legacytx.StdTx,
|
|||
}
|
||||
|
||||
// CopyTx copies a Tx to a new TxBuilder, allowing conversion between
|
||||
// different transaction formats.
|
||||
func CopyTx(tx signing.Tx, builder client.TxBuilder) error {
|
||||
// different transaction formats. If ignoreSignatureError is true, copying will continue
|
||||
// tx even if the signature cannot be set in the target builder resulting in an unsigned tx.
|
||||
func CopyTx(tx signing.Tx, builder client.TxBuilder, ignoreSignatureError bool) error {
|
||||
err := builder.SetMsgs(tx.GetMsgs()...)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -48,7 +49,13 @@ func CopyTx(tx signing.Tx, builder client.TxBuilder) error {
|
|||
|
||||
err = builder.SetSignatures(sigs...)
|
||||
if err != nil {
|
||||
return err
|
||||
if ignoreSignatureError {
|
||||
// we call SetSignatures() agan with no args to clear any signatures in case the
|
||||
// previous call to SetSignatures() had any partial side-effects
|
||||
_ = builder.SetSignatures()
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
builder.SetMemo(tx.GetMemo())
|
||||
|
@ -58,6 +65,7 @@ func CopyTx(tx signing.Tx, builder client.TxBuilder) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ConvertAndEncodeStdTx encodes the stdTx as a transaction in the format specified by txConfig
|
||||
func ConvertAndEncodeStdTx(txConfig client.TxConfig, stdTx legacytx.StdTx) ([]byte, error) {
|
||||
builder := txConfig.NewTxBuilder()
|
||||
|
||||
|
@ -67,7 +75,7 @@ func ConvertAndEncodeStdTx(txConfig client.TxConfig, stdTx legacytx.StdTx) ([]by
|
|||
if _, ok := builder.GetTx().(legacytx.StdTx); ok {
|
||||
theTx = stdTx
|
||||
} else {
|
||||
err := CopyTx(stdTx, builder)
|
||||
err := CopyTx(stdTx, builder, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ type TestSuite struct {
|
|||
}
|
||||
|
||||
func (s *TestSuite) SetupSuite() {
|
||||
encCfg := simapp.MakeEncodingConfig()
|
||||
encCfg := simapp.MakeTestEncodingConfig()
|
||||
s.encCfg = encCfg
|
||||
s.protoCfg = tx.NewTxConfig(codec.NewProtoCodec(encCfg.InterfaceRegistry), tx.DefaultSignModes)
|
||||
s.aminoCfg = legacytx.StdTxConfig{Cdc: encCfg.Amino}
|
||||
|
@ -68,10 +68,10 @@ func (s *TestSuite) TestCopyTx() {
|
|||
protoBuilder := s.protoCfg.NewTxBuilder()
|
||||
buildTestTx(s.T(), protoBuilder)
|
||||
aminoBuilder := s.aminoCfg.NewTxBuilder()
|
||||
err := tx2.CopyTx(protoBuilder.GetTx(), aminoBuilder)
|
||||
err := tx2.CopyTx(protoBuilder.GetTx(), aminoBuilder, false)
|
||||
s.Require().NoError(err)
|
||||
protoBuilder2 := s.protoCfg.NewTxBuilder()
|
||||
err = tx2.CopyTx(aminoBuilder.GetTx(), protoBuilder2)
|
||||
err = tx2.CopyTx(aminoBuilder.GetTx(), protoBuilder2, false)
|
||||
s.Require().NoError(err)
|
||||
bz, err := s.protoCfg.TxEncoder()(protoBuilder.GetTx())
|
||||
s.Require().NoError(err)
|
||||
|
@ -83,10 +83,10 @@ func (s *TestSuite) TestCopyTx() {
|
|||
aminoBuilder = s.aminoCfg.NewTxBuilder()
|
||||
buildTestTx(s.T(), aminoBuilder)
|
||||
protoBuilder = s.protoCfg.NewTxBuilder()
|
||||
err = tx2.CopyTx(aminoBuilder.GetTx(), protoBuilder)
|
||||
err = tx2.CopyTx(aminoBuilder.GetTx(), protoBuilder, false)
|
||||
s.Require().NoError(err)
|
||||
aminoBuilder2 := s.aminoCfg.NewTxBuilder()
|
||||
err = tx2.CopyTx(protoBuilder.GetTx(), aminoBuilder2)
|
||||
err = tx2.CopyTx(protoBuilder.GetTx(), aminoBuilder2, false)
|
||||
s.Require().NoError(err)
|
||||
bz, err = s.aminoCfg.TxEncoder()(aminoBuilder.GetTx())
|
||||
s.Require().NoError(err)
|
||||
|
@ -108,6 +108,23 @@ func (s *TestSuite) TestConvertTxToStdTx() {
|
|||
s.Require().Equal(sig.PubKey, stdTx.Signatures[0].PubKey)
|
||||
s.Require().Equal(sig.Data.(*signing2.SingleSignatureData).Signature, stdTx.Signatures[0].Signature)
|
||||
|
||||
// SIGN_MODE_DIRECT should fall back to an unsigned tx
|
||||
err = protoBuilder.SetSignatures(signing2.SignatureV2{
|
||||
PubKey: pub1,
|
||||
Data: &signing2.SingleSignatureData{
|
||||
SignMode: signing2.SignMode_SIGN_MODE_DIRECT,
|
||||
Signature: []byte("dummy"),
|
||||
},
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
stdTx, err = tx2.ConvertTxToStdTx(s.encCfg.Amino, protoBuilder.GetTx())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(memo, stdTx.Memo)
|
||||
s.Require().Equal(gas, stdTx.Fee.Gas)
|
||||
s.Require().Equal(fee, stdTx.Fee.Amount)
|
||||
s.Require().Equal(msg, stdTx.Msgs[0])
|
||||
s.Require().Empty(stdTx.Signatures)
|
||||
|
||||
// std tx
|
||||
aminoBuilder := s.aminoCfg.NewTxBuilder()
|
||||
buildTestTx(s.T(), aminoBuilder)
|
||||
|
@ -127,7 +144,7 @@ func (s *TestSuite) TestConvertAndEncodeStdTx() {
|
|||
decodedTx, err := s.protoCfg.TxDecoder()(txBz)
|
||||
s.Require().NoError(err)
|
||||
aminoBuilder2 := s.aminoCfg.NewTxBuilder()
|
||||
s.Require().NoError(tx2.CopyTx(decodedTx.(signing.Tx), aminoBuilder2))
|
||||
s.Require().NoError(tx2.CopyTx(decodedTx.(signing.Tx), aminoBuilder2, false))
|
||||
s.Require().Equal(stdTx, aminoBuilder2.GetTx())
|
||||
|
||||
// just use amino everywhere
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
)
|
||||
|
||||
func NewTestTxConfig() client.TxConfig {
|
||||
cfg := simapp.MakeEncodingConfig()
|
||||
cfg := simapp.MakeTestEncodingConfig()
|
||||
return cfg.TxConfig
|
||||
}
|
||||
|
||||
|
|
|
@ -139,6 +139,7 @@ func (cdc *LegacyAmino) MustUnmarshalBinaryLengthPrefixed(bz []byte, ptr interfa
|
|||
}
|
||||
}
|
||||
|
||||
// MarshalJSON implements codec.Marshaler interface
|
||||
func (cdc *LegacyAmino) MarshalJSON(o interface{}) ([]byte, error) {
|
||||
err := cdc.jsonMarshalAnys(o)
|
||||
if err != nil {
|
||||
|
@ -155,6 +156,7 @@ func (cdc *LegacyAmino) MustMarshalJSON(o interface{}) []byte {
|
|||
return bz
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements codec.Marshaler interface
|
||||
func (cdc *LegacyAmino) UnmarshalJSON(bz []byte, ptr interface{}) error {
|
||||
err := cdc.Amino.UnmarshalJSON(bz, ptr)
|
||||
if err != nil {
|
||||
|
|
|
@ -4,10 +4,9 @@ import (
|
|||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
)
|
||||
|
|
|
@ -11,10 +11,10 @@ import (
|
|||
|
||||
// ProtoMarshalJSON provides an auxiliary function to return Proto3 JSON encoded
|
||||
// bytes of a message.
|
||||
func ProtoMarshalJSON(msg proto.Message) ([]byte, error) {
|
||||
func ProtoMarshalJSON(msg proto.Message, resolver jsonpb.AnyResolver) ([]byte, error) {
|
||||
// We use the OrigName because camel casing fields just doesn't make sense.
|
||||
// EmitDefaults is also often the more expected behavior for CLI users
|
||||
jm := &jsonpb.Marshaler{OrigName: true, EmitDefaults: true}
|
||||
jm := &jsonpb.Marshaler{OrigName: true, EmitDefaults: true, AnyResolver: resolver}
|
||||
err := types.UnpackInterfaces(msg, types.ProtoJSONPacker{JSONPBMarshaler: jm})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -11,17 +11,25 @@ import (
|
|||
"github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
// ProtoCodecMarshaler defines an interface for codecs that utilize Protobuf for both
|
||||
// binary and JSON encoding.
|
||||
type ProtoCodecMarshaler interface {
|
||||
Marshaler
|
||||
InterfaceRegistry() types.InterfaceRegistry
|
||||
}
|
||||
|
||||
// ProtoCodec defines a codec that utilizes Protobuf for both binary and JSON
|
||||
// encoding.
|
||||
type ProtoCodec struct {
|
||||
anyUnpacker types.AnyUnpacker
|
||||
interfaceRegistry types.InterfaceRegistry
|
||||
}
|
||||
|
||||
var _ Marshaler = &ProtoCodec{}
|
||||
var _ ProtoCodecMarshaler = &ProtoCodec{}
|
||||
|
||||
// NewProtoCodec returns a reference to a new ProtoCodec
|
||||
func NewProtoCodec(anyUnpacker types.AnyUnpacker) *ProtoCodec {
|
||||
return &ProtoCodec{anyUnpacker: anyUnpacker}
|
||||
func NewProtoCodec(interfaceRegistry types.InterfaceRegistry) *ProtoCodec {
|
||||
return &ProtoCodec{interfaceRegistry: interfaceRegistry}
|
||||
}
|
||||
|
||||
// MarshalBinaryBare implements BinaryMarshaler.MarshalBinaryBare method.
|
||||
|
@ -67,7 +75,7 @@ func (pc *ProtoCodec) UnmarshalBinaryBare(bz []byte, ptr ProtoMarshaler) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = types.UnpackInterfaces(ptr, pc.anyUnpacker)
|
||||
err = types.UnpackInterfaces(ptr, pc.interfaceRegistry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -113,7 +121,7 @@ func (pc *ProtoCodec) MarshalJSON(o proto.Message) ([]byte, error) {
|
|||
return nil, fmt.Errorf("cannot protobuf JSON encode unsupported type: %T", o)
|
||||
}
|
||||
|
||||
return ProtoMarshalJSON(m)
|
||||
return ProtoMarshalJSON(m, pc.interfaceRegistry)
|
||||
}
|
||||
|
||||
// MustMarshalJSON implements JSONMarshaler.MustMarshalJSON method,
|
||||
|
@ -135,12 +143,13 @@ func (pc *ProtoCodec) UnmarshalJSON(bz []byte, ptr proto.Message) error {
|
|||
return fmt.Errorf("cannot protobuf JSON decode unsupported type: %T", ptr)
|
||||
}
|
||||
|
||||
err := jsonpb.Unmarshal(strings.NewReader(string(bz)), m)
|
||||
unmarshaler := jsonpb.Unmarshaler{AnyResolver: pc.interfaceRegistry}
|
||||
err := unmarshaler.Unmarshal(strings.NewReader(string(bz)), m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return types.UnpackInterfaces(ptr, pc.anyUnpacker)
|
||||
return types.UnpackInterfaces(ptr, pc.interfaceRegistry)
|
||||
}
|
||||
|
||||
// MustUnmarshalJSON implements JSONMarshaler.MustUnmarshalJSON method,
|
||||
|
@ -155,5 +164,9 @@ func (pc *ProtoCodec) MustUnmarshalJSON(bz []byte, ptr proto.Message) {
|
|||
// it unpacks the value in any to the interface pointer passed in as
|
||||
// iface.
|
||||
func (pc *ProtoCodec) UnpackAny(any *types.Any, iface interface{}) error {
|
||||
return pc.anyUnpacker.UnpackAny(any, iface)
|
||||
return pc.interfaceRegistry.UnpackAny(any, iface)
|
||||
}
|
||||
|
||||
func (pc *ProtoCodec) InterfaceRegistry() types.InterfaceRegistry {
|
||||
return pc.interfaceRegistry
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
|
@ -98,6 +99,23 @@ func UnsafePackAny(x interface{}) *Any {
|
|||
return &Any{cachedValue: x}
|
||||
}
|
||||
|
||||
// PackAny is a checked and safe version of UnsafePackAny. It assures that
|
||||
// `x` implements the proto.Message interface and uses it to serialize `x`.
|
||||
// [DEPRECATED]: should be moved away: https://github.com/cosmos/cosmos-sdk/issues/7479
|
||||
func PackAny(x interface{}) (*Any, error) {
|
||||
if x == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if intoany, ok := x.(IntoAny); ok {
|
||||
return intoany.AsAny(), nil
|
||||
}
|
||||
protoMsg, ok := x.(proto.Message)
|
||||
if !ok {
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "Expecting %T to implement proto.Message", x)
|
||||
}
|
||||
return NewAnyWithValue(protoMsg)
|
||||
}
|
||||
|
||||
// GetCachedValue returns the cached value from the Any if present
|
||||
func (any *Any) GetCachedValue() interface{} {
|
||||
return any.cachedValue
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/gogo/protobuf/jsonpb"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
|
@ -24,6 +26,7 @@ type AnyUnpacker interface {
|
|||
// implementations that can be safely unpacked from Any
|
||||
type InterfaceRegistry interface {
|
||||
AnyUnpacker
|
||||
jsonpb.AnyResolver
|
||||
|
||||
// RegisterInterface associates protoName as the public name for the
|
||||
// interface passed in as iface. This is to be used primarily to create
|
||||
|
@ -43,6 +46,17 @@ type InterfaceRegistry interface {
|
|||
// registry.RegisterImplementations((*sdk.Msg)(nil), &MsgSend{}, &MsgMultiSend{})
|
||||
RegisterImplementations(iface interface{}, impls ...proto.Message)
|
||||
|
||||
// RegisterCustomTypeURL allows a protobuf message to be registered as a
|
||||
// google.protobuf.Any with a custom typeURL (besides its own canonical
|
||||
// typeURL). iface should be an interface as type, as in RegisterInterface
|
||||
// and RegisterImplementations.
|
||||
//
|
||||
// Ex:
|
||||
// This will allow us to pack service methods in Any's using the full method name
|
||||
// as the type URL and the request body as the value, and allow us to unpack
|
||||
// such packed methods using the normal UnpackAny method for the interface iface.
|
||||
RegisterCustomTypeURL(iface interface{}, typeURL string, impl proto.Message)
|
||||
|
||||
// ListAllInterfaces list the type URLs of all registered interfaces.
|
||||
ListAllInterfaces() []string
|
||||
|
||||
|
@ -78,6 +92,7 @@ type UnpackInterfacesMessage interface {
|
|||
type interfaceRegistry struct {
|
||||
interfaceNames map[string]reflect.Type
|
||||
interfaceImpls map[reflect.Type]interfaceMap
|
||||
typeURLMap map[string]reflect.Type
|
||||
}
|
||||
|
||||
type interfaceMap = map[string]reflect.Type
|
||||
|
@ -87,6 +102,7 @@ func NewInterfaceRegistry() InterfaceRegistry {
|
|||
return &interfaceRegistry{
|
||||
interfaceNames: map[string]reflect.Type{},
|
||||
interfaceImpls: map[reflect.Type]interfaceMap{},
|
||||
typeURLMap: map[string]reflect.Type{},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,21 +116,31 @@ func (registry *interfaceRegistry) RegisterInterface(protoName string, iface int
|
|||
}
|
||||
|
||||
func (registry *interfaceRegistry) RegisterImplementations(iface interface{}, impls ...proto.Message) {
|
||||
for _, impl := range impls {
|
||||
typeURL := "/" + proto.MessageName(impl)
|
||||
registry.registerImpl(iface, typeURL, impl)
|
||||
}
|
||||
}
|
||||
|
||||
func (registry *interfaceRegistry) RegisterCustomTypeURL(iface interface{}, typeURL string, impl proto.Message) {
|
||||
registry.registerImpl(iface, typeURL, impl)
|
||||
}
|
||||
|
||||
func (registry *interfaceRegistry) registerImpl(iface interface{}, typeURL string, impl proto.Message) {
|
||||
ityp := reflect.TypeOf(iface).Elem()
|
||||
imap, found := registry.interfaceImpls[ityp]
|
||||
if !found {
|
||||
imap = map[string]reflect.Type{}
|
||||
}
|
||||
|
||||
for _, impl := range impls {
|
||||
implType := reflect.TypeOf(impl)
|
||||
if !implType.AssignableTo(ityp) {
|
||||
panic(fmt.Errorf("type %T doesn't actually implement interface %+v", impl, ityp))
|
||||
}
|
||||
|
||||
imap["/"+proto.MessageName(impl)] = implType
|
||||
implType := reflect.TypeOf(impl)
|
||||
if !implType.AssignableTo(ityp) {
|
||||
panic(fmt.Errorf("type %T doesn't actually implement interface %+v", impl, ityp))
|
||||
}
|
||||
|
||||
imap[typeURL] = implType
|
||||
registry.typeURLMap[typeURL] = implType
|
||||
|
||||
registry.interfaceImpls[ityp] = imap
|
||||
}
|
||||
|
||||
|
@ -146,6 +172,11 @@ func (registry *interfaceRegistry) ListImplementations(ifaceName string) []strin
|
|||
}
|
||||
|
||||
func (registry *interfaceRegistry) UnpackAny(any *Any, iface interface{}) error {
|
||||
// here we gracefully handle the case in which `any` itself is `nil`, which may occur in message decoding
|
||||
if any == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if any.TypeUrl == "" {
|
||||
// if TypeUrl is empty return nil because without it we can't actually unpack anything
|
||||
return nil
|
||||
|
@ -198,6 +229,23 @@ func (registry *interfaceRegistry) UnpackAny(any *Any, iface interface{}) error
|
|||
return nil
|
||||
}
|
||||
|
||||
// Resolve returns the proto message given its typeURL. It works with types
|
||||
// registered with RegisterInterface/RegisterImplementations, as well as those
|
||||
// registered with RegisterWithCustomTypeURL.
|
||||
func (registry *interfaceRegistry) Resolve(typeURL string) (proto.Message, error) {
|
||||
typ, found := registry.typeURLMap[typeURL]
|
||||
if !found {
|
||||
return nil, fmt.Errorf("unable to resolve type URL %s", typeURL)
|
||||
}
|
||||
|
||||
msg, ok := reflect.New(typ.Elem()).Interface().(proto.Message)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("can't resolve type URL %s", typeURL)
|
||||
}
|
||||
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
// UnpackInterfaces is a convenience function that calls UnpackInterfaces
|
||||
// on x if x implements UnpackInterfacesMessage
|
||||
func UnpackInterfaces(x interface{}, unpacker AnyUnpacker) error {
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
package types_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/gogo/protobuf/jsonpb"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
grpc2 "google.golang.org/grpc"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
)
|
||||
|
||||
|
@ -153,3 +158,60 @@ func TestAny_ProtoJSON(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Equal(t, spot, ha2.Animal.GetCachedValue())
|
||||
}
|
||||
|
||||
// this instance of grpc.ClientConn is used to test packing service method
|
||||
// requests into Any's
|
||||
type testAnyPackClient struct {
|
||||
any types.Any
|
||||
interfaceRegistry types.InterfaceRegistry
|
||||
}
|
||||
|
||||
var _ grpc.ClientConn = &testAnyPackClient{}
|
||||
|
||||
func (t *testAnyPackClient) Invoke(_ context.Context, method string, args, _ interface{}, _ ...grpc2.CallOption) error {
|
||||
reqMsg, ok := args.(proto.Message)
|
||||
if !ok {
|
||||
return fmt.Errorf("can't proto marshal %T", args)
|
||||
}
|
||||
|
||||
// registry the method request type with the interface registry
|
||||
t.interfaceRegistry.RegisterCustomTypeURL((*interface{})(nil), method, reqMsg)
|
||||
|
||||
bz, err := proto.Marshal(reqMsg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.any.TypeUrl = method
|
||||
t.any.Value = bz
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *testAnyPackClient) NewStream(context.Context, *grpc2.StreamDesc, string, ...grpc2.CallOption) (grpc2.ClientStream, error) {
|
||||
return nil, fmt.Errorf("not supported")
|
||||
}
|
||||
|
||||
func TestAny_ServiceRequestProtoJSON(t *testing.T) {
|
||||
interfaceRegistry := types.NewInterfaceRegistry()
|
||||
anyPacker := &testAnyPackClient{interfaceRegistry: interfaceRegistry}
|
||||
dogMsgClient := testdata.NewMsgClient(anyPacker)
|
||||
_, err := dogMsgClient.CreateDog(context.Background(), &testdata.MsgCreateDog{Dog: &testdata.Dog{
|
||||
Name: "spot",
|
||||
}})
|
||||
require.NoError(t, err)
|
||||
|
||||
// marshal JSON
|
||||
cdc := codec.NewProtoCodec(interfaceRegistry)
|
||||
bz, err := cdc.MarshalJSON(&anyPacker.any)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t,
|
||||
`{"@type":"/testdata.Msg/CreateDog","dog":{"size":"","name":"spot"}}`,
|
||||
string(bz))
|
||||
|
||||
// unmarshal JSON
|
||||
var any2 types.Any
|
||||
err = cdc.UnmarshalJSON(bz, &any2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, anyPacker.any, any2)
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ func benchmarkRejectUnknownFields(b *testing.B, parallel bool) {
|
|||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
n1A := new(testdata.Nested1A)
|
||||
if err := unknownproto.RejectUnknownFieldsStrict(n1BBlob, n1A); err == nil {
|
||||
if err := unknownproto.RejectUnknownFieldsStrict(n1BBlob, n1A, unknownproto.DefaultAnyResolver{}); err == nil {
|
||||
b.Fatal("expected an error")
|
||||
}
|
||||
b.SetBytes(int64(len(n1BBlob)))
|
||||
|
@ -68,7 +68,7 @@ func benchmarkRejectUnknownFields(b *testing.B, parallel bool) {
|
|||
for pb.Next() {
|
||||
// To simulate the conditions of multiple transactions being processed in parallel.
|
||||
n1A := new(testdata.Nested1A)
|
||||
if err := unknownproto.RejectUnknownFieldsStrict(n1BBlob, n1A); err == nil {
|
||||
if err := unknownproto.RejectUnknownFieldsStrict(n1BBlob, n1A, unknownproto.DefaultAnyResolver{}); err == nil {
|
||||
b.Fatal("expected an error")
|
||||
}
|
||||
mu.Lock()
|
||||
|
|
|
@ -7,8 +7,10 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/gogo/protobuf/jsonpb"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
|
||||
"google.golang.org/protobuf/encoding/protowire"
|
||||
|
@ -24,8 +26,9 @@ type descriptorIface interface {
|
|||
|
||||
// RejectUnknownFieldsStrict rejects any bytes bz with an error that has unknown fields for the provided proto.Message type.
|
||||
// This function traverses inside of messages nested via google.protobuf.Any. It does not do any deserialization of the proto.Message.
|
||||
func RejectUnknownFieldsStrict(bz []byte, msg proto.Message) error {
|
||||
_, err := RejectUnknownFields(bz, msg, false)
|
||||
// An AnyResolver must be provided for traversing inside google.protobuf.Any's.
|
||||
func RejectUnknownFieldsStrict(bz []byte, msg proto.Message, resolver jsonpb.AnyResolver) error {
|
||||
_, err := RejectUnknownFields(bz, msg, false, resolver)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -34,7 +37,8 @@ func RejectUnknownFieldsStrict(bz []byte, msg proto.Message) error {
|
|||
// hasUnknownNonCriticals will be set to true if non-critical fields were encountered during traversal. This flag can be
|
||||
// used to treat a message with non-critical field different in different security contexts (such as transaction signing).
|
||||
// This function traverses inside of messages nested via google.protobuf.Any. It does not do any deserialization of the proto.Message.
|
||||
func RejectUnknownFields(bz []byte, msg proto.Message, allowUnknownNonCriticals bool) (hasUnknownNonCriticals bool, err error) {
|
||||
// An AnyResolver must be provided for traversing inside google.protobuf.Any's.
|
||||
func RejectUnknownFields(bz []byte, msg proto.Message, allowUnknownNonCriticals bool, resolver jsonpb.AnyResolver) (hasUnknownNonCriticals bool, err error) {
|
||||
if len(bz) == 0 {
|
||||
return hasUnknownNonCriticals, nil
|
||||
}
|
||||
|
@ -115,9 +119,12 @@ func RejectUnknownFields(bz []byte, msg proto.Message, allowUnknownNonCriticals
|
|||
_, o := protowire.ConsumeVarint(fieldBytes)
|
||||
fieldBytes = fieldBytes[o:]
|
||||
|
||||
var msg proto.Message
|
||||
var err error
|
||||
|
||||
if protoMessageName == ".google.protobuf.Any" {
|
||||
// Firstly typecheck types.Any to ensure nothing snuck in.
|
||||
hasUnknownNonCriticalsChild, err := RejectUnknownFields(fieldBytes, (*types.Any)(nil), allowUnknownNonCriticals)
|
||||
hasUnknownNonCriticalsChild, err := RejectUnknownFields(fieldBytes, (*types.Any)(nil), allowUnknownNonCriticals, resolver)
|
||||
hasUnknownNonCriticals = hasUnknownNonCriticals || hasUnknownNonCriticalsChild
|
||||
if err != nil {
|
||||
return hasUnknownNonCriticals, err
|
||||
|
@ -129,14 +136,18 @@ func RejectUnknownFields(bz []byte, msg proto.Message, allowUnknownNonCriticals
|
|||
}
|
||||
protoMessageName = any.TypeUrl
|
||||
fieldBytes = any.Value
|
||||
msg, err = resolver.Resolve(protoMessageName)
|
||||
if err != nil {
|
||||
return hasUnknownNonCriticals, err
|
||||
}
|
||||
} else {
|
||||
msg, err = protoMessageForTypeName(protoMessageName[1:])
|
||||
if err != nil {
|
||||
return hasUnknownNonCriticals, err
|
||||
}
|
||||
}
|
||||
|
||||
msg, err := protoMessageForTypeName(protoMessageName[1:])
|
||||
if err != nil {
|
||||
return hasUnknownNonCriticals, err
|
||||
}
|
||||
|
||||
hasUnknownNonCriticalsChild, err := RejectUnknownFields(fieldBytes, msg, allowUnknownNonCriticals)
|
||||
hasUnknownNonCriticalsChild, err := RejectUnknownFields(fieldBytes, msg, allowUnknownNonCriticals, resolver)
|
||||
hasUnknownNonCriticals = hasUnknownNonCriticals || hasUnknownNonCriticalsChild
|
||||
if err != nil {
|
||||
return hasUnknownNonCriticals, err
|
||||
|
@ -401,3 +412,23 @@ func getDescriptorInfo(desc descriptorIface, msg proto.Message) (map[int32]*desc
|
|||
|
||||
return tagNumToTypeIndex, md, nil
|
||||
}
|
||||
|
||||
// DefaultAnyResolver is a default implementation of AnyResolver which uses
|
||||
// the default encoding of type URLs as specified by the protobuf specification.
|
||||
type DefaultAnyResolver struct{}
|
||||
|
||||
var _ jsonpb.AnyResolver = DefaultAnyResolver{}
|
||||
|
||||
// Resolve is the AnyResolver.Resolve method.
|
||||
func (d DefaultAnyResolver) Resolve(typeURL string) (proto.Message, error) {
|
||||
// Only the part of typeURL after the last slash is relevant.
|
||||
mname := typeURL
|
||||
if slash := strings.LastIndex(mname, "/"); slash >= 0 {
|
||||
mname = mname[slash+1:]
|
||||
}
|
||||
mt := proto.MessageType(mname)
|
||||
if mt == nil {
|
||||
return nil, fmt.Errorf("unknown message type %q", mname)
|
||||
}
|
||||
return reflect.New(mt.Elem()).Interface().(proto.Message), nil
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ func TestRejectUnknownFieldsRepeated(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
hasUnknownNonCriticals, gotErr := RejectUnknownFields(protoBlob, tt.recv, tt.allowUnknownNonCriticals)
|
||||
hasUnknownNonCriticals, gotErr := RejectUnknownFields(protoBlob, tt.recv, tt.allowUnknownNonCriticals, DefaultAnyResolver{})
|
||||
require.Equal(t, tt.wantErr, gotErr)
|
||||
require.Equal(t, tt.hasUnknownNonCriticals, hasUnknownNonCriticals)
|
||||
})
|
||||
|
@ -289,7 +289,7 @@ func TestRejectUnknownFields_allowUnknownNonCriticals(t *testing.T) {
|
|||
}
|
||||
|
||||
c1 := new(testdata.Customer1)
|
||||
_, gotErr := RejectUnknownFields(blob, c1, tt.allowUnknownNonCriticals)
|
||||
_, gotErr := RejectUnknownFields(blob, c1, tt.allowUnknownNonCriticals, DefaultAnyResolver{})
|
||||
if !reflect.DeepEqual(gotErr, tt.wantErr) {
|
||||
t.Fatalf("Error mismatch\nGot:\n%s\n\nWant:\n%s", gotErr, tt.wantErr)
|
||||
}
|
||||
|
@ -490,7 +490,7 @@ func TestRejectUnknownFieldsNested(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
gotErr := RejectUnknownFieldsStrict(protoBlob, tt.recv)
|
||||
gotErr := RejectUnknownFieldsStrict(protoBlob, tt.recv, DefaultAnyResolver{})
|
||||
if !reflect.DeepEqual(gotErr, tt.wantErr) {
|
||||
t.Fatalf("Error mismatch\nGot:\n%s\n\nWant:\n%s", gotErr, tt.wantErr)
|
||||
}
|
||||
|
@ -643,7 +643,7 @@ func TestRejectUnknownFieldsFlat(t *testing.T) {
|
|||
}
|
||||
|
||||
c1 := new(testdata.Customer1)
|
||||
gotErr := RejectUnknownFieldsStrict(blob, c1)
|
||||
gotErr := RejectUnknownFieldsStrict(blob, c1, DefaultAnyResolver{})
|
||||
if !reflect.DeepEqual(gotErr, tt.wantErr) {
|
||||
t.Fatalf("Error mismatch\nGot:\n%s\n\nWant:\n%s", gotErr, tt.wantErr)
|
||||
}
|
||||
|
@ -660,7 +660,7 @@ func TestPackedEncoding(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
unmarshalled := &testdata.TestRepeatedUints{}
|
||||
_, err = RejectUnknownFields(marshalled, unmarshalled, false)
|
||||
_, err = RejectUnknownFields(marshalled, unmarshalled, false, DefaultAnyResolver{})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,20 +7,19 @@ import (
|
|||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// MarshalYAML marshals the provided toPrint content with the provided JSON marshaler
|
||||
// by encoding JSON, decoding JSON, and then encoding YAML.
|
||||
// MarshalYAML marshals toPrint using jsonMarshaler 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 JSONMarshaler, toPrint proto.Message) ([]byte, error) {
|
||||
// only the JSONMarshaler has full context as to how the JSON
|
||||
// mashalling should look (which may be different for amino & proto codecs)
|
||||
// so we need to use it to marshal toPrint first
|
||||
// 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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// generate YAML by decoding and re-encoding JSON as YAML
|
||||
// generate YAML by decoding JSON and re-encoding to YAML
|
||||
var j interface{}
|
||||
|
||||
err = json.Unmarshal(bz, &j)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -119,32 +119,6 @@ f_install_protoc_gen_swagger() {
|
|||
f_print_done
|
||||
}
|
||||
|
||||
f_install_clang_format() {
|
||||
f_print_installing_with_padding clang-format
|
||||
|
||||
if which clang-format &>/dev/null ; then
|
||||
echo -e "\talready installed. Skipping."
|
||||
return 0
|
||||
fi
|
||||
|
||||
case "${UNAME_S}" in
|
||||
Linux)
|
||||
if [ -e /etc/debian_version ]; then
|
||||
echo -e "\tRun: sudo apt-get install clang-format" >&2
|
||||
elif [ -e /etc/fedora-release ]; then
|
||||
echo -e "\tRun: sudo dnf install clang" >&2
|
||||
else
|
||||
echo -e "\tRun (as root): subscription-manager repos --enable rhel-7-server-devtools-rpms ; yum install llvm-toolset-7" >&2
|
||||
fi
|
||||
;;
|
||||
Darwin)
|
||||
echo "\tRun: brew install clang-format" >&2
|
||||
;;
|
||||
*)
|
||||
echo "\tunknown operating system. Skipping." >&2
|
||||
esac
|
||||
}
|
||||
|
||||
f_ensure_tools
|
||||
f_ensure_dirs
|
||||
f_install_protoc
|
||||
|
@ -152,4 +126,3 @@ f_install_buf
|
|||
f_install_protoc_gen_gocosmos
|
||||
f_install_protoc_gen_grpc_gateway
|
||||
f_install_protoc_gen_swagger
|
||||
f_install_clang_format
|
||||
|
|
|
@ -15,12 +15,12 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
|
|||
// TODO We now register both Tendermint's PubKey and our own PubKey. In the
|
||||
// long-term, we should move away from Tendermint's PubKey, and delete
|
||||
// these lines.
|
||||
registry.RegisterInterface("tendermint.crypto.Pubkey", (*tmcrypto.PubKey)(nil))
|
||||
registry.RegisterInterface("tendermint.crypto.PubKey", (*tmcrypto.PubKey)(nil))
|
||||
registry.RegisterImplementations((*tmcrypto.PubKey)(nil), &ed25519.PubKey{})
|
||||
registry.RegisterImplementations((*tmcrypto.PubKey)(nil), &secp256k1.PubKey{})
|
||||
registry.RegisterImplementations((*tmcrypto.PubKey)(nil), &multisig.LegacyAminoPubKey{})
|
||||
|
||||
registry.RegisterInterface("cosmos.crypto.Pubkey", (*cryptotypes.PubKey)(nil))
|
||||
registry.RegisterInterface("cosmos.crypto.PubKey", (*cryptotypes.PubKey)(nil))
|
||||
registry.RegisterImplementations((*cryptotypes.PubKey)(nil), &ed25519.PubKey{})
|
||||
registry.RegisterImplementations((*cryptotypes.PubKey)(nil), &secp256k1.PubKey{})
|
||||
registry.RegisterImplementations((*cryptotypes.PubKey)(nil), &multisig.LegacyAminoPubKey{})
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
# ADR Creation Process
|
||||
|
||||
1. Copy the `adr-template.md` file. Use the following filename pattern: `adr-next_number-title.md`
|
||||
2. Create a draft Pull Request if you want to get an early feedback.
|
||||
3. Make sure the context and a solution is clear and well documented.
|
||||
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.
|
||||
|
||||
1. Every proposal SHOULD start with a new GitHub Issue or be a result of existing Issues. The Issue should contain just a brief proposal summary.
|
||||
|
||||
2. Once the motivation is validated, a GitHub Pull Request (PR) is created with a new document based on the `adr-template.md`.
|
||||
|
||||
3. An ADR doesn't have to arrive to `master` with an _accepted_ status in a single PR. If the motivation is clear and the solution is sound, we SHOULD be able to merge it and keep a _proposed_ status. It's preferable to have an iterative approach rather than long, not merged Pull Requests.
|
||||
|
||||
4. If a _proposed_ ADR is merged, then it should clearly document outstanding issues either in ADR document notes or in a GitHub Issue.
|
||||
|
||||
5. The PR SHOULD always be merged. In the case of a faulty ADR, we still prefer to merge it with a _rejected_ status. The only time the ADR SHOULD NOT be merged is if the author abandons it.
|
||||
|
||||
6. Merged ADRs SHOULD NOT be pruned.
|
||||
|
||||
|
||||
### ADR status
|
||||
|
||||
Status has two components:
|
||||
|
||||
```
|
||||
{CONSENSUS STATUS} {IMPLEMENTATION STATUS}
|
||||
```
|
||||
|
||||
IMPLEMENTATION STATUS is either `Implemented` or `Not Implemented`.
|
||||
|
||||
#### Consensus Status
|
||||
|
||||
```
|
||||
DRAFT -> PROPOSED -> LAST CALL yyyy-mm-dd -> ACCEPTED | REJECTED -> SUPERSEEDED by ADR-xxx
|
||||
\ |
|
||||
\ |
|
||||
v v
|
||||
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.
|
||||
+ `ACCEPTED`: ADR which will represent a currently implemented or to be implemented architecture design.
|
||||
+ `REJECTED`: ADR can go from PROPOSED or ACCEPTED to rejected if the consensus among project stakeholders will decide so.
|
||||
+ `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.
|
||||
+ Avoid using a first, personal form.
|
|
@ -8,8 +8,15 @@ parent:
|
|||
|
||||
This is a location to record all high-level architecture decisions in the Cosmos-SDK.
|
||||
|
||||
An Architectural Decision (**AD**) is a software design choice that addresses a functional or non-functional requirement that is architecturally significant.
|
||||
An Architecturally Significant Requirement (**ASR**) is a requirement that has a measurable effect on a software system’s architecture and quality.
|
||||
An Architectural Decision Record (**ADR**) captures a single AD, such as often done when writing personal notes or meeting minutes; the collection of ADRs created and maintained in a project constitute its decision log. All these are within the topic of Architectural Knowledge Management (AKM).
|
||||
|
||||
You can read more about the ADR concept in this [blog post](https://product.reverb.com/documenting-architecture-decisions-the-reverb-way-a3563bb24bd0#.78xhdix6t).
|
||||
|
||||
## Rationale
|
||||
|
||||
ADRs are intended to be the primary mechanism for proposing new feature designs and new processes, for collecting community input on an issue, and for documenting the design decisions.
|
||||
An ADR should provide:
|
||||
|
||||
- Context on the relevant goals and the current state
|
||||
|
@ -25,19 +32,29 @@ 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.
|
||||
|
||||
Note the context/background should be written in the present tense.
|
||||
|
||||
Please add a entry below in your Pull Request for an ADR.
|
||||
## Creating new ADR
|
||||
|
||||
Read about the [PROCESS](./PROCESS.md).
|
||||
|
||||
## ADR Table of Contents
|
||||
|
||||
### Accepted
|
||||
|
||||
- [ADR 001: Coin Source Tracing](./adr-001-coin-source-tracing.md)
|
||||
- [ADR 002: SDK Documentation Structure](./adr-002-docs-structure.md)
|
||||
- [ADR 003: Dynamic Capability Store](./adr-003-dynamic-capability-store.md)
|
||||
- [ADR 004: Split Denomination Keys](./adr-004-split-denomination-keys.md)
|
||||
- [ADR 006: Secret Store Replacement](./adr-006-secret-store-replacement.md)
|
||||
- [ADR 009: Evidence Module](./adr-009-evidence-module.md)
|
||||
- [ADR 010: Modular AnteHandler](./adr-010-modular-antehandler.md)
|
||||
- [ADR 019: Protocol Buffer State Encoding](./adr-019-protobuf-state-encoding.md)
|
||||
- [ADR 020: Protocol Buffer Transaction Encoding](./adr-020-protobuf-transaction-encoding.md)
|
||||
- [ADR 026: IBC Client Recovery Mechanisms](./adr-026-ibc-client-recovery-mechanisms.md)
|
||||
- [ADR 029: Fee Grant Module](./adr-029-fee-grant-module.md)
|
||||
|
||||
### Proposed
|
||||
|
||||
- [ADR 003: Dynamic Capability Store](./adr-003-dynamic-capability-store.md)
|
||||
- [ADR 004: Split Denomination Keys](./adr-004-split-denomination-keys.md)
|
||||
- [ADR 011: Generalize Genesis Accounts](./adr-011-generalize-genesis-accounts.md)
|
||||
- [ADR 012: State Accessors](./adr-012-state-accessors.md)
|
||||
- [ADR 013: Metrics](./adr-013-metrics.md)
|
||||
|
@ -45,12 +62,12 @@ Please add a entry below in your Pull Request for an ADR.
|
|||
- [ADR 016: Validator Consensus Key Rotation](./adr-016-validator-consensus-key-rotation.md)
|
||||
- [ADR 017: Historical Header Module](./adr-017-historical-header-module.md)
|
||||
- [ADR 018: Extendable Voting Periods](./adr-018-extendable-voting-period.md)
|
||||
- [ADR 019: Protocol Buffer State Encoding](./adr-019-protobuf-state-encoding.md)
|
||||
- [ADR 020: Protocol Buffer Transaction Encoding](./adr-020-protobuf-transaction-encoding.md)
|
||||
- [ADR 021: Protocol Buffer Query Encoding](./adr-021-protobuf-query-encoding.md)
|
||||
- [ADR 022: Custom baseapp panic handling](./adr-022-custom-panic-handling.md)
|
||||
- [ADR 023: Protocol Buffer Naming and Versioning](./adr-023-protobuf-naming.md)
|
||||
- [ADR 024: Coin Metadata](./adr-024-coin-metadata.md)
|
||||
- [ADR 025: IBC Passive Channels](./adr-025-ibc-passive-channels.md)
|
||||
- [ADR 026: IBC Client Recovery Mechanisms](./adr-026-ibc-client-recovery-mechanisms.md)
|
||||
- [ADR 027: Deterministic Protobuf Serialization](./adr-027-deterministic-protobuf-serialization.md)
|
||||
- [ADR 028: Public Key Addresses](./adr-028-public-key-addresses.md)
|
||||
- [ADR 031: Protobuf Msg Services](./adr-031-msg-service.md)
|
||||
- [ADR 032: Typed Events](./adr-032-typed-events.md)
|
||||
|
|
|
@ -9,8 +9,9 @@
|
|||
- 2020 May 14: Describe public key encoding
|
||||
- 2020 June 08: Store `TxBody` and `AuthInfo` as bytes in `SignDoc`; Document `TxRaw` as broadcast and storage type.
|
||||
- 2020 August 07: Use ADR 027 for serializing `SignDoc`.
|
||||
- 2020 August 19: Move sequence field from `SignDoc` to `SignerInfo`.
|
||||
- 2020 August 19: Move sequence field from `SignDoc` to `SignerInfo`, as discussed in [#6966](https://github.com/cosmos/cosmos-sdk/issues/6966).
|
||||
- 2020 September 25: Remove `PublicKey` type in favor of `secp256k1.PubKey`, `ed25519.PubKey` and `multisig.LegacyAminoPubKey`.
|
||||
- 2020 October 15: Add `GetAccount` and `GetAccountWithHeight` methods to the `AccountRetriever` interface.
|
||||
|
||||
## Status
|
||||
|
||||
|
@ -315,6 +316,8 @@ and messages.
|
|||
|
||||
```go
|
||||
type AccountRetriever interface {
|
||||
GetAccount(clientCtx Context, addr sdk.AccAddress) (client.Account, error)
|
||||
GetAccountWithHeight(clientCtx Context, addr sdk.AccAddress) (client.Account, int64, error)
|
||||
EnsureExists(clientCtx client.Context, addr sdk.AccAddress) error
|
||||
GetAccountNumberSequence(clientCtx client.Context, addr sdk.AccAddress) (uint64, uint64, error)
|
||||
}
|
||||
|
|
|
@ -109,12 +109,12 @@ func (q Querier) QueryBalance(ctx context.Context, params *types.QueryBalancePar
|
|||
### Custom Query Registration and Routing
|
||||
|
||||
Query server implementations as above would be registered with `AppModule`s using
|
||||
a new method `RegisterQueryServer(grpc.Server)` which could be implemented simply
|
||||
a new method `RegisterQueryService(grpc.Server)` which could be implemented simply
|
||||
as below:
|
||||
|
||||
```go
|
||||
// x/bank/module.go
|
||||
func (am AppModule) RegisterQueryServer(server grpc.Server) {
|
||||
func (am AppModule) RegisterQueryService(server grpc.Server) {
|
||||
types.RegisterQueryServer(server, keeper.Querier{am.keeper})
|
||||
}
|
||||
```
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
# ADR 028: Public Key Addresses
|
||||
|
||||
## Changelog
|
||||
|
||||
- 2020/08/18: Initial version
|
||||
|
||||
## Status
|
||||
|
||||
Proposed
|
||||
|
||||
## Abstract
|
||||
|
||||
This ADR defines a canonical 20-byte address format for new public key algorithms, multisig public keys, and module
|
||||
accounts using string prefixes.
|
||||
|
||||
## Context
|
||||
|
||||
Issue [\#3685](https://github.com/cosmos/cosmos-sdk/issues/3685) identified that public key
|
||||
address spaces are currently overlapping. One initial proposal was extending the address length and
|
||||
adding prefixes for different types of addresses.
|
||||
|
||||
@ethanfrey explained an alternate approach originally used in https://github.com/iov-one/weave:
|
||||
|
||||
> I spent quite a bit of time thinking about this issue while building weave... The other cosmos Sdk.
|
||||
|
||||
> Basically I define a condition to be a type and format as human readable string with some binary data appended. This condition is hashed into an Address (again at 20 bytes). The use of this prefix makes it impossible to find a preimage for a given address with a different condition (eg ed25519 vs secp256k1).
|
||||
|
||||
> This is explained in depth here https://weave.readthedocs.io/en/latest/design/permissions.html
|
||||
|
||||
> And the code is here, look mainly at the top where we process conditions. https://github.com/iov-one/weave/blob/master/conditions.go
|
||||
|
||||
And explained how this approach should be sufficiently collision resistant:
|
||||
> Yeah, AFAIK, 20 bytes should be collision resistance when the preimages are unique and not malleable. A space of 2^160 would expect some collision to be likely around 2^80 elements (birthday paradox). And if you want to find a collision for some existing element in the database, it is still 2^160. 2^80 only is if all these elements are written to state.
|
||||
|
||||
> The good example you brought up was eg. a public key bytes being a valid public key on two algorithms supported by the codec. Meaning if either was broken, you would break accounts even if they were secured with the safer variant. This is only as the issue when no differentiating type info is present in the preimage (before hashing into an address).
|
||||
|
||||
> I would like to hear an argument if the 20 bytes space is an actual issue for security, as I would be happy to increase my address sizes in weave. I just figured cosmos and ethereum and bitcoin all use 20 bytes, it should be good enough. And the arguments above which made me feel it was secure. But I have not done a deeper analysis.
|
||||
|
||||
In discussions in [\#5694](https://github.com/cosmos/cosmos-sdk/issues/5694), we agreed to go with an
|
||||
approach similar to this where essentially we take the first 20 bytes of the `sha256` hash of
|
||||
the key type concatenated with the key bytes, summarized as `Sha256(KeyTypePrefix || Keybytes)[:20]`.
|
||||
|
||||
## Decision
|
||||
|
||||
### Legacy Public Key Addresses Don't Change
|
||||
|
||||
`secp256k1` and multisig public keys are currently in use in existing Cosmos SDK zones. They use the following
|
||||
address formats:
|
||||
|
||||
- secp256k1: `ripemd160(sha256(pk_bytes))[:20]`
|
||||
- legacy amino multisig: `sha256(aminoCdc.Marshal(pk))[:20]`
|
||||
|
||||
We don't want to change existing addresses. So the addresses for these two key types will remain the same.
|
||||
|
||||
The current multisig public keys use amino serialization to generate the address. We will retain
|
||||
those public keys and their address formatting, and call them "legacy amino" multisig public keys
|
||||
in protobuf. We will also create multisig public keys without amino addresses to be described below.
|
||||
|
||||
|
||||
### Canonical Address Format
|
||||
|
||||
We have three types of accounts we would like to create addresses for in the future:
|
||||
- regular public key addresses for new signature algorithms (ex. `sr25519`).
|
||||
- public key addresses for multisig public keys that don't use amino encoding
|
||||
- module accounts: basically any accounts which cannot sign transactions and
|
||||
which are managed internally by modules
|
||||
|
||||
To address all of these use cases we propose the following basic `AddressHash` function,
|
||||
based on the discussions in [\#5694](https://github.com/cosmos/cosmos-sdk/issues/5694):
|
||||
|
||||
```go
|
||||
func AddressHash(prefix string, contents []byte) []byte {
|
||||
preImage := []byte(prefix)
|
||||
if len(contents) != 0 {
|
||||
preImage = append(preImage, 0)
|
||||
preImage = append(preImage, contents...)
|
||||
}
|
||||
return sha256.Sum256(preImage)[:20]
|
||||
}
|
||||
```
|
||||
|
||||
`AddressHash` always take a string `prefix` as a starting point which should represent the
|
||||
type of public key (ex. `sr25519`) or module account being used (ex. `staking` or `group`).
|
||||
For public keys, the `contents` parameter is used to specify the binary contents of the public
|
||||
key. For module accounts, `contents` can be left empty (for modules which don't manage "sub-accounts"),
|
||||
or can be some module-specific content to specify different pools (ex. `bonded` or `not-bonded` for `staking`)
|
||||
or managed accounts (ex. different accounts managed by the `group` module).
|
||||
|
||||
In the `preImage`, the byte value `0` is used as the separator between `prefix` and `contents`. This is a logical
|
||||
choice given that `0` is an invalid value for a string character and is commonly used as a null terminator.
|
||||
|
||||
### Canonical Public Key Address Prefixes
|
||||
|
||||
All public key types will have a unique protobuf message type such as:
|
||||
|
||||
```proto
|
||||
package cosmos.crypto.sr25519;
|
||||
|
||||
message PubKey {
|
||||
bytes key = 1;
|
||||
}
|
||||
```
|
||||
|
||||
All protobuf messages have unique fully qualified names, in this example `cosmos.crypto.sr25519.PubKey`.
|
||||
These names are derived directly from .proto files in a standardized way and used
|
||||
in other places such as the type URL in `Any`s. Since there is an easy and obvious
|
||||
way to get this name for every protobuf type, we can use this message name as the
|
||||
key type `prefix` when creating addresses. For all basic public keys, `contents`
|
||||
should just be the raw unencoded public key bytes.
|
||||
|
||||
Thus the canonical address for new public key types would be `AddressHash(proto.MessageName(pk), pk.Bytes)`.
|
||||
|
||||
### Multisig Addresses
|
||||
|
||||
For new multisig public keys, we define a custom address format not based on any encoding scheme
|
||||
(amino or protobuf). This avoids issues with non-determinism in the encoding scheme. It also
|
||||
ensures that multisig public keys which differ simply in the ordering of keys have the same
|
||||
address by sorting child public keys first.
|
||||
|
||||
First we define a proto message for multisig public keys:
|
||||
```proto
|
||||
package cosmos.crypto.multisig;
|
||||
|
||||
message PubKey {
|
||||
uint32 threshold = 1;
|
||||
repeated google.protobuf.Any public_keys = 2;
|
||||
}
|
||||
```
|
||||
|
||||
We define the following `Address()` function for this public key:
|
||||
|
||||
```
|
||||
func (multisig PubKey) Address() {
|
||||
// first gather all the addresses of each nested public key
|
||||
var addresses [][]byte
|
||||
for key := range multisig.Keys {
|
||||
addresses = append(joinedAddresses, key.Address())
|
||||
}
|
||||
|
||||
// then sort them in ascending order
|
||||
addresses = Sort(addresses)
|
||||
|
||||
// then concatenate them together
|
||||
var joinedAddresses []byte
|
||||
for addr := range addresses {
|
||||
joinedAddresses := append(joinedAddresses, addr...)
|
||||
}
|
||||
|
||||
// form the string prefix from the message name (cosmos.crypto.multisig.PubKey) and the threshold joined together
|
||||
prefix := fmt.Sprintf("%s/%d", proto.MessageName(multisig), multisig.Threshold)
|
||||
|
||||
// use the standard AddressHash function
|
||||
return AddressHash(prefix, joinedAddresses)
|
||||
}
|
||||
```
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
- a simple algorithm for generating addresses for new public keys and module accounts
|
||||
|
||||
### Negative
|
||||
- addresses do not communicate key type, a prefixed approach would have done this
|
||||
|
||||
### Neutral
|
||||
- protobuf message names are used as key type prefixes
|
||||
|
||||
## References
|
|
@ -0,0 +1,162 @@
|
|||
# ADR 029: Fee Grant Module
|
||||
|
||||
## Changelog
|
||||
|
||||
- 2020/08/18: Initial Draft
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
In order to make blockchain transactions, the signing account must possess a sufficient balance of the right denomination
|
||||
in order to pay fees. There are classes of transactions where needing to maintain a wallet with sufficient fees is a
|
||||
barrier to adoption.
|
||||
|
||||
For instance, when proper permissions are setup, someone may temporarily delegate the ability to vote on proposals to
|
||||
a "burner" account that is stored on a mobile phone with only minimal security.
|
||||
|
||||
Other use cases include workers tracking items in a supply chain or farmers submitting field data for analytics
|
||||
or compliance purposes.
|
||||
|
||||
For all of these use cases, UX would be significantly enhanced by obviating the need for these accounts to always
|
||||
maintain the appropriate fee balance. This is especially true if we wanted to achieve enterprise adoption for something
|
||||
like supply chain tracking.
|
||||
|
||||
While one solution would be to have a service that fills up these accounts automatically with the appropriate fees, a better UX
|
||||
would be provided by allowing these accounts to pull from a common fee pool account with proper spending limits.
|
||||
A single pool would reduce the churn of making lots of small "fill up" transactions and also more effectively leverages
|
||||
the resources of the organization setting up the pool.
|
||||
|
||||
## Decision
|
||||
|
||||
As a solution we propose a module, `x/feegrant` which allows one account, the "granter" to grant another account, the "grantee"
|
||||
an allowance to spend the granter's account balance for fees within certain well-defined limits.
|
||||
|
||||
Fee allowances are defined by the extensible `FeeAllowanceI` interface:
|
||||
|
||||
```go
|
||||
type FeeAllowanceI {
|
||||
// Accept can use fee payment requested as well as timestamp/height of the current block
|
||||
// to determine whether or not to process this. This is checked in
|
||||
// Keeper.UseGrantedFees and the return values should match how it is handled there.
|
||||
//
|
||||
// If it returns an error, the fee payment is rejected, otherwise it is accepted.
|
||||
// The FeeAllowance implementation is expected to update it's internal state
|
||||
// and will be saved again after an acceptance.
|
||||
//
|
||||
// If remove is true (regardless of the error), the FeeAllowance will be deleted from storage
|
||||
// (eg. when it is used up). (See call to RevokeFeeAllowance in Keeper.UseGrantedFees)
|
||||
Accept(fee sdk.Coins, blockTime time.Time, blockHeight int64) (remove bool, err error)
|
||||
}
|
||||
```
|
||||
|
||||
Two basic fee allowance types, `BasicFeeAllowance` and `PeriodicFeeAllowance` are defined to support known use cases:
|
||||
|
||||
```proto
|
||||
// BasicFeeAllowance implements FeeAllowance with a one-time grant of tokens
|
||||
// that optionally expires. The delegatee can use up to SpendLimit to cover fees.
|
||||
message BasicFeeAllowance {
|
||||
// spend_limit specifies the maximum amount of tokens that can be spent
|
||||
// by this allowance and will be updated as tokens are spent. If it is
|
||||
// empty, there is no spend limit and any amount of coins can be spent.
|
||||
repeated cosmos_sdk.v1.Coin spend_limit = 1;
|
||||
|
||||
// expires_at specifies an optional time when this allowance expires
|
||||
ExpiresAt expiration = 2;
|
||||
}
|
||||
|
||||
// PeriodicFeeAllowance extends FeeAllowance to allow for both a maximum cap,
|
||||
// as well as a limit per time period.
|
||||
message PeriodicFeeAllowance {
|
||||
BasicFeeAllowance basic = 1;
|
||||
|
||||
// period specifies the time duration in which period_spend_limit coins can
|
||||
// be spent before that allowance is reset
|
||||
Duration period = 2;
|
||||
|
||||
// period_spend_limit specifies the maximum number of coins that can be spent
|
||||
// in the period
|
||||
repeated cosmos_sdk.v1.Coin period_spend_limit = 3;
|
||||
|
||||
// period_can_spend is the number of coins left to be spent before the period_reset time
|
||||
repeated cosmos_sdk.v1.Coin period_can_spend = 4;
|
||||
|
||||
// period_reset is the time at which this period resets and a new one begins,
|
||||
// it is calculated from the start time of the first transaction after the
|
||||
// last period ended
|
||||
ExpiresAt period_reset = 5;
|
||||
}
|
||||
|
||||
// ExpiresAt is a point in time where something expires.
|
||||
// It may be *either* block time or block height
|
||||
message ExpiresAt {
|
||||
oneof sum {
|
||||
google.protobuf.Timestamp time = 1;
|
||||
uint64 height = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Duration is a repeating unit of either clock time or number of blocks.
|
||||
message Duration {
|
||||
oneof sum {
|
||||
google.protobuf.Duration duration = 1;
|
||||
uint64 blocks = 2;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Allowances can be granted and revoked using `MsgGrantFeeAllowance` and `MsgRevokeFeeAllowance`:
|
||||
|
||||
```proto
|
||||
message MsgGrantFeeAllowance {
|
||||
string granter = 1;
|
||||
string grantee = 2;
|
||||
google.protobuf.Any allowance = 3;
|
||||
}
|
||||
|
||||
// MsgRevokeFeeAllowance removes any existing FeeAllowance from Granter to Grantee.
|
||||
message MsgRevokeFeeAllowance {
|
||||
string granter = 1;
|
||||
string grantee = 2;
|
||||
}
|
||||
```
|
||||
|
||||
In order to use allowances in transactions, we add a new field `granter` to the transaction `Fee` type:
|
||||
```proto
|
||||
package cosmos.tx.v1beta1;
|
||||
|
||||
message Fee {
|
||||
repeated cosmos.base.v1beta1.Coin amount = 1;
|
||||
uint64 gas_limit = 2;
|
||||
string payer = 3;
|
||||
string granter = 4;
|
||||
}
|
||||
```
|
||||
|
||||
`granter` must either be left empty or must correspond to an account which has granted
|
||||
a fee allowance to fee payer (either the first signer or the value of the `payer` field).
|
||||
|
||||
A new `AnteDecorator` named `DeductGrantedFeeDecorator` will be created in order to process transactions with `fee_payer`
|
||||
set and correctly deduct fees based on fee allowances.
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
- improved UX for use cases where it is cumbersome to maintain an account balance just for fees
|
||||
|
||||
### Negative
|
||||
|
||||
### Neutral
|
||||
|
||||
- a new field must be added to the transaction `Fee` message and a new `AnteDecorator` must be
|
||||
created to use it
|
||||
|
||||
## References
|
||||
|
||||
- Blog article describing initial work: https://medium.com/regen-network/hacking-the-cosmos-cosmwasm-and-key-management-a08b9f561d1b
|
||||
- Initial public specification: https://gist.github.com/aaronc/b60628017352df5983791cad30babe56
|
||||
- Original subkeys proposal from B-harvest which influenced this design: https://github.com/cosmos/cosmos-sdk/issues/4480
|
|
@ -0,0 +1,238 @@
|
|||
# ADR 031: Protobuf Msg Services
|
||||
|
||||
## Changelog
|
||||
|
||||
- 2020-10-05: Initial Draft
|
||||
|
||||
## Status
|
||||
|
||||
Proposed
|
||||
|
||||
## Abstract
|
||||
|
||||
We want to leverage protobuf `service` definitions for defining `Msg`s which will give us significant developer UX
|
||||
improvements in terms of the code that is generated and the fact that return types will now be well defined.
|
||||
|
||||
## Context
|
||||
|
||||
Currently `Msg` handlers in the Cosmos SDK do have return values that are placed in the `data` field of the response.
|
||||
These return values, however, are not specified anywhere except in the golang handler code.
|
||||
|
||||
In early conversations [it was proposed](https://docs.google.com/document/d/1eEgYgvgZqLE45vETjhwIw4VOqK-5hwQtZtjVbiXnIGc/edit)
|
||||
that `Msg` return types be captured using a protobuf extension field, ex:
|
||||
|
||||
```protobuf
|
||||
package cosmos.gov;
|
||||
|
||||
message MsgSubmitProposal
|
||||
option (cosmos_proto.msg_return) = “uint64”;
|
||||
string delegator_address = 1;
|
||||
string validator_address = 2;
|
||||
repeated sdk.Coin amount = 3;
|
||||
}
|
||||
```
|
||||
|
||||
This was never adopted, however.
|
||||
|
||||
Having a well-specified return value for `Msg`s would improve client UX. For instance,
|
||||
in `x/gov`, `MsgSubmitProposal` returns the proposal ID as a big-endian `uint64`.
|
||||
This isn’t really documented anywhere and clients would need to know the internals
|
||||
of the SDK to parse that value and return it to users.
|
||||
|
||||
Also, there may be cases where we want to use these return values programatically.
|
||||
For instance, https://github.com/cosmos/cosmos-sdk/issues/7093 proposes a method for
|
||||
doing inter-module Ocaps using the `Msg` router. A well-defined return type would
|
||||
improve the developer UX for this approach.
|
||||
|
||||
In addition, handler registration of `Msg` types tends to add a bit of
|
||||
boilerplate on top of keepers and is usually done through manual type switches.
|
||||
This isn't necessarily bad, but it does add overhead to creating modules.
|
||||
|
||||
## Decision
|
||||
|
||||
We decide to use protobuf `service` definitions for defining `Msg`s as well as
|
||||
the code generated by them as a replacement for `Msg` handlers.
|
||||
|
||||
Below we define how this will look for the `SubmitProposal` message from `x/gov` module.
|
||||
We start with a `Msg` `service` definition:
|
||||
|
||||
```proto
|
||||
package cosmos.gov;
|
||||
|
||||
service Msg {
|
||||
rpc SubmitProposal(MsgSubmitProposal) returns (MsgSubmitProposalResponse);
|
||||
}
|
||||
|
||||
// Note that for backwards compatibility this uses MsgSubmitProposal as the request
|
||||
// type instead of the more canonical MsgSubmitProposalRequest
|
||||
message MsgSubmitProposal {
|
||||
google.protobuf.Any content = 1;
|
||||
string proposer = 2;
|
||||
}
|
||||
|
||||
message MsgSubmitProposalResponse {
|
||||
uint64 proposal_id;
|
||||
}
|
||||
```
|
||||
|
||||
While this is most commonly used for gRPC, overloading protobuf `service` definitions like this does not violate
|
||||
the intent of the [protobuf spec](https://developers.google.com/protocol-buffers/docs/proto3#services) which says:
|
||||
> If you don’t want to use gRPC, it’s also possible to use protocol buffers with your own RPC implementation.
|
||||
With this approach, we would get an auto-generated `MsgServer` interface:
|
||||
|
||||
In addition to clearly specifying return types, this has the benefit of generating client and server code. On the server
|
||||
side, this is almost like an automatically generated keeper method and could maybe be used intead of keepers eventually
|
||||
(see [\#7093](https://github.com/cosmos/cosmos-sdk/issues/7093)):
|
||||
|
||||
```go
|
||||
package gov
|
||||
|
||||
type MsgServer interface {
|
||||
SubmitProposal(context.Context, *MsgSubmitProposal) (*MsgSubmitProposalResponse, error)
|
||||
}
|
||||
```
|
||||
|
||||
On the client side, developers could take advantage of this by creating RPC implementations that encapsulate transaction
|
||||
logic. Protobuf libraries that use asynchronous callbacks, like [protobuf.js](https://github.com/protobufjs/protobuf.js#using-services)
|
||||
could use this to register callbacks for specific messages even for transactions that include multiple `Msg`s.
|
||||
|
||||
For backwards compatibility, existing `Msg` types should be used as the request parameter
|
||||
for `service` definitions. Newer `Msg` types which only support `service` definitions
|
||||
should use the more canonical `Msg...Request` names.
|
||||
|
||||
### Encoding
|
||||
|
||||
Currently, we are encoding `Msg`s as `Any` in `Tx`s which involves packing the
|
||||
binary-encoded `Msg` with its type URL.
|
||||
|
||||
The type URL for `MsgSubmitProposal` based on the proto3 spec is `/cosmos.gov.MsgSubmitProposal`.
|
||||
|
||||
The fully-qualified name for the `SubmitProposal` service method above (also
|
||||
based on the proto3 and gRPC specs) is `/cosmos.gov.Msg/SubmitProposal` which varies
|
||||
by a single `/` character. The generated `.pb.go` files for protobuf `service`s
|
||||
include names of this form and any compliant protobuf/gRPC code generator will
|
||||
generate the same name.
|
||||
|
||||
In order to encode service methods in transactions, we encode them as `Any`s in
|
||||
the same `TxBody.messages` field as other `Msg`s. We simply set `Any.type_url`
|
||||
to the full-qualified method name (ex. `/cosmos.gov.Msg/SubmitProposal`) and
|
||||
set `Any.value` to the protobuf encoding of the request message
|
||||
(`MsgSubmitProposal` in this case).
|
||||
|
||||
### Decoding
|
||||
|
||||
When decoding, `TxBody.UnpackInterfaces` will need a special case
|
||||
to detect if `Any` type URLs match the service method format (ex. `/cosmos.gov.Msg/SubmitProposal`)
|
||||
by checking for two `/` characters. Messages that are method names plus request parameters
|
||||
instead of a normal `Any` messages will get unpacked into the `ServiceMsg` struct:
|
||||
|
||||
```go
|
||||
type ServiceMsg struct {
|
||||
// MethodName is the fully-qualified service name
|
||||
MethodName string
|
||||
// Request is the request payload
|
||||
Request MsgRequest
|
||||
}
|
||||
```
|
||||
|
||||
### Routing
|
||||
|
||||
In the future, `service` definitions may become the primary method for defining
|
||||
`Msg`s. As a starting point, we need to integrate with the SDK's existing routing
|
||||
and `Msg` interface.
|
||||
|
||||
To do this, `ServiceMsg` implements the `sdk.Msg` interface and its handler does the
|
||||
actual method routing, allowing this feature to be added incrementally on top of
|
||||
existing functionality.
|
||||
|
||||
### `MsgRequest` interface
|
||||
|
||||
All request messages will need to implement the `MsgRequest` interface which is a
|
||||
simplified version of `Msg`, without `Route()`, `Type()` and `GetSignBytes()` which
|
||||
are no longer needed:
|
||||
|
||||
```go
|
||||
type MsgRequest interface {
|
||||
proto.Message
|
||||
ValidateBasic() error
|
||||
GetSigners() []AccAddress
|
||||
}
|
||||
```
|
||||
|
||||
`ServiceMsg` will forward its `ValidateBasic` and `GetSigners` methods to the `MsgRequest`
|
||||
methods.
|
||||
|
||||
### Module Configuration
|
||||
|
||||
In [ADR 021](./adr-021-protobuf-query-encoding.md), we introduced a method `RegisterQueryService`
|
||||
to `AppModule` which allows for modules to register gRPC queriers.
|
||||
|
||||
To register `Msg` services, we attempt a more extensible approach by converting `RegisterQueryService`
|
||||
to a more generic `RegisterServices` method:
|
||||
|
||||
```go
|
||||
type AppModule interface {
|
||||
RegisterServices(Configurator)
|
||||
...
|
||||
}
|
||||
|
||||
type Configurator interface {
|
||||
QueryServer() grpc.Server
|
||||
MsgServer() grpc.Server
|
||||
}
|
||||
|
||||
// example module:
|
||||
func (am AppModule) RegisterServices(cfg Configurator) {
|
||||
types.RegisterQueryServer(cfg.QueryServer(), keeper)
|
||||
types.RegisterMsgServer(cfg.MsgServer(), keeper)
|
||||
}
|
||||
```
|
||||
|
||||
The `RegisterServices` method and the `Configurator` interface are intended to
|
||||
evolve to satisfy the use cases discussed in [\#7093](https://github.com/cosmos/cosmos-sdk/issues/7093)
|
||||
and [\#7122](https://github.com/cosmos/cosmos-sdk/issues/7421).
|
||||
|
||||
When `Msg` services are registered, the framework _should_ verify that all `Msg...Request` types
|
||||
implement the `MsgRequest` interface described above and throw an error during initialization rather
|
||||
than later when transactions are processed.
|
||||
|
||||
### `Msg` Service Implementation
|
||||
|
||||
Just like query services, `Msg` service methods can retrieve the `sdk.Context`
|
||||
from the `context.Context` parameter method using the `sdk.UnwrapSDKContext`
|
||||
method:
|
||||
|
||||
```go
|
||||
package gov
|
||||
|
||||
func (k Keeper) SubmitProposal(goCtx context.Context, params *types.MsgSubmitProposal) (*MsgSubmitProposalResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
The `sdk.Context` should have an `EventManager` already attached by the `ServiceMsg`
|
||||
router.
|
||||
|
||||
Separate handler definition is no longer needed with this approach.
|
||||
|
||||
## Consequences
|
||||
|
||||
### Pros
|
||||
- communicates return type clearly
|
||||
- manual handler registration and return type marshaling is no longer needed, just implement the interface and register it
|
||||
- some keeper code could be automatically generate, this would improve the UX of [\#7093](https://github.com/cosmos/cosmos-sdk/issues/7093) approach (1) if we chose to adopt that
|
||||
- generated client code could be useful for clients
|
||||
|
||||
### Cons
|
||||
- supporting both this and the current concrete `Msg` type approach simultaneously could be confusing
|
||||
(we could choose to deprecate the current approach)
|
||||
- using `service` definitions outside the context of gRPC could be confusing (but doesn’t violate the proto3 spec)
|
||||
|
||||
## References
|
||||
|
||||
- [Initial Github Issue \#7122](https://github.com/cosmos/cosmos-sdk/issues/7122)
|
||||
- [proto 3 Language Guide: Defining Services](https://developers.google.com/protocol-buffers/docs/proto3#services)
|
||||
- [Initial pre-`Any` `Msg` designs](https://docs.google.com/document/d/1eEgYgvgZqLE45vETjhwIw4VOqK-5hwQtZtjVbiXnIGc)
|
||||
- [ADR 020](./adr-020-protobuf-transaction-encoding.md)
|
||||
- [ADR 021](./adr-021-protobuf-query-encoding.md)
|
|
@ -0,0 +1,319 @@
|
|||
# ADR 032: Typed Events
|
||||
|
||||
## Changelog
|
||||
|
||||
- 28-Sept-2020: Initial Draft
|
||||
|
||||
## Authors
|
||||
|
||||
- Anil Kumar (@anilcse)
|
||||
- Jack Zampolin (@jackzampolin)
|
||||
- Adam Bozanich (@boz)
|
||||
|
||||
## Status
|
||||
|
||||
Proposed
|
||||
|
||||
## Abstract
|
||||
|
||||
Currently in the SDK, events are defined in the handlers for each message as well as `BeginBlock` and `EndBlock`. Each module doesn't have types defined for each event, they are implemented as `map[string]string`. Above all else this makes these events difficult to consume as it requires a great deal of raw string matching and parsing. This proposal focuses on updating the events to use **typed events** defined in each module such that emiting and subscribing to events will be much easier. This workflow comes from the experience of the Akash Network team.
|
||||
|
||||
## Context
|
||||
|
||||
Currently in the SDK, events are defined in the handlers for each message, meaning each module doesn't have a cannonical set of types for each event. Above all else this makes these events difficult to consume as it requires a great deal of raw string matching and parsing. This proposal focuses on updating the events to use **typed events** defined in each module such that emiting and subscribing to events will be much easier. This workflow comes from the experience of the Akash Network team.
|
||||
|
||||
[Our platform](http://github.com/ovrclk/akash) requires a number of programatic on chain interactions both on the provider (datacenter - to bid on new orders and listen for leases created) and user (application developer - to send the app manifest to the provider) side. In addition the Akash team is now maintaining the IBC [`relayer`](https://github.com/ovrclk/relayer), another very event driven process. In working on these core pieces of infrastructure, and integrating lessons learned from Kubernetes developement, our team has developed a standard method for defining and consuming typed events in SDK modules. We have found that it is extremely useful in building this type of event driven application.
|
||||
|
||||
As the SDK gets used more extensively for apps like `peggy`, other peg zones, IBC, DeFi, etc... there will be an exploding demand for event driven applications to support new features desired by users. We propose upstreaming our findings into the SDK to enable all SDK applications to quickly and easily build event driven apps to aid their core application. Wallets, exchanges, explorers, and defi protocols all stand to benefit from this work.
|
||||
|
||||
If this proposal is accepted, users will be able to build event driven SDK apps in go by just writing `EventHandler`s for their specific event types and passing them to `EventEmitters` that are defined in the SDK.
|
||||
|
||||
The end of this proposal contains a detailed example of how to consume events after this refactor.
|
||||
|
||||
This proposal is specifically about how to consume these events as a client of the blockchain, not for intermodule communication.
|
||||
|
||||
## Decision
|
||||
|
||||
__Step-1__: Implement additional functionality in the `types` package: `EmitTypedEvent` and `ParseTypedEvent` functions
|
||||
|
||||
```go
|
||||
// types/events.go
|
||||
|
||||
// EmitTypedEvent takes typed event and emits converting it into sdk.Event
|
||||
func (em *EventManager) EmitTypedEvent(event proto.Message) error {
|
||||
evtType := proto.MessageName(event)
|
||||
evtJSON, err := codec.ProtoMarshalJSON(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var attrMap map[string]json.RawMessage
|
||||
err = json.Unmarshal(evtJSON, &attrMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var attrs []abci.EventAttribute
|
||||
for k, v := range attrMap {
|
||||
attrs = append(attrs, abci.EventAttribute{
|
||||
Key: []byte(k),
|
||||
Value: v,
|
||||
})
|
||||
}
|
||||
|
||||
em.EmitEvent(Event{
|
||||
Type: evtType,
|
||||
Attributes: attrs,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseTypedEvent converts abci.Event back to typed event
|
||||
func ParseTypedEvent(event abci.Event) (proto.Message, error) {
|
||||
concreteGoType := proto.MessageType(event.Type)
|
||||
if concreteGoType == nil {
|
||||
return nil, fmt.Errorf("failed to retrieve the message of type %q", event.Type)
|
||||
}
|
||||
|
||||
var value reflect.Value
|
||||
if concreteGoType.Kind() == reflect.Ptr {
|
||||
value = reflect.New(concreteGoType.Elem())
|
||||
} else {
|
||||
value = reflect.Zero(concreteGoType)
|
||||
}
|
||||
|
||||
protoMsg, ok := value.Interface().(proto.Message)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%q does not implement proto.Message", event.Type)
|
||||
}
|
||||
|
||||
attrMap := make(map[string]json.RawMessage)
|
||||
for _, attr := range event.Attributes {
|
||||
attrMap[string(attr.Key)] = attr.Value
|
||||
}
|
||||
|
||||
attrBytes, err := json.Marshal(attrMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = jsonpb.Unmarshal(strings.NewReader(string(attrBytes)), protoMsg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return protoMsg, nil
|
||||
}
|
||||
```
|
||||
|
||||
Here, the `EmitTypedEvent` is a method on `EventManager` which takes typed event as input and apply json serialization on it. Then it maps the JSON key/value pairs to `event.Attributes` and emits it in form of `sdk.Event`. `Event.Type` will be the type URL of the proto message.
|
||||
|
||||
When we subscribe to emitted events on the tendermint websocket, they are emitted in the form of an `abci.Event`. `ParseTypedEvent` parses the event back to it's original proto message.
|
||||
|
||||
__Step-2__: Add proto definitions for typed events for msgs in each module:
|
||||
|
||||
For example, let's take `MsgSubmitProposal` of `gov` module and implement this event's type.
|
||||
|
||||
```protobuf
|
||||
// proto/cosmos/gov/v1beta1/gov.proto
|
||||
// Add typed event definition
|
||||
|
||||
package cosmos.gov.v1beta1;
|
||||
|
||||
message EventSubmitProposal {
|
||||
string from_address = 1;
|
||||
uint64 proposal_id = 2;
|
||||
TextProposal proposal = 3;
|
||||
}
|
||||
```
|
||||
|
||||
__Step-3__: Refactor event emission to use the typed event created and emit using `sdk.EmitTypedEvent`:
|
||||
|
||||
```go
|
||||
// x/gov/handler.go
|
||||
func handleMsgSubmitProposal(ctx sdk.Context, keeper keeper.Keeper, msg types.MsgSubmitProposalI) (*sdk.Result, error) {
|
||||
...
|
||||
types.Context.EventManager().EmitTypedEvent(
|
||||
&EventSubmitProposal{
|
||||
FromAddress: fromAddress,
|
||||
ProposalId: id,
|
||||
Proposal: proposal,
|
||||
},
|
||||
)
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
#### How to subscribe to these typed events in `Client`
|
||||
|
||||
> NOTE: Full code example below
|
||||
|
||||
Users will be able to subscribe using `client.Context.Client.Subscribe` and consume events which are emitted using `EventHandler`s.
|
||||
|
||||
Akash Network has built a simple [`pubsub`](https://github.com/ovrclk/akash/blob/90d258caeb933b611d575355b8df281208a214f8/pubsub/bus.go#L20). This can be used to subscribe to `abci.Events` and [publish](https://github.com/ovrclk/akash/blob/90d258caeb933b611d575355b8df281208a214f8/events/publish.go#L21) them as typed events.
|
||||
|
||||
Please see the below code sample for more detail on this flow looks for clients.
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
* Improves consistency of implementation for the events currently in the sdk
|
||||
* Provides a much more ergonomic way to handle events and facilitates writing event driven applications
|
||||
* This implementation will support a middleware ecosystem of `EventHandler`s
|
||||
|
||||
### Negative
|
||||
|
||||
|
||||
## Detailed code example of publishing events
|
||||
|
||||
This ADR also proposes adding affordances to emit and consume these events. This way developers will only need to write
|
||||
`EventHandler`s which define the actions they desire to take.
|
||||
|
||||
```go
|
||||
// EventEmitter is a type that describes event emitter functions
|
||||
// This should be defined in `types/events.go`
|
||||
type EventEmitter func(context.Context, client.Context, ...EventHandler) error
|
||||
|
||||
// EventHandler is a type of function that handles events coming out of the event bus
|
||||
// This should be defined in `types/events.go`
|
||||
type EventHandler func(proto.Message) error
|
||||
|
||||
// Sample use of the functions below
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
if err := TxEmitter(ctx, client.Context{}.WithNodeURI("tcp://localhost:26657"), SubmitProposalEventHandler); err != nil {
|
||||
cancel()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SubmitProposalEventHandler is an example of an event handler that prints proposal details
|
||||
// when any EventSubmitProposal is emitted.
|
||||
func SubmitProposalEventHandler(ev proto.Message) (err error) {
|
||||
switch event := ev.(type) {
|
||||
// Handle governance proposal events creation events
|
||||
case govtypes.EventSubmitProposal:
|
||||
// Users define business logic here e.g.
|
||||
fmt.Println(ev.FromAddress, ev.ProposalId, ev.Proposal)
|
||||
return nil
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// TxEmitter is an example of an event emitter that emits just transaction events. This can and
|
||||
// should be implemented somewhere in the SDK. The SDK can include an EventEmitters for tm.event='Tx'
|
||||
// and/or tm.event='NewBlock' (the new block events may contain typed events)
|
||||
func TxEmitter(ctx context.Context, cliCtx client.Context, ehs ...EventHandler) (err error) {
|
||||
// Instantiate and start tendermint RPC client
|
||||
client, err := cliCtx.GetNode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = client.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Start the pubsub bus
|
||||
bus := pubsub.NewBus()
|
||||
defer bus.Close()
|
||||
|
||||
// Initialize a new error group
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
// Publish chain events to the pubsub bus
|
||||
eg.Go(func() error {
|
||||
return PublishChainTxEvents(ctx, client, bus, simapp.ModuleBasics)
|
||||
})
|
||||
|
||||
// Subscribe to the bus events
|
||||
subscriber, err := bus.Subscribe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Handle all the events coming out of the bus
|
||||
eg.Go(func() error {
|
||||
var err error
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case <-subscriber.Done():
|
||||
return nil
|
||||
case ev := <-subscriber.Events():
|
||||
for _, eh := range ehs {
|
||||
if err = eh(ev); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return group.Wait()
|
||||
}
|
||||
|
||||
// PublishChainTxEvents events using tmclient. Waits on context shutdown signals to exit.
|
||||
func PublishChainTxEvents(ctx context.Context, client tmclient.EventsClient, bus pubsub.Bus, mb module.BasicManager) (err error) {
|
||||
// Subscribe to transaction events
|
||||
txch, err := client.Subscribe(ctx, "txevents", "tm.event='Tx'", 100)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Unsubscribe from transaction events on function exit
|
||||
defer func() {
|
||||
err = client.UnsubscribeAll(ctx, "txevents")
|
||||
}()
|
||||
|
||||
// Use errgroup to manage concurrency
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
// Publish transaction events in a goroutine
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
break
|
||||
case ed := <-ch:
|
||||
switch evt := ed.Data.(type) {
|
||||
case tmtypes.EventDataTx:
|
||||
if !evt.Result.IsOK() {
|
||||
continue
|
||||
}
|
||||
// range over events, parse them using the basic manager and
|
||||
// send them to the pubsub bus
|
||||
for _, abciEv := range events {
|
||||
typedEvent, err := sdk.ParseTypedEvent(abciEv)
|
||||
if err != nil {
|
||||
return er
|
||||
}
|
||||
if err := bus.Publish(typedEvent); err != nil {
|
||||
bus.Close()
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
||||
// Exit on error or context cancelation
|
||||
return g.Wait()
|
||||
}
|
||||
```
|
||||
|
||||
## References
|
||||
- [Publish Custom Events via a bus](https://github.com/ovrclk/akash/blob/90d258caeb933b611d575355b8df281208a214f8/events/publish.go#L19-L58)
|
||||
- [Consuming the events in `Client`](https://github.com/ovrclk/deploy/blob/bf6c633ab6c68f3026df59efd9982d6ca1bf0561/cmd/event-handlers.go#L57)
|
|
@ -6,8 +6,10 @@
|
|||
|
||||
## Status
|
||||
|
||||
> A decision may be "proposed" if the project stakeholders haven't agreed with it yet, or "accepted" once it is agreed. If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement.
|
||||
> {Deprecated|Proposed|Accepted} {Implemented|Not Implemented}
|
||||
{DRAFT | PROPOSED} Not Implemented
|
||||
|
||||
> Please have a look at the [PROCESS](./PROCESS.md#adr-status) page.
|
||||
> Use DRAFT if the ADR is in a draft stage (draft PR) or PROPOSED if it's in review.
|
||||
|
||||
|
||||
## Abstract
|
||||
|
|
|
@ -6,11 +6,11 @@ parent:
|
|||
|
||||
# Basics
|
||||
|
||||
This repository contains reference documentation on the basic concepts of the Cosmos SDK.
|
||||
This repository contains reference documentation on the basic concepts of the Cosmos SDK.
|
||||
|
||||
1. [Anatomy of an SDK Application](./app-anatomy.md)
|
||||
2. [Lifecycle of a transaction](./tx-lifecycle.md)
|
||||
3. [Accounts](./accounts.md)
|
||||
4. [Gas and Fees](./gas-fees.md)
|
||||
|
||||
After reading the basics, head on to the [Core Reference](../core/README.md) for more advanced material.
|
||||
After reading the basics, head on to the [Core Reference](../core/README.md) for more advanced material.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
order: 3
|
||||
-->
|
||||
|
||||
# Accounts
|
||||
# Accounts
|
||||
|
||||
This document describes the in-built accounts system of the Cosmos SDK. {synopsis}
|
||||
|
||||
|
@ -12,9 +12,9 @@ This document describes the in-built accounts system of the Cosmos SDK. {synopsi
|
|||
|
||||
## Account Definition
|
||||
|
||||
In the Cosmos SDK, an *account* designates a pair of *public key* `PubKey` and *private key* `PrivKey`. The `PubKey` can be derived to generate various `Addresses`, which are used to identify users (among other parties) in the application. `Addresses` are also associated with [`message`s](../building-modules/messages-and-queries.md#messages) to identify the sender of the `message`. The `PrivKey` is used to generate [digital signatures](#signatures) to prove that an `Address` associated with the `PrivKey` approved of a given `message`.
|
||||
In the Cosmos SDK, an _account_ designates a pair of _public key_ `PubKey` and _private key_ `PrivKey`. The `PubKey` can be derived to generate various `Addresses`, which are used to identify users (among other parties) in the application. `Addresses` are also associated with [`message`s](../building-modules/messages-and-queries.md#messages) to identify the sender of the `message`. The `PrivKey` is used to generate [digital signatures](#signatures) to prove that an `Address` associated with the `PrivKey` approved of a given `message`.
|
||||
|
||||
To derive `PubKey`s and `PrivKey`s, the Cosmos SDK uses a standard called [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). This standard defines how to build an HD wallet, where a wallet is a set of accounts. At the core of every account, there is a seed, which takes the form of a 12 or 24-words mnemonic. From this mnemonic, it is possible to derive any number of `PrivKey`s using one-way cryptographic function. Then, a `PubKey` can be derived from the `PrivKey`. Naturally, the mnemonic is the most sensitive information, as private keys can always be re-generated if the mnemonic is preserved.
|
||||
To derive `PubKey`s and `PrivKey`s, the Cosmos SDK uses a standard called [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). This standard defines how to build an HD wallet, where a wallet is a set of accounts. At the core of every account, there is a seed, which takes the form of a 12 or 24-words mnemonic. From this mnemonic, it is possible to derive any number of `PrivKey`s using one-way cryptographic function. Then, a `PubKey` can be derived from the `PrivKey`. Naturally, the mnemonic is the most sensitive information, as private keys can always be re-generated if the mnemonic is preserved.
|
||||
|
||||
```
|
||||
Account 0 Account 1 Account 2
|
||||
|
@ -56,65 +56,65 @@ To derive `PubKey`s and `PrivKey`s, the Cosmos SDK uses a standard called [BIP32
|
|||
+-------------------+
|
||||
```
|
||||
|
||||
In the Cosmos SDK, accounts are stored and managed via an object called a [`Keybase`](#keybase).
|
||||
In the Cosmos SDK, accounts are stored and managed via an object called a [`Keyring`](#keyring).
|
||||
|
||||
## Keybase
|
||||
## Keyring
|
||||
|
||||
A `Keybase` is an object that stores and manages accounts. In the Cosmos SDK, a `Keybase` implementation follows the `Keybase` interface:
|
||||
A `Keyring` is an object that stores and manages accounts. In the Cosmos SDK, a `Keyring` implementation follows the `Keyring` interface:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/types.go#L13-L86
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keyring/keyring.go#L50-L88
|
||||
|
||||
The default implementation of `Keybase` of the Cosmos SDK is `dbKeybase`.
|
||||
The default implementation of `Keyring` comes from the third-party [`99designs/keyring`](https://github.com/99designs/keyring) library.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/keybase.go
|
||||
A few notes on the `Keyring` methods:
|
||||
|
||||
A few notes on the `Keybase` methods as implemented in `dbKeybase`:
|
||||
- `Sign(uid string, msg []byte) ([]byte, tmcrypto.PubKey, error)` strictly deals with the signature of the `message` bytes. Some preliminary work should be done beforehand to prepare and encode the `message` into a canonical `[]byte` form, and this is done in the `GetSignBytes` method. See an example of `message` preparation from the `x/bank` module. Note that signature verification is not implemented in the SDK by default. It is deferred to the [`anteHandler`](#antehandler).
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/x/bank/types/msgs.go#L51-L54
|
||||
- `NewAccount(uid, mnemonic, bip39Passwd, hdPath string, algo SignatureAlgo) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `NewAccount` method derives keys and addresses using the algorithm specified in the last argument `algo`. Currently, the SDK supports two public key algorithms:
|
||||
- `secp256k1`, as implemented in the [SDK's `crypto/keys/secp256k1` package](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/secp256k1/secp256k1.go),
|
||||
- `ed25519`, as implemented in the [SDK's `crypto/keys/ed25519` package](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/ed25519/ed25519.go).
|
||||
- `ExportPrivKeyArmor(uid, encryptPassphrase string) (armor string, err error)` exports a private key in ASCII-armored encrypted format, using the given passphrase. You can then either import it again into the keyring using the `ImportPrivKey(uid, armor, passphrase string)` function, or decrypt it into a raw private key using the `UnarmorDecryptPrivKey(armorStr string, passphrase string)` function.
|
||||
|
||||
- `Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error)` strictly deals with the signature of the `message` bytes. Some preliminary work should be done beforehand to prepare and encode the `message` into a canonical `[]byte` form. See an example of `message` preparation from the `auth` module. Note that signature verification is not implemented in the SDK by default. It is deferred to the [`anteHandler`](#antehandler).
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/auth/types/txbuilder.go#L176-L209
|
||||
- `CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error)` creates a new mnemonic and prints it in the logs, but it **does not persist it on disk**.
|
||||
- `CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `CreateAccount` method derives keys and addresses using `secp256k1` as implemented in the [Tendermint library](https://github.com/tendermint/tendermint/tree/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/secp256k1). As a result, it only works for creating account keys and addresses, not consensus keys. See [`Addresses`](#addresses) for more.
|
||||
|
||||
The current implementation of `dbKeybase` is basic and does not offer on-demand locking. If an instance of `dbKeybase` is created, the underlying `db` is locked meaning no other process can access it besides the one in which it was instantiated. This is the reason why the default SDK client uses another implementation of the `Keybase` interface called `lazyKeybase`:
|
||||
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/lazy_keybase.go
|
||||
|
||||
`lazyKeybase` is simple wrapper around `dbKeybase` which locks the database only when operations are to be performed and unlocks it immediately after. With the `lazyKeybase`, it is possible for the [command-line interface](../interfaces/cli.md) to create a new account while the [rest server](../interfaces/rest.md) is running. It is also possible to pipe multiple CLI commands.
|
||||
Also see the [`Addresses`](#addresses) section for more information.
|
||||
|
||||
## Addresses and PubKeys
|
||||
|
||||
`Addresses` and `PubKey`s are both public information that identify actors in the application. There are 3 main types of `Addresses`/`PubKeys` available by default in the Cosmos SDK:
|
||||
|
||||
- Addresses and Keys for **accounts**, which identify users (e.g. the sender of a `message`). They are derived using the **`secp256k1`** curve.
|
||||
- Addresses and Keys for **validator operators**, which identify the operators of validators. They are derived using the **`secp256k1`** curve.
|
||||
- Addresses and Keys for **accounts**, which identify users (e.g. the sender of a `message`). They are derived using the **`secp256k1`** curve.
|
||||
- Addresses and Keys for **validator operators**, which identify the operators of validators. They are derived using the **`secp256k1`** curve.
|
||||
- Addresses and Keys for **consensus nodes**, which identify the validator nodes participating in consensus. They are derived using the **`ed25519`** curve.
|
||||
|
||||
| | Address bech32 Prefix | Pubkey bech32 Prefix | Curve | Address byte length | Pubkey byte length |
|
||||
|--------------------|-----------------------|----------------------|-------------|---------------------|--------------------|
|
||||
| ------------------ | --------------------- | -------------------- | ----------- | ------------------- | ------------------ |
|
||||
| Accounts | cosmos | cosmospub | `secp256k1` | `20` | `33` |
|
||||
| Validator Operator | cosmosvaloper | cosmosvaloperpub | `secp256k1` | `20` | `33` |
|
||||
| Consensus Nodes | cosmosvalcons | cosmosvalconspub | `ed25519` | `20` | `32` |
|
||||
| Consensus Nodes | cosmosvalcons | cosmosvalconspub | `ed25519` | `20` | `32` |
|
||||
|
||||
### PubKeys
|
||||
|
||||
`PubKey`s used in the Cosmos SDK follow the `Pubkey` interface defined in tendermint's `crypto` package:
|
||||
`PubKey`s used in the Cosmos SDK are Protobuf messages and extend the `Pubkey` interface defined in tendermint's `crypto` package:
|
||||
|
||||
+++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/crypto.go#L22-L27
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/types/types.go#L8-L13
|
||||
|
||||
For `secp256k1` keys, the actual implementation can be found [here](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/secp256k1/secp256k1.go#L140). For `ed25519` keys, it can be found [here](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/ed25519/ed25519.go#L135).
|
||||
+++ https://github.com/tendermint/tendermint/blob/01c32c62e8840d812359c9e87e9c575aa67acb09/crypto/crypto.go#L22-L28
|
||||
|
||||
Note that in the Cosmos SDK, `Pubkeys` are not manipulated in their raw form. Instead, they are double encoded using [`Amino`](../core/encoding.md#amino) and [`bech32`](https://en.bitcoin.it/wiki/Bech32). In the SDK is done by first calling the `Bytes()` method on the raw `Pubkey` (which applies amino encoding), and then the `ConvertAndEncode` method of `bech32`.
|
||||
- For `secp256k1` keys, the actual implementation can be found [here](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/secp256k1/secp256k1.go).
|
||||
- For `ed25519` keys, it can be found [here](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/ed25519/ed25519.go).
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/address.go#L579-L729
|
||||
In both case, the actual key (as raw bytes) is the compressed form of the pubkey. The first byte is a `0x02` byte if the `y`-coordinate is the lexicographically largest of the two associated with the `x`-coordinate. Otherwise the first byte is a `0x03`. This prefix is followed with the `x`-coordinate.
|
||||
|
||||
Note that in the Cosmos SDK, `Pubkeys` are not manipulated in their raw bytes form. Instead, they are encoded to string using [`Amino`](../core/encoding.md#amino) and [`bech32`](https://en.bitcoin.it/wiki/Bech32). In the SDK, it is done by first calling the `Bytes()` method on the raw `Pubkey` (which applies amino encoding), and then the `ConvertAndEncode` method of `bech32`.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/types/address.go#L579-L729
|
||||
|
||||
### Addresses
|
||||
|
||||
The Cosmos SDK comes by default with 3 types of addresses:
|
||||
|
||||
- `AccAddress` for accounts.
|
||||
- `ValAddress` for validator operators.
|
||||
- `ConsAddress` for validator nodes.
|
||||
- `ValAddress` for validator operators.
|
||||
- `ConsAddress` for validator nodes.
|
||||
|
||||
Each of these address types are an alias for an hex-encoded `[]byte` array of length 20. Here is the standard way to obtain an address `aa` from a `Pubkey pub`:
|
||||
|
||||
|
@ -124,12 +124,12 @@ aa := sdk.AccAddress(pub.Address().Bytes())
|
|||
|
||||
These addresses implement the `Address` interface:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/address.go#L71-L80
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/types/address.go#L73-L82
|
||||
|
||||
Of note, the `Marhsal()` and `Bytes()` method both return the same raw `[]byte` form of the address, the former being needed for Protobuff compatibility. Also, the `String()` method is used to return the `bech32` encoded form of the address, which should be the only address format with which end-user interract. Next is an example:
|
||||
Of note, the `Marshal()` and `Bytes()` method both return the same raw `[]byte` form of the address, the former being needed for Protobuf compatibility. Also, the `String()` method is used to return the `bech32` encoded form of the address, which should be the only address format with which end-user interract. Here is an example:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/address.go#L229-L243
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/types/address.go#L232-L246
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn about [gas and fees](./gas-fees.md) {hide}
|
||||
Learn about [gas and fees](./gas-fees.md) {hide}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
order: 1
|
||||
-->
|
||||
|
||||
# Anatomy of an SDK Application
|
||||
# Anatomy of an SDK Application
|
||||
|
||||
This document describes the core parts of a Cosmos SDK application. Throughout the document, a placeholder application named `app` will be used. {synopsis}
|
||||
|
||||
|
@ -44,53 +44,54 @@ In general, the core of the state-machine is defined in a file called `app.go`.
|
|||
|
||||
The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts:
|
||||
|
||||
- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of `baseapp`. When a transaction is relayed by Tendermint to the application, `app` uses `baseapp`'s methods to route them to the appropriate module. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the [routing logic](../core/baseapp.md#routing).
|
||||
- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a [`multistore`](../core/store.md#multistore) (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../core/ocap.md) of the Cosmos SDK.
|
||||
- **A list of module's `keeper`s.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that the latter can only access the authorized functions.
|
||||
- **A reference to a [`codec`](../core/encoding.md).** The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](../core/encoding.md).
|
||||
- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](../core/baseapp.md#routing), [query routes](../core/baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker).
|
||||
- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of `baseapp`. When a transaction is relayed by Tendermint to the application, `app` uses `baseapp`'s methods to route them to the appropriate module. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the [routing logic](../core/baseapp.md#routing).
|
||||
- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a [`multistore`](../core/store.md#multistore) (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../core/ocap.md) of the Cosmos SDK.
|
||||
- **A list of module's `keeper`s.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that the latter can only access the authorized functions.
|
||||
- **A reference to an [`appCodec`](../core/encoding.md).** The application's `appCodec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The default codec is [Protocol Buffers](../core/encoding.md).
|
||||
- **A reference to a [`legacyAmino`](../core/encoding.md) codec.** Some parts of the SDK have not been migrated to use the `appCodec` above, and are still hardcoded to use Amino. Other parts explicity use Amino for backwards compatibility. For these reasons, the application still holds a reference to the legacy Amino codec. Please note that the Amino codec will be removed from the SDK in the upcoming releases.
|
||||
- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](../core/baseapp.md#routing), [gRPC query services](../core/baseapp.md#grpc-query-services) and [legacy Tendermint query routes](../core/baseapp.md#legacy-query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker).
|
||||
|
||||
See an example of application type definition from [`gaia`](https://github.com/cosmos/gaia)
|
||||
See an example of application type definition from `simapp`, the SDK's own app used for demo and testing purposes:
|
||||
|
||||
+++ https://github.com/cosmos/gaia/blob/5bc422e6868d04747e50b467e8eeb31ae2fe98a3/app/app.go#L87-L115
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/simapp/app.go#L140-L179
|
||||
|
||||
### Constructor Function
|
||||
|
||||
This function constructs a new application of the type defined in the section above. It must fulfill the `AppCreator` signature in order to be used in the [`start` command](../core/node.md#start-command) of the application's daemon command.
|
||||
This function constructs a new application of the type defined in the section above. It must fulfill the `AppCreator` signature in order to be used in the [`start` command](../core/node.md#start-command) of the application's daemon command.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/constructors.go#L20
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/server/types/app.go#L42-L44
|
||||
|
||||
Here are the main actions performed by this function:
|
||||
|
||||
- Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager)
|
||||
- Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys.
|
||||
- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`.
|
||||
- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules.
|
||||
- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here.
|
||||
- With the module manager, register the [application's modules' invariants](../building-modules/invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix.
|
||||
- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions.
|
||||
- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`.
|
||||
- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules.
|
||||
- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing), [`gRPC query services`](../core/baseapp.md#grpc-query-services) and [`legacy query routes`](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the `routes` defined here. Likewise, when a gRPC request is received by the application, it is routed to the appropriate module's [`gRPC query service`](#grpc-query-services) using the gRPC routes defined here. The SDK still supports legacy Tendermint queries, and these queries are routes using the `legacy query routes`.
|
||||
- With the module manager, register the [application's modules' invariants](../building-modules/invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix.
|
||||
- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions.
|
||||
- Set the remainer of application's parameters:
|
||||
+ [`InitChainer`](#initchainer): used to initialize the application when it is first started.
|
||||
+ [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block).
|
||||
+ [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification.
|
||||
- Mount the stores.
|
||||
- Return the application.
|
||||
- [`InitChainer`](#initchainer): used to initialize the application when it is first started.
|
||||
- [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block).
|
||||
- [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification.
|
||||
- Mount the stores.
|
||||
- Return the application.
|
||||
|
||||
Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time.
|
||||
|
||||
See an example of application constructor from [`gaia`](https://github.com/cosmos/gaia):
|
||||
See an example of application constructor from `simapp`:
|
||||
|
||||
+++ https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L110-L222
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/simapp/app.go#L190-L427
|
||||
|
||||
### InitChainer
|
||||
|
||||
The `InitChainer` is a function that initializes the state of the application from a genesis file (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its [constructor](#constructor-function) via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method.
|
||||
The `InitChainer` is a function that initializes the state of the application from a genesis file (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its [constructor](#constructor-function) via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method.
|
||||
|
||||
In general, the `InitChainer` is mostly composed of the [`InitGenesis`](../building-modules/genesis.md#initgenesis) function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the [module manager's](../building-modules/module-manager.md) `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`.
|
||||
|
||||
See an example of an `InitChainer` from [`gaia`](https://github.com/cosmos/gaia):
|
||||
|
||||
+++ https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L235-L239
|
||||
See an example of an `InitChainer` from `simapp`:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/simapp/app.go#L450-L455
|
||||
|
||||
### BeginBlocker and EndBlocker
|
||||
|
||||
|
@ -98,48 +99,58 @@ The SDK offers developers the possibility to implement automatic execution of co
|
|||
|
||||
In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the [`BeginBlock` and `EndBlock`](../building-modules/beginblock-endblock.md) functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done via the [module manager](../building-modules/module-manager.md) in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions.
|
||||
|
||||
As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./gas-fees.md) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution.
|
||||
As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./gas-fees.md) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution.
|
||||
|
||||
See an example of `BeginBlocker` and `EndBlocker` functions from [`gaia`](https://github.com/cosmos/gaia)
|
||||
See an example of `BeginBlocker` and `EndBlocker` functions from `simapp`
|
||||
|
||||
+++ https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L224-L232
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/simapp/app.go#L440-L448
|
||||
|
||||
### Register Codec
|
||||
|
||||
The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a [codec `cdc`](../core/encoding.md) (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterLegacyAminoCodec` function.
|
||||
The `EncodingConfig` structure is the last important part of the `app.go` file. The goal of this structure is to define the codecs that will be used throughout the app.
|
||||
|
||||
To register the application's modules, the `MakeCodec` function calls `RegisterLegacyAminoCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager).
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/simapp/params/encoding.go#L9-L16
|
||||
|
||||
See an example of a `MakeCodec` from [`gaia`](https://github.com/cosmos/gaia):
|
||||
|
||||
+++ https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L64-L70
|
||||
Here are descriptions of what each of the four fields means:
|
||||
|
||||
- `InterfaceRegistry`: The `InterfaceRegistry` is used by the Protobuf codec to handle interfaces, which are encoded and decoded (we also say "unpacked") using [`google.protobuf.Any`](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). `Any` could be thought as a struct which contains a `type_url` (the concrete type of the interface) and a `value` (its encoded bytes). `InterfaceRegistry` provides a mechanism for registering interfaces and implementations that can be safely unpacked from `Any`. Each of the application's modules implements the `RegisterInterfaces` method, which can be used to register the module's own interfaces and implementations.
|
||||
- To go more into details, the SDK uses an implementation of the Protobuf specification called [`gogoprotobuf`](https://github.com/gogo/protobuf). By default, the [gogo protobuf implementation of `Any`](https://godoc.org/github.com/gogo/protobuf/types) uses [global type registration](https://github.com/gogo/protobuf/blob/master/proto/properties.go#L540) to decode values packed in `Any` into concrete Go types. This introduces a vulnerability where any malicious module in the dependency tree could registry a type with the global protobuf registry and cause it to be loaded and unmarshaled by a transaction that referenced it in the `type_url` field. For more information, please refer to [ADR-019](../architecture/adr-019-protobuf-state-encoding.md).
|
||||
- `Marshaler`: The `Marshaler` is the default codec used throughout the SDK. It is composed of a `BinaryMarshaler` used to encode and decode state, and a `JSONMarshaler` used to output data to the users (for example in the [CLI](#cli)). By default, the SDK uses Protobuf as `Marshaler`.
|
||||
- `TxConfig`: `TxConfig` defines an interface a client can utilize to generate an application-defined concrete transaction type. Currently, the SDK handles two transaction types: `SIGN_MODE_DIRECT` (which uses Protobuf binary as over-the-wire encoding) and `SIGN_MODE_LEGACY_AMINO_JSON` (which depends on Amino). Read more about transactions [here](../core/transactions.md).
|
||||
- `Amino`: Some legacy parts of the SDK still use Amino for backwards-compatibility. Each module exposes a `RegisterLegacyAmino` method to register the module's specific types within Amino. This `Amino` codec should not be used by app developers anymore, and will be removed in future releases.
|
||||
|
||||
The SDK exposes a `MakeCodecs` function used to create a `EncodingConfig`. It uses Protobuf as default `Marshaler`, and passes it down to the app's `appCodec` field. It also instantiates a legacy `Amino` codec inside the app's `legacyAmino` field.
|
||||
|
||||
See an example of a `MakeCodecs` from `simapp`:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/simapp/app.go#L429-L435
|
||||
|
||||
## Modules
|
||||
|
||||
[Modules](../building-modules/intro.md) are the heart and soul of SDK applications. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist yet, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules).
|
||||
[Modules](../building-modules/intro.md) are the heart and soul of SDK applications. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist yet, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules).
|
||||
|
||||
### Application Module Interface
|
||||
|
||||
Modules must implement [interfaces](../building-modules/module-manager.md#application-module-interfaces) defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`.
|
||||
Modules must implement [interfaces](../building-modules/module-manager.md#application-module-interfaces) defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`.
|
||||
|
||||
`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules.
|
||||
`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules.
|
||||
|
||||
### Message Types
|
||||
|
||||
[`Message`s](../building-modules/messages-and-queries.md#messages) are objects defined by each module that implement the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transactions.md) contains one or multiple `messages`.
|
||||
[`Message`s](../building-modules/messages-and-queries.md#messages) are objects defined by each module that implement the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transactions.md) contains one or multiple `messages`.
|
||||
|
||||
When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction:
|
||||
|
||||
1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`.
|
||||
2. Then, it verifies a few things about the transaction like [fee payment and signatures](#gas-fees.md#antehandler) before extracting the message(s) contained in the transaction.
|
||||
3. With the `Type()` method of the `message`, `baseapp` is able to route it to the appropriate module's [`handler`](#handler) in order for it to be processed.
|
||||
4. If the message is successfully processed, the state is updated.
|
||||
2. Then, it verifies a few things about the transaction like [fee payment and signatures](#gas-fees.md#antehandler) before extracting the message(s) contained in the transaction.
|
||||
3. With the `Type()` method of the `message`, `baseapp` is able to route it to the appropriate module's [`handler`](#handler) in order for it to be processed.
|
||||
4. If the message is successfully processed, the state is updated.
|
||||
|
||||
For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md).
|
||||
|
||||
Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/bank/internal/types/msgs.go#L10-L15
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/proto/cosmos/bank/v1beta1/tx.proto#L10-L19
|
||||
|
||||
It is processed by the `handler` of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state.
|
||||
|
||||
|
@ -150,25 +161,36 @@ The [`handler`](../building-modules/handler.md) refers to the part of the module
|
|||
The `handler` of a module is generally defined in a file called `handler.go` and consists of:
|
||||
|
||||
- A **switch function** `NewHandler` to route the message to the appropriate `handler` function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). Next is an example of such a switch from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice)
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/master/nameservice/x/nameservice/handler.go#L12-L26
|
||||
- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state.
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/master/nameservice/x/nameservice/handler.go#L12-L26
|
||||
- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state.
|
||||
|
||||
Handler functions return a result of type `sdk.Result`, which informs the application on whether the message was successfully processed:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/result.go#L15-L40
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/types/result.go#L15-L40
|
||||
|
||||
### Querier
|
||||
### gRPC Query Services
|
||||
|
||||
[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s `handleQueryCustom` method using `queryRoute`:
|
||||
gRPC query services are introduced in the v0.40 Stargate release. They allow users to query the state using [gRPC](https://grpc.io). They are enabled by default, and can be configued under the `grpc.enable` and `grpc.address` fields inside `app.toml`.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/abci.go#L395-L453
|
||||
gRPC query services are defined in the module's Protobuf definition, specifically inside `query.proto`. The `query.proto` definition file exposes a single `Query` [Protobuf service](https://developers.google.com/protocol-buffers/docs/proto#services). Each gRPC query endpoint corresponds to a service method, starting with the `rpc` keyword, inside the `Query` service.
|
||||
|
||||
The `Querier` of a module is defined in a file called `querier.go`, and consists of:
|
||||
Protobuf generates a `QueryServer` interface for each module, containing all the service methods. A module's [`keeper`](#keeper) then needs to implement this `QueryServer` interface, by providing the concrete implementation of each service method. This concrete implementation is the handler of the corresponding gRPC query endpoint.
|
||||
|
||||
Finally, each module should also implement the `RegisterQueryService` method as part of the [`AppModule` interface](#application-module-interface). This method should call the `RegisterQueryServer` function provided by the generated Protobuf code.
|
||||
|
||||
### Legacy Querier
|
||||
|
||||
Legacy queriers were queriers used before the introduction of Protobuf and gRPC in the SDK. They are present for existing modules, but will be deprecated in a future release of the SDK. If you are developing new modules, gRPC query services should be preferred, and you only need to implement the `LegacyQuerierHandler` interface if you wish to use legacy queriers.
|
||||
|
||||
[`Legacy queriers`](../building-modules/query-services.md#legacy-queriers) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#application-interface) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s `handleQueryCustom` method using `queryRoute`:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/baseapp/abci.go#L388-L418
|
||||
|
||||
The `Querier` of a module is defined in a file called `keeper/querier.go`, and consists of:
|
||||
|
||||
- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice):
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/keeper/querier.go#L19-L32
|
||||
- **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON.
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/keeper/querier.go#L19-L32
|
||||
- **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON.
|
||||
|
||||
### Keeper
|
||||
|
||||
|
@ -184,36 +206,54 @@ The `keeper` type definition generally consists of:
|
|||
|
||||
Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). The rest of the file defines the `keeper`'s methods, primarily getters and setters.
|
||||
|
||||
### Command-Line and REST Interfaces
|
||||
### Command-Line, gRPC Services and REST Interfaces
|
||||
|
||||
Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module.
|
||||
Each module defines command-line commands, gRPC services and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module.
|
||||
|
||||
#### CLI
|
||||
|
||||
Generally, the [commands related to a module](../building-modules/module-interfaces.md#cli) are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra):
|
||||
|
||||
- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata.
|
||||
- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](../core/baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied.
|
||||
- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata.
|
||||
- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](../core/baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied.
|
||||
|
||||
#### REST
|
||||
#### gRPC
|
||||
|
||||
The [module's REST interface](../building-modules/module-interfaces.md#rest) lets users generate transactions and query the state through REST calls to the application's [light client daemon](../core/node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of:
|
||||
[gRPC](https://grpc.io) is a modern open source high performance RPC framework that has support in multiple languages. It is the recommended way for external clients (such as wallets, browsers and other backend services) to interact with a node.
|
||||
|
||||
Each module can expose gRPC endpoints, called [service methods](https://grpc.io/docs/what-is-grpc/core-concepts/#service-definition) and are defined in the [module's Protobuf `query.proto` file](#grpc-query-services). A service method is defined by its name, input arguments and output response. The module then needs to:
|
||||
|
||||
- define a `RegisterGRPCRoutes` method on `AppModuleBasic` to wire the client gRPC requests to the correct handler inside the module.
|
||||
- for each service method, define a corresponding handler. The handler implements the core logic necessary to serve the gRPC request, and is located in the `keeper/grpc_query.go` file.
|
||||
|
||||
#### gRPC-gateway REST Endpoints
|
||||
|
||||
Some external clients may not wish to use gRPC. The SDK provides in this case a gRPC gateway service, which exposes each gRPC service as a correspoding REST endpoint. Please refer to the [grpc-gateway](https://grpc-ecosystem.github.io/grpc-gateway/) documentation to learn more.
|
||||
|
||||
The REST endpoints are defined in the Protobuf files, along with the gRPC services, using Protobuf annotations. Modules that want to expose REST queries should add `google.api.http` annotations to their `rpc` methods. By default, all REST endpoints defined in the SDK have an URL starting with the `/cosmos/` prefix.
|
||||
|
||||
The SDK also provides a development endpoint to generate [Swagger](https://swagger.io/) definition files for these REST endpoints. This endpoint can be enabled inside the `app.toml` config file, under the `api.swagger` key.
|
||||
|
||||
#### Legacy API REST Endpoints
|
||||
|
||||
The [module's Legacy REST interface](../building-modules/module-interfaces.md#legacy-rest) lets users generate transactions and query the state through REST calls to the application's Legacy API Service. REST routes are defined in a file `client/rest/rest.go`, which is composed of:
|
||||
|
||||
- A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux).
|
||||
- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the base `request` type of the Cosmos SDK:
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/rest/rest.go#L47-L60
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/types/rest/rest.go#L62-L76
|
||||
- One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request.
|
||||
|
||||
These Legacy API endpoints are present in the SDK for backward compatibility purposes and will be removed in the next release.
|
||||
|
||||
## Application Interface
|
||||
|
||||
[Interfaces](../interfaces/interfaces-intro.md) let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block.
|
||||
|
||||
The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains:
|
||||
The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application is the same as the daemon (e.g. `appd`), and defined in a file called `appd/main.go`. The file contains:
|
||||
|
||||
- **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`.
|
||||
- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI.
|
||||
- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI.
|
||||
- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`.
|
||||
- **A `main()` function**, which is executed to build the `appd` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appd`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`.
|
||||
- **Query commands** are added by calling the `queryCmd` function. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appd query [query]` of the CLI.
|
||||
- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appd tx [tx]` of the CLI.
|
||||
|
||||
See an example of an application's main command-line file from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice)
|
||||
|
||||
|
@ -221,11 +261,11 @@ See an example of an application's main command-line file from the [nameservice
|
|||
|
||||
## Dependencies and Makefile
|
||||
|
||||
This section is optional, as developers are free to choose their dependency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. See an example from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice):
|
||||
This section is optional, as developers are free to choose their dependency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. See an example from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice):
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/go.mod#L1-L18
|
||||
|
||||
For building the application, a [Makefile](https://en.wikipedia.org/wiki/Makefile) is generally used. The Makefile primarily ensures that the `go.mod` is run before building the two entrypoints to the application, [`appd`](#node-client) and [`appcli`](#application-interface). See an example of Makefile from the [nameservice tutorial]()
|
||||
For building the application, a [Makefile](https://en.wikipedia.org/wiki/Makefile) is generally used. The Makefile primarily ensures that the `go.mod` is run before building the two entrypoints to the application, [`appd`](#node-client) and [`appd`](#application-interface). See an example of Makefile from the [nameservice tutorial]()
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/Makefile
|
||||
|
||||
|
|
|
@ -28,10 +28,11 @@ There are several required and optional flags for transaction creation. The `--f
|
|||
|
||||
Additionally, there are several [flags](../interfaces/cli.md) users can use to indicate how much they are willing to pay in [fees](./gas-fees.md):
|
||||
|
||||
* `--gas` refers to how much [gas](./gas-fees.md), which represents computational resources, `Tx` consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing `auto` as the value for `--gas`.
|
||||
* `--gas-adjustment` (optional) can be used to scale `gas` up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas.
|
||||
* `--gas-prices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, `--gas-prices=0.025uatom, 0.025upho` means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas.
|
||||
* `--fees` specifies how much in fees the user is willing to pay in total.
|
||||
- `--gas` refers to how much [gas](./gas-fees.md), which represents computational resources, `Tx` consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing `auto` as the value for `--gas`.
|
||||
- `--gas-adjustment` (optional) can be used to scale `gas` up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas.
|
||||
- `--gas-prices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, `--gas-prices=0.025uatom, 0.025upho` means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas.
|
||||
- `--fees` specifies how much in fees the user is willing to pay in total.
|
||||
- `--timeout-height` specifies a block timeout height to prevent the tx from being committed past a certain height.
|
||||
|
||||
The ultimate value of the fees paid is equal to the gas multiplied by the gas prices. In other words, `fees = ceil(gas * gasPrices)`. Thus, since fees can be calculated using gas prices and vice versa, the users specify only one of the two.
|
||||
|
||||
|
@ -42,7 +43,7 @@ Later, validators decide whether or not to include the transaction in their bloc
|
|||
Users of application `app` can enter the following command into their CLI to generate a transaction to send 1000uatom from a `senderAddress` to a `recipientAddress`. It specifies how much gas they are willing to pay: an automatic estimate scaled up by 1.5 times, with a gas price of 0.025uatom per unit gas.
|
||||
|
||||
```bash
|
||||
appcli tx send <recipientAddress> 1000uatom --from <senderAddress> --gas auto --gas-adjustment 1.5 --gas-prices 0.025uatom
|
||||
appd tx send <recipientAddress> 1000uatom --from <senderAddress> --gas auto --gas-adjustment 1.5 --gas-prices 0.025uatom
|
||||
```
|
||||
|
||||
#### Other Transaction Creation Methods
|
||||
|
@ -60,11 +61,11 @@ Each full-node (running Tendermint) that receives a `Tx` sends an [ABCI message]
|
|||
The full-nodes perform stateless, then stateful checks on `Tx` during `CheckTx`, with the goal to
|
||||
identify and reject an invalid transaction as early on as possible to avoid wasted computation.
|
||||
|
||||
***Stateless*** checks do not require nodes to access state - light clients or offline nodes can do
|
||||
**_Stateless_** checks do not require nodes to access state - light clients or offline nodes can do
|
||||
them - and are thus less computationally expensive. Stateless checks include making sure addresses
|
||||
are not empty, enforcing nonnegative numbers, and other logic specified in the definitions.
|
||||
|
||||
***Stateful*** checks validate transactions and messages based on a committed state. Examples
|
||||
**_Stateful_** checks validate transactions and messages based on a committed state. Examples
|
||||
include checking that the relevant values exist and are able to be transacted with, the address
|
||||
has sufficient funds, and the sender is authorized or has the correct ownership to transact.
|
||||
At any given moment, full-nodes typically have [multiple versions](../core/baseapp.md#volatile-states)
|
||||
|
@ -140,39 +141,39 @@ locally, this process yields a single, unambiguous result, since the messages' s
|
|||
explicitly ordered in the block proposal.
|
||||
|
||||
```
|
||||
-----------------------
|
||||
-----------------------
|
||||
|Receive Block Proposal|
|
||||
-----------------------
|
||||
|
|
||||
-----------------------
|
||||
|
|
||||
v
|
||||
-----------------------
|
||||
| BeginBlock |
|
||||
-----------------------
|
||||
|
|
||||
v
|
||||
-----------------------
|
||||
| DeliverTx(tx0) |
|
||||
| DeliverTx(tx1) |
|
||||
| DeliverTx(tx2) |
|
||||
| DeliverTx(tx3) |
|
||||
| . |
|
||||
-----------------------
|
||||
| BeginBlock |
|
||||
-----------------------
|
||||
|
|
||||
v
|
||||
-----------------------
|
||||
| DeliverTx(tx0) |
|
||||
| DeliverTx(tx1) |
|
||||
| DeliverTx(tx2) |
|
||||
| DeliverTx(tx3) |
|
||||
| . |
|
||||
| . |
|
||||
| . |
|
||||
-----------------------
|
||||
|
|
||||
v
|
||||
-----------------------
|
||||
| EndBlock |
|
||||
|
|
||||
v
|
||||
-----------------------
|
||||
|
|
||||
v
|
||||
| EndBlock |
|
||||
-----------------------
|
||||
| Consensus |
|
||||
|
|
||||
v
|
||||
-----------------------
|
||||
|
|
||||
v
|
||||
| Consensus |
|
||||
-----------------------
|
||||
| Commit |
|
||||
|
|
||||
v
|
||||
-----------------------
|
||||
| Commit |
|
||||
-----------------------
|
||||
```
|
||||
|
||||
|
@ -184,30 +185,29 @@ to during consensus. Under the hood, `DeliverTx` is almost identical to `CheckTx
|
|||
[`runTx`](../core/baseapp.md#runtx) function in deliver mode instead of check mode.
|
||||
Instead of using their `checkState`, full-nodes use `deliverState`:
|
||||
|
||||
* **Decoding:** Since `DeliverTx` is an ABCI call, `Tx` is received in the encoded `[]byte` form.
|
||||
Nodes first unmarshal the transaction, then call `runTx` in `runTxModeDeliver`, which is very
|
||||
similar to `CheckTx` but also executes and writes state changes.
|
||||
- **Decoding:** Since `DeliverTx` is an ABCI call, `Tx` is received in the encoded `[]byte` form.
|
||||
Nodes first unmarshal the transaction, using the [`TxConfig`](./app-anatomy#register-codec) defined in the app, then call `runTx` in `runTxModeDeliver`, which is very similar to `CheckTx` but also executes and writes state changes.
|
||||
|
||||
* **Checks:** Full-nodes call `validateBasicMsgs` and the `AnteHandler` again. This second check
|
||||
happens because they may not have seen the same transactions during the addition to Mempool stage\
|
||||
and a malicious proposer may have included invalid ones. One difference here is that the
|
||||
`AnteHandler` will not compare `gas-prices` to the node's `min-gas-prices` since that value is local
|
||||
to each node - differing values across nodes would yield nondeterministic results.
|
||||
- **Checks:** Full-nodes call `validateBasicMsgs` and the `AnteHandler` again. This second check
|
||||
happens because they may not have seen the same transactions during the addition to Mempool stage\
|
||||
and a malicious proposer may have included invalid ones. One difference here is that the
|
||||
`AnteHandler` will not compare `gas-prices` to the node's `min-gas-prices` since that value is local
|
||||
to each node - differing values across nodes would yield nondeterministic results.
|
||||
|
||||
* **Route and Handler:** While `CheckTx` would have exited, `DeliverTx` continues to run
|
||||
[`runMsgs`](../core/baseapp.md#runtx-and-runmsgs) to fully execute each `Msg` within the transaction.
|
||||
Since the transaction may have messages from different modules, `baseapp` needs to know which module
|
||||
to find the appropriate Handler. Thus, the `route` function is called via the [module manager](../building-modules/module-manager.md) to
|
||||
retrieve the route name and find the [`Handler`](../building-modules/handler.md) within the module.
|
||||
- **Route and Handler:** While `CheckTx` would have exited, `DeliverTx` continues to run
|
||||
[`runMsgs`](../core/baseapp.md#runtx-and-runmsgs) to fully execute each `Msg` within the transaction.
|
||||
Since the transaction may have messages from different modules, `baseapp` needs to know which module
|
||||
to find the appropriate Handler. Thus, the `route` function is called via the [module manager](../building-modules/module-manager.md) to
|
||||
retrieve the route name and find the [`Handler`](../building-modules/handler.md) within the module.
|
||||
|
||||
* **Handler:** The `handler`, a step up from `AnteHandler`, is responsible for executing each
|
||||
message in the `Tx` and causes state transitions to persist in `deliverTxState`. It is defined
|
||||
within a `Msg`'s module and writes to the appropriate stores within the module.
|
||||
- **Handler:** The `handler`, a step up from `AnteHandler`, is responsible for executing each
|
||||
message in the `Tx` and causes state transitions to persist in `deliverTxState`. It is defined
|
||||
within a `Msg`'s module and writes to the appropriate stores within the module.
|
||||
|
||||
* **Gas:** While a `Tx` is being delivered, a `GasMeter` is used to keep track of how much
|
||||
gas is being used; if execution completes, `GasUsed` is set and returned in the
|
||||
`abci.ResponseDeliverTx`. If execution halts because `BlockGasMeter` or `GasMeter` has run out or something else goes
|
||||
wrong, a deferred function at the end appropriately errors or panics.
|
||||
- **Gas:** While a `Tx` is being delivered, a `GasMeter` is used to keep track of how much
|
||||
gas is being used; if execution completes, `GasUsed` is set and returned in the
|
||||
`abci.ResponseDeliverTx`. If execution halts because `BlockGasMeter` or `GasMeter` has run out or something else goes
|
||||
wrong, a deferred function at the end appropriately errors or panics.
|
||||
|
||||
If there are any failed state changes resulting from a `Tx` being invalid or `GasMeter` running out,
|
||||
the transaction processing terminates and any state changes are reverted. Invalid transactions in a
|
||||
|
@ -219,14 +219,14 @@ The final step is for nodes to commit the block and state changes. Validator nod
|
|||
perform the previous step of executing state transitions in order to validate the transactions,
|
||||
then sign the block to confirm it. Full nodes that are not validators do not
|
||||
participate in consensus - i.e. they cannot vote - but listen for votes to understand whether or
|
||||
not they should commit the state changes.
|
||||
not they should commit the state changes.
|
||||
|
||||
When they receive enough validator votes (2/3+ *precommits* weighted by voting power), full nodes commit to a new block to be added to the blockchain and
|
||||
When they receive enough validator votes (2/3+ _precommits_ weighted by voting power), full nodes commit to a new block to be added to the blockchain and
|
||||
finalize the state transitions in the application layer. A new state root is generated to serve as
|
||||
a merkle proof for the state transitions. Applications use the [`Commit`](../core/baseapp.md#commit)
|
||||
ABCI method inherited from [Baseapp](../core/baseapp.md); it syncs all the state transitions by
|
||||
writing the `deliverState` into the application's internal state. As soon as the state changes are
|
||||
committed, `checkState` start afresh from the most recently committed state and `deliverState`
|
||||
committed, `checkState` start afresh from the most recently committed state and `deliverState`
|
||||
resets to `nil` in order to be consistent and reflect the changes.
|
||||
|
||||
Note that not all blocks have the same number of transactions and it is possible for consensus to
|
||||
|
|
|
@ -12,7 +12,7 @@ This repository contains documentation on concepts developers need to know in or
|
|||
2. [`AppModule` Interface and Module Manager](./module-manager.md)
|
||||
3. [Messages and Queries](./messages-and-queries.md)
|
||||
4. [`Handler`s - Processing Messages](./handler.md)
|
||||
5. [`Querier`s - Processing Queries](./querier.md)
|
||||
5. [Query Services - Processing Queries](./query-services.md)
|
||||
6. [BeginBlocker and EndBlocker](./beginblock-endblock.md)
|
||||
7. [`Keeper`s](./keeper.md)
|
||||
8. [Invariants](./invariants.md)
|
||||
|
|
|
@ -28,11 +28,11 @@ It is possible for developers to defined the order of execution between the `Beg
|
|||
|
||||
See an example implementation of `BeginBlocker` from the `distr` module:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/distribution/abci.go#L10-L32
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/f33749263f4ecc796115ad6e789cb0f7cddf9148/x/distribution/abci.go#L14-L38
|
||||
|
||||
and an example implementation of `EndBlocker` from the `staking` module:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/staking/handler.go#L44-L96
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/f33749263f4ecc796115ad6e789cb0f7cddf9148/x/staking/abci.go#L22-L27
|
||||
|
||||
## Next {hide}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ execution.
|
|||
|
||||
Example:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.38.1/x/distribution/keeper/querier.go#L62-L80
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/b2d48a9e815fe534a7faeec6ca2adb0874252b81/x/bank/keeper/keeper.go#L85-L122
|
||||
|
||||
Regardless if an error is wrapped or not, the SDK's `errors` package provides an API to determine if
|
||||
an error is of a particular kind via `Is`.
|
||||
|
|
|
@ -13,25 +13,25 @@ Modules generally handle a subset of the state and, as such, they need to define
|
|||
|
||||
## Type Definition
|
||||
|
||||
The subset of the genesis state defined from a given module is generally defined in a `./internal/types/genesis.go` file, along with the `DefaultGenesis` and `ValidateGenesis` methods. The struct defining the module's subset of the genesis state is usually called `GenesisState` and contains all the module-related values that need to be initialized during the genesis process.
|
||||
The subset of the genesis state defined from a given module is generally defined in a `genesis.proto` file ([more info](../core/encoding.md#gogoproto) on how to define protobuf messages). The struct defining the module's subset of the genesis state is usually called `GenesisState` and contains all the module-related values that need to be initialized during the genesis process.
|
||||
|
||||
See an example of `GenesisState` type definition from the nameservice tutorial
|
||||
See an example of `GenesisState` protobuf message definition from the `auth` module:
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L10-L12
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/a9547b54ffac9729fe1393651126ddfc0d236cff/proto/cosmos/auth/v1beta1/genesis.proto
|
||||
|
||||
Next we present the main genesis-related methods that need to be implemented by module developers in order for their module to be used in Cosmos SDK applications.
|
||||
|
||||
### `DefaultGenesis`
|
||||
|
||||
The `DefaultGenesis()` method is a simple method that calls the constructor function for `GenesisState` with the default value for each parameter. See an example from the `nameservice` module:
|
||||
The `DefaultGenesis()` method is a simple method that calls the constructor function for `GenesisState` with the default value for each parameter. See an example from the `auth` module:
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L33-L37
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/64b6bb5270e1a3b688c2d98a8f481ae04bb713ca/x/auth/module.go#L48-L52
|
||||
|
||||
### `ValidateGenesis`
|
||||
|
||||
The `ValidateGenesis(genesisState GenesisState)` method is called to verify that the provided `genesisState` is correct. It should perform validity checks on each of the parameter listed in `GenesisState`. See an example from the `nameservice` module:
|
||||
The `ValidateGenesis(genesisState GenesisState)` method is called to verify that the provided `genesisState` is correct. It should perform validity checks on each of the parameter listed in `GenesisState`. See an example from the `auth` module:
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L18-L31
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/64b6bb5270e1a3b688c2d98a8f481ae04bb713ca/x/auth/types/genesis.go#L57-L70
|
||||
|
||||
## Other Genesis Methods
|
||||
|
||||
|
@ -43,18 +43,18 @@ The `InitGenesis` method is executed during [`InitChain`](../core/baseapp.md#ini
|
|||
|
||||
The [module manager](./module-manager.md#manager) of the application is responsible for calling the `InitGenesis` method of each of the application's modules, in order. This order is set by the application developer via the manager's `SetOrderGenesisMethod`, which is called in the [application's constructor function](../basics/app-anatomy.md#constructor-function)
|
||||
|
||||
See an example of `InitGenesis` from the nameservice tutorial
|
||||
See an example of `InitGenesis` from the `auth` module
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L39-L44
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/64b6bb5270e1a3b688c2d98a8f481ae04bb713ca/x/auth/genesis.go#L13-L28
|
||||
|
||||
### `ExportGenesis`
|
||||
|
||||
The `ExportGenesis` method is executed whenever an export of the state is made. It takes the latest known version of the subset of the state managed by the module and creates a new `GenesisState` out of it. This is mainly used when the chain needs to be upgraded via a hard fork.
|
||||
|
||||
See an example of `ExportGenesis` from the nameservice tutorial.
|
||||
See an example of `ExportGenesis` from the `auth` module.
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L46-L57
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/64b6bb5270e1a3b688c2d98a8f481ae04bb713ca/x/auth/genesis.go#L31-L42
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn about [modules interfaces](#module-interfaces.md) {hide}
|
||||
Learn about [modules interfaces](module-interfaces.md) {hide}
|
|
@ -21,8 +21,8 @@ Let us break it down:
|
|||
|
||||
- The [`Msg`](./messages-and-queries.md#messages) is the actual object being processed.
|
||||
- The [`Context`](../core/context.md) contains all the necessary information needed to process the `msg`, as well as a cache-wrapped copy of the latest state. If the `msg` is succesfully processed, the modified version of the temporary state contained in the `ctx` will be written to the main state.
|
||||
- The [`Result`] returned to `baseapp`, which contains (among other things) information on the execution of the `handler`, [`gas`](../basics/gas-fees.md) consumption and [`events`](../core/events.md).
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/result.go#L15-L40
|
||||
- The [`*Result`] returned to `baseapp`, which contains (among other things) information on the execution of the `handler` and [`events`](../core/events.md).
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/base/abci/v1beta1/abci.proto#L81-L95
|
||||
|
||||
## Implementation of a module `handler`s
|
||||
|
||||
|
@ -37,10 +37,10 @@ func NewHandler(keeper Keeper) sdk.Handler {
|
|||
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
|
||||
ctx = ctx.WithEventManager(sdk.NewEventManager())
|
||||
switch msg := msg.(type) {
|
||||
case MsgType1:
|
||||
case *MsgType1:
|
||||
return handleMsgType1(ctx, keeper, msg)
|
||||
|
||||
case MsgType2:
|
||||
case *MsgType2:
|
||||
return handleMsgType2(ctx, keeper, msg)
|
||||
|
||||
default:
|
||||
|
@ -69,16 +69,28 @@ ctx.EventManager().EmitEvent(
|
|||
|
||||
These `events` are relayed back to the underlying consensus engine and can be used by service providers to implement services around the application. Click [here](../core/events.md) to learn more about `events`.
|
||||
|
||||
Finally, the `handler` function returns a `sdk.Result` which contains the aforementioned `events` and an optional `Data` field.
|
||||
Finally, the `handler` function returns a `*sdk.Result` which contains the aforementioned `events` and an optional `Data` field.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/result.go#L15-L40
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/base/abci/v1beta1/abci.proto#L81-L95
|
||||
|
||||
Next is an example of how to return a `Result` from the `gov` module:
|
||||
Next is an example of how to return a `*Result` from the `gov` module:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/gov/handler.go#L59-L62
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/gov/handler.go#L67-L70
|
||||
|
||||
For a deeper look at `handler`s, see this [example implementation of a `handler` function](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/handler.go) from the nameservice tutorial.
|
||||
For a deeper look at `handler`s, see this [example implementation of a `handler` function](https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/gov/handler.go) from the `gov` module.
|
||||
|
||||
The `handler` can then be registered from [`AppModule.Route()`](./module-manager.md#appmodule) as shown in the example below:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/228728cce2af8d494c8b4e996d011492139b04ab/x/gov/module.go#L143-L146
|
||||
|
||||
## Telemetry
|
||||
|
||||
New [telemetry metrics](../core/telemetry.md) can be created from the `handler` when handling messages for instance.
|
||||
|
||||
This is an example from the `auth` module:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/auth/vesting/handler.go#L68-L80
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn about [queriers](./querier.md) {hide}
|
||||
Learn about [query services](./query-services.md) {hide}
|
||||
|
|
|
@ -81,7 +81,7 @@ Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module
|
|||
- Custom [`message` types](./messages-and-queries.md#messages) to trigger state-transitions.
|
||||
- A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing).
|
||||
- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state.
|
||||
- A [`querier`](./querier.md), used to process user queries when they are routed to the module by [`baseapp`](../core/baseapp.md#query-routing).
|
||||
- A [query service](./query-services.md), used to process user queries when they are routed to the module by [`baseapp`](../core/baseapp.md#query-routing).
|
||||
- Interfaces, for end users to query the subset of the state defined by the module and create `message`s of the custom types defined in the module.
|
||||
|
||||
In addition to these components, modules implement the `AppModule` interface in order to be managed by the [`module manager`](./module-manager.md).
|
||||
|
@ -91,4 +91,3 @@ Please refer to the [structure document](./structure.md) to learn about the reco
|
|||
## Next {hide}
|
||||
|
||||
Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) {hide}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ An `Invariant` is a function that checks for a particular invariant within a mod
|
|||
|
||||
where the `string` return value is the invariant message, which can be used when printing logs, and the `bool` return value is the actual result of the invariant check.
|
||||
|
||||
In practice, each module implements `Invariant`s in a `./internal/keeper/invariants.go` file within the module's folder. The standard is to implement one `Invariant` function per logical grouping of invariants with the following model:
|
||||
In practice, each module implements `Invariant`s in a `./keeper/invariants.go` file within the module's folder. The standard is to implement one `Invariant` function per logical grouping of invariants with the following model:
|
||||
|
||||
```go
|
||||
// Example for an Invariant that checks balance-related invariants
|
||||
|
@ -74,7 +74,7 @@ At its core, the `InvariantRegistry` is defined in the SDK as an interface:
|
|||
|
||||
Typically, this interface is implemented in the `keeper` of a specific module. The most used implementation of an `InvariantRegistry` can be found in the `crisis` module:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/crisis/internal/keeper/keeper.go#L45-L49
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/keeper/keeper.go#L50-L54
|
||||
|
||||
The `InvariantRegistry` is therefore typically instantiated by instantiating the `keeper` of the `crisis` module in the [application's constructor function](../basics/app-anatomy.md#constructor-function).
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ The core idea behind the object-capabilities approach is to only reveal what is
|
|||
|
||||
## Type Definition
|
||||
|
||||
`keeper`s are generally implemented in a `internal/keeper/keeper.go` file located in the module's folder. By convention, the type `keeper` of a module is simply named `Keeper` and usually follows the following structure:
|
||||
`keeper`s are generally implemented in a `/keeper/keeper.go` file located in the module's folder. By convention, the type `keeper` of a module is simply named `Keeper` and usually follows the following structure:
|
||||
|
||||
```go
|
||||
type Keeper struct {
|
||||
|
@ -32,15 +32,15 @@ type Keeper struct {
|
|||
}
|
||||
```
|
||||
|
||||
For example, here is the [type definition of the `keeper` from the nameservice tutorial:
|
||||
For example, here is the type definition of the `keeper` from the `staking` module:
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/keeper/keeper.go#L10-L17
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/3bafd8255a502e5a9cee07391cf8261538245dfd/x/staking/keeper/keeper.go#L23-L33
|
||||
|
||||
Let us go through the different parameters:
|
||||
|
||||
- An expected `keeper` is a `keeper` external to a module that is required by the internal `keeper` of said module. External `keeper`s are listed in the internal `keeper`'s type definition as interfaces. These interfaces are themselves defined in a `internal/types/expected_keepers.go` file within the module's folder. In this context, interfaces are used to reduce the number of dependencies, as well as to facilitate the maintenance of the module itself.
|
||||
- An expected `keeper` is a `keeper` external to a module that is required by the internal `keeper` of said module. External `keeper`s are listed in the internal `keeper`'s type definition as interfaces. These interfaces are themselves defined in a `types/expected_keepers.go` file within the module's folder. In this context, interfaces are used to reduce the number of dependencies, as well as to facilitate the maintenance of the module itself.
|
||||
- `storeKey`s grant access to the store(s) of the [multistore](../core/store.md) managed by the module. They should always remain unexposed to external modules.
|
||||
- A [codec `cdc`](../core/encoding.md), used to marshall and unmarshall struct to/from `[]byte`.
|
||||
- A [codec `cdc`](../core/encoding.md), used to marshall and unmarshall struct to/from `[]byte`, that can be any of `codec.BinaryMarshaler`,`codec.JSONMarshaler` or `codec.Marshaler` based on your requirements. It can be either a proto or amino codec as long as they implement these interfaces.
|
||||
|
||||
Of course, it is possible to define different types of internal `keeper`s for the same module (e.g. a read-only `keeper`). Each type of `keeper` comes with its own constructor function, which is called from the [application's constructor function](../basics/app-anatomy.md). This is where `keeper`s are instantiated, and where developers make sure to pass correct instances of modules' `keeper`s to other modules that require it.
|
||||
|
||||
|
@ -56,7 +56,7 @@ func (k Keeper) Get(ctx sdk.Context, key string) returnType
|
|||
|
||||
and go through the following steps:
|
||||
|
||||
1. Retrieve the appropriate store from the `ctx` using the `storeKey`. This is done through the `KVStore(storeKey sdk.StoreKey` method of the `ctx`.
|
||||
1. Retrieve the appropriate store from the `ctx` using the `storeKey`. This is done through the `KVStore(storeKey sdk.StoreKey)` method of the `ctx`. Then it's prefered to use the `prefix.Store` to access only the desired limited subset of the store for convenience and safety.
|
||||
2. If it exists, get the `[]byte` value stored at location `[]byte(key)` using the `Get(key []byte)` method of the store.
|
||||
3. Unmarshall the retrieved value from `[]byte` to `returnType` using the codec `cdc`. Return the value.
|
||||
|
||||
|
@ -68,11 +68,17 @@ func (k Keeper) Set(ctx sdk.Context, key string, value valueType)
|
|||
|
||||
and go through the following steps:
|
||||
|
||||
1. Retrieve the appropriate store from the `ctx` using the `storeKey`. This is done through the `KVStore(storeKey sdk.StoreKey` method of the `ctx`.
|
||||
2. Marhsall `value` to `[]byte` using the codec `cdc`.
|
||||
1. Retrieve the appropriate store from the `ctx` using the `storeKey`. This is done through the `KVStore(storeKey sdk.StoreKey)` method of the `ctx`. Then it's prefered to use the `prefix.Store` to access only the desired limited subset of the store for convenience and safety.
|
||||
2. Marshal `value` to `[]byte` using the codec `cdc`.
|
||||
3. Set the encoded value in the store at location `key` using the `Set(key []byte, value []byte)` method of the store.
|
||||
|
||||
For more, see an example of `keeper`'s [methods implementation from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/keeper/keeper.go).
|
||||
For more, see an example of `keeper`'s [methods implementation from the `staking` module](https://github.com/cosmos/cosmos-sdk/blob/3bafd8255a502e5a9cee07391cf8261538245dfd/x/staking/keeper/keeper.go).
|
||||
|
||||
The [module `KVStore`](../core/store.md#kvstore-and-commitkvstore-interfaces) also provides an `Iterator()` method which returns an `Iterator` object to iterate over a domain of keys.
|
||||
|
||||
This is an example from the `auth` module to iterate accounts:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/bf8809ef9840b4f5369887a38d8345e2380a567f/x/auth/keeper/account.go#L70-L83
|
||||
|
||||
## Next {hide}
|
||||
|
||||
|
|
|
@ -16,39 +16,47 @@ order: 3
|
|||
|
||||
When a transaction is relayed from the underlying consensus engine to the SDK application, it is first decoded by [`baseapp`](../core/baseapp.md). Then, each `message` contained in the transaction is extracted and routed to the appropriate module via `baseapp`'s `router` so that it can be processed by the module's [`handler`](./handler.md). For a more detailed explanation of the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md).
|
||||
|
||||
Defining `message`s is the responsibility of module developers. Typically, they are defined in a `./internal/types/msgs.go` file inside the module's folder. The `message`'s type definition usually includes a list of parameters needed to process the message that will be provided by end-users when they want to create a new transaction containing said `message`.
|
||||
Defining `message`s is the responsibility of module developers. Typically, they are defined as protobuf messages in a `proto/` directory (see more info about [conventions and naming](../core/encoding.md#faq)). The `message`'s definition usually includes a list of parameters needed to process the message that will be provided by end-users when they want to create a new transaction containing said `message`.
|
||||
|
||||
```go
|
||||
// Example of a message type definition
|
||||
Here's an example of a protobuf message definition:
|
||||
|
||||
type MsgSubmitProposal struct {
|
||||
Content Content `json:"content" yaml:"content"`
|
||||
InitialDeposit sdk.Coins `json:"initial_deposit" yaml:"initial_deposit"`
|
||||
Proposer sdk.AccAddress `json:"proposer" yaml:"proposer"`
|
||||
}
|
||||
```
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/gov/v1beta1/tx.proto#L15-L27
|
||||
|
||||
The `Msg` is typically accompanied by a standard constructor function, that is called from one of the [module's interface](./module-interfaces.md). `message`s also need to implement the [`Msg`] interface:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L7-L29
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/4a1b2fba43b1052ca162b3a1e0b6db6db9c26656/types/tx_msg.go#L10-L33
|
||||
|
||||
It contains the following methods:
|
||||
It extends `proto.Message` and contains the following methods:
|
||||
|
||||
- `Route() string`: Name of the route for this message. Typically all `message`s in a module have the same route, which is most often the module's name.
|
||||
- `Type() string`: Type of the message, used primarly in [events](../core/events.md). This should return a message-specific `string`, typically the denomination of the message itself.
|
||||
- `ValidateBasic() Error`: This method is called by `baseapp` very early in the processing of the `message` (in both [`CheckTx`](../core/baseapp.md#checktx) and [`DeliverTx`](../core/baseapp.md#delivertx)), in order to discard obviously invalid messages. `ValidateBasic` should only include *stateless* checks, i.e. checks that do not require access to the state. This usually consists in checking that the message's parameters are correctly formatted and valid (i.e. that the `amount` is strictly positive for a transfer).
|
||||
- `ValidateBasic() error`: This method is called by `baseapp` very early in the processing of the `message` (in both [`CheckTx`](../core/baseapp.md#checktx) and [`DeliverTx`](../core/baseapp.md#delivertx)), in order to discard obviously invalid messages. `ValidateBasic` should only include *stateless* checks, i.e. checks that do not require access to the state. This usually consists in checking that the message's parameters are correctly formatted and valid (i.e. that the `amount` is strictly positive for a transfer).
|
||||
- `GetSignBytes() []byte`: Return the canonical byte representation of the message. Used to generate a signature.
|
||||
- `GetSigners() []AccAddress`: Return the list of signers. The SDK will make sure that each `message` contained in a transaction is signed by all the signers listed in the list returned by this method.
|
||||
|
||||
See an example implementation of a `message` from the `nameservice` module:
|
||||
See an example implementation of a `message` from the `gov` module:
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/types/msgs.go#L10-L51
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/gov/types/msgs.go#L94-L136
|
||||
|
||||
## Queries
|
||||
|
||||
A `query` is a request for information made by end-users of applications through an interface and processed by a full-node. A `query` is received by a full-node through its consensus engine and relayed to the application via the ABCI. It is then routed to the appropriate module via `baseapp`'s `queryrouter` so that it can be processed by the module's [`querier`](./querier.md). For a deeper look at the lifecycle of a `query`, click [here](../interfaces/query-lifecycle.md).
|
||||
A `query` is a request for information made by end-users of applications through an interface and processed by a full-node. A `query` is received by a full-node through its consensus engine and relayed to the application via the ABCI. It is then routed to the appropriate module via `baseapp`'s `queryrouter` so that it can be processed by the module's query service (./query-services.md). For a deeper look at the lifecycle of a `query`, click [here](../interfaces/query-lifecycle.md).
|
||||
|
||||
Contrary to `message`s, there is usually no specific `query` object defined by module developers. Instead, the SDK takes the simpler approach of using a simple `path` to define each `query`. The `path` contains the `query` type and all the arguments needed in order to process it. For most module queries, the `path` should look like the following:
|
||||
### gRPC Queries
|
||||
|
||||
Starting from v0.40, the prefered way to define queries is by using [Protobuf services](https://developers.google.com/protocol-buffers/docs/proto#services). A `Query` service should be created per module in `query.proto`. This service lists endpoints starting with `rpc`.
|
||||
|
||||
Here's an example of such a `Query` service definition:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/auth/v1beta1/query.proto#L12-L23
|
||||
|
||||
As `proto.Message`s, generated `Response` types implement by default `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer).
|
||||
|
||||
A `RegisterQueryServer` method is also generated and should be used to register the module's query server in `RegisterQueryService` method from the [`AppModule` interface](./module-manager.md#appmodule).
|
||||
|
||||
### Legacy Queries
|
||||
|
||||
Before the introduction of Protobuf and gRPC in the SDK, there was usually no specific `query` object defined by module developers, contrary to `message`s. Instead, the SDK took the simpler approach of using a simple `path` to define each `query`. The `path` contains the `query` type and all the arguments needed in order to process it. For most module queries, the `path` should look like the following:
|
||||
|
||||
```
|
||||
queryCategory/queryRoute/queryType/arg1/arg2/...
|
||||
|
@ -58,18 +66,24 @@ where:
|
|||
|
||||
- `queryCategory` is the category of the `query`, typically `custom` for module queries. It is used to differentiate between different kinds of queries within `baseapp`'s [`Query` method](../core/baseapp.md#query).
|
||||
- `queryRoute` is used by `baseapp`'s [`queryRouter`](../core/baseapp.md#query-routing) to map the `query` to its module. Usually, `queryRoute` should be the name of the module.
|
||||
- `queryType` is used by the module's [`querier`](./querier.md) to map the `query` to the appropriate `querier function` within the module.
|
||||
- `queryType` is used by the module's [`querier`](./query-services.md#legacy-queriers) to map the `query` to the appropriate `querier function` within the module.
|
||||
- `args` are the actual arguments needed to process the `query`. They are filled out by the end-user. Note that for bigger queries, you might prefer passing arguments in the `Data` field of the request `req` instead of the `path`.
|
||||
|
||||
The `path` for each `query` must be defined by the module developer in the module's [command-line interface file](./module-interfaces.md#query-commands).Overall, there are 3 mains components module developers need to implement in order to make the subset of the state defined by their module queryable:
|
||||
|
||||
- A [`querier`](./querier.md), to process the `query` once it has been [routed to the module](../core/baseapp.md#query-routing).
|
||||
- A [`querier`](./query-services.md#legacy-queriers), to process the `query` once it has been [routed to the module](../core/baseapp.md#query-routing).
|
||||
- [Query commands](./module-interfaces.md#query-commands) in the module's CLI file, where the `path` for each `query` is specified.
|
||||
- `query` return types. Typically defined in a file `internal/types/querier.go`, they specify the result type of each of the module's `queries`. These custom types must implement the `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer).
|
||||
- `query` return types. Typically defined in a file `types/querier.go`, they specify the result type of each of the module's `queries`. These custom types must implement the `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer).
|
||||
|
||||
See an example of `query` return types from the `nameservice` module:
|
||||
### Store Queries
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/types/querier.go#L5-L21
|
||||
Store queries query directly for store keys. They use `clientCtx.QueryABCI(req abci.RequestQuery)` to return the full `abci.ResponseQuery` with inclusion Merkle proofs.
|
||||
|
||||
See following examples:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/080fcf1df25ccdf97f3029b6b6f83caaf5a235e4/x/ibc/core/client/query.go#L36-L46
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/080fcf1df25ccdf97f3029b6b6f83caaf5a235e4/baseapp/abci.go#L722-L749
|
||||
|
||||
## Next {hide}
|
||||
|
||||
|
|
|
@ -16,49 +16,47 @@ One of the main interfaces for an application is the [command-line interface](..
|
|||
|
||||
### Transaction Commands
|
||||
|
||||
[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions prefixed with `GetCmd` and include the name of the command.
|
||||
[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions and include the name of the command.
|
||||
|
||||
Here is an example from the `nameservice` module:
|
||||
Here is an example from the `auth` module:
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/client/cli/tx.go#L33-L58
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/64b6bb5270e1a3b688c2d98a8f481ae04bb713ca/x/auth/client/cli/tx_sign.go#L160-L194
|
||||
|
||||
This getter function creates the command for the Buy Name transaction. It does the following:
|
||||
This getter function creates the command for the `Sign` transaction. It does the following:
|
||||
|
||||
- **Construct the command:** Read the [Cobra Documentation](https://github.com/spf13/cobra) for details on how to create commands.
|
||||
- **Construct the command:** Read the [Cobra Documentation](https://godoc.org/github.com/spf13/cobra) for details on how to create commands.
|
||||
- **Use:** Specifies the format of a command-line entry users should type in order to invoke this command. In this case, the user uses `buy-name` as the name of the transaction command and provides the `name` the user wishes to buy and the `amount` the user is willing to pay.
|
||||
- **Args:** The number of arguments the user provides, in this case exactly two: `name` and `amount`.
|
||||
- **Short and Long:** A description for the function is provided here. A `Short` description is expected, and `Long` can be used to provide a more detailed description when a user uses the `--help` flag to ask for more information.
|
||||
- **RunE:** Defines a function that can return an error, called when the command is executed. Using `Run` would do the same thing, but would not allow for errors to be returned.
|
||||
- **`RunE` Function Body:** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new transaction that is ready to be relayed to nodes.
|
||||
- The function should first initialize a [`TxBuilder`](../core/transactions.md#txbuilder) with the application `codec`'s `TxEncoder`, as well as a new [`Context`](../interfaces/query-lifecycle.md#context) with the `codec` and `AccountDecoder`. These contexts contain all the information provided by the user and will be used to transfer this user-specific information between processes. To learn more about how contexts are used in a transaction, click [here](../core/transactions.md#transaction-generation).
|
||||
- If applicable, the command's arguments are parsed. Here, the `amount` given by the user is parsed into a denomination of `coins`.
|
||||
- If applicable, the `Context` is used to retrieve any parameters such as the transaction originator's address to be used in the transaction. Here, the `from` address is retrieved by calling `cliCtx.getFromAddress()`.
|
||||
- The function should first get the `clientCtx` with `client.GetClientContextFromCmd(cmd)` and `client.ReadTxCommandFlags(clientCtx, cmd.Flags())`. This context contains all the information provided by the user and will be used to transfer this user-specific information between processes. To learn more about how contexts are used in a transaction, click [here](../core/transactions.md#transaction-generation).
|
||||
- If applicable, the command's arguments are parsed.
|
||||
- If applicable, the `Context` is used to retrieve any parameters such as the transaction originator's address to be used in the transaction. Here, the `from` address is retrieved by calling `clientCtx.GetFromAddress()`.
|
||||
- A [message](./messages-and-queries.md) is created using all parameters parsed from the command arguments and `Context`. The constructor function of the specific message type is called directly. It is good practice to call `ValidateBasic()` on the newly created message to run a sanity check and check for invalid arguments.
|
||||
- Depending on what the user wants, the transaction is either generated offline or signed and broadcasted to the preconfigured node using `GenerateOrBroadcastMsgs()`.
|
||||
- **Flags.** Add any [flags](#flags) to the command. No flags were specified here, but all transaction commands have flags to provide additional information from the user (e.g. amount of fees they are willing to pay). These _persistent_ [transaction flags](../interfaces/cli.md#flags) can be added to a higher-level command so that they apply to all transaction commands.
|
||||
- **Flags.** Add any [flags](#flags) to the command. All transaction commands have flags to provide additional information from the user (e.g. amount of fees they are willing to pay). These _persistent_ [transaction flags](../interfaces/cli.md#flags) can be added to a higher-level command so that they apply to all transaction commands.
|
||||
|
||||
Finally, the module needs to have a `GetTxCmd()`, which aggregates all of the transaction commands of the module. Often, each command getter function has its own file in the module's `cli` folder, and a separate `tx.go` file contains `GetTxCmd()`. Application developers wishing to include the module's transactions will call this function to add them as subcommands in their CLI. Here is the `auth` `GetTxCmd()` function, which adds the `Sign` and `MultiSign` commands.
|
||||
Finally, the module needs to have a `GetTxCmd()`, which aggregates all of the transaction commands of the module. Often, each command getter function has its own file in the module's `cli` folder, and a separate `tx.go` file contains `GetTxCmd()`. Application developers wishing to include the module's transactions will call this function to add them as subcommands in their CLI. Here is the `auth` `GetTxCmd()` function, which adds the `Sign`, `MultiSign`, `ValidateSignatures` and `SignBatch` commands.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/67f6b021180c7ef0bcf25b6597a629aca27766b8/x/auth/client/cli/tx.go#L11-L25
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/351192aa0b52a42b66ff06e81cfa7a9e26667a7f/x/auth/client/cli/tx.go#L10-L26
|
||||
|
||||
An application using this module likely adds `auth` module commands to its root `TxCmd` command by calling `txCmd.AddCommand(authModuleClient.GetTxCmd())`.
|
||||
|
||||
### Query Commands
|
||||
|
||||
[Queries](./messages-and-queries.md#queries) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions and have the prefix `GetCmdQuery`. Here is an example of a query command from the `nameservice` module:
|
||||
[Queries](./messages-and-queries.md#queries) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions. Here is an example of a query command from the `auth` module:
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/client/cli/query.go#L52-L73
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/auth/client/cli/query.go#L76-L108
|
||||
|
||||
This query returns the address that owns a particular name. The getter function does the following:
|
||||
This query returns the account at a given address. The getter function does the following:
|
||||
|
||||
- **`codec` and `queryRoute`.** In addition to taking in the application `codec`, query command getters also take a `queryRoute` used to construct a path [Baseapp](../core/baseapp.md#query-routing) uses to route the query in the application.
|
||||
- **Construct the command.** Read the [Cobra Documentation](https://github.com/spf13/cobra) and the [transaction command](#transaction-commands) example above for more information. The user must type `whois` and provide the `name` they are querying for as the only argument.
|
||||
- **Construct the command.** Read the [Cobra Documentation](https://godoc.org/github.com/spf13/cobra) and the [transaction command](#transaction-commands) example above for more information. The user must type `account` and provide the `address` they are querying for as the only argument.
|
||||
- **`RunE`.** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new query that is ready to be relayed to nodes.
|
||||
- The function should first initialize a new [`Context`](../interfaces/query-lifecycle.md#context) with the application `codec`.
|
||||
- The function should first initialize a new client [`Context`](../interfaces/query-lifecycle.md#context) as described in the [previous section](#transaction-commands)
|
||||
- If applicable, the `Context` is used to retrieve any parameters (e.g. the query originator's address to be used in the query) and marshal them with the query parameter type, in preparation to be relayed to a node. There are no `Context` parameters in this case because the query does not involve any information about the user.
|
||||
- The `queryRoute` is used to construct a `path` [`baseapp`](../core/baseapp.md) will use to route the query to the appropriate [querier](./querier.md). The expected format for a query `path` is "queryCategory/queryRoute/queryType/arg1/arg2/...", where `queryCategory` can be `p2p`, `store`, `app`, or `custom`, `queryRoute` is the name of the module, and `queryType` is the name of the query type defined within the module. [`baseapp`](../core/baseapp.md) can handle each type of `queryCategory` by routing it to a module querier or retrieving results directly from stores and functions for querying peer nodes. Module queries are `custom` type queries (some SDK modules have exceptions, such as `auth` and `gov` module queries).
|
||||
- The `Context` `QueryWithData()` function is used to relay the query to a node and retrieve the response. It requires the `path`. It returns the result and height of the query upon success or an error if the query fails.
|
||||
- The `codec` is used to nmarshal the response and the `Context` is used to print the output back to the user.
|
||||
- A new `queryClient` should be initialized using `NewQueryClient(clientCtx)`, this method being generated from `query.proto`. Then it can be used to call the appropriate [query](./messages-and-queries.md#grpc-queries).
|
||||
- The `clientCtx.PrintOutput` method is used to print the output back to the user.
|
||||
- **Flags.** Add any [flags](#flags) to the command.
|
||||
|
||||
Finally, the module also needs a `GetQueryCmd`, which aggregates all of the query commands of the module. Application developers wishing to include the module's queries will call this function to add them as subcommands in their CLI. Its structure is identical to the `GetTxCmd` command shown above.
|
||||
|
@ -71,9 +69,9 @@ The flags for a module are typically found in a `flags.go` file in the `./x/modu
|
|||
|
||||
For full details on flags, visit the [Cobra Documentation](https://github.com/spf13/cobra).
|
||||
|
||||
For example, the SDK `./client/flags` package includes a `PostCommands()` function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from.
|
||||
For example, the SDK `./client/flags` package includes a `AddTxFlagsToCmd(cmd *cobra.Command)` function that adds necessary flags to a transaction command, such as the `from` flag to indicate which address the transaction originates from.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/client/flags/flags.go#L85-L116
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/cfb5fc03e5092395403d10156c0ee96e6ff1ddbe/client/flags/flags.go#L85-L112
|
||||
|
||||
Here is an example of how to add a flag using the `from` flag from this function.
|
||||
|
||||
|
@ -89,11 +87,54 @@ A flag can be marked as _required_ so that an error is automatically thrown if t
|
|||
cmd.MarkFlagRequired(FlagFrom)
|
||||
```
|
||||
|
||||
Since `PostCommands()` includes all of the basic flags required for a transaction command, module developers may choose not to add any of their own (specifying arguments instead may often be more appropriate). For a full list of what flags are included in the `PostCommands()` function, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags).
|
||||
Since `AddTxFlagsToCmd(cmd *cobra.Command)` includes all of the basic flags required for a transaction command, module developers may choose not to add any of their own (specifying arguments instead may often be more appropriate).
|
||||
|
||||
## REST
|
||||
Similarly, there is a `AddQueryFlagsToCmd(cmd *cobra.Command)` to add common flags to a module query command.
|
||||
|
||||
Applications typically support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](https://lunie.io). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder.
|
||||
## gRPC
|
||||
|
||||
[gRPC](https://grpc.io/) is the prefered way for external clients like wallets and exchanges to interact with a node.
|
||||
|
||||
In addition to providing an ABCI query pathway, modules [custom queries](./messages-and-queries.md#grpc-queries) can provide a GRPC proxy server that routes requests in the GRPC protocol to ABCI query requests under the hood.
|
||||
|
||||
In order to do that, module should implement `RegisterGRPCRoutes(clientCtx client.Context, mux *runtime.ServeMux)` on `AppModuleBasic` to wire the client gRPC requests to the correct handler inside the module.
|
||||
|
||||
Here's an example from the `auth` module:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/64b6bb5270e1a3b688c2d98a8f481ae04bb713ca/x/auth/module.go#L69-L72
|
||||
|
||||
## gRPC-gateway REST
|
||||
|
||||
Applications typically support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](https://lunie.io). Thus, application developers can also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers.
|
||||
|
||||
[grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway) translates REST calls into gRPC calls, which might be useful for clients that do not use gRPC.
|
||||
|
||||
Modules that want to expose REST queries should add `google.api.http` annotations to their `rpc` methods, such as in the example below from the `auth` module:
|
||||
|
||||
```proto
|
||||
// Query defines the gRPC querier service.
|
||||
service Query{
|
||||
// Account returns account details based on address.
|
||||
rpc Account (QueryAccountRequest) returns (QueryAccountResponse) {
|
||||
option (google.api.http).get = "/cosmos/auth/v1beta1/accounts/{address}";
|
||||
}
|
||||
|
||||
// Params queries all parameters.
|
||||
rpc Params (QueryParamsRequest) returns (QueryParamsResponse) {
|
||||
option (google.api.http).get = "/cosmos/auth/v1beta1/params";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
gRPC gateway is started in-process along with the application and Tendermint. It can be enabled or disabled by setting gRPC Configuration `enable` in `app.toml`.
|
||||
|
||||
The SDK provides a command for generating [Swagger](https://swagger.io/) documentation (`protoc-gen-swagger`). Setting `swagger` in `app.toml` defines if swagger documentation should be automatically registered.
|
||||
|
||||
## Legacy REST
|
||||
|
||||
Legacy REST endpoints will be deprecated. But developers may choose to keep using legacy REST endpoints for backward compatibility, although the recommended way is to use [gRPC](#grpc) and [gRPC-gateway](#grpc-gateway-rest).
|
||||
|
||||
With this implementation, module developers need to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder.
|
||||
|
||||
To support HTTP requests, the module developer needs to define possible request types, how to handle them, and provide a way to register them with a provided router.
|
||||
|
||||
|
@ -101,11 +142,11 @@ To support HTTP requests, the module developer needs to define possible request
|
|||
|
||||
Request types, which define structured interactions from users, must be defined for all _transaction_ requests. Users using this method to interact with an application will send HTTP Requests with the required fields in order to trigger state changes in the application. Conventionally, each request is named with the suffix `Req`, e.g. `SendReq` for a Send transaction. Each struct should include a base request [`baseReq`](../interfaces/rest.md#basereq), the name of the transaction, and all the arguments the user must provide for the transaction.
|
||||
|
||||
Here is an example of a request to buy a name from the `nameservice` module:
|
||||
Here is an example of a request to send coins from the `bank` module:
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/master/nameservice/x/nameservice/client/rest/tx.go#L14-L19
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7f59723d889b69ca19966167f0b3a7fec7a39e53/x/bank/client/rest/tx.go#L15-L19
|
||||
|
||||
The `BaseReq` includes basic information that every request needs to have, similar to required flags in a CLI. All of these values, including `GasPrices` and `AccountNumber`, will be provided in the request body. The user will also need to specify the arguments `Name` and `Amount` fields in the body and `Buyer` will be provided by the user's address.
|
||||
The `BaseReq` includes basic information that every request needs to have, similar to required flags in a CLI. All of these values, including `GasPrices` and `AccountNumber`, will be provided in the request body. The user will also need to specify the argument `Amount` fields in the body.
|
||||
|
||||
#### BaseReq
|
||||
|
||||
|
@ -116,6 +157,7 @@ The `BaseReq` includes basic information that every request needs to have, simil
|
|||
- `ChainID` specifies the unique identifier of the blockchain the transaction pertains to.
|
||||
- `AccountNumber` is an identifier for the account.
|
||||
- `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks.
|
||||
- `TimeoutHeight` allows a transaction to be rejected if it's committed at a height greater than the timeout.
|
||||
- `Gas` refers to how much [gas](../basics/gas-fees.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`.
|
||||
- `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas.
|
||||
- `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas.
|
||||
|
@ -124,17 +166,17 @@ The `BaseReq` includes basic information that every request needs to have, simil
|
|||
|
||||
### Request Handlers
|
||||
|
||||
Request handlers must be defined for both transaction and query requests. Handlers' arguments include a reference to the application's `codec` and the [`Context`](../interfaces/query-lifecycle.md#context) created in the user interaction.
|
||||
Request handlers must be defined for both transaction and query requests. Handlers' arguments include a reference to the [client `Context`](../interfaces/query-lifecycle.md#context).
|
||||
|
||||
Here is an example of a request handler for the nameservice module `buyNameReq` request (the same one shown above):
|
||||
Here is an example of a request handler for the `bank` module `SendReq` request (the same one shown above):
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/master/nameservice/x/nameservice/client/rest/tx.go#L21-L57
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7f59723d889b69ca19966167f0b3a7fec7a39e53/x/bank/client/rest/tx.go#L21-L51
|
||||
|
||||
The request handler can be broken down as follows:
|
||||
|
||||
- **Parse Request:** The request handler first attempts to parse the request, and then run `Sanitize` and `ValidateBasic` on the underlying `BaseReq` to check the validity of the request. Next, it attempts to parse the arguments `Buyer` and `Amount` to the types `AccountAddress` and `Coins` respectively.
|
||||
- **Message:** Then, a [message](./messages-and-queries.md) of the type `MsgBuyName` (defined by the module developer to trigger the state changes for this transaction) is created from the values and another sanity check, `ValidateBasic` is run on it.
|
||||
- **Generate Transaction:** Finally, the HTTP `ResponseWriter`, application [`codec`](../core/encoding.md), [`Context`](../interfaces/query-lifecycle.md#context), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request.
|
||||
- **Parse Request:** First, it tries to parse the argument `address` into a `AccountAddress`. Then, the request handler attempts to parse the request, and then run `Sanitize` and `ValidateBasic` on the underlying `BaseReq` to check the validity of the request. Finally, it attempts to parse `BaseReq.From` to the type `AccountAddress`.
|
||||
- **Message:** Then, a [message](./messages-and-queries.md#messages) of the type `MsgSend` (defined by the module developer to trigger the state changes for this transaction) is created from the values.
|
||||
- **Generate Transaction:** Finally, the HTTP `ResponseWriter`, client `Context`, request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGeneratedTxResponse` to further process the request.
|
||||
|
||||
To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation).
|
||||
|
||||
|
|
|
@ -29,15 +29,17 @@ are only used for genesis can take advantage of the `Module` patterns without ha
|
|||
|
||||
The `AppModuleBasic` interface defines the independent methods modules need to implement.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L46-L59
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/325be6ff215db457c6fc7668109640cd7fdac461/types/module/module.go#L49-L63
|
||||
|
||||
Let us go through the methods:
|
||||
|
||||
- `Name()`: Returns the name of the module as a `string`.
|
||||
- `RegisterLegacyAminoCodec(*codec.LegacyAmino)`: Registers the `amino` codec for the module, which is used to marhsal and unmarshal structs to/from `[]byte` in order to persist them in the moduel's `KVStore`.
|
||||
- `DefaultGenesis()`: Returns a default [`GenesisState`](./genesis.md#genesisstate) for the module, marshalled to `json.RawMessage`. The default `GenesisState` need to be defined by the module developer and is primarily used for testing.
|
||||
- `ValidateGenesis(json.RawMessage)`: Used to validate the `GenesisState` defined by a module, given in its `json.RawMessage` form. It will usually unmarshall the `json` before running a custom [`ValidateGenesis`](./genesis.md#validategenesis) function defined by the module developer.
|
||||
- `RegisterLegacyAminoCodec(*codec.LegacyAmino)`: Registers the `amino` codec for the module, which is used to marshal and unmarshal structs to/from `[]byte` in order to persist them in the module's `KVStore`.
|
||||
- `RegisterInterfaces(codectypes.InterfaceRegistry)`: Registers a module's interface types and their concrete implementations as `proto.Message`.
|
||||
- `DefaultGenesis(codec.JSONMarshaler)`: Returns a default [`GenesisState`](./genesis.md#genesisstate) for the module, marshalled to `json.RawMessage`. The default `GenesisState` need to be defined by the module developer and is primarily used for testing.
|
||||
- `ValidateGenesis(codec.JSONMarshaler, client.TxEncodingConfig, json.RawMessage)`: Used to validate the `GenesisState` defined by a module, given in its `json.RawMessage` form. It will usually unmarshall the `json` before running a custom [`ValidateGenesis`](./genesis.md#validategenesis) function defined by the module developer.
|
||||
- `RegisterRESTRoutes(client.Context, *mux.Router)`: Registers the REST routes for the module. These routes will be used to map REST request to the module in order to process them. See [../interfaces/rest.md] for more.
|
||||
- `RegisterGRPCRoutes(client.Context, *runtime.ServeMux)`: Registers gRPC routes for the module.
|
||||
- `GetTxCmd()`: Returns the root [`Tx` command](./module-interfaces.md#tx) for the module. The subcommands of this root command are used by end-users to generate new transactions containing [`message`s](./messages-and-queries.md#queries) defined in the module.
|
||||
- `GetQueryCmd()`: Return the root [`query` command](./module-interfaces.md#query) for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module.
|
||||
|
||||
|
@ -47,20 +49,20 @@ All the `AppModuleBasic` of an application are managed by the [`BasicManager`](#
|
|||
|
||||
The `AppModuleGenesis` interface is a simple embedding of the `AppModuleBasic` interface with two added methods.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L126-L131
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/325be6ff215db457c6fc7668109640cd7fdac461/types/module/module.go#L152-L158
|
||||
|
||||
Let us go through the two added methods:
|
||||
|
||||
- `InitGenesis(sdk.Context, json.RawMessage)`: Initializes the subset of the state managed by the module. It is called at genesis (i.e. when the chain is first started).
|
||||
- `ExportGenesis(sdk.Context)`: Exports the latest subset of the state managed by the module to be used in a new genesis file. `ExportGenesis` is called for each module when a new chain is started from the state of an existing chain.
|
||||
- `InitGenesis(sdk.Context, codec.JSONMarshaler, json.RawMessage)`: Initializes the subset of the state managed by the module. It is called at genesis (i.e. when the chain is first started).
|
||||
- `ExportGenesis(sdk.Context, codec.JSONMarshaler)`: Exports the latest subset of the state managed by the module to be used in a new genesis file. `ExportGenesis` is called for each module when a new chain is started from the state of an existing chain.
|
||||
|
||||
It does not have its own manager, and exists separately from [`AppModule`](#appmodule) only for modules that exist only to implement genesis functionalities, so that they can be managed without having to implement all of `AppModule`'s methods. If the module is not only used during genesis, `InitGenesis(sdk.Context, json.RawMessage)` and `ExportGenesis(sdk.Context)` will generally be defined as methods of the concrete type implementing hte `AppModule` interface.
|
||||
It does not have its own manager, and exists separately from [`AppModule`](#appmodule) only for modules that exist only to implement genesis functionalities, so that they can be managed without having to implement all of `AppModule`'s methods. If the module is not only used during genesis, `InitGenesis(sdk.Context, codec.JSONMarshaler, json.RawMessage)` and `ExportGenesis(sdk.Context, codec.JSONMarshaler)` will generally be defined as methods of the concrete type implementing hte `AppModule` interface.
|
||||
|
||||
### `AppModule`
|
||||
|
||||
The `AppModule` interface defines the inter-dependent methods modules need to implement.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L133-L149
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/228728cce2af8d494c8b4e996d011492139b04ab/types/module/module.go#L160-L182
|
||||
|
||||
`AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter.
|
||||
|
||||
|
@ -68,8 +70,9 @@ Let us go through the methods of `AppModule`:
|
|||
|
||||
- `RegisterInvariants(sdk.InvariantRegistry)`: Registers the [`invariants`](./invariants.md) of the module. If the invariants deviates from its predicted value, the [`InvariantRegistry`](./invariants.md#registry) triggers appropriate logic (most often the chain will be halted).
|
||||
- `Route()`: Returns the route for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`baseapp`](../core/baseapp.md#message-routing).
|
||||
- `QuerierRoute()`: Returns the name of the module's query route, for [`queries`](./messages-and-queries.md#queries) to be routes to the module by [`baseapp`](../core/baseapp.md#query-routing).
|
||||
- `NewQuerierHandler()`: Returns a [`querier`](./querier.md) given the query `path`, in order to process the `query`.
|
||||
- `QuerierRoute()` (deprecated): Returns the name of the module's query route, for [`queries`](./messages-and-queries.md#queries) to be routes to the module by [`baseapp`](../core/baseapp.md#query-routing).
|
||||
- `LegacyQuerierHandler(*codec.LegacyAmino)` (deprecated): Returns a [`querier`](./query-services.md#legacy-queriers) given the query `path`, in order to process the `query`.
|
||||
- `RegisterQueryService(grpc.Server)`: Allows a module to register a gRPC query service.
|
||||
- `BeginBlock(sdk.Context, abci.RequestBeginBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. Implement empty if no logic needs to be triggered at the beginning of each block for this module.
|
||||
- `EndBlock(sdk.Context, abci.RequestEndBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. This is also where the module can inform the underlying consensus engine of validator set changes (e.g. the `staking` module). Implement empty if no logic needs to be triggered at the beginning of each block for this module.
|
||||
|
||||
|
@ -103,15 +106,17 @@ Module managers are used to manage collections of `AppModuleBasic` and `AppModul
|
|||
|
||||
The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L61-L63
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/325be6ff215db457c6fc7668109640cd7fdac461/types/module/module.go#L65-L66
|
||||
|
||||
It implements the following methods:
|
||||
|
||||
- `NewBasicManager(modules ...AppModuleBasic)`: Constructor function. It takes a list of the application's `AppModuleBasic` and builds a new `BasicManager`. This function is generally called in the `init()` function of [`app.go`](../basics/app-anatomy.md#core-application-file) to quickly initialize the independent elements of the application's modules (click [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L59-L74) to see an example).
|
||||
- `RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)`: Registers the [`codec`s](../core/encoding.md) of each of the application's `AppModuleBasic`. This function is usually called early on in the [application's construction](../basics/app-anatomy.md#constructor).
|
||||
- `DefaultGenesis()`: Provides default genesis information for modules in the application by calling the [`DefaultGenesis()`](./genesis.md#defaultgenesis) function of each module. It is used to construct a default genesis file for the application.
|
||||
- `ValidateGenesis(genesis map[string]json.RawMessage)`: Validates the genesis information modules by calling the [`ValidateGenesis()`](./genesis.md#validategenesis) function of each module.
|
||||
- `RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)`: Registers the [`codec.LegacyAmino`s](../core/encoding.md#amino) of each of the application's `AppModuleBasic`. This function is usually called early on in the [application's construction](../basics/app-anatomy.md#constructor).
|
||||
- `RegisterInterfaces(registry codectypes.InterfaceRegistry)`: Registers interface types and implementations of each of the application's `AppModuleBasic`.
|
||||
- `DefaultGenesis(cdc codec.JSONMarshaler)`: Provides default genesis information for modules in the application by calling the [`DefaultGenesis(cdc codec.JSONMarshaler)`](./genesis.md#defaultgenesis) function of each module. It is used to construct a default genesis file for the application.
|
||||
- `ValidateGenesis(cdc codec.JSONMarshaler, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)`: Validates the genesis information modules by calling the [`ValidateGenesis(codec.JSONMarshaler, client.TxEncodingConfig, json.RawMessage)`](./genesis.md#validategenesis) function of each module.
|
||||
- `RegisterRESTRoutes(ctx client.Context, rtr *mux.Router)`: Registers REST routes for modules by calling the [`RegisterRESTRoutes`](./module-interfaces.md#register-routes) function of each module. This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md).
|
||||
- `RegisterGRPCRoutes(clientCtx client.Context, rtr *runtime.ServeMux)`: Registers gRPC routes for modules.
|
||||
- `AddTxCommands(rootTxCmd *cobra.Command)`: Adds modules' transaction commands to the application's [`rootTxCommand`](../interfaces/cli.md#transaction-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md).
|
||||
- `AddQueryCommands(rootQueryCmd *cobra.Command)`: Adds modules' query commands to the application's [`rootQueryCommand`](../interfaces/cli.md#query-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md).
|
||||
|
||||
|
@ -119,7 +124,7 @@ It implements the following methods:
|
|||
|
||||
The `Manager` is a structure that holds all the `AppModule` of an application, and defines the order of execution between several key components of these modules:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L190-L198
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/325be6ff215db457c6fc7668109640cd7fdac461/types/module/module.go#L223-L231
|
||||
|
||||
The module manager is used throughout the application whenever an action on a collection of modules is required. It implements the following methods:
|
||||
|
||||
|
@ -129,12 +134,17 @@ The module manager is used throughout the application whenever an action on a co
|
|||
- `SetOrderBeginBlockers(moduleNames ...string)`: Sets the order in which the `BeginBlock()` function of each module will be called at the beginning of each block. This function is generally called from the application's main [constructor function](../basics/app-anatomy.md#constructor-function).
|
||||
- `SetOrderEndBlockers(moduleNames ...string)`: Sets the order in which the `EndBlock()` function of each module will be called at the beginning of each block. This function is generally called from the application's main [constructor function](../basics/app-anatomy.md#constructor-function).
|
||||
- `RegisterInvariants(ir sdk.InvariantRegistry)`: Registers the [invariants](./invariants.md) of each module.
|
||||
- `RegisterRoutes(router sdk.Router, queryRouter sdk.QueryRouter)`: Registers module routes to the application's `router`, in order to route [`message`s](./messages-and-queries.md#messages) to the appropriate [`handler`](./handler.md), and module query routes to the application's `queryRouter`, in order to route [`queries`](./messages-and-queries.md#queries) to the appropriate [`querier`](./querier.md).
|
||||
- `InitGenesis(ctx sdk.Context, genesisData map[string]json.RawMessage)`: Calls the [`InitGenesis`](./genesis.md#initgenesis) function of each module when the application is first started, in the order defined in `OrderInitGenesis`. Returns an `abci.ResponseInitChain` to the underlying consensus engine, which can contain validator updates.
|
||||
- `ExportGenesis(ctx sdk.Context)`: Calls the [`ExportGenesis`](./genesis.md#exportgenesis) function of each module, in the order defined in `OrderExportGenesis`. The export constructs a genesis file from a previously existing state, and is mainly used when a hard-fork upgrade of the chain is required.
|
||||
- `RegisterRoutes(router sdk.Router, queryRouter sdk.QueryRouter, legacyQuerierCdc *codec.LegacyAmino)`: Registers module routes to the application's `router`, in order to route [`message`s](./messages-and-queries.md#messages) to the appropriate [`handler`](./handler.md), and module query routes to the application's `queryRouter`, in order to route [`queries`](./messages-and-queries.md#queries) to the appropriate [`querier`](./query-services.md#legacy-queriers).
|
||||
- `RegisterQueryServices(grpcRouter grpc.Server)`: Registers all module gRPC query services.
|
||||
- `InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, genesisData map[string]json.RawMessage)`: Calls the [`InitGenesis`](./genesis.md#initgenesis) function of each module when the application is first started, in the order defined in `OrderInitGenesis`. Returns an `abci.ResponseInitChain` to the underlying consensus engine, which can contain validator updates.
|
||||
- `ExportGenesis(ctx sdk.Context, cdc codec.JSONMarshaler)`: Calls the [`ExportGenesis`](./genesis.md#exportgenesis) function of each module, in the order defined in `OrderExportGenesis`. The export constructs a genesis file from a previously existing state, and is mainly used when a hard-fork upgrade of the chain is required.
|
||||
- `BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)`: At the beginning of each block, this function is called from [`baseapp`](../core/baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseBeginBlock` which contains the aforementioned events.
|
||||
- `EndBlock(ctx sdk.Context, req abci.RequestEndBlock)`: At the end of each block, this function is called from [`baseapp`](../core/baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseEndBlock` which contains the aforementioned events, as well as validator set updates (if any).
|
||||
|
||||
Here's an example of a concrete integration within an application:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/2323f1ac0e9a69a0da6b43693061036134193464/simapp/app.go#L315-L362
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn more about [`message`s and `queries`](./messages-and-queries.md) {hide}
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
<!--
|
||||
order: 5
|
||||
-->
|
||||
|
||||
# Queriers
|
||||
|
||||
A `Querier` designates a function that processes [`queries`](./messages-and-queries.md#queries). `querier`s are specific to the module in which they are defined, and only process `queries` defined within said module. They are called from `baseapp`'s [`Query` method](../core/baseapp.md#query). {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Module Manager](./module-manager.md) {prereq}
|
||||
- [Messages and Queries](./messages-and-queries.md) {prereq}
|
||||
|
||||
## `Querier` type
|
||||
|
||||
The `querier` type defined in the Cosmos SDK specifies the typical structure of a `querier` function:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/queryable.go#L6
|
||||
|
||||
Let us break it down:
|
||||
|
||||
- The `path` is an array of `string`s that contains the type of the query, and that can also contain `query` arguments. See [`queries`](./messages-and-queries.md#queries) for more information.
|
||||
- The `req` itself is primarily used to retrieve arguments if they are too large to fit in the `path`. This is done using the `Data` field of `req`.
|
||||
- The [`Context`](../core/context.md) contains all the necessary information needed to process the `query`, as well as a cache-wrapped copy of the latest state. It is primarily used by the [`keeper`](./keeper.md) to access the state.
|
||||
- The result `res` returned to `baseapp`, marhsalled using the application's [`codec`](../core/encoding.md).
|
||||
|
||||
## Implementation of a module `querier`s
|
||||
|
||||
Module `querier`s are typically implemented in a `./internal/keeper/querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `keeper/querier.go`, which looks like the following:
|
||||
|
||||
```go
|
||||
func NewQuerier(keeper Keeper) sdk.Querier {
|
||||
return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) {
|
||||
switch path[0] {
|
||||
case QueryType1:
|
||||
return queryType1(ctx, path[1:], req, keeper)
|
||||
|
||||
case QueryType2:
|
||||
return queryType2(ctx, path[1:], req, keeper)
|
||||
|
||||
default:
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This simple switch returns a `querier` function specific to the type of the received `query`. At this point of the [query lifecycle](../interfaces/query-lifecycle.md), the first element of the `path` (`path[0]`) contains the type of the query. The following elements are either empty or contain arguments needed to process the query.
|
||||
|
||||
The `querier` functions themselves are pretty straighforward. They generally fetch a value or values from the state using the [`keeper`](./keeper.md). Then, they marshall the value(s) using the [`codec`](../core/encoding.md) and return the `[]byte` obtained as result.
|
||||
|
||||
For a deeper look at `querier`s, see this [example implementation of a `querier` function](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/keeper/querier.go) from the nameservice tutorial.
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn about [`BeginBlocker` and `EndBlocker`](./beginblock-endblock.md) {hide}
|
|
@ -0,0 +1,77 @@
|
|||
<!--
|
||||
order: 5
|
||||
-->
|
||||
|
||||
# Query Services
|
||||
|
||||
A query service processes [`queries`](./messages-and-queries.md#queries). Query services are specific to the module in which they are defined, and only process `queries` defined within said module. They are called from `baseapp`'s [`Query` method](../core/baseapp.md#query). {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Module Manager](./module-manager.md) {prereq}
|
||||
- [Messages and Queries](./messages-and-queries.md) {prereq}
|
||||
|
||||
## `Querier` type
|
||||
|
||||
The `querier` type defined in the Cosmos SDK will be deprecated in favor of [gRPC Services](#grpc-service). It specifies the typical structure of a `querier` function:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/9a183ffbcc0163c8deb71c7fd5f8089a83e58f05/types/queryable.go#L9
|
||||
|
||||
Let us break it down:
|
||||
|
||||
- The `path` is an array of `string`s that contains the type of the query, and that can also contain `query` arguments. See [`queries`](./messages-and-queries.md#queries) for more information.
|
||||
- The `req` itself is primarily used to retrieve arguments if they are too large to fit in the `path`. This is done using the `Data` field of `req`.
|
||||
- The [`Context`](../core/context.md) contains all the necessary information needed to process the `query`, as well as a cache-wrapped copy of the latest state. It is primarily used by the [`keeper`](./keeper.md) to access the state.
|
||||
- The result `res` returned to `baseapp`, marshalled using the application's [`codec`](../core/encoding.md).
|
||||
|
||||
## Implementation of a module query service
|
||||
|
||||
### gRPC Service
|
||||
|
||||
When defining a Protobuf `Query` service, a `QueryServer` interface is generated for each module with all the service methods:
|
||||
|
||||
```go
|
||||
type QueryServer interface {
|
||||
QueryBalance(context.Context, *QueryBalanceParams) (*types.Coin, error)
|
||||
QueryAllBalances(context.Context, *QueryAllBalancesParams) (*QueryAllBalancesResponse, error)
|
||||
}
|
||||
```
|
||||
|
||||
These custom queries methods should be implemented by a module's keeper, typically in `./keeper/grpc_query.go`. The first parameter of these methods is a generic `context.Context`, whereas querier methods generally need an instance of `sdk.Context` to read
|
||||
from the store. Therefore, the SDK provides a function `sdk.UnwrapSDKContext` to retrieve the `sdk.Context` from the provided
|
||||
`context.Context`.
|
||||
|
||||
Here's an example implementation for the bank module:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/bank/keeper/grpc_query.go
|
||||
|
||||
### Legacy Queriers
|
||||
|
||||
Module legacy `querier`s are typically implemented in a `./keeper/querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `keeper/querier.go`, which looks like the following:
|
||||
|
||||
```go
|
||||
func NewQuerier(keeper Keeper) sdk.Querier {
|
||||
return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) {
|
||||
switch path[0] {
|
||||
case QueryType1:
|
||||
return queryType1(ctx, path[1:], req, keeper)
|
||||
|
||||
case QueryType2:
|
||||
return queryType2(ctx, path[1:], req, keeper)
|
||||
|
||||
default:
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This simple switch returns a `querier` function specific to the type of the received `query`. At this point of the [query lifecycle](../interfaces/query-lifecycle.md), the first element of the `path` (`path[0]`) contains the type of the query. The following elements are either empty or contain arguments needed to process the query.
|
||||
|
||||
The `querier` functions themselves are pretty straighforward. They generally fetch a value or values from the state using the [`keeper`](./keeper.md). Then, they marshall the value(s) using the [`codec`](../core/encoding.md) and return the `[]byte` obtained as result.
|
||||
|
||||
For a deeper look at `querier`s, see this [example implementation of a `querier` function](https://github.com/cosmos/cosmos-sdk/blob/7f59723d889b69ca19966167f0b3a7fec7a39e53/x/gov/keeper/querier.go) from the bank module.
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Learn about [`BeginBlocker` and `EndBlocker`](./beginblock-endblock.md) {hide}
|
|
@ -27,6 +27,7 @@ x/{module}
|
|||
│ ├── keeper.go
|
||||
│ ├── ...
|
||||
│ └── querier.go
|
||||
│ └── grpc_query.go
|
||||
├── types
|
||||
│ ├── codec.go
|
||||
│ ├── errors.go
|
||||
|
@ -36,10 +37,12 @@ x/{module}
|
|||
│ ├── keys.go
|
||||
│ ├── msgs.go
|
||||
│ ├── params.go
|
||||
│ ├── types.pb.go
|
||||
│ ├── types.proto
|
||||
│ ├── ...
|
||||
│ └── querier.go
|
||||
│ └── {module_name}.pb.go
|
||||
│ └── query.pb.go
|
||||
│ └── genesis.pb.go
|
||||
├── simulation
|
||||
│ ├── decoder.go
|
||||
│ ├── genesis.go
|
||||
|
|
|
@ -200,7 +200,7 @@ The application's `router` is initilalized with all the routes using the applica
|
|||
|
||||
### Query Routing
|
||||
|
||||
Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a `query router`, which maps module names to module `querier`s. The `queryRouter` is called during the initial stages of `query` processing, which is done via the [`Query` ABCI message](#query).
|
||||
Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/query-services.md). To do so, `baseapp` holds a `query router`, which maps module names to module `querier`s. The `queryRouter` is called during the initial stages of `query` processing, which is done via the [`Query` ABCI message](#query).
|
||||
|
||||
Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor).
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ Modules are encouraged to utilize Protobuf encoding for their respective types.
|
|||
Protobuf types can be defined to encode:
|
||||
- state
|
||||
- [`Msg`s](../building-modules/messages-and-queries.md#messages)
|
||||
- [queries](../building-modules/querier.md)
|
||||
- [Query services](../building-modules/query-services.md)
|
||||
- [genesis](../building-modules/genesis.md)
|
||||
|
||||
**Naming and conventions**
|
||||
|
|
|
@ -39,7 +39,7 @@ A transaction is created by an end-user through one of the possible [interfaces]
|
|||
|
||||
Application developers create entrypoints to the application by creating a [command-line interface](../interfaces/cli.md) and/or [REST interface](../interfaces/rest.md), typically found in the application's `./cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests.
|
||||
|
||||
For the [command-line interface](../building-modules/module-interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../building-modules/module-interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers.
|
||||
For the [command-line interface](../building-modules/module-interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../building-modules/module-interfaces.md#legacy-rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers.
|
||||
|
||||
When users interact with the application's interfaces, they invoke the underlying modules' handlers or command functions, directly creating messages.
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ params := types.NewQueryDelegatorParams(delegatorAddr)
|
|||
|
||||
#### Query Route Creation
|
||||
|
||||
Important to note is that there will never be a "query" object created for `Query`; the SDK actually takes a simpler approach. Instead of an object, all the full-node needs to process a query is its `route` which specifies exactly which module to route the query to and the name of this query type. The `route` will be passed to the application `baseapp`, then module, then [querier](../building-modules/querier.md), and each will understand the `route` and pass it to the appropriate next step. [`baseapp`](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking`, and the `staking` module querier supports the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`.
|
||||
Important to note is that there will never be a "query" object created for `Query`; the SDK actually takes a simpler approach. Instead of an object, all the full-node needs to process a query is its `route` which specifies exactly which module to route the query to and the name of this query type. The `route` will be passed to the application `baseapp`, then module, then [querier](../building-modules/query-services.md#legacy-queriers), and each will understand the `route` and pass it to the appropriate next step. [`baseapp`](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking`, and the `staking` module querier supports the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`.
|
||||
|
||||
Here is what the code looks like:
|
||||
|
||||
|
@ -133,9 +133,9 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation
|
|||
|
||||
## Application Query Handling
|
||||
|
||||
When a query is received by the full-node after it has been relayed from the underlying consensus engine, it is now being handled within an environment that understands application-specific types and has a copy of the state. [`baseapp`](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by `baseapp` or the stores, but the `custom` query type requires `baseapp` to route the query to a module's [querier](../building-modules/querier.md).
|
||||
When a query is received by the full-node after it has been relayed from the underlying consensus engine, it is now being handled within an environment that understands application-specific types and has a copy of the state. [`baseapp`](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by `baseapp` or the stores, but the `custom` query type requires `baseapp` to route the query to a module's [query service](../building-modules/query-services.md).
|
||||
|
||||
Since `Query` is a custom query type from the `staking` module, `baseapp` first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier, and routes the query to the module. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. Read more about queriers [here](../building-modules/querier.md).
|
||||
Since `Query` is a custom query type from the `staking` module, `baseapp` first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier, and routes the query to the module. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. Read more about query services [here](../building-modules/query-services.md).
|
||||
|
||||
Once a result is received from the querier, `baseapp` begins the process of returning a response to the user.
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ order: 4
|
|||
|
||||
# REST Interface
|
||||
|
||||
This document describes how to create a REST interface for an SDK **application**. A separate document for creating a [**module**](../building-modules/intro.md) REST interface can be found [here](#../module-interfaces.md#rest). {synopsis}
|
||||
This document describes how to create a REST interface for an SDK **application**. A separate document for creating a [**module**](../building-modules/intro.md) REST interface can be found [here](#../module-interfaces.md#legacy-rest). {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
|
@ -41,7 +41,7 @@ In order to enable the REST Server in an SDK application, the `rest.ServeCommand
|
|||
|
||||
## Registering Routes
|
||||
|
||||
To include routes for each module in an application, the CLI must have some kind of function to register routes in its REST Server. This function is called `RegisterRoutes()`, and is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules/module-interfaces.md#rest) function, application developers simply use the [Module Manager](../building-modules/module-manager.md) to call this function for each module (this is done in the [application's constructor](../basics/app-anatomy.md#constructor-function)).
|
||||
To include routes for each module in an application, the CLI must have some kind of function to register routes in its REST Server. This function is called `RegisterRoutes()`, and is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules/module-interfaces.md#legacy-rest) function, application developers simply use the [Module Manager](../building-modules/module-manager.md) to call this function for each module (this is done in the [application's constructor](../basics/app-anatomy.md#constructor-function)).
|
||||
|
||||
At the bare minimum, a `RegisterRoutes()` function should use the SDK client package `RegisterRoutes()` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes()` for all of its modules. This is done in the `main.go` file of the CLI (typically located in `./cmd/appcli/main.go`).
|
||||
|
||||
|
|
|
@ -19,33 +19,28 @@ element as a part of a larger description.
|
|||
|
||||
## Common Layout
|
||||
|
||||
The specifications should be contained in a single `README.md` file inside the
|
||||
`spec/` folder of a given module.
|
||||
The following generalized file structure should be used to breakdown
|
||||
specifications for modules. With the exception of README.md, `XX` at the
|
||||
beginning of the file name should be replaced with a number to indicate
|
||||
document flow (ex. read `01_state.md` before `02_state_transitions.md`). The
|
||||
following list is nonbinding and all files are optional.
|
||||
|
||||
The following generalized document structure should be used to breakdown
|
||||
specifications for modules. Each bullet item corresponds to a new section in
|
||||
the document, and should begin with a secondary heading (`## {HEADING}` in
|
||||
Markdown). The `XX` at the beginning of the section name should be replaced
|
||||
with a number to indicate document flow (ex. read `01. Concepts` before
|
||||
`02. State Transitions`). The following list is nonbinding and all sections are
|
||||
optional.
|
||||
|
||||
- `XX. Abstract` - overview of the module
|
||||
- `XX. Concepts` - describe specialized concepts and definitions used throughout the spec
|
||||
- `XX. State` - specify and describe structures expected to marshalled into the store, and their keys
|
||||
- `XX. State Transitions` - standard state transition operations triggered by hooks, messages, etc.
|
||||
- `XX. Messages` - specify message structure(s) and expected state machine behaviour(s)
|
||||
- `XX. BeginBlock` - specify any begin-block operations
|
||||
- `XX. EndBlock` - specify any end-block operations
|
||||
- `XX. Hooks` - describe available hooks to be called by/from this module
|
||||
- `XX. Events` - list and describe event tags used
|
||||
- `XX. Params` - list all module parameters, their types (in JSON) and examples
|
||||
- `XX. Future Improvements` - describe future improvements of this module
|
||||
- `XX. Appendix` - supplementary details referenced elsewhere within the spec
|
||||
- `README.md` - overview of the module
|
||||
- `XX_concepts.md` - describe specialized concepts and definitions used throughout the spec
|
||||
- `XX_state.md` - specify and describe structures expected to marshalled into the store, and their keys
|
||||
- `XX_state_transitions.md` - standard state transition operations triggered by hooks, messages, etc.
|
||||
- `XX_messages.md` - specify message structure(s) and expected state machine behaviour(s)
|
||||
- `XX_begin_block.md` - specify any begin-block operations
|
||||
- `XX_end_block.md` - specify any end-block operations
|
||||
- `XX_hooks.md` - describe available hooks to be called by/from this module
|
||||
- `XX_events.md` - list and describe event tags used
|
||||
- `XX_params.md` - list all module parameters, their types (in JSON) and examples
|
||||
- `XX_future_improvements.md` - describe future improvements of this module
|
||||
- `XX_appendix.md` - supplementary details referenced elsewhere within the spec
|
||||
|
||||
### Notation for key-value mapping
|
||||
|
||||
Within the `State` section, the following notation `->` should be used to describe key to
|
||||
Within `state.md` the following notation `->` should be used to describe key to
|
||||
value mapping:
|
||||
|
||||
```
|
||||
|
|
26
go.mod
26
go.mod
|
@ -4,35 +4,40 @@ module github.com/cosmos/cosmos-sdk
|
|||
|
||||
require (
|
||||
github.com/99designs/keyring v1.1.6
|
||||
github.com/DataDog/zstd v1.4.5 // indirect
|
||||
github.com/armon/go-metrics v0.3.4
|
||||
github.com/bgentry/speakeasy v0.1.0
|
||||
github.com/btcsuite/btcd v0.21.0-beta
|
||||
github.com/btcsuite/btcutil v1.0.2
|
||||
github.com/confio/ics23/go v0.0.0-20200817220745-f173e6211efb
|
||||
github.com/confio/ics23/go v0.6.3
|
||||
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d
|
||||
github.com/cosmos/iavl v0.15.0-rc3
|
||||
github.com/cosmos/iavl v0.15.0-rc4
|
||||
github.com/cosmos/ledger-cosmos-go v0.11.1
|
||||
github.com/dgraph-io/badger/v2 v2.2007.2 // indirect
|
||||
github.com/dgraph-io/ristretto v0.0.3 // indirect
|
||||
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
|
||||
github.com/enigmampc/btcutil v1.0.3-0.20200723161021-e2fb6adb2a25
|
||||
github.com/gogo/gateway v1.1.0
|
||||
github.com/gogo/protobuf v1.3.1
|
||||
github.com/golang/mock v1.4.4
|
||||
github.com/golang/protobuf v1.4.2
|
||||
github.com/golang/protobuf v1.4.3
|
||||
github.com/golang/snappy v0.0.2 // indirect
|
||||
github.com/gorilla/handlers v1.5.1
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.15.0
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.15.2
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/magiconair/properties v1.8.4
|
||||
github.com/mattn/go-isatty v0.0.12
|
||||
github.com/otiai10/copy v1.2.0
|
||||
github.com/pelletier/go-toml v1.8.0 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.7.1
|
||||
github.com/prometheus/client_golang v1.8.0
|
||||
github.com/prometheus/common v0.14.0
|
||||
github.com/rakyll/statik v0.1.7
|
||||
github.com/regen-network/cosmos-proto v0.3.0
|
||||
github.com/spf13/afero v1.2.2 // indirect
|
||||
github.com/spf13/cast v1.3.1
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/spf13/cobra v1.1.1
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect; indirects
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/viper v1.7.1
|
||||
|
@ -40,11 +45,12 @@ require (
|
|||
github.com/tendermint/btcd v0.1.1
|
||||
github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15
|
||||
github.com/tendermint/go-amino v0.16.0
|
||||
github.com/tendermint/tendermint v0.34.0-rc4.0.20201005135527-d7d0ffea13c6
|
||||
github.com/tendermint/tendermint v0.34.0-rc5
|
||||
github.com/tendermint/tm-db v0.6.2
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987
|
||||
google.golang.org/grpc v1.32.0
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee
|
||||
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10 // indirect
|
||||
google.golang.org/genproto v0.0.0-20201014134559-03b6142f0dc9
|
||||
google.golang.org/grpc v1.33.0
|
||||
google.golang.org/protobuf v1.25.0
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
)
|
||||
|
|
78
go.sum
78
go.sum
|
@ -26,6 +26,8 @@ github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:
|
|||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM=
|
||||
github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
|
||||
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
|
@ -103,8 +105,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
|||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/confio/ics23/go v0.0.0-20200817220745-f173e6211efb h1:+7FsS1gZ1Km5LRjGV2hztpier/5i6ngNjvNpxbWP5I0=
|
||||
github.com/confio/ics23/go v0.0.0-20200817220745-f173e6211efb/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg=
|
||||
github.com/confio/ics23/go v0.6.3 h1:PuGK2V1NJWZ8sSkNDq91jgT/cahFEW9RGp4Y5jxulf0=
|
||||
github.com/confio/ics23/go v0.6.3/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
|
@ -117,8 +119,8 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc
|
|||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU=
|
||||
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
|
||||
github.com/cosmos/iavl v0.15.0-rc3 h1:rSm60IFfDCD9qDfvXKEmaJhcv0rB5uCbVlBDKsynxqw=
|
||||
github.com/cosmos/iavl v0.15.0-rc3/go.mod h1:rQ2zK/LuivThMjve3Yr6VkjvCqCXl+fgHCY7quiUA68=
|
||||
github.com/cosmos/iavl v0.15.0-rc4 h1:P1wmET7BueqCzfxsn+BzVkDWDLY9ij2JNwkbIdM7RG8=
|
||||
github.com/cosmos/iavl v0.15.0-rc4/go.mod h1:5CsecJdh44Uj4vZ6WSPeWq84hNW5BwRI36ZsAbfJvRw=
|
||||
github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4=
|
||||
github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY=
|
||||
github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI=
|
||||
|
@ -135,17 +137,19 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/decred/dcrd/lru v1.0.0 h1:Kbsb1SFDsIlaupWPwsPp+dkxiBY1frcS07PCPgotKz8=
|
||||
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
|
||||
github.com/dgraph-io/badger/v2 v2.0.3 h1:inzdf6VF/NZ+tJ8RwwYMjJMvsOALTHYdozn0qSl6XJI=
|
||||
github.com/dgraph-io/badger/v2 v2.0.3/go.mod h1:3KY8+bsP8wI0OEnQJAKpd4wIJW/Mm32yw2j/9FUVnIM=
|
||||
github.com/dgraph-io/badger/v2 v2.2007.1 h1:t36VcBCpo4SsmAD5M8wVv1ieVzcALyGfaJ92z4ccULM=
|
||||
github.com/dgraph-io/badger/v2 v2.2007.1/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE=
|
||||
github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3 h1:MQLRM35Pp0yAyBYksjbj1nZI/w6eyRY/mWoM1sFf4kU=
|
||||
github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
|
||||
github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k=
|
||||
github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE=
|
||||
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA=
|
||||
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
|
||||
github.com/dgraph-io/ristretto v0.0.3 h1:jh22xisGBjrEVnRZ1DVTpBVQm0Xndu8sMl0CWDzSIBI=
|
||||
github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
|
||||
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
|
@ -225,9 +229,13 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
|||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw=
|
||||
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
|
@ -247,6 +255,7 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI
|
|||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
|
@ -265,16 +274,14 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U
|
|||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.1/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.7 h1:Nk5kuHrnWUTf/0GL1a/vchH/om9Ap2/HnVna+jYZgTY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.7/go.mod h1:oYZKL012gGh6LMyg/xA7Q2yq6j8bu0wa+9w14EEthWU=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.15.0 h1:ntPNC9TD/6l2XDenJZe6T5lSMg95thpV9sGAqHX4WU8=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.15.0/go.mod h1:vO11I9oWA+KsxmfFQPhLnnIb1VDE24M+pdxZFiuZcA8=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.15.2 h1:HC+hWRWf+v5zTMPyoaYTKIJih+4sd4XRWmj0qlG87Co=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.15.2/go.mod h1:vO11I9oWA+KsxmfFQPhLnnIb1VDE24M+pdxZFiuZcA8=
|
||||
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU=
|
||||
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0=
|
||||
github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s=
|
||||
|
@ -377,8 +384,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
|
|||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0=
|
||||
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM=
|
||||
github.com/minio/highwayhash v1.0.0 h1:iMSDhgUILCr0TNm8LWlSjF8N0ZIj2qbO8WHp6Q/J2BA=
|
||||
github.com/minio/highwayhash v1.0.0/go.mod h1:xQboMTeM9nY9v/LlAOxFctujiv5+Aq2hR5dxBpaMbdc=
|
||||
github.com/minio/highwayhash v1.0.1 h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz/0=
|
||||
github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
|
@ -473,6 +478,8 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD
|
|||
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.8.0 h1:zvJNkoCFAnYFNC24FV8nW4JdRJ3GIFcLbg65lL/JDcw=
|
||||
github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
|
@ -497,6 +504,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
|
|||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4=
|
||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ=
|
||||
github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc=
|
||||
|
@ -543,6 +552,8 @@ github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3
|
|||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
|
||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
|
@ -552,6 +563,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
|||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
|
||||
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
|
@ -568,7 +580,6 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd
|
|||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
|
||||
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok=
|
||||
|
@ -579,12 +590,9 @@ github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RM
|
|||
github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk=
|
||||
github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E=
|
||||
github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=
|
||||
github.com/tendermint/tendermint v0.34.0-rc3 h1:d7Fsd5rdbxq4GmJ0kRfx7l7LesQM7e70f0ytWLTQ/Go=
|
||||
github.com/tendermint/tendermint v0.34.0-rc3/go.mod h1:BoHcEpjfpBHc1Be7RQz3AHaXFNObcDG7SNHCev6Or4g=
|
||||
github.com/tendermint/tendermint v0.34.0-rc4.0.20201005135527-d7d0ffea13c6 h1:gqZ0WDpDYgMm/iaiMEXvI1nt/GoWCuwtBomVpUMiAIs=
|
||||
github.com/tendermint/tendermint v0.34.0-rc4.0.20201005135527-d7d0ffea13c6/go.mod h1:BSXqR6vWbOecet726v66qVwSkFDLfEeBrq+EhkKbij4=
|
||||
github.com/tendermint/tm-db v0.6.1 h1:w3X87itMPXopcRPlFiqspEKhw4FXihPk2rnFFkP0zGk=
|
||||
github.com/tendermint/tm-db v0.6.1/go.mod h1:m3x9kRP4UFd7JODJL0yBAZqE7wTw+S37uAE90cTx7OA=
|
||||
github.com/tendermint/tendermint v0.34.0-rc4/go.mod h1:yotsojf2C1QBOw4dZrTcxbyxmPUrT4hNuOQWX9XUwB4=
|
||||
github.com/tendermint/tendermint v0.34.0-rc5 h1:2bnQfWyOMfTCbol5pwB8CgM2nxi6/Kz6zqlS6Udm/Cg=
|
||||
github.com/tendermint/tendermint v0.34.0-rc5/go.mod h1:yotsojf2C1QBOw4dZrTcxbyxmPUrT4hNuOQWX9XUwB4=
|
||||
github.com/tendermint/tm-db v0.6.2 h1:DOn8jwCdjJblrCFJbtonEIPD1IuJWpbRUUdR8GWE4RM=
|
||||
github.com/tendermint/tm-db v0.6.2/go.mod h1:GYtQ67SUvATOcoY8/+x6ylk8Qo02BQyLrAs+yAcLvGI=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
|
@ -627,12 +635,11 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
@ -679,8 +686,9 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
|
|||
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc h1:zK/HqS5bZxDptfPJNq8v7vJfXtkU7r9TLIoSr1bXaP4=
|
||||
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10 h1:YfxMZzv3PjGonQYNUaeU2+DhAdqOxerQ30JFB6WgAXo=
|
||||
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -727,8 +735,9 @@ golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed h1:J22ig1FUekjjkmZUM7pTKixYm8DvrYsvrBZdunYeIuQ=
|
||||
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88=
|
||||
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
|
@ -761,7 +770,6 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn
|
|||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200110213125-a7a6caa82ab2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa h1:5E4dL8+NgFOgjwbTKz+OOEGGhP+ectTmF842l6KjupQ=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -794,8 +802,8 @@ google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfG
|
|||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 h1:PDIOdWxZ8eRizhKa1AAvY53xsvLB1cWorMjslvY3VA8=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201014134559-03b6142f0dc9 h1:fG84H9C3EXfuDlzkG+VEPDYHHExklP6scH1QZ5gQTqU=
|
||||
google.golang.org/genproto v0.0.0-20201014134559-03b6142f0dc9/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
|
@ -811,11 +819,10 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
|
|||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0=
|
||||
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.0 h1:IBKSUNL2uBS2DkJBncPP+TwT0sp9tgA8A75NjHt6umg=
|
||||
google.golang.org/grpc v1.33.0/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
@ -831,8 +838,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
|
|||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
|
@ -849,6 +856,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
|
|
|
@ -7,6 +7,15 @@ import "cosmos/bank/v1beta1/bank.proto";
|
|||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types";
|
||||
|
||||
// Msg defines the bank Msg service.
|
||||
service Msg {
|
||||
// Send defines a method for sending coins from one account to another account.
|
||||
rpc Send(MsgSend) returns (MsgSendResponse);
|
||||
|
||||
// MultiSend defines a method for sending coins from some accounts to other accounts.
|
||||
rpc MultiSend(MsgMultiSend) returns (MsgMultiSendResponse);
|
||||
}
|
||||
|
||||
// MsgSend represents a message to send coins from one account to another.
|
||||
message MsgSend {
|
||||
option (gogoproto.equal) = false;
|
||||
|
@ -18,6 +27,9 @@ message MsgSend {
|
|||
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
|
||||
}
|
||||
|
||||
// MsgSendResponse defines the Msg/Send response type.
|
||||
message MsgSendResponse { }
|
||||
|
||||
// MsgMultiSend represents an arbitrary multi-in, multi-out send message.
|
||||
message MsgMultiSend {
|
||||
option (gogoproto.equal) = false;
|
||||
|
@ -25,3 +37,6 @@ message MsgMultiSend {
|
|||
repeated Input inputs = 1 [(gogoproto.nullable) = false];
|
||||
repeated Output outputs = 2 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
// MsgMultiSendResponse defines the Msg/MultiSend response type.
|
||||
message MsgMultiSendResponse { }
|
||||
|
|
|
@ -5,6 +5,12 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/crisis/types";
|
|||
|
||||
import "gogoproto/gogo.proto";
|
||||
|
||||
// Msg defines the bank Msg service.
|
||||
service Msg {
|
||||
// VerifyInvariant defines a method to verify a particular invariance.
|
||||
rpc VerifyInvariant(MsgVerifyInvariant) returns (MsgVerifyInvariantResponse);
|
||||
}
|
||||
|
||||
// MsgVerifyInvariant represents a message to verify a particular invariance.
|
||||
message MsgVerifyInvariant {
|
||||
option (gogoproto.equal) = false;
|
||||
|
@ -14,3 +20,6 @@ message MsgVerifyInvariant {
|
|||
string invariant_module_name = 2 [(gogoproto.moretags) = "yaml:\"invariant_module_name\""];
|
||||
string invariant_route = 3 [(gogoproto.moretags) = "yaml:\"invariant_route\""];
|
||||
}
|
||||
|
||||
// MsgVerifyInvariantResponse defines the Msg/VerifyInvariant response type.
|
||||
message MsgVerifyInvariantResponse { }
|
||||
|
|
|
@ -7,6 +7,25 @@ option (gogoproto.equal_all) = true;
|
|||
import "gogoproto/gogo.proto";
|
||||
import "cosmos/base/v1beta1/coin.proto";
|
||||
|
||||
// Msg defines the distribution Msg service.
|
||||
service Msg {
|
||||
// SetWithdrawAddress defines a method to change the withdraw address
|
||||
// for a delegator (or validator self-delegation).
|
||||
rpc SetWithdrawAddress(MsgSetWithdrawAddress) returns (MsgSetWithdrawAddressResponse);
|
||||
|
||||
// WithdrawDelegatorReward defines a method to withdraw rewards of delegator
|
||||
// from a single validator.
|
||||
rpc WithdrawDelegatorReward(MsgWithdrawDelegatorReward) returns (MsgWithdrawDelegatorRewardResponse);
|
||||
|
||||
// WithdrawValidatorCommission defines a method to withdraw the
|
||||
// full commission to the validator address.
|
||||
rpc WithdrawValidatorCommission(MsgWithdrawValidatorCommission) returns (MsgWithdrawValidatorCommissionResponse);
|
||||
|
||||
// FundCommunityPool defines a method to allow an account to directly
|
||||
// fund the community pool.
|
||||
rpc FundCommunityPool(MsgFundCommunityPool) returns (MsgFundCommunityPoolResponse);
|
||||
}
|
||||
|
||||
// MsgSetWithdrawAddress sets the withdraw address for
|
||||
// a delegator (or validator self-delegation).
|
||||
message MsgSetWithdrawAddress {
|
||||
|
@ -17,6 +36,9 @@ message MsgSetWithdrawAddress {
|
|||
string withdraw_address = 2 [(gogoproto.moretags) = "yaml:\"withdraw_address\""];
|
||||
}
|
||||
|
||||
// MsgSetWithdrawAddressResponse defines the Msg/SetWithdrawAddress response type.
|
||||
message MsgSetWithdrawAddressResponse { }
|
||||
|
||||
// MsgWithdrawDelegatorReward represents delegation withdrawal to a delegator
|
||||
// from a single validator.
|
||||
message MsgWithdrawDelegatorReward {
|
||||
|
@ -27,6 +49,9 @@ message MsgWithdrawDelegatorReward {
|
|||
string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""];
|
||||
}
|
||||
|
||||
// MsgWithdrawDelegatorRewardResponse defines the Msg/WithdrawDelegatorReward response type.
|
||||
message MsgWithdrawDelegatorRewardResponse { }
|
||||
|
||||
// MsgWithdrawValidatorCommission withdraws the full commission to the validator
|
||||
// address.
|
||||
message MsgWithdrawValidatorCommission {
|
||||
|
@ -36,6 +61,9 @@ message MsgWithdrawValidatorCommission {
|
|||
string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""];
|
||||
}
|
||||
|
||||
// MsgWithdrawValidatorCommissionResponse defines the Msg/WithdrawValidatorCommission response type.
|
||||
message MsgWithdrawValidatorCommissionResponse { }
|
||||
|
||||
// MsgFundCommunityPool allows an account to directly
|
||||
// fund the community pool.
|
||||
message MsgFundCommunityPool {
|
||||
|
@ -45,4 +73,7 @@ message MsgFundCommunityPool {
|
|||
repeated cosmos.base.v1beta1.Coin amount = 1
|
||||
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
|
||||
string depositor = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// MsgFundCommunityPoolResponse defines the Msg/FundCommunityPool response type.
|
||||
message MsgFundCommunityPoolResponse { }
|
||||
|
|
|
@ -8,6 +8,13 @@ import "gogoproto/gogo.proto";
|
|||
import "google/protobuf/any.proto";
|
||||
import "cosmos_proto/cosmos.proto";
|
||||
|
||||
// Msg defines the evidence Msg service.
|
||||
service Msg {
|
||||
// SubmitEvidence submits an arbitrary Evidence of misbehavior such as equivocation or
|
||||
// counterfactual signing.
|
||||
rpc SubmitEvidence(MsgSubmitEvidence) returns (MsgSubmitEvidenceResponse);
|
||||
}
|
||||
|
||||
// MsgSubmitEvidence represents a message that supports submitting arbitrary
|
||||
// Evidence of misbehavior such as equivocation or counterfactual signing.
|
||||
message MsgSubmitEvidence {
|
||||
|
@ -17,3 +24,9 @@ message MsgSubmitEvidence {
|
|||
string submitter = 1;
|
||||
google.protobuf.Any evidence = 2 [(cosmos_proto.accepts_interface) = "Evidence"];
|
||||
}
|
||||
|
||||
// MsgSubmitEvidenceResponse defines the Msg/SubmitEvidence response type.
|
||||
message MsgSubmitEvidenceResponse {
|
||||
// hash defines the hash of the evidence.
|
||||
bytes hash = 4;
|
||||
}
|
||||
|
|
|
@ -8,14 +8,26 @@ import "gogoproto/gogo.proto";
|
|||
import "google/protobuf/any.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types";
|
||||
option (gogoproto.goproto_stringer_all) = false;
|
||||
option (gogoproto.stringer_all) = false;
|
||||
option (gogoproto.goproto_getters_all) = false;
|
||||
|
||||
// Msg defines the bank Msg service.
|
||||
service Msg {
|
||||
// SubmitProposal defines a method to create new proposal given a content.
|
||||
rpc SubmitProposal(MsgSubmitProposal) returns (MsgSubmitProposalResponse);
|
||||
|
||||
// Vote defines a method to add a vote on a specific proposal.
|
||||
rpc Vote(MsgVote) returns (MsgVoteResponse);
|
||||
|
||||
// Deposit defines a method to add deposit on a specific proposal.
|
||||
rpc Deposit(MsgDeposit) returns (MsgDepositResponse);
|
||||
}
|
||||
|
||||
// MsgSubmitProposal defines an sdk.Msg type that supports submitting arbitrary
|
||||
// proposal Content.
|
||||
message MsgSubmitProposal {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_stringer) = false;
|
||||
option (gogoproto.stringer) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
google.protobuf.Any content = 1 [(cosmos_proto.accepts_interface) = "Content"];
|
||||
repeated cosmos.base.v1beta1.Coin initial_deposit = 2 [
|
||||
|
@ -26,21 +38,38 @@ message MsgSubmitProposal {
|
|||
string proposer = 3;
|
||||
}
|
||||
|
||||
// MsgSubmitProposalResponse defines the Msg/SubmitProposal response type.
|
||||
message MsgSubmitProposalResponse {
|
||||
uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""];
|
||||
}
|
||||
|
||||
// MsgVote defines a message to cast a vote.
|
||||
message MsgVote {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_stringer) = false;
|
||||
option (gogoproto.stringer) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""];
|
||||
string voter = 2;
|
||||
VoteOption option = 3;
|
||||
}
|
||||
|
||||
// MsgVoteResponse defines the Msg/Vote response type.
|
||||
message MsgVoteResponse {}
|
||||
|
||||
// MsgDeposit defines a message to submit a deposit to an existing proposal.
|
||||
message MsgDeposit {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_stringer) = false;
|
||||
option (gogoproto.stringer) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""];
|
||||
string depositor = 2;
|
||||
repeated cosmos.base.v1beta1.Coin amount = 3
|
||||
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
|
||||
}
|
||||
}
|
||||
|
||||
// MsgDepositResponse defines the Msg/Deposit response type.
|
||||
message MsgDepositResponse {}
|
||||
|
|
|
@ -6,12 +6,21 @@ option (gogoproto.equal_all) = true;
|
|||
|
||||
import "gogoproto/gogo.proto";
|
||||
|
||||
// MsgUnjail is an sdk.Msg used for unjailing a jailed validator, thus returning
|
||||
// them into the bonded validator set, so they can begin receiving provisions
|
||||
// and rewards again.
|
||||
// Msg defines the slashing Msg service.
|
||||
service Msg {
|
||||
// Unjail defines a method for unjailing a jailed validator, thus returning
|
||||
// them into the bonded validator set, so they can begin receiving provisions
|
||||
// and rewards again.
|
||||
rpc Unjail(MsgUnjail) returns (MsgUnjailResponse);
|
||||
}
|
||||
|
||||
// MsgUnjail defines the Msg/Unjail request type
|
||||
message MsgUnjail {
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
option (gogoproto.goproto_stringer) = true;
|
||||
|
||||
string validator_addr = 1 [(gogoproto.moretags) = "yaml:\"address\"", (gogoproto.jsontag) = "address"];
|
||||
}
|
||||
}
|
||||
|
||||
// MsgUnjailResponse defines the Msg/Unjail response type
|
||||
message MsgUnjailResponse {}
|
|
@ -2,10 +2,13 @@ syntax = "proto3";
|
|||
package cosmos.staking.v1beta1;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "tendermint/types/types.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
import "cosmos_proto/cosmos.proto";
|
||||
import "cosmos/base/v1beta1/coin.proto";
|
||||
import "tendermint/types/types.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types";
|
||||
|
||||
|
@ -73,10 +76,12 @@ message Validator {
|
|||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string operator_address = 1 [(gogoproto.moretags) = "yaml:\"operator_address\""];
|
||||
string consensus_pubkey = 2 [(gogoproto.moretags) = "yaml:\"consensus_pubkey\""];
|
||||
bool jailed = 3;
|
||||
int32 status = 4 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.BondStatus"];
|
||||
string tokens = 5 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
|
||||
google.protobuf.Any consensus_pubkey = 2 [
|
||||
(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey",
|
||||
(gogoproto.moretags) = "yaml:\"consensus_pubkey\""];
|
||||
bool jailed = 3;
|
||||
BondStatus status = 4;
|
||||
string tokens = 5 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
|
||||
string delegator_shares = 6 [
|
||||
(gogoproto.moretags) = "yaml:\"delegator_shares\"",
|
||||
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
|
||||
|
@ -94,6 +99,20 @@ message Validator {
|
|||
];
|
||||
}
|
||||
|
||||
// BondStatus is the status of a validator.
|
||||
enum BondStatus {
|
||||
option (gogoproto.goproto_enum_prefix) = false;
|
||||
|
||||
// UNSPECIFIED defines an invalid validator status.
|
||||
BOND_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "Unspecified"];
|
||||
// UNBONDED defines a validator that is not bonded.
|
||||
BOND_STATUS_UNBONDED = 1 [(gogoproto.enumvalue_customname) = "Unbonded"];
|
||||
// UNBONDING defines a validator that is unbonding.
|
||||
BOND_STATUS_UNBONDING = 2 [(gogoproto.enumvalue_customname) = "Unbonding"];
|
||||
// BONDED defines a validator that is bonded.
|
||||
BOND_STATUS_BONDED = 3 [(gogoproto.enumvalue_customname) = "Bonded"];
|
||||
}
|
||||
|
||||
// ValAddresses defines a repeated set of validator addresses.
|
||||
message ValAddresses {
|
||||
option (gogoproto.goproto_stringer) = false;
|
||||
|
|
|
@ -1,13 +1,38 @@
|
|||
syntax = "proto3";
|
||||
package cosmos.staking.v1beta1;
|
||||
|
||||
import "google/protobuf/any.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "gogoproto/gogo.proto";
|
||||
|
||||
import "cosmos_proto/cosmos.proto";
|
||||
import "cosmos/base/v1beta1/coin.proto";
|
||||
import "cosmos/staking/v1beta1/staking.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types";
|
||||
|
||||
// MsgCreateValidator defines an SDK message for creating a new validator.
|
||||
// Msg defines the staking Msg service.
|
||||
service Msg {
|
||||
// CreateValidator defines a method for creating a new validator.
|
||||
rpc CreateValidator(MsgCreateValidator) returns (MsgCreateValidatorResponse);
|
||||
|
||||
// EditValidator defines a method for editing an existing validator.
|
||||
rpc EditValidator(MsgEditValidator) returns (MsgEditValidatorResponse);
|
||||
|
||||
// Delegate defines a method for performing a delegation of coins
|
||||
// from a delegator to a validator.
|
||||
rpc Delegate(MsgDelegate) returns (MsgDelegateResponse);
|
||||
|
||||
// BeginRedelegate defines a method for performing a redelegation
|
||||
// of coins from a delegator and source validator to a destination validator.
|
||||
rpc BeginRedelegate(MsgBeginRedelegate) returns (MsgBeginRedelegateResponse);
|
||||
|
||||
// Undelegate defines a method for performing an undelegation from a
|
||||
// delegate and a validator.
|
||||
rpc Undelegate(MsgUndelegate) returns (MsgUndelegateResponse);
|
||||
}
|
||||
|
||||
// MsgCreateValidator defines a SDK message for creating a new validator.
|
||||
message MsgCreateValidator {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
@ -21,11 +46,14 @@ message MsgCreateValidator {
|
|||
];
|
||||
string delegator_address = 4 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
|
||||
string validator_address = 5 [(gogoproto.moretags) = "yaml:\"validator_address\""];
|
||||
string pubkey = 6;
|
||||
google.protobuf.Any pubkey = 6 [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey"];
|
||||
cosmos.base.v1beta1.Coin value = 7 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
// MsgEditValidator defines an SDK message for editing an existing validator.
|
||||
// MsgCreateValidatorResponse defines the Msg/CreateValidator response type.
|
||||
message MsgCreateValidatorResponse { }
|
||||
|
||||
// MsgEditValidator defines a SDK message for editing an existing validator.
|
||||
message MsgEditValidator {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
@ -48,7 +76,10 @@ message MsgEditValidator {
|
|||
];
|
||||
}
|
||||
|
||||
// MsgDelegate defines an SDK message for performing a delegation of coins
|
||||
// MsgEditValidatorResponse defines the Msg/EditValidator response type.
|
||||
message MsgEditValidatorResponse { }
|
||||
|
||||
// MsgDelegate defines a SDK message for performing a delegation of coins
|
||||
// from a delegator to a validator.
|
||||
message MsgDelegate {
|
||||
option (gogoproto.equal) = false;
|
||||
|
@ -59,7 +90,10 @@ message MsgDelegate {
|
|||
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
// MsgBeginRedelegate defines an SDK message for performing a redelegation
|
||||
// MsgDelegateResponse defines the Msg/Delegate response type.
|
||||
message MsgDelegateResponse { }
|
||||
|
||||
// MsgBeginRedelegate defines a SDK message for performing a redelegation
|
||||
// of coins from a delegator and source validator to a destination validator.
|
||||
message MsgBeginRedelegate {
|
||||
option (gogoproto.equal) = false;
|
||||
|
@ -71,7 +105,12 @@ message MsgBeginRedelegate {
|
|||
cosmos.base.v1beta1.Coin amount = 4 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
// MsgUndelegate defines an SDK message for performing an undelegation from a
|
||||
// MsgBeginRedelegateResponse defines the Msg/BeginRedelegate response type.
|
||||
message MsgBeginRedelegateResponse {
|
||||
google.protobuf.Timestamp completion_time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
|
||||
}
|
||||
|
||||
// MsgUndelegate defines a SDK message for performing an undelegation from a
|
||||
// delegate and a validator.
|
||||
message MsgUndelegate {
|
||||
option (gogoproto.equal) = false;
|
||||
|
@ -80,4 +119,9 @@ message MsgUndelegate {
|
|||
string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
|
||||
string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""];
|
||||
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
|
||||
}
|
||||
}
|
||||
|
||||
// MsgUndelegateResponse defines the Msg/Undelegate response type.
|
||||
message MsgUndelegateResponse {
|
||||
google.protobuf.Timestamp completion_time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
|
||||
}
|
||||
|
|
|
@ -6,6 +6,15 @@ import "cosmos/base/v1beta1/coin.proto";
|
|||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/auth/vesting/types";
|
||||
|
||||
|
||||
// Msg defines the bank Msg service.
|
||||
service Msg {
|
||||
// CreateVestingAccount defines a method that enables creating a vesting
|
||||
// account.
|
||||
rpc CreateVestingAccount(MsgCreateVestingAccount) returns (MsgCreateVestingAccountResponse);
|
||||
}
|
||||
|
||||
|
||||
// MsgCreateVestingAccount defines a message that enables creating a vesting
|
||||
// account.
|
||||
message MsgCreateVestingAccount {
|
||||
|
@ -19,3 +28,6 @@ message MsgCreateVestingAccount {
|
|||
int64 end_time = 4 [(gogoproto.moretags) = "yaml:\"end_time\""];
|
||||
bool delayed = 5;
|
||||
}
|
||||
|
||||
// MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type.
|
||||
message MsgCreateVestingAccountResponse { }
|
|
@ -4,34 +4,6 @@ package ibc.applications.transfer.v1;
|
|||
option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types";
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "cosmos/base/v1beta1/coin.proto";
|
||||
import "ibc/core/client/v1/client.proto";
|
||||
|
||||
// MsgTransfer defines a msg to transfer fungible tokens (i.e Coins) between
|
||||
// ICS20 enabled chains. See ICS Spec here:
|
||||
// https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#data-structures
|
||||
message MsgTransfer {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// the port on which the packet will be sent
|
||||
string source_port = 1 [(gogoproto.moretags) = "yaml:\"source_port\""];
|
||||
// the channel by which the packet will be sent
|
||||
string source_channel = 2 [(gogoproto.moretags) = "yaml:\"source_channel\""];
|
||||
// the tokens to be transferred
|
||||
cosmos.base.v1beta1.Coin token = 3 [(gogoproto.nullable) = false];
|
||||
// the sender address
|
||||
string sender = 4;
|
||||
// the recipient address on the destination chain
|
||||
string receiver = 5;
|
||||
// Timeout height relative to the current block height.
|
||||
// The timeout is disabled when set to 0.
|
||||
ibc.core.client.v1.Height timeout_height = 6
|
||||
[(gogoproto.moretags) = "yaml:\"timeout_height\"", (gogoproto.nullable) = false];
|
||||
// Timeout timestamp (in nanoseconds) relative to the current block timestamp.
|
||||
// The timeout is disabled when set to 0.
|
||||
uint64 timeout_timestamp = 7 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""];
|
||||
}
|
||||
|
||||
// FungibleTokenPacketData defines a struct for the packet payload
|
||||
// See FungibleTokenPacketData spec:
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
syntax = "proto3";
|
||||
package ibc.applications.transfer.v1;
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types";
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "cosmos/base/v1beta1/coin.proto";
|
||||
import "ibc/core/client/v1/client.proto";
|
||||
|
||||
// Msg defines the ibc/transfer Msg service.
|
||||
service Msg {
|
||||
// Transfer defines a rpc handler method for MsgTransfer.
|
||||
rpc Transfer(MsgTransfer) returns (MsgTransferResponse);
|
||||
}
|
||||
|
||||
// MsgTransfer defines a msg to transfer fungible tokens (i.e Coins) between
|
||||
// ICS20 enabled chains. See ICS Spec here:
|
||||
// https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#data-structures
|
||||
message MsgTransfer {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// the port on which the packet will be sent
|
||||
string source_port = 1 [(gogoproto.moretags) = "yaml:\"source_port\""];
|
||||
// the channel by which the packet will be sent
|
||||
string source_channel = 2 [(gogoproto.moretags) = "yaml:\"source_channel\""];
|
||||
// the tokens to be transferred
|
||||
cosmos.base.v1beta1.Coin token = 3 [(gogoproto.nullable) = false];
|
||||
// the sender address
|
||||
string sender = 4;
|
||||
// the recipient address on the destination chain
|
||||
string receiver = 5;
|
||||
// Timeout height relative to the current block height.
|
||||
// The timeout is disabled when set to 0.
|
||||
ibc.core.client.v1.Height timeout_height = 6
|
||||
[(gogoproto.moretags) = "yaml:\"timeout_height\"", (gogoproto.nullable) = false];
|
||||
// Timeout timestamp (in nanoseconds) relative to the current block timestamp.
|
||||
// The timeout is disabled when set to 0.
|
||||
uint64 timeout_timestamp = 7 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""];
|
||||
}
|
||||
|
||||
// MsgTransferResponse defines the Msg/Transfer response type.
|
||||
message MsgTransferResponse { }
|
|
@ -6,142 +6,6 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types";
|
|||
import "gogoproto/gogo.proto";
|
||||
import "ibc/core/client/v1/client.proto";
|
||||
|
||||
// MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It
|
||||
// is called by a relayer on Chain A.
|
||||
message MsgChannelOpenInit {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
|
||||
string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
|
||||
Channel channel = 3 [(gogoproto.nullable) = false];
|
||||
string signer = 4;
|
||||
}
|
||||
|
||||
// MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel
|
||||
// on Chain B.
|
||||
message MsgChannelOpenTry {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
|
||||
string desired_channel_id = 2 [(gogoproto.moretags) = "yaml:\"desired_channel_id\""];
|
||||
string counterparty_chosen_channel_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_chosen_channel_id\""];
|
||||
Channel channel = 4 [(gogoproto.nullable) = false];
|
||||
string counterparty_version = 5 [(gogoproto.moretags) = "yaml:\"counterparty_version\""];
|
||||
bytes proof_init = 6 [(gogoproto.moretags) = "yaml:\"proof_init\""];
|
||||
ibc.core.client.v1.Height proof_height = 7
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 8;
|
||||
}
|
||||
|
||||
// MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge
|
||||
// the change of channel state to TRYOPEN on Chain B.
|
||||
message MsgChannelOpenAck {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
|
||||
string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
|
||||
string counterparty_channel_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_channel_id\""];
|
||||
string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""];
|
||||
bytes proof_try = 5 [(gogoproto.moretags) = "yaml:\"proof_try\""];
|
||||
ibc.core.client.v1.Height proof_height = 6
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 7;
|
||||
}
|
||||
|
||||
// MsgChannelOpenConfirm defines a msg sent by a Relayer to Chain B to
|
||||
// acknowledge the change of channel state to OPEN on Chain A.
|
||||
message MsgChannelOpenConfirm {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
|
||||
string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
|
||||
bytes proof_ack = 3 [(gogoproto.moretags) = "yaml:\"proof_ack\""];
|
||||
ibc.core.client.v1.Height proof_height = 4
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 5;
|
||||
}
|
||||
|
||||
// MsgChannelCloseInit defines a msg sent by a Relayer to Chain A
|
||||
// to close a channel with Chain B.
|
||||
message MsgChannelCloseInit {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
|
||||
string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
|
||||
string signer = 3;
|
||||
}
|
||||
|
||||
// MsgChannelCloseConfirm defines a msg sent by a Relayer to Chain B
|
||||
// to acknowledge the change of channel state to CLOSED on Chain A.
|
||||
message MsgChannelCloseConfirm {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
|
||||
string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
|
||||
bytes proof_init = 3 [(gogoproto.moretags) = "yaml:\"proof_init\""];
|
||||
ibc.core.client.v1.Height proof_height = 4
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 5;
|
||||
}
|
||||
|
||||
// MsgRecvPacket receives incoming IBC packet
|
||||
message MsgRecvPacket {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
Packet packet = 1 [(gogoproto.nullable) = false];
|
||||
bytes proof = 2;
|
||||
ibc.core.client.v1.Height proof_height = 3
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 4;
|
||||
}
|
||||
|
||||
// MsgTimeout receives timed-out packet
|
||||
message MsgTimeout {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
Packet packet = 1 [(gogoproto.nullable) = false];
|
||||
bytes proof = 2;
|
||||
ibc.core.client.v1.Height proof_height = 3
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
uint64 next_sequence_recv = 4 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""];
|
||||
string signer = 5;
|
||||
}
|
||||
|
||||
// MsgTimeoutOnClose timed-out packet upon counterparty channel closure.
|
||||
message MsgTimeoutOnClose {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
Packet packet = 1 [(gogoproto.nullable) = false];
|
||||
bytes proof = 2;
|
||||
bytes proof_close = 3 [(gogoproto.moretags) = "yaml:\"proof_close\""];
|
||||
ibc.core.client.v1.Height proof_height = 4
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
uint64 next_sequence_recv = 5 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""];
|
||||
string signer = 6;
|
||||
}
|
||||
|
||||
// MsgAcknowledgement receives incoming IBC acknowledgement
|
||||
message MsgAcknowledgement {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
Packet packet = 1 [(gogoproto.nullable) = false];
|
||||
bytes acknowledgement = 2;
|
||||
bytes proof = 3;
|
||||
ibc.core.client.v1.Height proof_height = 4
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 5;
|
||||
}
|
||||
|
||||
// Channel defines pipeline for exactly-once packet delivery between specific
|
||||
// modules on separate blockchains, which has at least one end capable of
|
||||
// sending packets and one end capable of receiving packets.
|
||||
|
@ -278,4 +142,4 @@ message Acknowledgement {
|
|||
bytes result = 21;
|
||||
string error = 22;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
syntax = "proto3";
|
||||
package ibc.core.channel.v1;
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types";
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "ibc/core/client/v1/client.proto";
|
||||
import "ibc/core/channel/v1/channel.proto";
|
||||
|
||||
// Msg defines the ibc/channel Msg service.
|
||||
service Msg {
|
||||
// ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit.
|
||||
rpc ChannelOpenInit(MsgChannelOpenInit) returns (MsgChannelOpenInitResponse);
|
||||
|
||||
// ChannelOpenTry defines a rpc handler method for MsgChannelOpenTry.
|
||||
rpc ChannelOpenTry(MsgChannelOpenTry) returns (MsgChannelOpenTryResponse);
|
||||
|
||||
// ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck.
|
||||
rpc ChannelOpenAck(MsgChannelOpenAck) returns (MsgChannelOpenAckResponse);
|
||||
|
||||
// ChannelOpenConfirm defines a rpc handler method for MsgChannelOpenConfirm.
|
||||
rpc ChannelOpenConfirm(MsgChannelOpenConfirm) returns (MsgChannelOpenConfirmResponse);
|
||||
|
||||
// ChannelCloseInit defines a rpc handler method for MsgChannelCloseInit.
|
||||
rpc ChannelCloseInit(MsgChannelCloseInit) returns (MsgChannelCloseInitResponse);
|
||||
|
||||
// ChannelCloseConfirm defines a rpc handler method for MsgChannelCloseConfirm.
|
||||
rpc ChannelCloseConfirm(MsgChannelCloseConfirm) returns (MsgChannelCloseConfirmResponse);
|
||||
|
||||
// RecvPacket defines a rpc handler method for MsgRecvPacket.
|
||||
rpc RecvPacket(MsgRecvPacket) returns (MsgRecvPacketResponse);
|
||||
|
||||
// Timeout defines a rpc handler method for MsgTimeout.
|
||||
rpc Timeout(MsgTimeout) returns (MsgTimeoutResponse);
|
||||
|
||||
// TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose.
|
||||
rpc TimeoutOnClose(MsgTimeoutOnClose) returns (MsgTimeoutOnCloseResponse);
|
||||
|
||||
// Acknowledgement defines a rpc handler method for MsgAcknowledgement.
|
||||
rpc Acknowledgement(MsgAcknowledgement) returns (MsgAcknowledgementResponse);
|
||||
}
|
||||
|
||||
// MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It
|
||||
// is called by a relayer on Chain A.
|
||||
message MsgChannelOpenInit {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
|
||||
string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
|
||||
Channel channel = 3 [(gogoproto.nullable) = false];
|
||||
string signer = 4;
|
||||
}
|
||||
|
||||
// MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type.
|
||||
message MsgChannelOpenInitResponse {}
|
||||
|
||||
// MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel
|
||||
// on Chain B.
|
||||
message MsgChannelOpenTry {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
|
||||
string desired_channel_id = 2 [(gogoproto.moretags) = "yaml:\"desired_channel_id\""];
|
||||
string counterparty_chosen_channel_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_chosen_channel_id\""];
|
||||
Channel channel = 4 [(gogoproto.nullable) = false];
|
||||
string counterparty_version = 5 [(gogoproto.moretags) = "yaml:\"counterparty_version\""];
|
||||
bytes proof_init = 6 [(gogoproto.moretags) = "yaml:\"proof_init\""];
|
||||
ibc.core.client.v1.Height proof_height = 7
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 8;
|
||||
}
|
||||
|
||||
// MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type.
|
||||
message MsgChannelOpenTryResponse {}
|
||||
|
||||
// MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge
|
||||
// the change of channel state to TRYOPEN on Chain B.
|
||||
message MsgChannelOpenAck {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
|
||||
string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
|
||||
string counterparty_channel_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_channel_id\""];
|
||||
string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""];
|
||||
bytes proof_try = 5 [(gogoproto.moretags) = "yaml:\"proof_try\""];
|
||||
ibc.core.client.v1.Height proof_height = 6
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 7;
|
||||
}
|
||||
|
||||
// MsgChannelOpenAckResponse defines the Msg/ChannelOpenAck response type.
|
||||
message MsgChannelOpenAckResponse {}
|
||||
|
||||
// MsgChannelOpenConfirm defines a msg sent by a Relayer to Chain B to
|
||||
// acknowledge the change of channel state to OPEN on Chain A.
|
||||
message MsgChannelOpenConfirm {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
|
||||
string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
|
||||
bytes proof_ack = 3 [(gogoproto.moretags) = "yaml:\"proof_ack\""];
|
||||
ibc.core.client.v1.Height proof_height = 4
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 5;
|
||||
}
|
||||
|
||||
// MsgChannelOpenConfirmResponse defines the Msg/ChannelOpenConfirm response type.
|
||||
message MsgChannelOpenConfirmResponse {}
|
||||
|
||||
// MsgChannelCloseInit defines a msg sent by a Relayer to Chain A
|
||||
// to close a channel with Chain B.
|
||||
message MsgChannelCloseInit {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
|
||||
string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
|
||||
string signer = 3;
|
||||
}
|
||||
|
||||
// MsgChannelCloseInitResponse defines the Msg/ChannelCloseInit response type.
|
||||
message MsgChannelCloseInitResponse {}
|
||||
|
||||
// MsgChannelCloseConfirm defines a msg sent by a Relayer to Chain B
|
||||
// to acknowledge the change of channel state to CLOSED on Chain A.
|
||||
message MsgChannelCloseConfirm {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""];
|
||||
string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""];
|
||||
bytes proof_init = 3 [(gogoproto.moretags) = "yaml:\"proof_init\""];
|
||||
ibc.core.client.v1.Height proof_height = 4
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 5;
|
||||
}
|
||||
|
||||
// MsgChannelCloseConfirmResponse defines the Msg/ChannelCloseConfirm response type.
|
||||
message MsgChannelCloseConfirmResponse {}
|
||||
|
||||
// MsgRecvPacket receives incoming IBC packet
|
||||
message MsgRecvPacket {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
Packet packet = 1 [(gogoproto.nullable) = false];
|
||||
bytes proof = 2;
|
||||
ibc.core.client.v1.Height proof_height = 3
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 4;
|
||||
}
|
||||
|
||||
// MsgRecvPacketResponse defines the Msg/RecvPacket response type.
|
||||
message MsgRecvPacketResponse {}
|
||||
|
||||
// MsgTimeout receives timed-out packet
|
||||
message MsgTimeout {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
Packet packet = 1 [(gogoproto.nullable) = false];
|
||||
bytes proof = 2;
|
||||
ibc.core.client.v1.Height proof_height = 3
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
uint64 next_sequence_recv = 4 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""];
|
||||
string signer = 5;
|
||||
}
|
||||
|
||||
// MsgTimeoutResponse defines the Msg/Timeout response type.
|
||||
message MsgTimeoutResponse {}
|
||||
|
||||
// MsgTimeoutOnClose timed-out packet upon counterparty channel closure.
|
||||
message MsgTimeoutOnClose {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
Packet packet = 1 [(gogoproto.nullable) = false];
|
||||
bytes proof = 2;
|
||||
bytes proof_close = 3 [(gogoproto.moretags) = "yaml:\"proof_close\""];
|
||||
ibc.core.client.v1.Height proof_height = 4
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
uint64 next_sequence_recv = 5 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""];
|
||||
string signer = 6;
|
||||
}
|
||||
|
||||
// MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type.
|
||||
message MsgTimeoutOnCloseResponse {}
|
||||
|
||||
// MsgAcknowledgement receives incoming IBC acknowledgement
|
||||
message MsgAcknowledgement {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
Packet packet = 1 [(gogoproto.nullable) = false];
|
||||
bytes acknowledgement = 2;
|
||||
bytes proof = 3;
|
||||
ibc.core.client.v1.Height proof_height = 4
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 5;
|
||||
}
|
||||
|
||||
// MsgAcknowledgementResponse defines the Msg/Acknowledgement response type.
|
||||
message MsgAcknowledgementResponse {}
|
|
@ -6,6 +6,91 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types";
|
|||
import "gogoproto/gogo.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
|
||||
// Msg defines the ibc/client Msg service.
|
||||
service Msg {
|
||||
// CreateClient defines a rpc handler method for MsgCreateClient.
|
||||
rpc CreateClient(MsgCreateClient) returns (MsgCreateClientResponse);
|
||||
|
||||
// UpdateClient defines a rpc handler method for MsgUpdateClient.
|
||||
rpc UpdateClient(MsgUpdateClient) returns (MsgUpdateClientResponse);
|
||||
|
||||
// UpgradeClient defines a rpc handler method for MsgUpgradeClient.
|
||||
rpc UpgradeClient(MsgUpgradeClient) returns (MsgUpgradeClientResponse);
|
||||
|
||||
// SubmitMisbehaviour defines a rpc handler method for MsgSubmitMisbehaviour.
|
||||
rpc SubmitMisbehaviour(MsgSubmitMisbehaviour) returns (MsgSubmitMisbehaviourResponse);
|
||||
}
|
||||
|
||||
// MsgCreateClient defines a message to create an IBC client
|
||||
message MsgCreateClient {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// client unique identifier
|
||||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
// light client state
|
||||
google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""];
|
||||
// consensus state associated with the client that corresponds to a given
|
||||
// height.
|
||||
google.protobuf.Any consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""];
|
||||
// signer address
|
||||
string signer = 4;
|
||||
}
|
||||
|
||||
// MsgCreateClientResponse defines the Msg/CreateClient response type.
|
||||
message MsgCreateClientResponse { }
|
||||
|
||||
// MsgUpdateClient defines an sdk.Msg to update a IBC client state using
|
||||
// the given header.
|
||||
message MsgUpdateClient {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// client unique identifier
|
||||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
// header to update the light client
|
||||
google.protobuf.Any header = 2;
|
||||
// signer address
|
||||
string signer = 3;
|
||||
}
|
||||
|
||||
// MsgUpdateClientResponse defines the Msg/UpdateClient response type.
|
||||
message MsgUpdateClientResponse { }
|
||||
|
||||
// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client state
|
||||
message MsgUpgradeClient {
|
||||
// client unique identifier
|
||||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
// upgraded client state
|
||||
google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""];
|
||||
// height at which old chain halts and upgrades (i.e last block executed)
|
||||
Height upgrade_height = 3 [(gogoproto.moretags) = "yaml:\"upgrade_height\""];
|
||||
// proof that old chain committed to new client
|
||||
bytes proof_upgrade = 4 [(gogoproto.moretags) = "yaml:\"proof_upgrade\""];
|
||||
// signer address
|
||||
string signer = 5;
|
||||
}
|
||||
|
||||
// MsgUpgradeClientResponse defines the Msg/UpgradeClient response type.
|
||||
message MsgUpgradeClientResponse { }
|
||||
|
||||
// MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for
|
||||
// light client misbehaviour.
|
||||
message MsgSubmitMisbehaviour {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// client unique identifier
|
||||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
// misbehaviour used for freezing the light client
|
||||
google.protobuf.Any misbehaviour = 2;
|
||||
// signer address
|
||||
string signer = 3;
|
||||
}
|
||||
|
||||
// MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response type.
|
||||
message MsgSubmitMisbehaviourResponse { }
|
||||
|
||||
// IdentifiedClientState defines a client state with an additional client
|
||||
// identifier field.
|
||||
message IdentifiedClientState {
|
||||
|
@ -48,64 +133,6 @@ message ClientUpdateProposal {
|
|||
google.protobuf.Any header = 4;
|
||||
}
|
||||
|
||||
// MsgCreateClient defines a message to create an IBC client
|
||||
message MsgCreateClient {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// client unique identifier
|
||||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
// light client state
|
||||
google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""];
|
||||
// consensus state associated with the client that corresponds to a given
|
||||
// height.
|
||||
google.protobuf.Any consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""];
|
||||
// signer address
|
||||
string signer = 4;
|
||||
}
|
||||
|
||||
// MsgUpdateClient defines an sdk.Msg to update a IBC client state using
|
||||
// the given header.
|
||||
message MsgUpdateClient {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// client unique identifier
|
||||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
// header to update the light client
|
||||
google.protobuf.Any header = 2;
|
||||
// signer address
|
||||
string signer = 3;
|
||||
}
|
||||
|
||||
// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client state
|
||||
message MsgUpgradeClient {
|
||||
// client unique identifier
|
||||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
// upgraded client state
|
||||
google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""];
|
||||
// height at which old chain halts and upgrades (i.e last block executed)
|
||||
Height upgrade_height = 3 [(gogoproto.moretags) = "yaml:\"upgrade_height\""];
|
||||
// proof that old chain committed to new client
|
||||
bytes proof_upgrade = 4 [(gogoproto.moretags) = "yaml:\"proof_upgrade\""];
|
||||
// signer address
|
||||
string signer = 5;
|
||||
}
|
||||
|
||||
// MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for
|
||||
// light client misbehaviour.
|
||||
message MsgSubmitMisbehaviour {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// client unique identifier
|
||||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
// misbehaviour used for freezing the light client
|
||||
google.protobuf.Any misbehaviour = 2;
|
||||
// signer address
|
||||
string signer = 3;
|
||||
}
|
||||
|
||||
// Height is a monotonically increasing data type
|
||||
// that can be compared against another Height for the purposes of updating and
|
||||
// freezing clients
|
||||
|
|
|
@ -4,86 +4,7 @@ package ibc.core.connection.v1;
|
|||
option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types";
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
import "ibc/core/commitment/v1/commitment.proto";
|
||||
import "ibc/core/client/v1/client.proto";
|
||||
|
||||
// MsgConnectionOpenInit defines the msg sent by an account on Chain A to
|
||||
// initialize a connection with Chain B.
|
||||
message MsgConnectionOpenInit {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""];
|
||||
Counterparty counterparty = 3 [(gogoproto.nullable) = false];
|
||||
string version = 4;
|
||||
string signer = 5;
|
||||
}
|
||||
|
||||
// MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a
|
||||
// connection on Chain B.
|
||||
message MsgConnectionOpenTry {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
string desired_connection_id = 2 [(gogoproto.moretags) = "yaml:\"desired_connection_id\""];
|
||||
string counterparty_chosen_connection_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_chosen_connection_id\""];
|
||||
google.protobuf.Any client_state = 4 [(gogoproto.moretags) = "yaml:\"client_state\""];
|
||||
Counterparty counterparty = 5 [(gogoproto.nullable) = false];
|
||||
repeated string counterparty_versions = 6 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""];
|
||||
ibc.core.client.v1.Height proof_height = 7
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
// proof of the initialization the connection on Chain A: `UNITIALIZED ->
|
||||
// INIT`
|
||||
bytes proof_init = 8 [(gogoproto.moretags) = "yaml:\"proof_init\""];
|
||||
// proof of client state included in message
|
||||
bytes proof_client = 9 [(gogoproto.moretags) = "yaml:\"proof_client\""];
|
||||
// proof of client consensus state
|
||||
bytes proof_consensus = 10 [(gogoproto.moretags) = "yaml:\"proof_consensus\""];
|
||||
ibc.core.client.v1.Height consensus_height = 11
|
||||
[(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 12;
|
||||
}
|
||||
|
||||
// MsgConnectionOpenAck defines a msg sent by a Relayer to Chain A to
|
||||
// acknowledge the change of connection state to TRYOPEN on Chain B.
|
||||
message MsgConnectionOpenAck {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""];
|
||||
string counterparty_connection_id = 2 [(gogoproto.moretags) = "yaml:\"counterparty_connection_id\""];
|
||||
string version = 3;
|
||||
google.protobuf.Any client_state = 4 [(gogoproto.moretags) = "yaml:\"client_state\""];
|
||||
ibc.core.client.v1.Height proof_height = 5
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
// proof of the initialization the connection on Chain B: `UNITIALIZED ->
|
||||
// TRYOPEN`
|
||||
bytes proof_try = 6 [(gogoproto.moretags) = "yaml:\"proof_try\""];
|
||||
// proof of client state included in message
|
||||
bytes proof_client = 7 [(gogoproto.moretags) = "yaml:\"proof_client\""];
|
||||
// proof of client consensus state
|
||||
bytes proof_consensus = 8 [(gogoproto.moretags) = "yaml:\"proof_consensus\""];
|
||||
ibc.core.client.v1.Height consensus_height = 9
|
||||
[(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 10;
|
||||
}
|
||||
|
||||
// MsgConnectionOpenConfirm defines a msg sent by a Relayer to Chain B to
|
||||
// acknowledge the change of connection state to OPEN on Chain A.
|
||||
message MsgConnectionOpenConfirm {
|
||||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""];
|
||||
// proof for the change of the connection state on Chain A: `INIT -> OPEN`
|
||||
bytes proof_ack = 2 [(gogoproto.moretags) = "yaml:\"proof_ack\""];
|
||||
ibc.core.client.v1.Height proof_height = 3
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 4;
|
||||
}
|
||||
|
||||
// ICS03 - Connection Data Structures as defined in
|
||||
// https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#data-structures
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue