mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-21 20:22:51 +00:00
Compare commits
93 Commits
wb/release
...
v0.34.21
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a41c5eec11 | ||
|
|
bca737c2d3 | ||
|
|
58669ae8c1 | ||
|
|
1f0cf7762b | ||
|
|
dd86d3e8bb | ||
|
|
27404910de | ||
|
|
08f55593dd | ||
|
|
9fdbd2e466 | ||
|
|
a80c6a229a | ||
|
|
d513c925dd | ||
|
|
dad439f115 | ||
|
|
fbd754b4de | ||
|
|
65367d7e94 | ||
|
|
c72335712b | ||
|
|
fb5cd16de2 | ||
|
|
708a62fc31 | ||
|
|
7e902dc79a | ||
|
|
0846f3e4c7 | ||
|
|
46badfabd9 | ||
|
|
eb465a3f4f | ||
|
|
d6be59788b | ||
|
|
f9f3bed808 | ||
|
|
64dfeb775c | ||
|
|
6688db7be1 | ||
|
|
d32df22c8b | ||
|
|
223ece93c8 | ||
|
|
ba1711e706 | ||
|
|
8df725f92f | ||
|
|
2b3737333f | ||
|
|
bbb5f3bfef | ||
|
|
d6b413ff8e | ||
|
|
7b615f8123 | ||
|
|
7d9447198c | ||
|
|
5276400c30 | ||
|
|
493dd69f31 | ||
|
|
1d9d947d88 | ||
|
|
479bdd71e6 | ||
|
|
17f4ea3680 | ||
|
|
5c32cfa00e | ||
|
|
5e354a3a57 | ||
|
|
9e14e954f9 | ||
|
|
6b7d30cf37 | ||
|
|
25101d1116 | ||
|
|
b83cc0aeda | ||
|
|
4a1df4911d | ||
|
|
a3cc3d98b9 | ||
|
|
fe024521ef | ||
|
|
02def9ca64 | ||
|
|
ce2409f3ff | ||
|
|
30915e9337 | ||
|
|
8a7affe3a0 | ||
|
|
851f404305 | ||
|
|
f63496dcd6 | ||
|
|
044b12585f | ||
|
|
ac2e7fab3d | ||
|
|
e6f0711648 | ||
|
|
603a1d6610 | ||
|
|
ad72896ca5 | ||
|
|
9afdac6b52 | ||
|
|
a694dad540 | ||
|
|
9d1556a5bc | ||
|
|
7ae73be891 | ||
|
|
bbb1506f5e | ||
|
|
7cb014cf27 | ||
|
|
004967f962 | ||
|
|
6670c24e5f | ||
|
|
b685ec7f2d | ||
|
|
016c91b50f | ||
|
|
34f23ab88a | ||
|
|
aef0bd874d | ||
|
|
d2bd4471bc | ||
|
|
c7006af6fd | ||
|
|
972eee6ebc | ||
|
|
b06540b5ff | ||
|
|
d1213f7e5f | ||
|
|
624bbac8f6 | ||
|
|
874c9a0951 | ||
|
|
986f8d6532 | ||
|
|
e40e7ea46e | ||
|
|
7fa34c63af | ||
|
|
da6ec8f082 | ||
|
|
efddab0734 | ||
|
|
3454f8cb89 | ||
|
|
2f231ceb95 | ||
|
|
6e85f46d9a | ||
|
|
89139784c5 | ||
|
|
ecf19029b4 | ||
|
|
9ae5797866 | ||
|
|
07670318a9 | ||
|
|
1e32a149dd | ||
|
|
2c553d735a | ||
|
|
799489e474 | ||
|
|
66b1a3ee4c |
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
@@ -7,4 +7,5 @@
|
||||
# global owners are only requested if there isn't a more specific
|
||||
# codeowner specified below. For this reason, the global codeowners
|
||||
# are often repeated in package-level definitions.
|
||||
* @ebuchman @cmwaters @tychoish @williambanfield @creachadair
|
||||
* @ebuchman @tendermint/tendermint-engineering
|
||||
|
||||
|
||||
37
.github/ISSUE_TEMPLATE/proposal.md
vendored
Normal file
37
.github/ISSUE_TEMPLATE/proposal.md
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
name: Protocol Change Proposal
|
||||
about: Create a proposal to request a change to the protocol
|
||||
|
||||
---
|
||||
|
||||
<!-- < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < ☺
|
||||
v ✰ Thanks for opening an issue! ✰
|
||||
v Before smashing the submit button please review the template.
|
||||
v Word of caution: Under-specified proposals may be rejected summarily
|
||||
☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -->
|
||||
|
||||
# Protocol Change Proposal
|
||||
|
||||
## Summary
|
||||
|
||||
<!-- Short, concise description of the proposed change -->
|
||||
|
||||
## Problem Definition
|
||||
|
||||
<!-- Why do we need this change?
|
||||
What problems may be addressed by introducing this change?
|
||||
What benefits does Tendermint stand to gain by including this change?
|
||||
Are there any disadvantages of including this change? -->
|
||||
|
||||
## Proposal
|
||||
|
||||
<!-- Detailed description of requirements of implementation -->
|
||||
|
||||
____
|
||||
|
||||
#### For Admin Use
|
||||
|
||||
- [ ] Not duplicate issue
|
||||
- [ ] Appropriate labels applied
|
||||
- [ ] Appropriate contributors tagged
|
||||
- [ ] Contributor assigned/self-assigned
|
||||
27
.github/dependabot.yml
vendored
27
.github/dependabot.yml
vendored
@@ -1,27 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "11:00"
|
||||
open-pull-requests-limit: 10
|
||||
- package-ecosystem: npm
|
||||
directory: "/docs"
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "11:00"
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- fadeev
|
||||
- package-ecosystem: gomod
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "11:00"
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- melekes
|
||||
- tessr
|
||||
labels:
|
||||
- T:dependencies
|
||||
75
.github/workflows/check-generated.yml
vendored
Normal file
75
.github/workflows/check-generated.yml
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
# Verify that generated code is up-to-date.
|
||||
#
|
||||
# Note that we run these checks regardless whether the input files have
|
||||
# changed, because generated code can change in response to toolchain updates
|
||||
# even if no files in the repository are modified.
|
||||
name: Check generated code
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check-mocks:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.18'
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: "Check generated mocks"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
readonly MOCKERY=2.12.3 # N.B. no leading "v"
|
||||
curl -sL "https://github.com/vektra/mockery/releases/download/v${MOCKERY}/mockery_${MOCKERY}_Linux_x86_64.tar.gz" | tar -C /usr/local/bin -xzf -
|
||||
make mockery 2>/dev/null
|
||||
|
||||
if ! git diff --stat --exit-code ; then
|
||||
echo ">> ERROR:"
|
||||
echo ">>"
|
||||
echo ">> Generated mocks require update (either Mockery or source files may have changed)."
|
||||
echo ">> Ensure your tools are up-to-date, re-run 'make mockery' and update this PR."
|
||||
echo ">>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
check-proto:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.18'
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 1 # we need a .git directory to run git diff
|
||||
|
||||
- name: "Check protobuf generated code"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
# Install buf and gogo tools, so that differences that arise from
|
||||
# toolchain differences are also caught.
|
||||
readonly tools="$(mktemp -d)"
|
||||
export PATH="${PATH}:${tools}/bin"
|
||||
export GOBIN="${tools}/bin"
|
||||
|
||||
go install github.com/bufbuild/buf/cmd/buf
|
||||
go install github.com/gogo/protobuf/protoc-gen-gogofaster@latest
|
||||
|
||||
make proto-gen
|
||||
|
||||
if ! git diff --stat --exit-code ; then
|
||||
echo ">> ERROR:"
|
||||
echo ">>"
|
||||
echo ">> Protobuf generated code requires update (either tools or .proto files may have changed)."
|
||||
echo ">> Ensure your tools are up-to-date, re-run 'make proto-gen' and update this PR."
|
||||
echo ">>"
|
||||
exit 1
|
||||
fi
|
||||
44
.github/workflows/coverage.yml
vendored
44
.github/workflows/coverage.yml
vendored
@@ -10,25 +10,25 @@ jobs:
|
||||
split-test-files:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Create a file with all the pkgs
|
||||
run: go list ./... > pkgs.txt
|
||||
- name: Split pkgs into 4 files
|
||||
run: split -d -n l/4 pkgs.txt pkgs.txt.part.
|
||||
# cache multiple
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "${{ github.sha }}-00"
|
||||
path: ./pkgs.txt.part.00
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "${{ github.sha }}-01"
|
||||
path: ./pkgs.txt.part.01
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "${{ github.sha }}-02"
|
||||
path: ./pkgs.txt.part.02
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "${{ github.sha }}-03"
|
||||
path: ./pkgs.txt.part.03
|
||||
@@ -42,11 +42,11 @@ jobs:
|
||||
goarch: ["arm", "amd64"]
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "^1.15.4"
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
go-version: "1.18"
|
||||
- uses: actions/checkout@v3
|
||||
- uses: technote-space/get-diff-action@v6
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
@@ -64,17 +64,17 @@ jobs:
|
||||
matrix:
|
||||
part: ["00", "01", "02", "03"]
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "^1.15.4"
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
go-version: "1.18"
|
||||
- uses: actions/checkout@v3
|
||||
- uses: technote-space/get-diff-action@v6
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- uses: actions/download-artifact@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: "${{ github.sha }}-${{ matrix.part }}"
|
||||
if: env.GIT_DIFF
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
run: |
|
||||
cat pkgs.txt.part.${{ matrix.part }} | xargs go test -mod=readonly -timeout 8m -race -coverprofile=${{ matrix.part }}profile.out -covermode=atomic
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "${{ github.sha }}-${{ matrix.part }}-coverage"
|
||||
path: ./${{ matrix.part }}profile.out
|
||||
@@ -91,33 +91,33 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: tests
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
- uses: actions/checkout@v3
|
||||
- uses: technote-space/get-diff-action@v6
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- uses: actions/download-artifact@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: "${{ github.sha }}-00-coverage"
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/download-artifact@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: "${{ github.sha }}-01-coverage"
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/download-artifact@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: "${{ github.sha }}-02-coverage"
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/download-artifact@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: "${{ github.sha }}-03-coverage"
|
||||
if: env.GIT_DIFF
|
||||
- run: |
|
||||
cat ./*profile.out | grep -v "mode: atomic" >> coverage.txt
|
||||
if: env.GIT_DIFF
|
||||
- uses: codecov/codecov-action@v1.0.13
|
||||
- uses: codecov/codecov-action@v3
|
||||
with:
|
||||
file: ./coverage.txt
|
||||
if: env.GIT_DIFF
|
||||
|
||||
8
.github/workflows/docker.yml
vendored
8
.github/workflows/docker.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/checkout@v3
|
||||
- name: Prepare
|
||||
id: prep
|
||||
run: |
|
||||
@@ -40,17 +40,17 @@ jobs:
|
||||
platforms: all
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to DockerHub
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Publish to Docker Hub
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
file: ./DOCKER/Dockerfile
|
||||
|
||||
6
.github/workflows/e2e-manual.yml
vendored
6
.github/workflows/e2e-manual.yml
vendored
@@ -14,11 +14,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.17'
|
||||
go-version: '1.18'
|
||||
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Build
|
||||
working-directory: test/e2e
|
||||
|
||||
10
.github/workflows/e2e-nightly-34x.yml
vendored
10
.github/workflows/e2e-nightly-34x.yml
vendored
@@ -21,11 +21,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.15.4'
|
||||
go-version: '1.18'
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: 'v0.34.x'
|
||||
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Notify Slack on failure
|
||||
uses: rtCamp/action-slack-notify@e9db0ef
|
||||
uses: rtCamp/action-slack-notify@f565a63638bd3615e76249bffab00fcb9dab90f7
|
||||
env:
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
||||
SLACK_CHANNEL: tendermint-internal
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Notify Slack on success
|
||||
uses: rtCamp/action-slack-notify@ae4223259071871559b6e9d08b24a63d71b3f0c0
|
||||
uses: rtCamp/action-slack-notify@f565a63638bd3615e76249bffab00fcb9dab90f7
|
||||
env:
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
||||
SLACK_CHANNEL: tendermint-internal
|
||||
|
||||
10
.github/workflows/e2e-nightly-master.yml
vendored
10
.github/workflows/e2e-nightly-master.yml
vendored
@@ -20,11 +20,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.15'
|
||||
go-version: '1.18'
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Build
|
||||
working-directory: test/e2e
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Notify Slack on failure
|
||||
uses: rtCamp/action-slack-notify@ae4223259071871559b6e9d08b24a63d71b3f0c0
|
||||
uses: rtCamp/action-slack-notify@f565a63638bd3615e76249bffab00fcb9dab90f7
|
||||
env:
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
||||
SLACK_CHANNEL: tendermint-internal
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Notify Slack on success
|
||||
uses: rtCamp/action-slack-notify@ae4223259071871559b6e9d08b24a63d71b3f0c0
|
||||
uses: rtCamp/action-slack-notify@f565a63638bd3615e76249bffab00fcb9dab90f7
|
||||
env:
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
||||
SLACK_CHANNEL: tendermint-internal
|
||||
|
||||
8
.github/workflows/e2e.yml
vendored
8
.github/workflows/e2e.yml
vendored
@@ -13,11 +13,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.15.4'
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
go-version: '1.18'
|
||||
- uses: actions/checkout@v3
|
||||
- uses: technote-space/get-diff-action@v6
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
|
||||
12
.github/workflows/fuzz-nightly.yml
vendored
12
.github/workflows/fuzz-nightly.yml
vendored
@@ -9,11 +9,11 @@ jobs:
|
||||
fuzz-nightly-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.15'
|
||||
go-version: '1.18'
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install go-fuzz
|
||||
working-directory: test/fuzz
|
||||
@@ -45,14 +45,14 @@ jobs:
|
||||
continue-on-error: true
|
||||
|
||||
- name: Archive crashers
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: crashers
|
||||
path: test/fuzz/**/crashers
|
||||
retention-days: 1
|
||||
|
||||
- name: Archive suppressions
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: suppressions
|
||||
path: test/fuzz/**/suppressions
|
||||
@@ -72,7 +72,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Notify Slack if any crashers
|
||||
uses: rtCamp/action-slack-notify@ae4223259071871559b6e9d08b24a63d71b3f0c0
|
||||
uses: rtCamp/action-slack-notify@f565a63638bd3615e76249bffab00fcb9dab90f7
|
||||
env:
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
||||
SLACK_CHANNEL: tendermint-internal
|
||||
|
||||
6
.github/workflows/linkchecker.yml
vendored
6
.github/workflows/linkchecker.yml
vendored
@@ -1,12 +1,12 @@
|
||||
name: Check Markdown links
|
||||
on:
|
||||
on:
|
||||
schedule:
|
||||
- cron: '* */24 * * *'
|
||||
jobs:
|
||||
markdown-link-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: gaurav-nelson/github-action-markdown-link-check@1.0.7
|
||||
- uses: actions/checkout@v3
|
||||
- uses: creachadair/github-action-markdown-link-check@master
|
||||
with:
|
||||
folder-path: "docs"
|
||||
|
||||
11
.github/workflows/lint.yml
vendored
11
.github/workflows/lint.yml
vendored
@@ -13,17 +13,20 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 8
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: technote-space/get-diff-action@v5
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.18'
|
||||
- uses: technote-space/get-diff-action@v6
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- uses: golangci/golangci-lint-action@v2.5.2
|
||||
- uses: golangci/golangci-lint-action@v3
|
||||
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.42.1
|
||||
version: v1.47.3
|
||||
args: --timeout 10m
|
||||
github-token: ${{ secrets.github_token }}
|
||||
if: env.GIT_DIFF
|
||||
|
||||
2
.github/workflows/linter.yml
vendored
2
.github/workflows/linter.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2.4.0
|
||||
uses: actions/checkout@v3
|
||||
- name: Lint Code Base
|
||||
uses: docker://github/super-linter:v3
|
||||
env:
|
||||
|
||||
51
.github/workflows/proto-docker.yml
vendored
51
.github/workflows/proto-docker.yml
vendored
@@ -1,51 +0,0 @@
|
||||
name: Build & Push TM Proto Builder
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "tools/proto/*"
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- "tools/proto/*"
|
||||
schedule:
|
||||
# run this job once a month to recieve any go or buf updates
|
||||
- cron: "* * 1 * *"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Prepare
|
||||
id: prep
|
||||
run: |
|
||||
DOCKER_IMAGE=tendermintdev/docker-build-proto
|
||||
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}"
|
||||
echo ::set-output name=tags::${TAGS}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Publish to Docker Hub
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: ./tools/proto
|
||||
file: ./tools/proto/Dockerfile
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.prep.outputs.tags }}
|
||||
21
.github/workflows/proto-lint.yml
vendored
Normal file
21
.github/workflows/proto-lint.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Protobuf Lint
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'proto/**'
|
||||
push:
|
||||
branches:
|
||||
- v0.34.x
|
||||
paths:
|
||||
- 'proto/**'
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: bufbuild/buf-setup-action@v1.6.0
|
||||
- uses: bufbuild/buf-lint-action@v1
|
||||
with:
|
||||
input: 'proto'
|
||||
22
.github/workflows/proto.yml
vendored
22
.github/workflows/proto.yml
vendored
@@ -1,22 +0,0 @@
|
||||
name: Protobuf
|
||||
# Protobuf runs buf (https://buf.build/) lint and check-breakage
|
||||
# This workflow is only run when a .proto file has been modified
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "**.proto"
|
||||
jobs:
|
||||
proto-lint:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 4
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: lint
|
||||
run: make proto-lint
|
||||
proto-breakage:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 4
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: check-breakage
|
||||
run: make proto-check-breaking-ci
|
||||
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
@@ -10,18 +10,18 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.15.4'
|
||||
go-version: '1.18'
|
||||
|
||||
- run: echo https://github.com/tendermint/tendermint/blob/${GITHUB_REF#refs/tags/}/CHANGELOG.md#${GITHUB_REF#refs/tags/} > ../release_notes.md
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
uses: goreleaser/goreleaser-action@v3
|
||||
with:
|
||||
version: latest
|
||||
args: release --rm-dist --release-notes=../release_notes.md
|
||||
|
||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-pr-message: "This pull request has been automatically marked as stale because it has not had
|
||||
|
||||
48
.github/workflows/tests.yml
vendored
48
.github/workflows/tests.yml
vendored
@@ -23,11 +23,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "^1.15.4"
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
go-version: "1.18"
|
||||
- uses: actions/checkout@v3
|
||||
- uses: technote-space/get-diff-action@v6
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
- name: install
|
||||
run: make install install_abci
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- uses: actions/cache@v2.1.4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
${{ runner.os }}-go-
|
||||
if: env.GIT_DIFF
|
||||
# Cache binaries for use by other jobs
|
||||
- uses: actions/cache@v2.1.4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-${{ github.sha }}-tm-binary
|
||||
@@ -55,24 +55,24 @@ jobs:
|
||||
needs: build
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "^1.15.4"
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
go-version: "^1.18"
|
||||
- uses: actions/checkout@v3
|
||||
- uses: technote-space/get-diff-action@v6
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- uses: actions/cache@v2.1.4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/cache@v2.1.4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-${{ github.sha }}-tm-binary
|
||||
@@ -87,24 +87,24 @@ jobs:
|
||||
needs: build
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "^1.15.4"
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
go-version: "^1.18"
|
||||
- uses: actions/checkout@v3
|
||||
- uses: technote-space/get-diff-action@v6
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- uses: actions/cache@v2.1.4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/cache@v2.1.4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-${{ github.sha }}-tm-binary
|
||||
@@ -118,24 +118,24 @@ jobs:
|
||||
needs: build
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "^1.15.4"
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v4
|
||||
go-version: "1.18"
|
||||
- uses: actions/checkout@v3
|
||||
- uses: technote-space/get-diff-action@v6
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
go.mod
|
||||
go.sum
|
||||
- uses: actions/cache@v2.1.4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
if: env.GIT_DIFF
|
||||
- uses: actions/cache@v2.1.4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-${{ github.sha }}-tm-binary
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -56,3 +56,9 @@ test/fuzz/**/corpus
|
||||
test/fuzz/**/crashers
|
||||
test/fuzz/**/suppressions
|
||||
test/fuzz/**/*.zip
|
||||
*.aux
|
||||
*.bbl
|
||||
*.blg
|
||||
*.pdf
|
||||
*.gz
|
||||
*.dvi
|
||||
|
||||
@@ -2,7 +2,7 @@ linters:
|
||||
enable:
|
||||
- asciicheck
|
||||
- bodyclose
|
||||
- deadcode
|
||||
# - deadcode
|
||||
- depguard
|
||||
- dogsled
|
||||
- dupl
|
||||
@@ -28,18 +28,22 @@ linters:
|
||||
# - maligned
|
||||
# - misspell
|
||||
- nakedret
|
||||
- nolintlint
|
||||
# - nolintlint
|
||||
- prealloc
|
||||
- staticcheck
|
||||
- structcheck
|
||||
# - structcheck // to be fixed by golangci-lint
|
||||
- stylecheck
|
||||
# - typecheck
|
||||
- unconvert
|
||||
# - unparam
|
||||
- unused
|
||||
# - unused
|
||||
- varcheck
|
||||
# - whitespace
|
||||
# - wsl
|
||||
disable:
|
||||
- unused
|
||||
- deadcode
|
||||
- nolintlint
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
@@ -60,8 +64,6 @@ linters-settings:
|
||||
# check-shadowing: true
|
||||
revive:
|
||||
min-confidence: 0
|
||||
maligned:
|
||||
suggest-new: true
|
||||
misspell:
|
||||
locale: US
|
||||
ignore-words:
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
default: true,
|
||||
MD007: { "indent": 4 }
|
||||
default: true
|
||||
MD001: false
|
||||
MD007: {indent: 4}
|
||||
MD013: false
|
||||
MD024: { siblings_only: true }
|
||||
MD024: {siblings_only: true}
|
||||
MD025: false
|
||||
MD033: { no-inline-html: false }
|
||||
no-hard-tabs: false
|
||||
whitespace: false
|
||||
MD033: false
|
||||
MD036: false
|
||||
MD010: false
|
||||
MD012: false
|
||||
MD028: false
|
||||
|
||||
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@@ -5,4 +5,5 @@
|
||||
"--proto_path=${workspaceRoot}/third_party/proto"
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
93
CHANGELOG.md
93
CHANGELOG.md
@@ -2,6 +2,87 @@
|
||||
|
||||
Friendly reminder, we have a [bug bounty program](https://hackerone.com/cosmos).
|
||||
|
||||
## v0.34.21
|
||||
|
||||
Release highlights include:
|
||||
|
||||
- A new `[storage]` configuration section and flag `discard_abci_responses`,
|
||||
which, if enabled, discards all ABCI responses except the latest one in order
|
||||
to reduce disk space usage in the state store. When enabled, the
|
||||
`block_results` RPC endpoint can no longer function and will return an error.
|
||||
- A new CLI command, `reindex-event`, to re-index block and tx events to the
|
||||
event sinks. You can run this command when the event store backend
|
||||
dropped/disconnected or you want to replace the backend. When
|
||||
`discard_abci_responses` is enabled, you will not be able to use this command.
|
||||
|
||||
Special thanks to external contributors on this release: @rootwarp & @animart
|
||||
|
||||
### FEATURES
|
||||
|
||||
- [cli] [\#9083](https://github.com/tendermint/tendermint/issues/9083) Backport command to reindex missed events (@cmwaters)
|
||||
- [cli] [\#9107](https://github.com/tendermint/tendermint/issues/9107) Add the `p2p.external-address` argument to set the node P2P external address (@amimart)
|
||||
|
||||
### IMPROVEMENTS
|
||||
|
||||
- [config] [\#9054](https://github.com/tendermint/tendermint/issues/9054) `discard_abci_responses` flag added to discard all ABCI
|
||||
responses except the last in order to save on storage space in the state
|
||||
store (@samricotta)
|
||||
|
||||
### BUG FIXES
|
||||
|
||||
- [mempool] [\#9033](https://github.com/tendermint/tendermint/issues/9033) Rework lock discipline to mitigate callback deadlocks in the
|
||||
priority mempool
|
||||
- [cli] [\#9103](https://github.com/tendermint/tendermint/issues/9103) fix unsafe-reset-all for working with home path (@rootwarp)
|
||||
|
||||
## v0.34.20
|
||||
|
||||
Special thanks to external contributors on this release: @joeabbey @yihuang
|
||||
|
||||
This release introduces a prioritized mempool. Further notes can be found in UPGRADING.md.
|
||||
|
||||
NOTE: There's a known issue when combining the prioritized mempool with the ABCI socket client, that the team are curently working to resolve. Read more about the issue [here](https://github.com/tendermint/tendermint/pull/9030).
|
||||
|
||||
### BUG FIXES
|
||||
|
||||
- [blocksync] [\#8496](https://github.com/tendermint/tendermint/pull/8496) validate block against state before persisting it to disk (@cmwaters)
|
||||
- [indexer] [#8625](https://github.com/tendermint/tendermint/pull/8625) Fix overriding tx index of duplicated txs. (@yihuang)
|
||||
- [mempool] [\#8962](https://github.com/tendermint/tendermint/issues/8962) Backport priority mempool fixes from v0.35.x to v0.34.x (@creachadair).
|
||||
|
||||
### FEATURES
|
||||
|
||||
- [cli] [\#8674] Add command to force compact goleveldb databases (@cmwaters)
|
||||
- [mempool] [\#8695] Port back the priority mempool. (@alexanderbez, @jmalicevic, @cmwaters)
|
||||
|
||||
### IMPROVEMENTS
|
||||
|
||||
- [logging] [\#8845](https://github.com/tendermint/tendermint/issues/8845) Add "Lazy" Stringers to defer Sprintf and Hash until logs print. (@joeabbey)
|
||||
|
||||
## v0.34.19
|
||||
|
||||
### BUG FIXES
|
||||
|
||||
- [cli] [\#8270](https://github.com/tendermint/tendermint/issues/8270) fix reset commands (@alexanderbez).
|
||||
|
||||
## v0.34.18
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
- CLI/RPC/Config
|
||||
- [cli] [\#8258](https://github.com/tendermint/tendermint/pull/8258) Fix a bug in the cli that caused `unsafe-reset-all` to panic
|
||||
|
||||
## v0.34.17
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
- CLI/RPC/Config
|
||||
|
||||
- [cli] [\#8081](https://github.com/tendermint/tendermint/issues/8081) make the reset command safe to use (@marbar3778).
|
||||
|
||||
### BUG FIXES
|
||||
|
||||
- [consensus] [\#8079](https://github.com/tendermint/tendermint/issues/8079) start the timeout ticker before relay (backport #7844) (@creachadair).
|
||||
- [consensus] [\#7992](https://github.com/tendermint/tendermint/issues/7992) [\#7994](https://github.com/tendermint/tendermint/issues/7994) change lock handling in handleMsg and reactor to alleviate issues gossiping during long ABCI calls (@williambanfield).
|
||||
|
||||
## v0.34.16
|
||||
|
||||
Special thanks to external contributors on this release: @yihuang
|
||||
@@ -1717,7 +1798,7 @@ more details.
|
||||
- [rpc] [\#3269](https://github.com/tendermint/tendermint/issues/2826) Limit number of unique clientIDs with open subscriptions. Configurable via `rpc.max_subscription_clients`
|
||||
- [rpc] [\#3269](https://github.com/tendermint/tendermint/issues/2826) Limit number of unique queries a given client can subscribe to at once. Configurable via `rpc.max_subscriptions_per_client`.
|
||||
- [rpc] [\#3435](https://github.com/tendermint/tendermint/issues/3435) Default ReadTimeout and WriteTimeout changed to 10s. WriteTimeout can increased by setting `rpc.timeout_broadcast_tx_commit` in the config.
|
||||
- [rpc/client] [\#3269](https://github.com/tendermint/tendermint/issues/3269) Update `EventsClient` interface to reflect new pubsub/eventBus API [ADR-33](https://github.com/tendermint/tendermint/blob/develop/docs/architecture/adr-033-pubsub.md). This includes `Subscribe`, `Unsubscribe`, and `UnsubscribeAll` methods.
|
||||
- [rpc/client] [\#3269](https://github.com/tendermint/tendermint/issues/3269) Update `EventsClient` interface to reflect new pubsub/eventBus API [ADR-33](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-033-pubsub.md). This includes `Subscribe`, `Unsubscribe`, and `UnsubscribeAll` methods.
|
||||
|
||||
* Apps
|
||||
- [abci] [\#3403](https://github.com/tendermint/tendermint/issues/3403) Remove `time_iota_ms` from BlockParams. This is a
|
||||
@@ -1770,7 +1851,7 @@ more details.
|
||||
- [blockchain] [\#3358](https://github.com/tendermint/tendermint/pull/3358) Fix timer leak in `BlockPool` (@guagualvcha)
|
||||
- [cmd] [\#3408](https://github.com/tendermint/tendermint/issues/3408) Fix `testnet` command's panic when creating non-validator configs (using `--n` flag) (@srmo)
|
||||
- [libs/db/remotedb/grpcdb] [\#3402](https://github.com/tendermint/tendermint/issues/3402) Close Iterator/ReverseIterator after use
|
||||
- [libs/pubsub] [\#951](https://github.com/tendermint/tendermint/issues/951), [\#1880](https://github.com/tendermint/tendermint/issues/1880) Use non-blocking send when dispatching messages [ADR-33](https://github.com/tendermint/tendermint/blob/develop/docs/architecture/adr-033-pubsub.md)
|
||||
- [libs/pubsub] [\#951](https://github.com/tendermint/tendermint/issues/951), [\#1880](https://github.com/tendermint/tendermint/issues/1880) Use non-blocking send when dispatching messages [ADR-33](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-033-pubsub.md)
|
||||
- [lite] [\#3364](https://github.com/tendermint/tendermint/issues/3364) Fix `/validators` and `/abci_query` proxy endpoints
|
||||
(@guagualvcha)
|
||||
- [p2p/conn] [\#3347](https://github.com/tendermint/tendermint/issues/3347) Reject all-zero shared secrets in the Diffie-Hellman step of secret-connection
|
||||
@@ -2468,7 +2549,7 @@ Special thanks to external contributors on this release:
|
||||
This release is mostly about the ConsensusParams - removing fields and enforcing MaxGas.
|
||||
It also addresses some issues found via security audit, removes various unused
|
||||
functions from `libs/common`, and implements
|
||||
[ADR-012](https://github.com/tendermint/tendermint/blob/develop/docs/architecture/adr-012-peer-transport.md).
|
||||
[ADR-012](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-012-peer-transport.md).
|
||||
|
||||
BREAKING CHANGES:
|
||||
|
||||
@@ -2549,7 +2630,7 @@ BREAKING CHANGES:
|
||||
- [abci] Added address of the original proposer of the block to Header
|
||||
- [abci] Change ABCI Header to match Tendermint exactly
|
||||
- [abci] [\#2159](https://github.com/tendermint/tendermint/issues/2159) Update use of `Validator` (see
|
||||
[ADR-018](https://github.com/tendermint/tendermint/blob/develop/docs/architecture/adr-018-ABCI-Validators.md)):
|
||||
[ADR-018](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-018-ABCI-Validators.md)):
|
||||
- Remove PubKey from `Validator` (so it's just Address and Power)
|
||||
- Introduce `ValidatorUpdate` (with just PubKey and Power)
|
||||
- InitChain and EndBlock use ValidatorUpdate
|
||||
@@ -2571,7 +2652,7 @@ BREAKING CHANGES:
|
||||
- [state] [\#1815](https://github.com/tendermint/tendermint/issues/1815) Validator set changes are now delayed by one block (!)
|
||||
- Add NextValidatorSet to State, changes on-disk representation of state
|
||||
- [state] [\#2184](https://github.com/tendermint/tendermint/issues/2184) Enforce ConsensusParams.BlockSize.MaxBytes (See
|
||||
[ADR-020](https://github.com/tendermint/tendermint/blob/develop/docs/architecture/adr-020-block-size.md)).
|
||||
[ADR-020](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-020-block-size.md)).
|
||||
- Remove ConsensusParams.BlockSize.MaxTxs
|
||||
- Introduce maximum sizes for all components of a block, including ChainID
|
||||
- [types] Updates to the block Header:
|
||||
@@ -2582,7 +2663,7 @@ BREAKING CHANGES:
|
||||
- [consensus] [\#2203](https://github.com/tendermint/tendermint/issues/2203) Implement BFT time
|
||||
- Timestamp in block must be monotonic and equal the median of timestamps in block's LastCommit
|
||||
- [crypto] [\#2239](https://github.com/tendermint/tendermint/issues/2239) Secp256k1 signature changes (See
|
||||
[ADR-014](https://github.com/tendermint/tendermint/blob/develop/docs/architecture/adr-014-secp-malleability.md)):
|
||||
[ADR-014](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-014-secp-malleability.md)):
|
||||
- format changed from DER to `r || s`, both little endian encoded as 32 bytes.
|
||||
- malleability removed by requiring `s` to be in canonical form.
|
||||
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
# Unreleased Changes
|
||||
|
||||
## v0.34.16
|
||||
|
||||
Special thanks to external contributors on this release:
|
||||
|
||||
Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermint).
|
||||
## v0.34.22
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
- CLI/RPC/Config
|
||||
|
||||
- [cli] \#8081 make the reset command safe to use (@marbar3778).
|
||||
|
||||
- Apps
|
||||
|
||||
- P2P Protocol
|
||||
@@ -25,3 +19,4 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
|
||||
### IMPROVEMENTS
|
||||
|
||||
### BUG FIXES
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# stage 1 Generate Tendermint Binary
|
||||
FROM golang:1.15-alpine as builder
|
||||
FROM golang:1.18-alpine as builder
|
||||
RUN apk update && \
|
||||
apk upgrade && \
|
||||
apk --no-cache add make
|
||||
@@ -8,7 +8,7 @@ WORKDIR /tendermint
|
||||
RUN make build-linux
|
||||
|
||||
# stage 2
|
||||
FROM golang:1.15-alpine
|
||||
FROM golang:1.18-alpine
|
||||
LABEL maintainer="hello@tendermint.com"
|
||||
|
||||
# Tendermint will be looking for the genesis file in /tendermint/config/genesis.json
|
||||
|
||||
50
Makefile
50
Makefile
@@ -13,7 +13,6 @@ endif
|
||||
LD_FLAGS = -X github.com/tendermint/tendermint/version.TMCoreSemVer=$(VERSION)
|
||||
BUILD_FLAGS = -mod=readonly -ldflags "$(LD_FLAGS)"
|
||||
HTTPS_GIT := https://github.com/tendermint/tendermint.git
|
||||
DOCKER_BUF := docker run -v $(shell pwd):/workspace --workdir /workspace bufbuild/buf
|
||||
CGO_ENABLED ?= 0
|
||||
|
||||
# handle nostrip
|
||||
@@ -70,34 +69,59 @@ install:
|
||||
CGO_ENABLED=$(CGO_ENABLED) go install $(BUILD_FLAGS) -tags $(BUILD_TAGS) ./cmd/tendermint
|
||||
.PHONY: install
|
||||
|
||||
|
||||
###############################################################################
|
||||
### Mocks ###
|
||||
###############################################################################
|
||||
|
||||
mockery:
|
||||
go generate -run="./scripts/mockery_generate.sh" ./...
|
||||
.PHONY: mockery
|
||||
|
||||
###############################################################################
|
||||
### Protobuf ###
|
||||
###############################################################################
|
||||
|
||||
proto-all: proto-gen proto-lint proto-check-breaking
|
||||
.PHONY: proto-all
|
||||
check-proto-deps:
|
||||
ifeq (,$(shell which protoc-gen-gogofaster))
|
||||
@go install github.com/gogo/protobuf/protoc-gen-gogofaster@latest
|
||||
endif
|
||||
.PHONY: check-proto-deps
|
||||
|
||||
proto-gen:
|
||||
@docker pull -q tendermintdev/docker-build-proto
|
||||
check-proto-format-deps:
|
||||
ifeq (,$(shell which clang-format))
|
||||
$(error "clang-format is required for Protobuf formatting. See instructions for your platform on how to install it.")
|
||||
endif
|
||||
.PHONY: check-proto-format-deps
|
||||
|
||||
proto-gen: check-proto-deps
|
||||
@echo "Generating Protobuf files"
|
||||
@docker run -v $(shell pwd):/workspace --workdir /workspace tendermintdev/docker-build-proto sh ./scripts/protocgen.sh
|
||||
@go run github.com/bufbuild/buf/cmd/buf generate
|
||||
@mv ./proto/tendermint/abci/types.pb.go ./abci/types/
|
||||
.PHONY: proto-gen
|
||||
|
||||
proto-lint:
|
||||
@$(DOCKER_BUF) check lint --error-format=json
|
||||
# These targets are provided for convenience and are intended for local
|
||||
# execution only.
|
||||
proto-lint: check-proto-deps
|
||||
@echo "Linting Protobuf files"
|
||||
@go run github.com/bufbuild/buf/cmd/buf lint
|
||||
.PHONY: proto-lint
|
||||
|
||||
proto-format:
|
||||
proto-format: check-proto-format-deps
|
||||
@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 {} \;
|
||||
@find . -name '*.proto' -path "./proto/*" -exec clang-format -i {} \;
|
||||
.PHONY: proto-format
|
||||
|
||||
proto-check-breaking:
|
||||
@$(DOCKER_BUF) check breaking --against-input .git#branch=master
|
||||
proto-check-breaking: check-proto-deps
|
||||
@echo "Checking for breaking changes in Protobuf files against local branch"
|
||||
@echo "Note: This is only useful if your changes have not yet been committed."
|
||||
@echo " Otherwise read up on buf's \"breaking\" command usage:"
|
||||
@echo " https://docs.buf.build/breaking/usage"
|
||||
@go run github.com/bufbuild/buf/cmd/buf breaking --against ".git"
|
||||
.PHONY: proto-check-breaking
|
||||
|
||||
proto-check-breaking-ci:
|
||||
@$(DOCKER_BUF) check breaking --against-input $(HTTPS_GIT)#branch=master
|
||||
@go run github.com/bufbuild/buf/cmd/buf breaking --against $(HTTPS_GIT)#branch=v0.34.x
|
||||
.PHONY: proto-check-breaking-ci
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -51,7 +51,7 @@ to notify you of vulnerabilities and fixes in Tendermint Core. You can subscribe
|
||||
|
||||
| Requirement | Notes |
|
||||
| ----------- | ---------------- |
|
||||
| Go version | Go1.15 or higher |
|
||||
| Go version | Go1.18 or higher |
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
23
UPGRADING.md
23
UPGRADING.md
@@ -2,13 +2,28 @@
|
||||
|
||||
This guide provides instructions for upgrading to specific versions of Tendermint Core.
|
||||
|
||||
## v0.34.20
|
||||
|
||||
### Feature: Priority Mempool
|
||||
|
||||
This release backports an implementation of the Priority Mempool from the v0.35
|
||||
branch. This implementation of the mempool permits the application to set a
|
||||
priority on each transaction during CheckTx, and during block selection the
|
||||
highest-priority transactions are chosen (subject to the constraints on size
|
||||
and gas cost).
|
||||
|
||||
Operators can enable the priority mempool by setting `mempool.version` to
|
||||
`"v1"` in the `config.toml`. For more technical details about the priority
|
||||
mempool, see [ADR 067: Mempool
|
||||
Refactor](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-067-mempool-refactor.md).
|
||||
|
||||
## v0.34.0
|
||||
|
||||
**Upgrading to Tendermint 0.34 requires a blockchain restart.**
|
||||
This release is not compatible with previous blockchains due to changes to
|
||||
the encoding format (see "Protocol Buffers," below) and the block header (see "Blockchain Protocol").
|
||||
|
||||
Note also that Tendermint 0.34 also requires Go 1.15 or higher.
|
||||
Note also that Tendermint 0.34 also requires Go 1.15 or higher.
|
||||
|
||||
### ABCI Changes
|
||||
|
||||
@@ -112,7 +127,7 @@ Tendermint 0.34 includes new and updated consensus parameters.
|
||||
|
||||
#### Evidence Parameters
|
||||
|
||||
* `MaxBytes`, which caps the total amount of evidence. The default is 1048576 (1 MB).
|
||||
* `MaxBytes`, which caps the total amount of evidence. The default is 1048576 (1 MB).
|
||||
|
||||
### Crypto
|
||||
|
||||
@@ -188,7 +203,7 @@ blockchains, we recommend that you check the chain ID.
|
||||
|
||||
### Version
|
||||
|
||||
Version is now set through Go linker flags `ld_flags`. Applications that are using tendermint as a library should set this at compile time.
|
||||
Version is now set through Go linker flags `ld_flags`. Applications that are using tendermint as a library should set this at compile time.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -196,7 +211,7 @@ Example:
|
||||
go install -mod=readonly -ldflags "-X github.com/tendermint/tendermint/version.TMCoreSemVer=$(go list -m github.com/tendermint/tendermint | sed 's/ /\@/g') -s -w " -trimpath ./cmd
|
||||
```
|
||||
|
||||
Additionally, the exported constant `version.Version` is now `version.TMCoreSemVer`.
|
||||
Additionally, the exported constant `version.Version` is now `version.TMCoreSemVer`.
|
||||
|
||||
## v0.33.4
|
||||
|
||||
|
||||
@@ -81,9 +81,15 @@ type ReqRes struct {
|
||||
*sync.WaitGroup
|
||||
*types.Response // Not set atomically, so be sure to use WaitGroup.
|
||||
|
||||
mtx tmsync.Mutex
|
||||
done bool // Gets set to true once *after* WaitGroup.Done().
|
||||
cb func(*types.Response) // A single callback that may be set.
|
||||
mtx tmsync.Mutex
|
||||
|
||||
// callbackInvoked as a variable to track if the callback was already
|
||||
// invoked during the regular execution of the request. This variable
|
||||
// allows clients to set the callback simultaneously without potentially
|
||||
// invoking the callback twice by accident, once when 'SetCallback' is
|
||||
// called and once during the normal request.
|
||||
callbackInvoked bool
|
||||
cb func(*types.Response) // A single callback that may be set.
|
||||
}
|
||||
|
||||
func NewReqRes(req *types.Request) *ReqRes {
|
||||
@@ -92,8 +98,8 @@ func NewReqRes(req *types.Request) *ReqRes {
|
||||
WaitGroup: waitGroup1(),
|
||||
Response: nil,
|
||||
|
||||
done: false,
|
||||
cb: nil,
|
||||
callbackInvoked: false,
|
||||
cb: nil,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +109,7 @@ func NewReqRes(req *types.Request) *ReqRes {
|
||||
func (r *ReqRes) SetCallback(cb func(res *types.Response)) {
|
||||
r.mtx.Lock()
|
||||
|
||||
if r.done {
|
||||
if r.callbackInvoked {
|
||||
r.mtx.Unlock()
|
||||
cb(r.Response)
|
||||
return
|
||||
@@ -122,6 +128,7 @@ func (r *ReqRes) InvokeCallback() {
|
||||
if r.cb != nil {
|
||||
r.cb(r.Response)
|
||||
}
|
||||
r.callbackInvoked = true
|
||||
}
|
||||
|
||||
// GetCallback returns the configured callback of the ReqRes object which may be
|
||||
@@ -136,13 +143,6 @@ func (r *ReqRes) GetCallback() func(*types.Response) {
|
||||
return r.cb
|
||||
}
|
||||
|
||||
// SetDone marks the ReqRes object as done.
|
||||
func (r *ReqRes) SetDone() {
|
||||
r.mtx.Lock()
|
||||
r.done = true
|
||||
r.mtx.Unlock()
|
||||
}
|
||||
|
||||
func waitGroup1() (wg *sync.WaitGroup) {
|
||||
wg = &sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
|
||||
@@ -66,7 +66,6 @@ func (cli *grpcClient) OnStart() error {
|
||||
cli.mtx.Lock()
|
||||
defer cli.mtx.Unlock()
|
||||
|
||||
reqres.SetDone()
|
||||
reqres.Done()
|
||||
|
||||
// Notify client listener if set
|
||||
@@ -75,9 +74,7 @@ func (cli *grpcClient) OnStart() error {
|
||||
}
|
||||
|
||||
// Notify reqRes listener if set
|
||||
if cb := reqres.GetCallback(); cb != nil {
|
||||
cb(reqres.Response)
|
||||
}
|
||||
reqres.InvokeCallback()
|
||||
}
|
||||
for reqres := range cli.chReqRes {
|
||||
if reqres != nil {
|
||||
@@ -343,7 +340,9 @@ func (cli *grpcClient) finishSyncCall(reqres *ReqRes) *types.Response {
|
||||
//----------------------------------------
|
||||
|
||||
func (cli *grpcClient) FlushSync() error {
|
||||
return nil
|
||||
reqres := cli.FlushAsync()
|
||||
cli.finishSyncCall(reqres).GetFlush()
|
||||
return cli.Error()
|
||||
}
|
||||
|
||||
func (cli *grpcClient) EchoSync(msg string) (*types.ResponseEcho, error) {
|
||||
|
||||
@@ -327,12 +327,13 @@ func (app *localClient) ApplySnapshotChunkSync(
|
||||
|
||||
func (app *localClient) callback(req *types.Request, res *types.Response) *ReqRes {
|
||||
app.Callback(req, res)
|
||||
return newLocalReqRes(req, res)
|
||||
rr := newLocalReqRes(req, res)
|
||||
rr.callbackInvoked = true
|
||||
return rr
|
||||
}
|
||||
|
||||
func newLocalReqRes(req *types.Request, res *types.Response) *ReqRes {
|
||||
reqRes := NewReqRes(req)
|
||||
reqRes.Response = res
|
||||
reqRes.SetDone()
|
||||
return reqRes
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package abcicli_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -118,3 +119,71 @@ func (slowApp) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
return types.ResponseBeginBlock{}
|
||||
}
|
||||
|
||||
// TestCallbackInvokedWhenSetLaet ensures that the callback is invoked when
|
||||
// set after the client completes the call into the app. Currently this
|
||||
// test relies on the callback being allowed to be invoked twice if set multiple
|
||||
// times, once when set early and once when set late.
|
||||
func TestCallbackInvokedWhenSetLate(t *testing.T) {
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
app := blockedABCIApplication{
|
||||
wg: wg,
|
||||
}
|
||||
_, c := setupClientServer(t, app)
|
||||
reqRes := c.CheckTxAsync(types.RequestCheckTx{})
|
||||
|
||||
done := make(chan struct{})
|
||||
cb := func(_ *types.Response) {
|
||||
close(done)
|
||||
}
|
||||
reqRes.SetCallback(cb)
|
||||
app.wg.Done()
|
||||
<-done
|
||||
|
||||
var called bool
|
||||
cb = func(_ *types.Response) {
|
||||
called = true
|
||||
}
|
||||
reqRes.SetCallback(cb)
|
||||
require.True(t, called)
|
||||
}
|
||||
|
||||
type blockedABCIApplication struct {
|
||||
wg *sync.WaitGroup
|
||||
types.BaseApplication
|
||||
}
|
||||
|
||||
func (b blockedABCIApplication) CheckTx(r types.RequestCheckTx) types.ResponseCheckTx {
|
||||
b.wg.Wait()
|
||||
return b.BaseApplication.CheckTx(r)
|
||||
}
|
||||
|
||||
// TestCallbackInvokedWhenSetEarly ensures that the callback is invoked when
|
||||
// set before the client completes the call into the app.
|
||||
func TestCallbackInvokedWhenSetEarly(t *testing.T) {
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
app := blockedABCIApplication{
|
||||
wg: wg,
|
||||
}
|
||||
_, c := setupClientServer(t, app)
|
||||
reqRes := c.CheckTxAsync(types.RequestCheckTx{})
|
||||
|
||||
done := make(chan struct{})
|
||||
cb := func(_ *types.Response) {
|
||||
close(done)
|
||||
}
|
||||
reqRes.SetCallback(cb)
|
||||
app.wg.Done()
|
||||
|
||||
called := func() bool {
|
||||
select {
|
||||
case <-done:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
require.Eventually(t, called, time.Second, time.Millisecond*25)
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ func TestValUpdates(t *testing.T) {
|
||||
|
||||
makeApplyBlock(t, kvstore, 2, diff, tx1, tx2, tx3)
|
||||
|
||||
vals1 = append(vals[:nInit-2], vals[nInit+1]) // nolint: gocritic
|
||||
vals1 = append(vals[:nInit-2], vals[nInit+1]) //nolint: gocritic
|
||||
vals2 = kvstore.Validators()
|
||||
valsEqual(t, vals1, vals2)
|
||||
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
Package server is used to start a new ABCI server.
|
||||
|
||||
It contains two server implementation:
|
||||
* gRPC server
|
||||
* socket server
|
||||
|
||||
- gRPC server
|
||||
- socket server
|
||||
*/
|
||||
package server
|
||||
|
||||
|
||||
@@ -1967,6 +1967,11 @@ type ResponseCheckTx struct {
|
||||
GasUsed int64 `protobuf:"varint,6,opt,name=gas_used,proto3" json:"gas_used,omitempty"`
|
||||
Events []Event `protobuf:"bytes,7,rep,name=events,proto3" json:"events,omitempty"`
|
||||
Codespace string `protobuf:"bytes,8,opt,name=codespace,proto3" json:"codespace,omitempty"`
|
||||
Sender string `protobuf:"bytes,9,opt,name=sender,proto3" json:"sender,omitempty"`
|
||||
Priority int64 `protobuf:"varint,10,opt,name=priority,proto3" json:"priority,omitempty"`
|
||||
// mempool_error is set by Tendermint.
|
||||
// ABCI applictions creating a ResponseCheckTX should not set mempool_error.
|
||||
MempoolError string `protobuf:"bytes,11,opt,name=mempool_error,json=mempoolError,proto3" json:"mempool_error,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ResponseCheckTx) Reset() { *m = ResponseCheckTx{} }
|
||||
@@ -2058,6 +2063,27 @@ func (m *ResponseCheckTx) GetCodespace() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ResponseCheckTx) GetSender() string {
|
||||
if m != nil {
|
||||
return m.Sender
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ResponseCheckTx) GetPriority() int64 {
|
||||
if m != nil {
|
||||
return m.Priority
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ResponseCheckTx) GetMempoolError() string {
|
||||
if m != nil {
|
||||
return m.MempoolError
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ResponseDeliverTx struct {
|
||||
Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
|
||||
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
|
||||
@@ -3199,179 +3225,181 @@ func init() {
|
||||
func init() { proto.RegisterFile("tendermint/abci/types.proto", fileDescriptor_252557cfdd89a31a) }
|
||||
|
||||
var fileDescriptor_252557cfdd89a31a = []byte{
|
||||
// 2741 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5a, 0x4b, 0x73, 0x1b, 0xc7,
|
||||
0x11, 0xc6, 0xfb, 0xd1, 0x24, 0x1e, 0x1c, 0xd1, 0x12, 0xb4, 0x92, 0x48, 0x79, 0x55, 0x72, 0x2c,
|
||||
0xd9, 0x26, 0x63, 0xaa, 0xa4, 0x48, 0xb1, 0x13, 0x9b, 0x80, 0x20, 0x83, 0x26, 0x4d, 0x30, 0x4b,
|
||||
0x48, 0xce, 0xcb, 0x5a, 0x2f, 0xb0, 0x43, 0x60, 0x2d, 0x60, 0x77, 0x8d, 0x1d, 0x50, 0xa4, 0x8f,
|
||||
0x71, 0x72, 0x51, 0x2e, 0xce, 0x2d, 0x17, 0xff, 0x8f, 0x9c, 0x72, 0xc9, 0xc5, 0x55, 0xb9, 0xf8,
|
||||
0x98, 0x93, 0x93, 0x92, 0x2a, 0x97, 0xfc, 0x81, 0x9c, 0x52, 0x49, 0xcd, 0x63, 0x5f, 0x00, 0x16,
|
||||
0x00, 0xed, 0xdc, 0x7c, 0x9b, 0x99, 0xed, 0xee, 0xc5, 0xf4, 0x4e, 0x7f, 0xfd, 0x75, 0x0f, 0xe0,
|
||||
0x12, 0xc1, 0xa6, 0x8e, 0x87, 0x03, 0xc3, 0x24, 0x9b, 0x5a, 0xbb, 0x63, 0x6c, 0x92, 0x53, 0x1b,
|
||||
0x3b, 0x1b, 0xf6, 0xd0, 0x22, 0x16, 0x2a, 0xf9, 0x0f, 0x37, 0xe8, 0x43, 0xe9, 0x4a, 0x40, 0xba,
|
||||
0x33, 0x3c, 0xb5, 0x89, 0xb5, 0x69, 0x0f, 0x2d, 0xeb, 0x88, 0xcb, 0x4b, 0x97, 0x03, 0x8f, 0x99,
|
||||
0x9d, 0xa0, 0xb5, 0xd0, 0x53, 0xa1, 0xfc, 0x04, 0x9f, 0xba, 0x4f, 0xaf, 0x4c, 0xe8, 0xda, 0xda,
|
||||
0x50, 0x1b, 0xb8, 0x8f, 0xd7, 0xbb, 0x96, 0xd5, 0xed, 0xe3, 0x4d, 0x36, 0x6b, 0x8f, 0x8e, 0x36,
|
||||
0x89, 0x31, 0xc0, 0x0e, 0xd1, 0x06, 0xb6, 0x10, 0x58, 0xed, 0x5a, 0x5d, 0x8b, 0x0d, 0x37, 0xe9,
|
||||
0x88, 0xaf, 0xca, 0x7f, 0xc8, 0x41, 0x56, 0xc1, 0x9f, 0x8e, 0xb0, 0x43, 0xd0, 0x16, 0xa4, 0x70,
|
||||
0xa7, 0x67, 0x55, 0xe2, 0x57, 0xe3, 0xaf, 0x2e, 0x6d, 0x5d, 0xde, 0x18, 0xdb, 0xdc, 0x86, 0x90,
|
||||
0xab, 0x77, 0x7a, 0x56, 0x23, 0xa6, 0x30, 0x59, 0x74, 0x1b, 0xd2, 0x47, 0xfd, 0x91, 0xd3, 0xab,
|
||||
0x24, 0x98, 0xd2, 0x95, 0x28, 0xa5, 0x07, 0x54, 0xa8, 0x11, 0x53, 0xb8, 0x34, 0x7d, 0x95, 0x61,
|
||||
0x1e, 0x59, 0x95, 0xe4, 0xec, 0x57, 0xed, 0x98, 0x47, 0xec, 0x55, 0x54, 0x16, 0x55, 0x01, 0x1c,
|
||||
0x4c, 0x54, 0xcb, 0x26, 0x86, 0x65, 0x56, 0x52, 0x4c, 0xf3, 0xe5, 0x28, 0xcd, 0x43, 0x4c, 0x9a,
|
||||
0x4c, 0xb0, 0x11, 0x53, 0xf2, 0x8e, 0x3b, 0xa1, 0x36, 0x0c, 0xd3, 0x20, 0x6a, 0xa7, 0xa7, 0x19,
|
||||
0x66, 0x25, 0x3d, 0xdb, 0xc6, 0x8e, 0x69, 0x90, 0x1a, 0x15, 0xa4, 0x36, 0x0c, 0x77, 0x42, 0xb7,
|
||||
0xfc, 0xe9, 0x08, 0x0f, 0x4f, 0x2b, 0x99, 0xd9, 0x5b, 0xfe, 0x19, 0x15, 0xa2, 0x5b, 0x66, 0xd2,
|
||||
0xa8, 0x0e, 0x4b, 0x6d, 0xdc, 0x35, 0x4c, 0xb5, 0xdd, 0xb7, 0x3a, 0x4f, 0x2a, 0x59, 0xa6, 0x2c,
|
||||
0x47, 0x29, 0x57, 0xa9, 0x68, 0x95, 0x4a, 0x36, 0x62, 0x0a, 0xb4, 0xbd, 0x19, 0x7a, 0x1b, 0x72,
|
||||
0x9d, 0x1e, 0xee, 0x3c, 0x51, 0xc9, 0x49, 0x25, 0xc7, 0x6c, 0xac, 0x47, 0xd9, 0xa8, 0x51, 0xb9,
|
||||
0xd6, 0x49, 0x23, 0xa6, 0x64, 0x3b, 0x7c, 0x48, 0xf7, 0xaf, 0xe3, 0xbe, 0x71, 0x8c, 0x87, 0x54,
|
||||
0x3f, 0x3f, 0x7b, 0xff, 0xf7, 0xb9, 0x24, 0xb3, 0x90, 0xd7, 0xdd, 0x09, 0x7a, 0x07, 0xf2, 0xd8,
|
||||
0xd4, 0xc5, 0x36, 0x80, 0x99, 0xb8, 0x1a, 0x79, 0x56, 0x4c, 0xdd, 0xdd, 0x44, 0x0e, 0x8b, 0x31,
|
||||
0xba, 0x0b, 0x99, 0x8e, 0x35, 0x18, 0x18, 0xa4, 0xb2, 0xc4, 0xb4, 0xd7, 0x22, 0x37, 0xc0, 0xa4,
|
||||
0x1a, 0x31, 0x45, 0xc8, 0xa3, 0x7d, 0x28, 0xf6, 0x0d, 0x87, 0xa8, 0x8e, 0xa9, 0xd9, 0x4e, 0xcf,
|
||||
0x22, 0x4e, 0x65, 0x99, 0x59, 0xb8, 0x1e, 0x65, 0x61, 0xcf, 0x70, 0xc8, 0xa1, 0x2b, 0xdc, 0x88,
|
||||
0x29, 0x85, 0x7e, 0x70, 0x81, 0xda, 0xb3, 0x8e, 0x8e, 0xf0, 0xd0, 0x33, 0x58, 0x29, 0xcc, 0xb6,
|
||||
0xd7, 0xa4, 0xd2, 0xae, 0x3e, 0xb5, 0x67, 0x05, 0x17, 0xd0, 0xaf, 0xe0, 0x5c, 0xdf, 0xd2, 0x74,
|
||||
0xcf, 0x9c, 0xda, 0xe9, 0x8d, 0xcc, 0x27, 0x95, 0x22, 0x33, 0x7a, 0x23, 0xf2, 0x47, 0x5a, 0x9a,
|
||||
0xee, 0x9a, 0xa8, 0x51, 0x85, 0x46, 0x4c, 0x59, 0xe9, 0x8f, 0x2f, 0xa2, 0xc7, 0xb0, 0xaa, 0xd9,
|
||||
0x76, 0xff, 0x74, 0xdc, 0x7a, 0x89, 0x59, 0xbf, 0x19, 0x65, 0x7d, 0x9b, 0xea, 0x8c, 0x9b, 0x47,
|
||||
0xda, 0xc4, 0x6a, 0x35, 0x0b, 0xe9, 0x63, 0xad, 0x3f, 0xc2, 0xf2, 0x0f, 0x60, 0x29, 0x10, 0xea,
|
||||
0xa8, 0x02, 0xd9, 0x01, 0x76, 0x1c, 0xad, 0x8b, 0x19, 0x32, 0xe4, 0x15, 0x77, 0x2a, 0x17, 0x61,
|
||||
0x39, 0x18, 0xde, 0xf2, 0xc0, 0x53, 0xa4, 0x81, 0x4b, 0x15, 0x8f, 0xf1, 0xd0, 0xa1, 0xd1, 0x2a,
|
||||
0x14, 0xc5, 0x14, 0x5d, 0x83, 0x02, 0x3b, 0x3e, 0xaa, 0xfb, 0x9c, 0xa2, 0x47, 0x4a, 0x59, 0x66,
|
||||
0x8b, 0x8f, 0x84, 0xd0, 0x3a, 0x2c, 0xd9, 0x5b, 0xb6, 0x27, 0x92, 0x64, 0x22, 0x60, 0x6f, 0xd9,
|
||||
0x42, 0x40, 0xfe, 0x31, 0x94, 0xc7, 0xa3, 0x1d, 0x95, 0x21, 0xf9, 0x04, 0x9f, 0x8a, 0xf7, 0xd1,
|
||||
0x21, 0x5a, 0x15, 0xdb, 0x62, 0xef, 0xc8, 0x2b, 0x62, 0x8f, 0x7f, 0x4d, 0x78, 0xca, 0x5e, 0x98,
|
||||
0xa3, 0xbb, 0x90, 0xa2, 0xa8, 0x29, 0x00, 0x50, 0xda, 0xe0, 0x90, 0xba, 0xe1, 0x42, 0xea, 0x46,
|
||||
0xcb, 0x85, 0xd4, 0x6a, 0xee, 0xab, 0x6f, 0xd6, 0x63, 0x5f, 0xfc, 0x7d, 0x3d, 0xae, 0x30, 0x0d,
|
||||
0x74, 0x91, 0x46, 0xa5, 0x66, 0x98, 0xaa, 0xa1, 0x8b, 0xf7, 0x64, 0xd9, 0x7c, 0x47, 0x47, 0xbb,
|
||||
0x50, 0xee, 0x58, 0xa6, 0x83, 0x4d, 0x67, 0xe4, 0xa8, 0x1c, 0xb2, 0x05, 0xec, 0x4d, 0x46, 0x4d,
|
||||
0xcd, 0x15, 0x3c, 0x60, 0x72, 0x4a, 0xa9, 0x13, 0x5e, 0x40, 0x0f, 0x00, 0x8e, 0xb5, 0xbe, 0xa1,
|
||||
0x6b, 0xc4, 0x1a, 0x3a, 0x95, 0xd4, 0xd5, 0xe4, 0x54, 0x33, 0x8f, 0x5c, 0x91, 0x87, 0xb6, 0xae,
|
||||
0x11, 0x5c, 0x4d, 0xd1, 0x5f, 0xab, 0x04, 0x34, 0xd1, 0x2b, 0x50, 0xd2, 0x6c, 0x5b, 0x75, 0x88,
|
||||
0x46, 0xb0, 0xda, 0x3e, 0x25, 0xd8, 0x61, 0x60, 0xb8, 0xac, 0x14, 0x34, 0xdb, 0x3e, 0xa4, 0xab,
|
||||
0x55, 0xba, 0x88, 0xae, 0x43, 0x91, 0x02, 0x9f, 0xa1, 0xf5, 0xd5, 0x1e, 0x36, 0xba, 0x3d, 0xc2,
|
||||
0x40, 0x2f, 0xa9, 0x14, 0xc4, 0x6a, 0x83, 0x2d, 0xca, 0xba, 0x77, 0x10, 0x18, 0xe8, 0x21, 0x04,
|
||||
0x29, 0x5d, 0x23, 0x1a, 0x73, 0xe4, 0xb2, 0xc2, 0xc6, 0x74, 0xcd, 0xd6, 0x48, 0x4f, 0xb8, 0x87,
|
||||
0x8d, 0xd1, 0x79, 0xc8, 0x08, 0xb3, 0x49, 0x66, 0x56, 0xcc, 0xe8, 0x37, 0xb3, 0x87, 0xd6, 0x31,
|
||||
0x66, 0x28, 0x9f, 0x53, 0xf8, 0x44, 0xfe, 0x6d, 0x02, 0x56, 0x26, 0xe0, 0x91, 0xda, 0xed, 0x69,
|
||||
0x4e, 0xcf, 0x7d, 0x17, 0x1d, 0xa3, 0x3b, 0xd4, 0xae, 0xa6, 0xe3, 0xa1, 0x48, 0x4b, 0x95, 0xa0,
|
||||
0x8b, 0x78, 0xca, 0x6d, 0xb0, 0xe7, 0xc2, 0x35, 0x42, 0x1a, 0x35, 0xa1, 0xdc, 0xd7, 0x1c, 0xa2,
|
||||
0x72, 0xb8, 0x51, 0x03, 0x29, 0x6a, 0x12, 0x64, 0xf7, 0x34, 0x17, 0xa0, 0xe8, 0x61, 0x17, 0x86,
|
||||
0x8a, 0xfd, 0xd0, 0x2a, 0x52, 0x60, 0xb5, 0x7d, 0xfa, 0x99, 0x66, 0x12, 0xc3, 0xc4, 0xea, 0xc4,
|
||||
0x97, 0xbb, 0x38, 0x61, 0xb4, 0x7e, 0x6c, 0xe8, 0xd8, 0xec, 0xb8, 0x9f, 0xec, 0x9c, 0xa7, 0xec,
|
||||
0x7d, 0x52, 0x47, 0x56, 0xa0, 0x18, 0x06, 0x78, 0x54, 0x84, 0x04, 0x39, 0x11, 0x0e, 0x48, 0x90,
|
||||
0x13, 0xf4, 0x43, 0x48, 0xd1, 0x4d, 0xb2, 0xcd, 0x17, 0xa7, 0x64, 0x57, 0xa1, 0xd7, 0x3a, 0xb5,
|
||||
0xb1, 0xc2, 0x24, 0x65, 0xd9, 0x8b, 0x06, 0x0f, 0xf4, 0xc7, 0xad, 0xca, 0x37, 0xa0, 0x34, 0x86,
|
||||
0xea, 0x81, 0xef, 0x17, 0x0f, 0x7e, 0x3f, 0xb9, 0x04, 0x85, 0x10, 0x84, 0xcb, 0xe7, 0x61, 0x75,
|
||||
0x1a, 0x22, 0xcb, 0x3d, 0x6f, 0x3d, 0x84, 0xac, 0xe8, 0x36, 0xe4, 0x3c, 0x48, 0xe6, 0xd1, 0x38,
|
||||
0xe9, 0x2b, 0x57, 0x58, 0xf1, 0x44, 0x69, 0x18, 0xd2, 0x63, 0xcd, 0xce, 0x43, 0x82, 0xfd, 0xf0,
|
||||
0xac, 0x66, 0xdb, 0x0d, 0xcd, 0xe9, 0xc9, 0x1f, 0x43, 0x25, 0x0a, 0x6e, 0xc7, 0xb6, 0x91, 0xf2,
|
||||
0x8e, 0xe1, 0x79, 0xc8, 0x1c, 0x59, 0xc3, 0x81, 0x46, 0x98, 0xb1, 0x82, 0x22, 0x66, 0xf4, 0x78,
|
||||
0x72, 0xe8, 0x4d, 0xb2, 0x65, 0x3e, 0x91, 0x55, 0xb8, 0x18, 0x09, 0xb9, 0x54, 0xc5, 0x30, 0x75,
|
||||
0xcc, 0xfd, 0x59, 0x50, 0xf8, 0xc4, 0x37, 0xc4, 0x7f, 0x2c, 0x9f, 0xd0, 0xd7, 0x3a, 0x6c, 0xaf,
|
||||
0xcc, 0x7e, 0x5e, 0x11, 0x33, 0xf9, 0x9f, 0x39, 0xc8, 0x29, 0xd8, 0xb1, 0x29, 0x26, 0xa0, 0x2a,
|
||||
0xe4, 0xf1, 0x49, 0x07, 0x73, 0x32, 0x14, 0x8f, 0x24, 0x13, 0x5c, 0xba, 0xee, 0x4a, 0xd2, 0x4c,
|
||||
0xee, 0xa9, 0xa1, 0x5b, 0x82, 0xf0, 0x45, 0x73, 0x37, 0xa1, 0x1e, 0x64, 0x7c, 0x77, 0x5c, 0xc6,
|
||||
0x97, 0x8c, 0x4c, 0xde, 0x5c, 0x6b, 0x8c, 0xf2, 0xdd, 0x12, 0x94, 0x2f, 0x35, 0xe7, 0x65, 0x21,
|
||||
0xce, 0x57, 0x0b, 0x71, 0xbe, 0xf4, 0x9c, 0x6d, 0x46, 0x90, 0xbe, 0x5a, 0x88, 0xf4, 0x65, 0xe6,
|
||||
0x18, 0x89, 0x60, 0x7d, 0x77, 0x5c, 0xd6, 0x97, 0x9d, 0xb3, 0xed, 0x31, 0xda, 0xf7, 0x20, 0x4c,
|
||||
0xfb, 0x38, 0x65, 0xbb, 0x16, 0xa9, 0x1d, 0xc9, 0xfb, 0x7e, 0x12, 0xe0, 0x7d, 0xf9, 0x48, 0xd2,
|
||||
0xc5, 0x8d, 0x4c, 0x21, 0x7e, 0xb5, 0x10, 0xf1, 0x83, 0x39, 0x3e, 0x88, 0x60, 0x7e, 0xef, 0x06,
|
||||
0x99, 0xdf, 0x52, 0x24, 0x79, 0x14, 0x87, 0x66, 0x1a, 0xf5, 0xbb, 0xe7, 0x51, 0xbf, 0xe5, 0x48,
|
||||
0xee, 0x2a, 0xf6, 0x30, 0xce, 0xfd, 0x9a, 0x13, 0xdc, 0x8f, 0x73, 0xb5, 0x57, 0x22, 0x4d, 0xcc,
|
||||
0x21, 0x7f, 0xcd, 0x09, 0xf2, 0x57, 0x9c, 0x63, 0x70, 0x0e, 0xfb, 0xfb, 0xf5, 0x74, 0xf6, 0x17,
|
||||
0xcd, 0xcf, 0xc4, 0xcf, 0x5c, 0x8c, 0xfe, 0xa9, 0x11, 0xf4, 0xaf, 0xcc, 0xcc, 0xbf, 0x16, 0x69,
|
||||
0xfe, 0xec, 0xfc, 0xef, 0x06, 0x4d, 0xb3, 0x63, 0xc0, 0x41, 0xa1, 0x0a, 0x0f, 0x87, 0xd6, 0x50,
|
||||
0x50, 0x2b, 0x3e, 0x91, 0x5f, 0xa5, 0x89, 0xdf, 0x07, 0x89, 0x19, 0x5c, 0x91, 0xa5, 0x84, 0x00,
|
||||
0x30, 0xc8, 0x7f, 0x8a, 0xfb, 0xba, 0x2c, 0x57, 0x06, 0x49, 0x43, 0x5e, 0x90, 0x86, 0x00, 0x85,
|
||||
0x4c, 0x84, 0x29, 0xe4, 0x3a, 0x2c, 0x51, 0xa8, 0x1f, 0x63, 0x87, 0x9a, 0xed, 0xb2, 0x43, 0x74,
|
||||
0x13, 0x56, 0x58, 0x2e, 0xe7, 0x44, 0x53, 0xe0, 0x7b, 0x8a, 0xa5, 0xa9, 0x12, 0x7d, 0xc0, 0x0f,
|
||||
0x27, 0x07, 0xfa, 0x37, 0xe0, 0x5c, 0x40, 0xd6, 0x4b, 0x21, 0x9c, 0x12, 0x95, 0x3d, 0xe9, 0x6d,
|
||||
0x91, 0x4b, 0x3e, 0xf0, 0x1d, 0xe4, 0x33, 0x4f, 0x04, 0xa9, 0x8e, 0xa5, 0x63, 0x01, 0xf0, 0x6c,
|
||||
0x4c, 0xd9, 0x68, 0xdf, 0xea, 0x0a, 0x18, 0xa7, 0x43, 0x2a, 0xe5, 0xa1, 0x60, 0x9e, 0x83, 0x9c,
|
||||
0xfc, 0x97, 0xb8, 0x6f, 0xcf, 0x27, 0xa3, 0xd3, 0x78, 0x63, 0xfc, 0xff, 0xc3, 0x1b, 0x13, 0xdf,
|
||||
0x9a, 0x37, 0x06, 0x13, 0x6c, 0x32, 0x9c, 0x60, 0xff, 0x1d, 0xf7, 0xbf, 0xb0, 0xc7, 0x02, 0xbf,
|
||||
0x9d, 0x47, 0xfc, 0x6c, 0x99, 0x66, 0xdf, 0x4b, 0x64, 0x4b, 0xc1, 0xed, 0x33, 0xec, 0xbd, 0x61,
|
||||
0x6e, 0x9f, 0xe5, 0xf9, 0x93, 0x4d, 0xd0, 0x5d, 0xc8, 0xb3, 0xa6, 0x8b, 0x6a, 0xd9, 0x8e, 0x00,
|
||||
0xdc, 0x4b, 0xc1, 0xbd, 0xf2, 0xde, 0xca, 0xc6, 0x01, 0x95, 0x69, 0xda, 0x8e, 0x92, 0xb3, 0xc5,
|
||||
0x28, 0x40, 0x04, 0xf2, 0x21, 0x3e, 0x7a, 0x19, 0xf2, 0xf4, 0xd7, 0x3b, 0xb6, 0xd6, 0xc1, 0x0c,
|
||||
0x3c, 0xf3, 0x8a, 0xbf, 0x20, 0x3f, 0x06, 0x34, 0x09, 0xdf, 0xa8, 0x01, 0x19, 0x7c, 0x8c, 0x4d,
|
||||
0x42, 0xbf, 0x1a, 0x75, 0xf7, 0xf9, 0x29, 0x64, 0x0f, 0x9b, 0xa4, 0x5a, 0xa1, 0x4e, 0xfe, 0xd7,
|
||||
0x37, 0xeb, 0x65, 0x2e, 0xfd, 0xba, 0x35, 0x30, 0x08, 0x1e, 0xd8, 0xe4, 0x54, 0x11, 0xfa, 0xf2,
|
||||
0xe7, 0x09, 0xca, 0xbc, 0x42, 0xd0, 0x3e, 0xd5, 0xb7, 0x6e, 0x00, 0x25, 0x02, 0xac, 0x7b, 0x31,
|
||||
0x7f, 0xaf, 0x01, 0x74, 0x35, 0x47, 0x7d, 0xaa, 0x99, 0x04, 0xeb, 0xc2, 0xe9, 0x81, 0x15, 0x24,
|
||||
0x41, 0x8e, 0xce, 0x46, 0x0e, 0xd6, 0x45, 0x01, 0xe0, 0xcd, 0x03, 0xfb, 0xcc, 0x7e, 0xb7, 0x7d,
|
||||
0x86, 0xbd, 0x9c, 0x1b, 0xf7, 0xf2, 0xef, 0x12, 0x7e, 0x94, 0xf8, 0x24, 0xf5, 0xfb, 0xe7, 0x87,
|
||||
0xdf, 0xb3, 0xca, 0x35, 0x9c, 0x63, 0xd1, 0x21, 0xac, 0x78, 0x51, 0xaa, 0x8e, 0x58, 0xf4, 0xba,
|
||||
0xe7, 0x6e, 0xd1, 0x30, 0x2f, 0x1f, 0x87, 0x97, 0x1d, 0xf4, 0x73, 0xb8, 0x30, 0x86, 0x40, 0x9e,
|
||||
0xe9, 0xc4, 0x82, 0x40, 0xf4, 0x52, 0x18, 0x88, 0x5c, 0xcb, 0xbe, 0xaf, 0x92, 0xdf, 0x31, 0x36,
|
||||
0x76, 0x68, 0x31, 0x14, 0x64, 0x0c, 0x53, 0xbf, 0xfe, 0x35, 0x28, 0x0c, 0x31, 0xa1, 0xf5, 0x79,
|
||||
0xa8, 0xdc, 0x5c, 0xe6, 0x8b, 0xa2, 0x88, 0x3d, 0x80, 0x97, 0xa6, 0x32, 0x07, 0xf4, 0x23, 0xc8,
|
||||
0xfb, 0xa4, 0x23, 0x1e, 0x51, 0xb9, 0x79, 0xd5, 0x88, 0x2f, 0x2b, 0xff, 0x39, 0xee, 0x9b, 0x0c,
|
||||
0xd7, 0x37, 0x75, 0xc8, 0x0c, 0xb1, 0x33, 0xea, 0xf3, 0x8a, 0xa3, 0xb8, 0xf5, 0xc6, 0x62, 0x9c,
|
||||
0x83, 0xae, 0x8e, 0xfa, 0x44, 0x11, 0xca, 0xf2, 0x63, 0xc8, 0xf0, 0x15, 0xb4, 0x04, 0xd9, 0x87,
|
||||
0xfb, 0xbb, 0xfb, 0xcd, 0x0f, 0xf7, 0xcb, 0x31, 0x04, 0x90, 0xd9, 0xae, 0xd5, 0xea, 0x07, 0xad,
|
||||
0x72, 0x1c, 0xe5, 0x21, 0xbd, 0x5d, 0x6d, 0x2a, 0xad, 0x72, 0x82, 0x2e, 0x2b, 0xf5, 0xf7, 0xeb,
|
||||
0xb5, 0x56, 0x39, 0x89, 0x56, 0xa0, 0xc0, 0xc7, 0xea, 0x83, 0xa6, 0xf2, 0xc1, 0x76, 0xab, 0x9c,
|
||||
0x0a, 0x2c, 0x1d, 0xd6, 0xf7, 0xef, 0xd7, 0x95, 0x72, 0x5a, 0x7e, 0x93, 0x96, 0x34, 0x11, 0x2c,
|
||||
0xc5, 0x2f, 0x5e, 0xe2, 0x81, 0xe2, 0x45, 0xfe, 0x63, 0x02, 0xa4, 0x68, 0xea, 0x81, 0xde, 0x1f,
|
||||
0xdb, 0xf8, 0xd6, 0x19, 0x78, 0xcb, 0xd8, 0xee, 0xd1, 0x75, 0x28, 0x0e, 0xf1, 0x11, 0x26, 0x9d,
|
||||
0x1e, 0xa7, 0x42, 0x3c, 0xb1, 0x15, 0x94, 0x82, 0x58, 0x65, 0x4a, 0x0e, 0x17, 0xfb, 0x04, 0x77,
|
||||
0x88, 0xca, 0xeb, 0x28, 0x7e, 0xe8, 0xf2, 0x54, 0x8c, 0xae, 0x1e, 0xf2, 0x45, 0xf9, 0xe3, 0x33,
|
||||
0xf9, 0x32, 0x0f, 0x69, 0xa5, 0xde, 0x52, 0x7e, 0x51, 0x4e, 0x22, 0x04, 0x45, 0x36, 0x54, 0x0f,
|
||||
0xf7, 0xb7, 0x0f, 0x0e, 0x1b, 0x4d, 0xea, 0xcb, 0x73, 0x50, 0x72, 0x7d, 0xe9, 0x2e, 0xa6, 0xe5,
|
||||
0xff, 0xc6, 0xa1, 0x34, 0x16, 0x20, 0x68, 0x0b, 0xd2, 0x9c, 0x4e, 0x47, 0x35, 0xdd, 0x59, 0x7c,
|
||||
0x8b, 0x68, 0xe2, 0xa2, 0xe8, 0x6d, 0xc8, 0x61, 0xd1, 0x27, 0x98, 0x16, 0x88, 0xbc, 0xbf, 0xe1,
|
||||
0x76, 0x12, 0x84, 0xaa, 0xa7, 0x81, 0xde, 0x81, 0xbc, 0x17, 0xe9, 0xa2, 0x86, 0x7b, 0x79, 0x52,
|
||||
0xdd, 0xc3, 0x08, 0xa1, 0xef, 0xeb, 0xa0, 0x7b, 0x3e, 0x27, 0x4b, 0x4d, 0x92, 0x78, 0xa1, 0xce,
|
||||
0x05, 0x84, 0xb2, 0x2b, 0x2f, 0xd7, 0x60, 0x29, 0xb0, 0x1f, 0x74, 0x09, 0xf2, 0x03, 0xed, 0x44,
|
||||
0xf4, 0x9f, 0x78, 0x07, 0x21, 0x37, 0xd0, 0x4e, 0x78, 0xeb, 0xe9, 0x02, 0x64, 0xe9, 0xc3, 0xae,
|
||||
0xc6, 0xd1, 0x26, 0xa9, 0x64, 0x06, 0xda, 0xc9, 0x7b, 0x9a, 0x23, 0x7f, 0x04, 0xc5, 0x70, 0xef,
|
||||
0x85, 0x9e, 0xc4, 0xa1, 0x35, 0x32, 0x75, 0x66, 0x23, 0xad, 0xf0, 0x09, 0xba, 0x0d, 0xe9, 0x63,
|
||||
0x8b, 0x83, 0xd5, 0xf4, 0x90, 0x7d, 0x64, 0x11, 0x1c, 0xe8, 0xdd, 0x70, 0x69, 0xf9, 0x33, 0x48,
|
||||
0x33, 0xf0, 0xa1, 0x40, 0xc2, 0xba, 0x28, 0x82, 0x8f, 0xd2, 0x31, 0xfa, 0x08, 0x40, 0x23, 0x64,
|
||||
0x68, 0xb4, 0x47, 0xbe, 0xe1, 0xf5, 0xe9, 0xe0, 0xb5, 0xed, 0xca, 0x55, 0x2f, 0x0b, 0x14, 0x5b,
|
||||
0xf5, 0x55, 0x03, 0x48, 0x16, 0x30, 0x28, 0xef, 0x43, 0x31, 0xac, 0x1b, 0xec, 0x67, 0x2e, 0x4f,
|
||||
0xe9, 0x67, 0x7a, 0x9c, 0xc7, 0x63, 0x4c, 0x49, 0xde, 0x31, 0x63, 0x13, 0xf9, 0x59, 0x1c, 0x72,
|
||||
0xad, 0x13, 0x71, 0xac, 0x23, 0x9a, 0x35, 0xbe, 0x6a, 0x22, 0xd8, 0x9a, 0xe0, 0xdd, 0x9f, 0xa4,
|
||||
0xd7, 0x53, 0x7a, 0xd7, 0x0b, 0xdc, 0xd4, 0xa2, 0xc5, 0xa3, 0xdb, 0x5c, 0x13, 0x60, 0xf5, 0x16,
|
||||
0xe4, 0xbd, 0x53, 0x45, 0x89, 0xbd, 0xa6, 0xeb, 0x43, 0xec, 0x38, 0x62, 0x6f, 0xee, 0x94, 0xf5,
|
||||
0xfe, 0xac, 0xa7, 0xa2, 0xf9, 0x91, 0x54, 0xf8, 0x44, 0xd6, 0xa1, 0x34, 0x96, 0xb6, 0xd0, 0x5b,
|
||||
0x90, 0xb5, 0x47, 0x6d, 0xd5, 0x75, 0xcf, 0x58, 0xf0, 0xb8, 0x24, 0x6f, 0xd4, 0xee, 0x1b, 0x9d,
|
||||
0x5d, 0x7c, 0xea, 0xfe, 0x18, 0x7b, 0xd4, 0xde, 0xe5, 0x5e, 0xe4, 0x6f, 0x49, 0x04, 0xdf, 0x72,
|
||||
0x0c, 0x39, 0xf7, 0x50, 0xa0, 0x9f, 0x06, 0xe3, 0xc4, 0xed, 0x08, 0x47, 0xa6, 0x52, 0x61, 0x3e,
|
||||
0x10, 0x26, 0x37, 0x61, 0xc5, 0x31, 0xba, 0x26, 0xd6, 0x55, 0xbf, 0xb4, 0x60, 0x6f, 0xcb, 0x29,
|
||||
0x25, 0xfe, 0x60, 0xcf, 0xad, 0x2b, 0xe4, 0xff, 0xc4, 0x21, 0xe7, 0x06, 0x2c, 0x7a, 0x33, 0x70,
|
||||
0xee, 0x8a, 0x53, 0x1a, 0x25, 0xae, 0xa0, 0xdf, 0xbe, 0x0b, 0xff, 0xd6, 0xc4, 0xd9, 0x7f, 0x6b,
|
||||
0x54, 0x1f, 0xd6, 0x6d, 0x88, 0xa7, 0xce, 0xdc, 0x10, 0x7f, 0x1d, 0x10, 0xb1, 0x88, 0xd6, 0x57,
|
||||
0x8f, 0x2d, 0x62, 0x98, 0x5d, 0x95, 0x3b, 0x9b, 0x33, 0xaa, 0x32, 0x7b, 0xf2, 0x88, 0x3d, 0x38,
|
||||
0x60, 0x7e, 0xff, 0x4d, 0x1c, 0x72, 0x5e, 0x6e, 0x3c, 0x6b, 0x37, 0xee, 0x3c, 0x64, 0x04, 0xfc,
|
||||
0xf3, 0x76, 0x9c, 0x98, 0x79, 0x8d, 0xe1, 0x54, 0xa0, 0x31, 0x2c, 0x41, 0x6e, 0x80, 0x89, 0xc6,
|
||||
0x08, 0x02, 0xaf, 0xee, 0xbc, 0xf9, 0xcd, 0x7b, 0xb0, 0x14, 0x68, 0x8c, 0xd2, 0xc8, 0xdb, 0xaf,
|
||||
0x7f, 0x58, 0x8e, 0x49, 0xd9, 0x67, 0x5f, 0x5e, 0x4d, 0xee, 0xe3, 0xa7, 0xf4, 0xcc, 0x2a, 0xf5,
|
||||
0x5a, 0xa3, 0x5e, 0xdb, 0x2d, 0xc7, 0xa5, 0xa5, 0x67, 0x5f, 0x5e, 0xcd, 0x2a, 0x98, 0xf5, 0x57,
|
||||
0x6e, 0x36, 0x60, 0x39, 0xf8, 0x55, 0xc2, 0x19, 0x04, 0x41, 0xf1, 0xfe, 0xc3, 0x83, 0xbd, 0x9d,
|
||||
0xda, 0x76, 0xab, 0xae, 0x3e, 0x6a, 0xb6, 0xea, 0xe5, 0x38, 0xba, 0x00, 0xe7, 0xf6, 0x76, 0xde,
|
||||
0x6b, 0xb4, 0xd4, 0xda, 0xde, 0x4e, 0x7d, 0xbf, 0xa5, 0x6e, 0xb7, 0x5a, 0xdb, 0xb5, 0xdd, 0x72,
|
||||
0x62, 0xeb, 0x73, 0x80, 0xd2, 0x76, 0xb5, 0xb6, 0x43, 0xb3, 0x9f, 0xd1, 0xd1, 0x44, 0xff, 0x2a,
|
||||
0xc5, 0x8a, 0xeb, 0x99, 0x37, 0xb2, 0xd2, 0xec, 0xf6, 0x1d, 0x7a, 0x00, 0x69, 0x56, 0x77, 0xa3,
|
||||
0xd9, 0x57, 0xb4, 0xd2, 0x9c, 0x7e, 0x1e, 0xfd, 0x31, 0x2c, 0x3c, 0x66, 0xde, 0xd9, 0x4a, 0xb3,
|
||||
0xdb, 0x7b, 0x48, 0x81, 0xbc, 0x5f, 0x38, 0xcf, 0xbf, 0xc3, 0x95, 0x16, 0x68, 0xf9, 0x51, 0x9b,
|
||||
0x7e, 0x59, 0x30, 0xff, 0x4e, 0x53, 0x5a, 0x00, 0xc0, 0xd0, 0x1e, 0x64, 0xdd, 0x82, 0x6b, 0xde,
|
||||
0x2d, 0xab, 0x34, 0xb7, 0x1d, 0x47, 0x3f, 0x01, 0x2f, 0x8c, 0x67, 0x5f, 0x19, 0x4b, 0x73, 0x7a,
|
||||
0x8b, 0x68, 0x07, 0x32, 0x82, 0xeb, 0xce, 0xb9, 0x39, 0x95, 0xe6, 0xb5, 0xd7, 0xa8, 0xd3, 0xfc,
|
||||
0x8e, 0xc3, 0xfc, 0x8b, 0x70, 0x69, 0x81, 0xb6, 0x29, 0x7a, 0x08, 0x10, 0x28, 0x83, 0x17, 0xb8,
|
||||
0xe1, 0x96, 0x16, 0x69, 0x87, 0xa2, 0x26, 0xe4, 0xbc, 0x72, 0x67, 0xee, 0x7d, 0xb3, 0x34, 0xbf,
|
||||
0x2f, 0x89, 0x1e, 0x43, 0x21, 0xcc, 0xf3, 0x17, 0xbb, 0x45, 0x96, 0x16, 0x6c, 0x38, 0x52, 0xfb,
|
||||
0x61, 0xd2, 0xbf, 0xd8, 0xad, 0xb2, 0xb4, 0x60, 0xff, 0x11, 0x7d, 0x02, 0x2b, 0x93, 0xa4, 0x7c,
|
||||
0xf1, 0x4b, 0x66, 0xe9, 0x0c, 0x1d, 0x49, 0x34, 0x00, 0x34, 0x85, 0xcc, 0x9f, 0xe1, 0xce, 0x59,
|
||||
0x3a, 0x4b, 0x83, 0xb2, 0x5a, 0xff, 0xea, 0xf9, 0x5a, 0xfc, 0xeb, 0xe7, 0x6b, 0xf1, 0x7f, 0x3c,
|
||||
0x5f, 0x8b, 0x7f, 0xf1, 0x62, 0x2d, 0xf6, 0xf5, 0x8b, 0xb5, 0xd8, 0xdf, 0x5e, 0xac, 0xc5, 0x7e,
|
||||
0xf9, 0x5a, 0xd7, 0x20, 0xbd, 0x51, 0x7b, 0xa3, 0x63, 0x0d, 0x36, 0x83, 0x7f, 0x88, 0x99, 0xf6,
|
||||
0x27, 0x9d, 0x76, 0x86, 0x25, 0xaa, 0x5b, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x3b, 0xae, 0x48,
|
||||
0xb4, 0xc4, 0x23, 0x00, 0x00,
|
||||
// 2782 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5a, 0x4b, 0x77, 0x23, 0xc5,
|
||||
0xf5, 0xd7, 0x5b, 0xea, 0x2b, 0xeb, 0xe1, 0x1a, 0x33, 0x08, 0x31, 0xd8, 0x43, 0x73, 0xe0, 0x0f,
|
||||
0x03, 0xd8, 0x7f, 0xcc, 0x81, 0x40, 0x20, 0x01, 0x4b, 0x68, 0x90, 0xb1, 0xb1, 0x9c, 0xb6, 0x66,
|
||||
0xc8, 0x8b, 0x69, 0x5a, 0xea, 0xb2, 0xd4, 0x8c, 0xd4, 0xdd, 0x74, 0x97, 0x8c, 0xc5, 0x32, 0x8f,
|
||||
0x0d, 0xd9, 0x90, 0x5d, 0x36, 0x7c, 0x8f, 0xac, 0xb2, 0xc9, 0x86, 0x73, 0xb2, 0x61, 0x99, 0x45,
|
||||
0x0e, 0xc9, 0x99, 0x39, 0xd9, 0xe4, 0x0b, 0x64, 0x95, 0x93, 0x9c, 0x7a, 0xf4, 0x4b, 0x52, 0x4b,
|
||||
0x32, 0x64, 0x97, 0x5d, 0xd5, 0xed, 0x7b, 0x6f, 0xab, 0xaa, 0xeb, 0xfe, 0xee, 0xef, 0xde, 0x12,
|
||||
0x3c, 0x4e, 0xb0, 0xa9, 0x63, 0x67, 0x6c, 0x98, 0x64, 0x4f, 0xeb, 0xf5, 0x8d, 0x3d, 0x32, 0xb5,
|
||||
0xb1, 0xbb, 0x6b, 0x3b, 0x16, 0xb1, 0x50, 0x25, 0x78, 0xb8, 0x4b, 0x1f, 0xd6, 0x9f, 0x08, 0x69,
|
||||
0xf7, 0x9d, 0xa9, 0x4d, 0xac, 0x3d, 0xdb, 0xb1, 0xac, 0x73, 0xae, 0x5f, 0xbf, 0x11, 0x7a, 0xcc,
|
||||
0xfc, 0x84, 0xbd, 0x45, 0x9e, 0x0a, 0xe3, 0xfb, 0x78, 0xea, 0x3d, 0x7d, 0x62, 0xce, 0xd6, 0xd6,
|
||||
0x1c, 0x6d, 0xec, 0x3d, 0xde, 0x19, 0x58, 0xd6, 0x60, 0x84, 0xf7, 0xd8, 0xac, 0x37, 0x39, 0xdf,
|
||||
0x23, 0xc6, 0x18, 0xbb, 0x44, 0x1b, 0xdb, 0x42, 0x61, 0x6b, 0x60, 0x0d, 0x2c, 0x36, 0xdc, 0xa3,
|
||||
0x23, 0x2e, 0x95, 0x7f, 0x5b, 0x80, 0xbc, 0x82, 0x3f, 0x99, 0x60, 0x97, 0xa0, 0x7d, 0xc8, 0xe0,
|
||||
0xfe, 0xd0, 0xaa, 0x25, 0x6f, 0x26, 0x9f, 0x2d, 0xee, 0xdf, 0xd8, 0x9d, 0x59, 0xdc, 0xae, 0xd0,
|
||||
0x6b, 0xf5, 0x87, 0x56, 0x3b, 0xa1, 0x30, 0x5d, 0xf4, 0x0a, 0x64, 0xcf, 0x47, 0x13, 0x77, 0x58,
|
||||
0x4b, 0x31, 0xa3, 0x27, 0xe2, 0x8c, 0x6e, 0x53, 0xa5, 0x76, 0x42, 0xe1, 0xda, 0xf4, 0x55, 0x86,
|
||||
0x79, 0x6e, 0xd5, 0xd2, 0xcb, 0x5f, 0x75, 0x68, 0x9e, 0xb3, 0x57, 0x51, 0x5d, 0xd4, 0x00, 0x70,
|
||||
0x31, 0x51, 0x2d, 0x9b, 0x18, 0x96, 0x59, 0xcb, 0x30, 0xcb, 0x27, 0xe3, 0x2c, 0xcf, 0x30, 0xe9,
|
||||
0x30, 0xc5, 0x76, 0x42, 0x91, 0x5c, 0x6f, 0x42, 0x7d, 0x18, 0xa6, 0x41, 0xd4, 0xfe, 0x50, 0x33,
|
||||
0xcc, 0x5a, 0x76, 0xb9, 0x8f, 0x43, 0xd3, 0x20, 0x4d, 0xaa, 0x48, 0x7d, 0x18, 0xde, 0x84, 0x2e,
|
||||
0xf9, 0x93, 0x09, 0x76, 0xa6, 0xb5, 0xdc, 0xf2, 0x25, 0xff, 0x88, 0x2a, 0xd1, 0x25, 0x33, 0x6d,
|
||||
0xd4, 0x82, 0x62, 0x0f, 0x0f, 0x0c, 0x53, 0xed, 0x8d, 0xac, 0xfe, 0xfd, 0x5a, 0x9e, 0x19, 0xcb,
|
||||
0x71, 0xc6, 0x0d, 0xaa, 0xda, 0xa0, 0x9a, 0xed, 0x84, 0x02, 0x3d, 0x7f, 0x86, 0xde, 0x84, 0x42,
|
||||
0x7f, 0x88, 0xfb, 0xf7, 0x55, 0x72, 0x59, 0x2b, 0x30, 0x1f, 0x3b, 0x71, 0x3e, 0x9a, 0x54, 0xaf,
|
||||
0x7b, 0xd9, 0x4e, 0x28, 0xf9, 0x3e, 0x1f, 0xd2, 0xf5, 0xeb, 0x78, 0x64, 0x5c, 0x60, 0x87, 0xda,
|
||||
0x4b, 0xcb, 0xd7, 0xff, 0x0e, 0xd7, 0x64, 0x1e, 0x24, 0xdd, 0x9b, 0xa0, 0xb7, 0x40, 0xc2, 0xa6,
|
||||
0x2e, 0x96, 0x01, 0xcc, 0xc5, 0xcd, 0xd8, 0xb3, 0x62, 0xea, 0xde, 0x22, 0x0a, 0x58, 0x8c, 0xd1,
|
||||
0x6b, 0x90, 0xeb, 0x5b, 0xe3, 0xb1, 0x41, 0x6a, 0x45, 0x66, 0xbd, 0x1d, 0xbb, 0x00, 0xa6, 0xd5,
|
||||
0x4e, 0x28, 0x42, 0x1f, 0x9d, 0x40, 0x79, 0x64, 0xb8, 0x44, 0x75, 0x4d, 0xcd, 0x76, 0x87, 0x16,
|
||||
0x71, 0x6b, 0x1b, 0xcc, 0xc3, 0xd3, 0x71, 0x1e, 0x8e, 0x0d, 0x97, 0x9c, 0x79, 0xca, 0xed, 0x84,
|
||||
0x52, 0x1a, 0x85, 0x05, 0xd4, 0x9f, 0x75, 0x7e, 0x8e, 0x1d, 0xdf, 0x61, 0xad, 0xb4, 0xdc, 0x5f,
|
||||
0x87, 0x6a, 0x7b, 0xf6, 0xd4, 0x9f, 0x15, 0x16, 0xa0, 0x9f, 0xc1, 0xb5, 0x91, 0xa5, 0xe9, 0xbe,
|
||||
0x3b, 0xb5, 0x3f, 0x9c, 0x98, 0xf7, 0x6b, 0x65, 0xe6, 0xf4, 0xb9, 0xd8, 0x1f, 0x69, 0x69, 0xba,
|
||||
0xe7, 0xa2, 0x49, 0x0d, 0xda, 0x09, 0x65, 0x73, 0x34, 0x2b, 0x44, 0xf7, 0x60, 0x4b, 0xb3, 0xed,
|
||||
0xd1, 0x74, 0xd6, 0x7b, 0x85, 0x79, 0xbf, 0x15, 0xe7, 0xfd, 0x80, 0xda, 0xcc, 0xba, 0x47, 0xda,
|
||||
0x9c, 0xb4, 0x91, 0x87, 0xec, 0x85, 0x36, 0x9a, 0x60, 0xf9, 0xff, 0xa0, 0x18, 0x0a, 0x75, 0x54,
|
||||
0x83, 0xfc, 0x18, 0xbb, 0xae, 0x36, 0xc0, 0x0c, 0x19, 0x24, 0xc5, 0x9b, 0xca, 0x65, 0xd8, 0x08,
|
||||
0x87, 0xb7, 0x3c, 0xf6, 0x0d, 0x69, 0xe0, 0x52, 0xc3, 0x0b, 0xec, 0xb8, 0x34, 0x5a, 0x85, 0xa1,
|
||||
0x98, 0xa2, 0xa7, 0xa0, 0xc4, 0x8e, 0x8f, 0xea, 0x3d, 0xa7, 0xe8, 0x91, 0x51, 0x36, 0x98, 0xf0,
|
||||
0xae, 0x50, 0xda, 0x81, 0xa2, 0xbd, 0x6f, 0xfb, 0x2a, 0x69, 0xa6, 0x02, 0xf6, 0xbe, 0x2d, 0x14,
|
||||
0xe4, 0xef, 0x43, 0x75, 0x36, 0xda, 0x51, 0x15, 0xd2, 0xf7, 0xf1, 0x54, 0xbc, 0x8f, 0x0e, 0xd1,
|
||||
0x96, 0x58, 0x16, 0x7b, 0x87, 0xa4, 0x88, 0x35, 0xfe, 0x29, 0xe5, 0x1b, 0xfb, 0x61, 0x8e, 0x5e,
|
||||
0x83, 0x0c, 0x45, 0x4d, 0x01, 0x80, 0xf5, 0x5d, 0x0e, 0xa9, 0xbb, 0x1e, 0xa4, 0xee, 0x76, 0x3d,
|
||||
0x48, 0x6d, 0x14, 0xbe, 0xfa, 0x66, 0x27, 0xf1, 0xc5, 0x5f, 0x77, 0x92, 0x0a, 0xb3, 0x40, 0x8f,
|
||||
0xd1, 0xa8, 0xd4, 0x0c, 0x53, 0x35, 0x74, 0xf1, 0x9e, 0x3c, 0x9b, 0x1f, 0xea, 0xe8, 0x08, 0xaa,
|
||||
0x7d, 0xcb, 0x74, 0xb1, 0xe9, 0x4e, 0x5c, 0x95, 0x43, 0xb6, 0x80, 0xbd, 0xf9, 0xa8, 0x69, 0x7a,
|
||||
0x8a, 0xa7, 0x4c, 0x4f, 0xa9, 0xf4, 0xa3, 0x02, 0x74, 0x1b, 0xe0, 0x42, 0x1b, 0x19, 0xba, 0x46,
|
||||
0x2c, 0xc7, 0xad, 0x65, 0x6e, 0xa6, 0x17, 0xba, 0xb9, 0xeb, 0xa9, 0xdc, 0xb1, 0x75, 0x8d, 0xe0,
|
||||
0x46, 0x86, 0xfe, 0x5a, 0x25, 0x64, 0x89, 0x9e, 0x81, 0x8a, 0x66, 0xdb, 0xaa, 0x4b, 0x34, 0x82,
|
||||
0xd5, 0xde, 0x94, 0x60, 0x97, 0x81, 0xe1, 0x86, 0x52, 0xd2, 0x6c, 0xfb, 0x8c, 0x4a, 0x1b, 0x54,
|
||||
0x88, 0x9e, 0x86, 0x32, 0x05, 0x3e, 0x43, 0x1b, 0xa9, 0x43, 0x6c, 0x0c, 0x86, 0x84, 0x81, 0x5e,
|
||||
0x5a, 0x29, 0x09, 0x69, 0x9b, 0x09, 0x65, 0xdd, 0x3f, 0x08, 0x0c, 0xf4, 0x10, 0x82, 0x8c, 0xae,
|
||||
0x11, 0x8d, 0x6d, 0xe4, 0x86, 0xc2, 0xc6, 0x54, 0x66, 0x6b, 0x64, 0x28, 0xb6, 0x87, 0x8d, 0xd1,
|
||||
0x75, 0xc8, 0x09, 0xb7, 0x69, 0xe6, 0x56, 0xcc, 0xe8, 0x37, 0xb3, 0x1d, 0xeb, 0x02, 0x33, 0x94,
|
||||
0x2f, 0x28, 0x7c, 0x22, 0xff, 0x2a, 0x05, 0x9b, 0x73, 0xf0, 0x48, 0xfd, 0x0e, 0x35, 0x77, 0xe8,
|
||||
0xbd, 0x8b, 0x8e, 0xd1, 0xab, 0xd4, 0xaf, 0xa6, 0x63, 0x47, 0xa4, 0xa5, 0x5a, 0x78, 0x8b, 0x78,
|
||||
0xca, 0x6d, 0xb3, 0xe7, 0x62, 0x6b, 0x84, 0x36, 0xea, 0x40, 0x75, 0xa4, 0xb9, 0x44, 0xe5, 0x70,
|
||||
0xa3, 0x86, 0x52, 0xd4, 0x3c, 0xc8, 0x1e, 0x6b, 0x1e, 0x40, 0xd1, 0xc3, 0x2e, 0x1c, 0x95, 0x47,
|
||||
0x11, 0x29, 0x52, 0x60, 0xab, 0x37, 0xfd, 0x4c, 0x33, 0x89, 0x61, 0x62, 0x75, 0xee, 0xcb, 0x3d,
|
||||
0x36, 0xe7, 0xb4, 0x75, 0x61, 0xe8, 0xd8, 0xec, 0x7b, 0x9f, 0xec, 0x9a, 0x6f, 0xec, 0x7f, 0x52,
|
||||
0x57, 0x56, 0xa0, 0x1c, 0x05, 0x78, 0x54, 0x86, 0x14, 0xb9, 0x14, 0x1b, 0x90, 0x22, 0x97, 0xe8,
|
||||
0xff, 0x21, 0x43, 0x17, 0xc9, 0x16, 0x5f, 0x5e, 0x90, 0x5d, 0x85, 0x5d, 0x77, 0x6a, 0x63, 0x85,
|
||||
0x69, 0xca, 0xb2, 0x1f, 0x0d, 0x3e, 0xe8, 0xcf, 0x7a, 0x95, 0x9f, 0x83, 0xca, 0x0c, 0xaa, 0x87,
|
||||
0xbe, 0x5f, 0x32, 0xfc, 0xfd, 0xe4, 0x0a, 0x94, 0x22, 0x10, 0x2e, 0x5f, 0x87, 0xad, 0x45, 0x88,
|
||||
0x2c, 0x0f, 0x7d, 0x79, 0x04, 0x59, 0xd1, 0x2b, 0x50, 0xf0, 0x21, 0x99, 0x47, 0xe3, 0xfc, 0x5e,
|
||||
0x79, 0xca, 0x8a, 0xaf, 0x4a, 0xc3, 0x90, 0x1e, 0x6b, 0x76, 0x1e, 0x52, 0xec, 0x87, 0xe7, 0x35,
|
||||
0xdb, 0x6e, 0x6b, 0xee, 0x50, 0xfe, 0x08, 0x6a, 0x71, 0x70, 0x3b, 0xb3, 0x8c, 0x8c, 0x7f, 0x0c,
|
||||
0xaf, 0x43, 0xee, 0xdc, 0x72, 0xc6, 0x1a, 0x61, 0xce, 0x4a, 0x8a, 0x98, 0xd1, 0xe3, 0xc9, 0xa1,
|
||||
0x37, 0xcd, 0xc4, 0x7c, 0x22, 0xab, 0xf0, 0x58, 0x2c, 0xe4, 0x52, 0x13, 0xc3, 0xd4, 0x31, 0xdf,
|
||||
0xcf, 0x92, 0xc2, 0x27, 0x81, 0x23, 0xfe, 0x63, 0xf9, 0x84, 0xbe, 0xd6, 0x65, 0x6b, 0x65, 0xfe,
|
||||
0x25, 0x45, 0xcc, 0xe4, 0xbf, 0x17, 0xa0, 0xa0, 0x60, 0xd7, 0xa6, 0x98, 0x80, 0x1a, 0x20, 0xe1,
|
||||
0xcb, 0x3e, 0xe6, 0x64, 0x28, 0x19, 0x4b, 0x26, 0xb8, 0x76, 0xcb, 0xd3, 0xa4, 0x99, 0xdc, 0x37,
|
||||
0x43, 0x2f, 0x0b, 0xc2, 0x17, 0xcf, 0xdd, 0x84, 0x79, 0x98, 0xf1, 0xbd, 0xea, 0x31, 0xbe, 0x74,
|
||||
0x6c, 0xf2, 0xe6, 0x56, 0x33, 0x94, 0xef, 0x65, 0x41, 0xf9, 0x32, 0x2b, 0x5e, 0x16, 0xe1, 0x7c,
|
||||
0xcd, 0x08, 0xe7, 0xcb, 0xae, 0x58, 0x66, 0x0c, 0xe9, 0x6b, 0x46, 0x48, 0x5f, 0x6e, 0x85, 0x93,
|
||||
0x18, 0xd6, 0xf7, 0xaa, 0xc7, 0xfa, 0xf2, 0x2b, 0x96, 0x3d, 0x43, 0xfb, 0x6e, 0x47, 0x69, 0x1f,
|
||||
0xa7, 0x6c, 0x4f, 0xc5, 0x5a, 0xc7, 0xf2, 0xbe, 0x1f, 0x84, 0x78, 0x9f, 0x14, 0x4b, 0xba, 0xb8,
|
||||
0x93, 0x05, 0xc4, 0xaf, 0x19, 0x21, 0x7e, 0xb0, 0x62, 0x0f, 0x62, 0x98, 0xdf, 0xdb, 0x61, 0xe6,
|
||||
0x57, 0x8c, 0x25, 0x8f, 0xe2, 0xd0, 0x2c, 0xa2, 0x7e, 0xaf, 0xfb, 0xd4, 0x6f, 0x23, 0x96, 0xbb,
|
||||
0x8a, 0x35, 0xcc, 0x72, 0xbf, 0xce, 0x1c, 0xf7, 0xe3, 0x5c, 0xed, 0x99, 0x58, 0x17, 0x2b, 0xc8,
|
||||
0x5f, 0x67, 0x8e, 0xfc, 0x95, 0x57, 0x38, 0x5c, 0xc1, 0xfe, 0x7e, 0xbe, 0x98, 0xfd, 0xc5, 0xf3,
|
||||
0x33, 0xf1, 0x33, 0xd7, 0xa3, 0x7f, 0x6a, 0x0c, 0xfd, 0xab, 0x32, 0xf7, 0xcf, 0xc7, 0xba, 0xbf,
|
||||
0x3a, 0xff, 0x7b, 0x8e, 0xa6, 0xd9, 0x19, 0xe0, 0xa0, 0x50, 0x85, 0x1d, 0xc7, 0x72, 0x04, 0xb5,
|
||||
0xe2, 0x13, 0xf9, 0x59, 0x9a, 0xf8, 0x03, 0x90, 0x58, 0xc2, 0x15, 0x59, 0x4a, 0x08, 0x01, 0x83,
|
||||
0xfc, 0xfb, 0x64, 0x60, 0xcb, 0x72, 0x65, 0x98, 0x34, 0x48, 0x82, 0x34, 0x84, 0x28, 0x64, 0x2a,
|
||||
0x4a, 0x21, 0x77, 0xa0, 0x48, 0xa1, 0x7e, 0x86, 0x1d, 0x6a, 0xb6, 0xc7, 0x0e, 0xd1, 0x2d, 0xd8,
|
||||
0x64, 0xb9, 0x9c, 0x13, 0x4d, 0x81, 0xef, 0x19, 0x96, 0xa6, 0x2a, 0xf4, 0x01, 0x3f, 0x9c, 0x1c,
|
||||
0xe8, 0x5f, 0x84, 0x6b, 0x21, 0x5d, 0x3f, 0x85, 0x70, 0x4a, 0x54, 0xf5, 0xb5, 0x0f, 0x44, 0x2e,
|
||||
0x79, 0x3f, 0xd8, 0xa0, 0x80, 0x79, 0x22, 0xc8, 0xf4, 0x2d, 0x1d, 0x0b, 0x80, 0x67, 0x63, 0xca,
|
||||
0x46, 0x47, 0xd6, 0x40, 0xc0, 0x38, 0x1d, 0x52, 0x2d, 0x1f, 0x05, 0x25, 0x0e, 0x72, 0xf2, 0x1f,
|
||||
0x93, 0x81, 0xbf, 0x80, 0x8c, 0x2e, 0xe2, 0x8d, 0xc9, 0xff, 0x0e, 0x6f, 0x4c, 0x7d, 0x6b, 0xde,
|
||||
0x18, 0x4e, 0xb0, 0xe9, 0x68, 0x82, 0xfd, 0x67, 0x32, 0xf8, 0xc2, 0x3e, 0x0b, 0xfc, 0x76, 0x3b,
|
||||
0x12, 0x64, 0xcb, 0x2c, 0xfb, 0x5e, 0x22, 0x5b, 0x0a, 0x6e, 0x9f, 0x63, 0xef, 0x8d, 0x72, 0xfb,
|
||||
0x3c, 0xcf, 0x9f, 0x6c, 0x82, 0x5e, 0x03, 0x89, 0x35, 0x5d, 0x54, 0xcb, 0x76, 0x05, 0xe0, 0x3e,
|
||||
0x1e, 0x5e, 0x2b, 0xef, 0xad, 0xec, 0x9e, 0x52, 0x9d, 0x8e, 0xed, 0x2a, 0x05, 0x5b, 0x8c, 0x42,
|
||||
0x44, 0x40, 0x8a, 0xf0, 0xd1, 0x1b, 0x20, 0xd1, 0x5f, 0xef, 0xda, 0x5a, 0x1f, 0x33, 0xf0, 0x94,
|
||||
0x94, 0x40, 0x20, 0xdf, 0x03, 0x34, 0x0f, 0xdf, 0xa8, 0x0d, 0x39, 0x7c, 0x81, 0x4d, 0x42, 0xbf,
|
||||
0x1a, 0xdd, 0xee, 0xeb, 0x0b, 0xc8, 0x1e, 0x36, 0x49, 0xa3, 0x46, 0x37, 0xf9, 0x1f, 0xdf, 0xec,
|
||||
0x54, 0xb9, 0xf6, 0x0b, 0xd6, 0xd8, 0x20, 0x78, 0x6c, 0x93, 0xa9, 0x22, 0xec, 0xe5, 0xbf, 0xa4,
|
||||
0x28, 0xf3, 0x8a, 0x40, 0xfb, 0xc2, 0xbd, 0xf5, 0x02, 0x28, 0x15, 0x62, 0xdd, 0xeb, 0xed, 0xf7,
|
||||
0x36, 0xc0, 0x40, 0x73, 0xd5, 0x4f, 0x35, 0x93, 0x60, 0x5d, 0x6c, 0x7a, 0x48, 0x82, 0xea, 0x50,
|
||||
0xa0, 0xb3, 0x89, 0x8b, 0x75, 0x51, 0x00, 0xf8, 0xf3, 0xd0, 0x3a, 0xf3, 0xdf, 0x6d, 0x9d, 0xd1,
|
||||
0x5d, 0x2e, 0xcc, 0xec, 0x72, 0x88, 0x15, 0x49, 0x61, 0x56, 0x44, 0x7f, 0x9b, 0xed, 0x18, 0x96,
|
||||
0x63, 0x90, 0x29, 0xfb, 0x34, 0x69, 0xc5, 0x9f, 0xd3, 0x3a, 0x73, 0x8c, 0xc7, 0xb6, 0x65, 0x8d,
|
||||
0x54, 0x0e, 0x5e, 0x45, 0x66, 0xba, 0x21, 0x84, 0x2d, 0x86, 0x61, 0xbf, 0x4e, 0x05, 0xe1, 0x17,
|
||||
0xb0, 0xdf, 0xff, 0xb9, 0x0d, 0x96, 0x7f, 0xc3, 0x4a, 0xe2, 0x68, 0xf2, 0x46, 0x67, 0xb0, 0xe9,
|
||||
0x87, 0xbf, 0x3a, 0x61, 0xb0, 0xe0, 0x1d, 0xe8, 0x75, 0xf1, 0xa3, 0x7a, 0x11, 0x15, 0xbb, 0xe8,
|
||||
0xc7, 0xf0, 0xe8, 0x0c, 0xb4, 0xf9, 0xae, 0x53, 0x6b, 0x22, 0xdc, 0x23, 0x51, 0x84, 0xf3, 0x3c,
|
||||
0x07, 0x7b, 0x95, 0xfe, 0x8e, 0x41, 0x77, 0x48, 0xab, 0xac, 0x30, 0x15, 0x59, 0xf8, 0xf5, 0x9f,
|
||||
0x82, 0x92, 0x83, 0x09, 0x2d, 0xfc, 0x23, 0x75, 0xec, 0x06, 0x17, 0x8a, 0xea, 0xf8, 0x14, 0x1e,
|
||||
0x59, 0x48, 0x49, 0xd0, 0xf7, 0x40, 0x0a, 0xd8, 0x4c, 0x32, 0xa6, 0x24, 0xf4, 0xcb, 0x9c, 0x40,
|
||||
0x57, 0xfe, 0x43, 0x32, 0x70, 0x19, 0x2d, 0x9c, 0x5a, 0x90, 0x73, 0xb0, 0x3b, 0x19, 0xf1, 0x52,
|
||||
0xa6, 0xbc, 0xff, 0xe2, 0x7a, 0x64, 0x86, 0x4a, 0x27, 0x23, 0xa2, 0x08, 0x63, 0xf9, 0x1e, 0xe4,
|
||||
0xb8, 0x04, 0x15, 0x21, 0x7f, 0xe7, 0xe4, 0xe8, 0xa4, 0xf3, 0xc1, 0x49, 0x35, 0x81, 0x00, 0x72,
|
||||
0x07, 0xcd, 0x66, 0xeb, 0xb4, 0x5b, 0x4d, 0x22, 0x09, 0xb2, 0x07, 0x8d, 0x8e, 0xd2, 0xad, 0xa6,
|
||||
0xa8, 0x58, 0x69, 0xbd, 0xd7, 0x6a, 0x76, 0xab, 0x69, 0xb4, 0x09, 0x25, 0x3e, 0x56, 0x6f, 0x77,
|
||||
0x94, 0xf7, 0x0f, 0xba, 0xd5, 0x4c, 0x48, 0x74, 0xd6, 0x3a, 0x79, 0xa7, 0xa5, 0x54, 0xb3, 0xf2,
|
||||
0x4b, 0xb4, 0x56, 0x8a, 0xa1, 0x3f, 0x41, 0x55, 0x94, 0x0c, 0x55, 0x45, 0xf2, 0xef, 0x52, 0x50,
|
||||
0x8f, 0xe7, 0x34, 0xe8, 0xbd, 0x99, 0x85, 0xef, 0x5f, 0x81, 0x10, 0xcd, 0xac, 0x1e, 0x3d, 0x0d,
|
||||
0x65, 0x07, 0x9f, 0x63, 0xd2, 0x1f, 0x72, 0x8e, 0xc5, 0x33, 0x66, 0x49, 0x29, 0x09, 0x29, 0x33,
|
||||
0x72, 0xb9, 0xda, 0xc7, 0xb8, 0x4f, 0x54, 0x0e, 0x45, 0xfc, 0xd0, 0x49, 0x54, 0x8d, 0x4a, 0xcf,
|
||||
0xb8, 0x50, 0xfe, 0xe8, 0x4a, 0x7b, 0x29, 0x41, 0x56, 0x69, 0x75, 0x95, 0x9f, 0x54, 0xd3, 0x08,
|
||||
0x41, 0x99, 0x0d, 0xd5, 0xb3, 0x93, 0x83, 0xd3, 0xb3, 0x76, 0x87, 0xee, 0xe5, 0x35, 0xa8, 0x78,
|
||||
0x7b, 0xe9, 0x09, 0xb3, 0xf2, 0xbf, 0x93, 0x50, 0x99, 0x09, 0x10, 0xb4, 0x0f, 0x59, 0xce, 0xd3,
|
||||
0xe3, 0xba, 0xf9, 0x2c, 0xbe, 0x45, 0x34, 0x71, 0x55, 0xf4, 0x26, 0x14, 0xb0, 0x68, 0x40, 0x2c,
|
||||
0x0a, 0x44, 0xde, 0x38, 0xf1, 0x5a, 0x14, 0xc2, 0xd4, 0xb7, 0x40, 0x6f, 0x81, 0xe4, 0x47, 0xba,
|
||||
0x28, 0x0e, 0x9f, 0x9c, 0x37, 0xf7, 0x31, 0x42, 0xd8, 0x07, 0x36, 0xe8, 0xf5, 0x80, 0xec, 0x65,
|
||||
0xe6, 0xab, 0x03, 0x61, 0xce, 0x15, 0x84, 0xb1, 0xa7, 0x2f, 0x37, 0xa1, 0x18, 0x5a, 0x0f, 0x7a,
|
||||
0x1c, 0xa4, 0xb1, 0x76, 0x29, 0x1a, 0x5b, 0xbc, 0x35, 0x51, 0x18, 0x6b, 0x97, 0xbc, 0xa7, 0xf5,
|
||||
0x28, 0xe4, 0xe9, 0xc3, 0x81, 0xc6, 0xd1, 0x26, 0xad, 0xe4, 0xc6, 0xda, 0xe5, 0xbb, 0x9a, 0x2b,
|
||||
0x7f, 0x08, 0xe5, 0x68, 0x53, 0x87, 0x9e, 0x44, 0xc7, 0x9a, 0x98, 0x3a, 0xf3, 0x91, 0x55, 0xf8,
|
||||
0x04, 0xbd, 0x02, 0xd9, 0x0b, 0x8b, 0x83, 0xd5, 0xe2, 0x90, 0xbd, 0x6b, 0x11, 0x1c, 0x6a, 0x0a,
|
||||
0x71, 0x6d, 0xf9, 0x33, 0xc8, 0x32, 0xf0, 0xa1, 0x40, 0xc2, 0xda, 0x33, 0x82, 0xe8, 0xd2, 0x31,
|
||||
0xfa, 0x10, 0x40, 0x23, 0xc4, 0x31, 0x7a, 0x93, 0xc0, 0xf1, 0xce, 0x62, 0xf0, 0x3a, 0xf0, 0xf4,
|
||||
0x1a, 0x37, 0x04, 0x8a, 0x6d, 0x05, 0xa6, 0x21, 0x24, 0x0b, 0x39, 0x94, 0x4f, 0xa0, 0x1c, 0xb5,
|
||||
0x0d, 0x37, 0x4a, 0x37, 0x16, 0x34, 0x4a, 0x7d, 0x32, 0xe5, 0x53, 0xb1, 0x34, 0x6f, 0xc5, 0xb1,
|
||||
0x89, 0xfc, 0x79, 0x12, 0x0a, 0xdd, 0x4b, 0x71, 0xac, 0x63, 0xba, 0x40, 0x81, 0x69, 0x2a, 0xdc,
|
||||
0xf3, 0xe0, 0x6d, 0xa5, 0xb4, 0xdf, 0xac, 0x7a, 0xdb, 0x0f, 0xdc, 0xcc, 0xba, 0x55, 0xa9, 0xd7,
|
||||
0xb5, 0x13, 0x60, 0xf5, 0x06, 0x48, 0xfe, 0xa9, 0xa2, 0x15, 0x83, 0xa6, 0xeb, 0x0e, 0x76, 0x5d,
|
||||
0xb1, 0x36, 0x6f, 0xca, 0x9a, 0x8a, 0xd6, 0xa7, 0xa2, 0xab, 0x92, 0x56, 0xf8, 0x44, 0xd6, 0xa1,
|
||||
0x32, 0x93, 0xb6, 0xd0, 0x1b, 0x90, 0xb7, 0x27, 0x3d, 0xd5, 0xdb, 0x9e, 0x99, 0xe0, 0xf1, 0xd8,
|
||||
0xe3, 0xa4, 0x37, 0x32, 0xfa, 0x47, 0x78, 0xea, 0xfd, 0x18, 0x7b, 0xd2, 0x3b, 0xe2, 0xbb, 0xc8,
|
||||
0xdf, 0x92, 0x0a, 0xbf, 0xe5, 0x02, 0x0a, 0xde, 0xa1, 0x40, 0x3f, 0x0c, 0xc7, 0x89, 0xd7, 0x6a,
|
||||
0x8e, 0x4d, 0xa5, 0xc2, 0x7d, 0x28, 0x4c, 0x6e, 0xc1, 0xa6, 0x6b, 0x0c, 0x4c, 0xac, 0xab, 0x41,
|
||||
0xcd, 0xc2, 0xde, 0x56, 0x50, 0x2a, 0xfc, 0xc1, 0xb1, 0x57, 0xb0, 0xc8, 0xff, 0x4a, 0x42, 0xc1,
|
||||
0x0b, 0x58, 0xf4, 0x52, 0xe8, 0xdc, 0x95, 0x17, 0x74, 0x60, 0x3c, 0xc5, 0xa0, 0x2f, 0x18, 0xfd,
|
||||
0xad, 0xa9, 0xab, 0xff, 0xd6, 0xb8, 0x06, 0xaf, 0xd7, 0x69, 0xcf, 0x5c, 0xb9, 0xd3, 0xfe, 0x02,
|
||||
0x20, 0x62, 0x11, 0x6d, 0xa4, 0x5e, 0x58, 0xc4, 0x30, 0x07, 0x2a, 0xdf, 0x6c, 0xce, 0xa8, 0xaa,
|
||||
0xec, 0xc9, 0x5d, 0xf6, 0xe0, 0x94, 0xed, 0xfb, 0x2f, 0x92, 0x50, 0xf0, 0x73, 0xe3, 0x55, 0xdb,
|
||||
0x7c, 0xd7, 0x21, 0x27, 0xe0, 0x9f, 0xf7, 0xf9, 0xc4, 0xcc, 0xef, 0x38, 0x67, 0x42, 0x1d, 0xe7,
|
||||
0x3a, 0x14, 0xc6, 0x98, 0x68, 0x8c, 0x20, 0xf0, 0xb2, 0xd1, 0x9f, 0xdf, 0x7a, 0x1d, 0x8a, 0xa1,
|
||||
0x8e, 0x2b, 0x8d, 0xbc, 0x93, 0xd6, 0x07, 0xd5, 0x44, 0x3d, 0xff, 0xf9, 0x97, 0x37, 0xd3, 0x27,
|
||||
0xf8, 0x53, 0x7a, 0x66, 0x95, 0x56, 0xb3, 0xdd, 0x6a, 0x1e, 0x55, 0x93, 0xf5, 0xe2, 0xe7, 0x5f,
|
||||
0xde, 0xcc, 0x2b, 0x98, 0x35, 0x6e, 0x6e, 0xb5, 0x61, 0x23, 0xfc, 0x55, 0xa2, 0x19, 0x04, 0x41,
|
||||
0xf9, 0x9d, 0x3b, 0xa7, 0xc7, 0x87, 0xcd, 0x83, 0x6e, 0x4b, 0xbd, 0xdb, 0xe9, 0xb6, 0xaa, 0x49,
|
||||
0xf4, 0x28, 0x5c, 0x3b, 0x3e, 0x7c, 0xb7, 0xdd, 0x55, 0x9b, 0xc7, 0x87, 0xad, 0x93, 0xae, 0x7a,
|
||||
0xd0, 0xed, 0x1e, 0x34, 0x8f, 0xaa, 0xa9, 0xfd, 0x5f, 0x02, 0x54, 0x0e, 0x1a, 0xcd, 0x43, 0x9a,
|
||||
0xfd, 0x8c, 0xbe, 0x26, 0x1a, 0x63, 0x19, 0x56, 0xb5, 0x2f, 0xbd, 0xea, 0xad, 0x2f, 0xef, 0x0b,
|
||||
0xa2, 0xdb, 0x90, 0x65, 0x05, 0x3d, 0x5a, 0x7e, 0xf7, 0x5b, 0x5f, 0xd1, 0x28, 0xa4, 0x3f, 0x86,
|
||||
0x85, 0xc7, 0xd2, 0xcb, 0xe0, 0xfa, 0xf2, 0xbe, 0x21, 0x52, 0x40, 0x0a, 0x2a, 0xf2, 0xd5, 0x97,
|
||||
0xc3, 0xf5, 0x35, 0x7a, 0x89, 0xd4, 0x67, 0x50, 0x16, 0xac, 0xbe, 0x2c, 0xad, 0xaf, 0x01, 0x60,
|
||||
0xe8, 0x18, 0xf2, 0x5e, 0x25, 0xb7, 0xea, 0xfa, 0xb6, 0xbe, 0xb2, 0xcf, 0x47, 0x3f, 0x01, 0xaf,
|
||||
0xb8, 0x97, 0xdf, 0x45, 0xd7, 0x57, 0x34, 0x2d, 0xd1, 0x21, 0xe4, 0x04, 0xd7, 0x5d, 0x71, 0x25,
|
||||
0x5b, 0x5f, 0xd5, 0xb7, 0xa3, 0x9b, 0x16, 0xb4, 0x32, 0x56, 0xdf, 0xb0, 0xd7, 0xd7, 0xe8, 0xc7,
|
||||
0xa2, 0x3b, 0x00, 0xa1, 0xfa, 0x7a, 0x8d, 0xab, 0xf3, 0xfa, 0x3a, 0x7d, 0x56, 0xd4, 0x81, 0x82,
|
||||
0x5f, 0xee, 0xac, 0xbc, 0xc8, 0xae, 0xaf, 0x6e, 0x78, 0xa2, 0x7b, 0x50, 0x8a, 0xf2, 0xfc, 0xf5,
|
||||
0xae, 0xa7, 0xeb, 0x6b, 0x76, 0x32, 0xa9, 0xff, 0x28, 0xe9, 0x5f, 0xef, 0xba, 0xba, 0xbe, 0x66,
|
||||
0x63, 0x13, 0x7d, 0x0c, 0x9b, 0xf3, 0xa4, 0x7c, 0xfd, 0xdb, 0xeb, 0xfa, 0x15, 0x5a, 0x9d, 0x68,
|
||||
0x0c, 0x68, 0x01, 0x99, 0xbf, 0xc2, 0x65, 0x76, 0xfd, 0x2a, 0x9d, 0xcf, 0x46, 0xeb, 0xab, 0x07,
|
||||
0xdb, 0xc9, 0xaf, 0x1f, 0x6c, 0x27, 0xff, 0xf6, 0x60, 0x3b, 0xf9, 0xc5, 0xc3, 0xed, 0xc4, 0xd7,
|
||||
0x0f, 0xb7, 0x13, 0x7f, 0x7e, 0xb8, 0x9d, 0xf8, 0xe9, 0xf3, 0x03, 0x83, 0x0c, 0x27, 0xbd, 0xdd,
|
||||
0xbe, 0x35, 0xde, 0x0b, 0xff, 0xd3, 0x66, 0xd1, 0xbf, 0x7f, 0x7a, 0x39, 0x96, 0xa8, 0x5e, 0xfe,
|
||||
0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4e, 0x2d, 0x07, 0xd8, 0x1d, 0x24, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@@ -5635,6 +5663,25 @@ func (m *ResponseCheckTx) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.MempoolError) > 0 {
|
||||
i -= len(m.MempoolError)
|
||||
copy(dAtA[i:], m.MempoolError)
|
||||
i = encodeVarintTypes(dAtA, i, uint64(len(m.MempoolError)))
|
||||
i--
|
||||
dAtA[i] = 0x5a
|
||||
}
|
||||
if m.Priority != 0 {
|
||||
i = encodeVarintTypes(dAtA, i, uint64(m.Priority))
|
||||
i--
|
||||
dAtA[i] = 0x50
|
||||
}
|
||||
if len(m.Sender) > 0 {
|
||||
i -= len(m.Sender)
|
||||
copy(dAtA[i:], m.Sender)
|
||||
i = encodeVarintTypes(dAtA, i, uint64(len(m.Sender)))
|
||||
i--
|
||||
dAtA[i] = 0x4a
|
||||
}
|
||||
if len(m.Codespace) > 0 {
|
||||
i -= len(m.Codespace)
|
||||
copy(dAtA[i:], m.Codespace)
|
||||
@@ -7390,6 +7437,17 @@ func (m *ResponseCheckTx) Size() (n int) {
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
}
|
||||
l = len(m.Sender)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
}
|
||||
if m.Priority != 0 {
|
||||
n += 1 + sovTypes(uint64(m.Priority))
|
||||
}
|
||||
l = len(m.MempoolError)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTypes(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
@@ -11929,6 +11987,89 @@ func (m *ResponseCheckTx) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
m.Codespace = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 9:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTypes
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthTypes
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthTypes
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Sender = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 10:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Priority", wireType)
|
||||
}
|
||||
m.Priority = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTypes
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Priority |= int64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 11:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field MempoolError", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTypes
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthTypes
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthTypes
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.MempoolError = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipTypes(dAtA[iNdEx:])
|
||||
|
||||
@@ -8,35 +8,34 @@ There are four different behaviours a reactor can report.
|
||||
|
||||
1. bad message
|
||||
|
||||
type badMessage struct {
|
||||
explanation string
|
||||
}
|
||||
type badMessage struct {
|
||||
explanation string
|
||||
}
|
||||
|
||||
This message will request the peer be stopped for an error
|
||||
# This message will request the peer be stopped for an error
|
||||
|
||||
2. message out of order
|
||||
|
||||
type messageOutOfOrder struct {
|
||||
explanation string
|
||||
}
|
||||
type messageOutOfOrder struct {
|
||||
explanation string
|
||||
}
|
||||
|
||||
This message will request the peer be stopped for an error
|
||||
# This message will request the peer be stopped for an error
|
||||
|
||||
3. consesnsus Vote
|
||||
|
||||
type consensusVote struct {
|
||||
explanation string
|
||||
}
|
||||
type consensusVote struct {
|
||||
explanation string
|
||||
}
|
||||
|
||||
This message will request the peer be marked as good
|
||||
# This message will request the peer be marked as good
|
||||
|
||||
4. block part
|
||||
|
||||
type blockPart struct {
|
||||
explanation string
|
||||
}
|
||||
type blockPart struct {
|
||||
explanation string
|
||||
}
|
||||
|
||||
This message will request the peer be marked as good
|
||||
|
||||
*/
|
||||
package behaviour
|
||||
|
||||
@@ -78,7 +78,7 @@ func TestBcStatusResponseMessageValidateBasic(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// nolint:lll // ignore line length in tests
|
||||
//nolint:lll // ignore line length in tests
|
||||
func TestBlockchainMessageVectors(t *testing.T) {
|
||||
block := types.MakeBlock(int64(3), []types.Tx{types.Tx("Hello World")}, nil, nil)
|
||||
block.Version.Block = 11 // overwrite updated protocol version
|
||||
|
||||
@@ -410,6 +410,7 @@ func (pool *BlockPool) sendError(err error, peerID p2p.ID) {
|
||||
}
|
||||
|
||||
// for debugging purposes
|
||||
//
|
||||
//nolint:unused
|
||||
func (pool *BlockPool) debug() string {
|
||||
pool.mtx.Lock()
|
||||
|
||||
@@ -304,7 +304,7 @@ func (bcR *BlockchainReactor) poolRoutine(stateSynced bool) {
|
||||
|
||||
case <-statusUpdateTicker.C:
|
||||
// ask for status updates
|
||||
go bcR.BroadcastStatusRequest() // nolint: errcheck
|
||||
go bcR.BroadcastStatusRequest() //nolint: errcheck
|
||||
|
||||
}
|
||||
}
|
||||
@@ -369,6 +369,12 @@ FOR_LOOP:
|
||||
// currently necessary.
|
||||
err := state.Validators.VerifyCommitLight(
|
||||
chainID, firstID, first.Height, second.LastCommit)
|
||||
|
||||
if err == nil {
|
||||
// validate the block before we persist it
|
||||
err = bcR.blockExec.ValidateBlock(state, first)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
bcR.Logger.Error("Error in validation", "err", err)
|
||||
peerID := bcR.pool.RedoRequest(first.Height)
|
||||
@@ -386,29 +392,29 @@ FOR_LOOP:
|
||||
bcR.Switch.StopPeerForError(peer2, fmt.Errorf("blockchainReactor validation error: %v", err))
|
||||
}
|
||||
continue FOR_LOOP
|
||||
} else {
|
||||
bcR.pool.PopRequest()
|
||||
|
||||
// TODO: batch saves so we dont persist to disk every block
|
||||
bcR.store.SaveBlock(first, firstParts, second.LastCommit)
|
||||
|
||||
// TODO: same thing for app - but we would need a way to
|
||||
// get the hash without persisting the state
|
||||
var err error
|
||||
state, _, err = bcR.blockExec.ApplyBlock(state, firstID, first)
|
||||
if err != nil {
|
||||
// TODO This is bad, are we zombie?
|
||||
panic(fmt.Sprintf("Failed to process committed block (%d:%X): %v", first.Height, first.Hash(), err))
|
||||
}
|
||||
blocksSynced++
|
||||
|
||||
if blocksSynced%100 == 0 {
|
||||
lastRate = 0.9*lastRate + 0.1*(100/time.Since(lastHundred).Seconds())
|
||||
bcR.Logger.Info("Fast Sync Rate", "height", bcR.pool.height,
|
||||
"max_peer_height", bcR.pool.MaxPeerHeight(), "blocks/s", lastRate)
|
||||
lastHundred = time.Now()
|
||||
}
|
||||
}
|
||||
|
||||
bcR.pool.PopRequest()
|
||||
|
||||
// TODO: batch saves so we dont persist to disk every block
|
||||
bcR.store.SaveBlock(first, firstParts, second.LastCommit)
|
||||
|
||||
// TODO: same thing for app - but we would need a way to
|
||||
// get the hash without persisting the state
|
||||
state, _, err = bcR.blockExec.ApplyBlock(state, firstID, first)
|
||||
if err != nil {
|
||||
// TODO This is bad, are we zombie?
|
||||
panic(fmt.Sprintf("Failed to process committed block (%d:%X): %v", first.Height, first.Hash(), err))
|
||||
}
|
||||
blocksSynced++
|
||||
|
||||
if blocksSynced%100 == 0 {
|
||||
lastRate = 0.9*lastRate + 0.1*(100/time.Since(lastHundred).Seconds())
|
||||
bcR.Logger.Info("Fast Sync Rate", "height", bcR.pool.height,
|
||||
"max_peer_height", bcR.pool.MaxPeerHeight(), "blocks/s", lastRate)
|
||||
lastHundred = time.Now()
|
||||
}
|
||||
|
||||
continue FOR_LOOP
|
||||
|
||||
case <-bcR.Quit():
|
||||
|
||||
@@ -70,7 +70,9 @@ func newBlockchainReactor(
|
||||
|
||||
blockDB := dbm.NewMemDB()
|
||||
stateDB := dbm.NewMemDB()
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
blockStore := store.NewBlockStore(blockDB)
|
||||
|
||||
state, err := stateStore.LoadFromDBOrGenesisDoc(genDoc)
|
||||
@@ -83,7 +85,9 @@ func newBlockchainReactor(
|
||||
// pool.height is determined from the store.
|
||||
fastSync := true
|
||||
db := dbm.NewMemDB()
|
||||
stateStore = sm.NewStore(db)
|
||||
stateStore = sm.NewStore(db, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(),
|
||||
mock.Mempool{}, sm.EmptyEvidencePool{})
|
||||
if err = stateStore.Save(state); err != nil {
|
||||
|
||||
@@ -534,8 +534,8 @@ func (bcR *BlockchainReactor) switchToConsensus() {
|
||||
// Called by FSM and pool:
|
||||
// - pool calls when it detects slow peer or when peer times out
|
||||
// - FSM calls when:
|
||||
// - adding a block (addBlock) fails
|
||||
// - reactor processing of a block reports failure and FSM sends back the peers of first and second blocks
|
||||
// - adding a block (addBlock) fails
|
||||
// - reactor processing of a block reports failure and FSM sends back the peers of first and second blocks
|
||||
func (bcR *BlockchainReactor) sendPeerError(err error, peerID p2p.ID) {
|
||||
bcR.Logger.Info("sendPeerError:", "peer", peerID, "error", err)
|
||||
msgData := bcFsmMessage{
|
||||
|
||||
@@ -102,7 +102,9 @@ func newBlockchainReactor(
|
||||
|
||||
blockDB := dbm.NewMemDB()
|
||||
stateDB := dbm.NewMemDB()
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
blockStore := store.NewBlockStore(blockDB)
|
||||
|
||||
state, err := stateStore.LoadFromDBOrGenesisDoc(genDoc)
|
||||
@@ -115,7 +117,9 @@ func newBlockchainReactor(
|
||||
// pool.height is determined from the store.
|
||||
fastSync := true
|
||||
db := dbm.NewMemDB()
|
||||
stateStore = sm.NewStore(db)
|
||||
stateStore = sm.NewStore(db, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(),
|
||||
mock.Mempool{}, sm.EmptyEvidencePool{})
|
||||
if err = stateStore.Save(state); err != nil {
|
||||
|
||||
@@ -59,22 +59,18 @@ func (mp mockPeer) TrySend(byte, []byte) bool { return true }
|
||||
func (mp mockPeer) Set(string, interface{}) {}
|
||||
func (mp mockPeer) Get(string) interface{} { return struct{}{} }
|
||||
|
||||
// nolint:unused // ignore
|
||||
type mockBlockStore struct {
|
||||
blocks map[int64]*types.Block
|
||||
}
|
||||
|
||||
// nolint:unused // ignore
|
||||
func (ml *mockBlockStore) Height() int64 {
|
||||
return int64(len(ml.blocks))
|
||||
}
|
||||
|
||||
// nolint:unused // ignore
|
||||
func (ml *mockBlockStore) LoadBlock(height int64) *types.Block {
|
||||
return ml.blocks[height]
|
||||
}
|
||||
|
||||
// nolint:unused // ignore
|
||||
func (ml *mockBlockStore) SaveBlock(block *types.Block, part *types.PartSet, commit *types.Commit) {
|
||||
ml.blocks[block.Height] = block
|
||||
}
|
||||
@@ -159,7 +155,9 @@ func newTestReactor(p testReactorParams) *BlockchainReactor {
|
||||
panic(fmt.Errorf("error start app: %w", err))
|
||||
}
|
||||
db := dbm.NewMemDB()
|
||||
stateStore := sm.NewStore(db)
|
||||
stateStore := sm.NewStore(db, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
appl = sm.NewBlockExecutor(stateStore, p.logger, proxyApp.Consensus(), mock.Mempool{}, sm.EmptyEvidencePool{})
|
||||
if err = stateStore.Save(state); err != nil {
|
||||
panic(err)
|
||||
@@ -504,14 +502,18 @@ func newReactorStore(
|
||||
|
||||
stateDB := dbm.NewMemDB()
|
||||
blockStore := store.NewBlockStore(dbm.NewMemDB())
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
state, err := stateStore.LoadFromDBOrGenesisDoc(genDoc)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("error constructing state from genesis file: %w", err))
|
||||
}
|
||||
|
||||
db := dbm.NewMemDB()
|
||||
stateStore = sm.NewStore(db)
|
||||
stateStore = sm.NewStore(db, sm.StoreOptions{
|
||||
DiscardABCIResponses: false},
|
||||
)
|
||||
blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(),
|
||||
mock.Mempool{}, sm.EmptyEvidencePool{})
|
||||
if err = stateStore.Save(state); err != nil {
|
||||
|
||||
@@ -52,13 +52,12 @@ func (rt *Routine) setLogger(logger log.Logger) {
|
||||
rt.logger = logger
|
||||
}
|
||||
|
||||
// nolint:unused
|
||||
func (rt *Routine) setMetrics(metrics *Metrics) {
|
||||
rt.metrics = metrics
|
||||
}
|
||||
|
||||
func (rt *Routine) start() {
|
||||
rt.logger.Info(fmt.Sprintf("%s: run", rt.name))
|
||||
rt.logger.Info("routine start", "msg", log.NewLazySprintf("%s: run", rt.name))
|
||||
running := atomic.CompareAndSwapUint32(rt.running, uint32(0), uint32(1))
|
||||
if !running {
|
||||
panic(fmt.Sprintf("%s is already running", rt.name))
|
||||
@@ -98,7 +97,7 @@ func (rt *Routine) start() {
|
||||
return
|
||||
}
|
||||
rt.metrics.EventsOut.With("routine", rt.name).Add(1)
|
||||
rt.logger.Debug(fmt.Sprintf("%s: produced %T %+v", rt.name, oEvent, oEvent))
|
||||
rt.logger.Debug("routine start", "msg", log.NewLazySprintf("%s: produced %T %+v", rt.name, oEvent, oEvent))
|
||||
|
||||
// Skip rTrySchedule and rProcessBlock events as they clutter the history
|
||||
// due to their frequency.
|
||||
@@ -118,7 +117,7 @@ func (rt *Routine) start() {
|
||||
|
||||
// XXX: look into returning OpError in the net package
|
||||
func (rt *Routine) send(event Event) bool {
|
||||
rt.logger.Debug(fmt.Sprintf("%s: received %T %+v", rt.name, event, event))
|
||||
rt.logger.Debug("routine send", "msg", log.NewLazySprintf("%s: received %T %+v", rt.name, event, event))
|
||||
if !rt.isRunning() {
|
||||
return false
|
||||
}
|
||||
@@ -150,7 +149,7 @@ func (rt *Routine) stop() {
|
||||
return
|
||||
}
|
||||
|
||||
rt.logger.Info(fmt.Sprintf("%s: stop", rt.name))
|
||||
rt.logger.Info("routine stop", "msg", log.NewLazySprintf("%s: stop", rt.name))
|
||||
rt.queue.Dispose() // this should block until all queue items are free?
|
||||
}
|
||||
|
||||
|
||||
9
buf.gen.yaml
Normal file
9
buf.gen.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
version: v1
|
||||
plugins:
|
||||
- name: gogofaster
|
||||
out: ./proto/
|
||||
opt:
|
||||
- Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types
|
||||
- Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration
|
||||
- plugins=grpc
|
||||
- paths=source_relative
|
||||
3
buf.work.yaml
Normal file
3
buf.work.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
version: v1
|
||||
directories:
|
||||
- proto
|
||||
66
cmd/tendermint/commands/compact.go
Normal file
66
cmd/tendermint/commands/compact.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
"github.com/syndtr/goleveldb/leveldb/opt"
|
||||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
)
|
||||
|
||||
var CompactGoLevelDBCmd = &cobra.Command{
|
||||
Use: "experimental-compact-goleveldb",
|
||||
Short: "force compacts the tendermint storage engine (only GoLevelDB supported)",
|
||||
Long: `
|
||||
This is a temporary utility command that performs a force compaction on the state
|
||||
and blockstores to reduce disk space for a pruning node. This should only be run
|
||||
once the node has stopped. This command will likely be omitted in the future after
|
||||
the planned refactor to the storage engine.
|
||||
|
||||
Currently, only GoLevelDB is supported.
|
||||
`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if config.DBBackend != "goleveldb" {
|
||||
return errors.New("compaction is currently only supported with goleveldb")
|
||||
}
|
||||
|
||||
compactGoLevelDBs(config.RootDir, logger)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func compactGoLevelDBs(rootDir string, logger log.Logger) {
|
||||
dbNames := []string{"state", "blockstore"}
|
||||
o := &opt.Options{
|
||||
DisableSeeksCompaction: true,
|
||||
}
|
||||
wg := sync.WaitGroup{}
|
||||
|
||||
for _, dbName := range dbNames {
|
||||
dbName := dbName
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
dbPath := filepath.Join(rootDir, "data", dbName+".db")
|
||||
store, err := leveldb.OpenFile(dbPath, o)
|
||||
if err != nil {
|
||||
logger.Error("failed to initialize tendermint db", "path", dbPath, "err", err)
|
||||
return
|
||||
}
|
||||
defer store.Close()
|
||||
|
||||
logger.Info("starting compaction...", "db", dbPath)
|
||||
|
||||
err = store.CompactRange(util.Range{Start: nil, Limit: nil})
|
||||
if err != nil {
|
||||
logger.Error("failed to compact tendermint db", "path", dbPath, "err", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
@@ -105,7 +105,7 @@ func killProc(pid uint64, dir string) error {
|
||||
// pipe STDERR output from tailing the Tendermint process to a file
|
||||
//
|
||||
// NOTE: This will only work on UNIX systems.
|
||||
cmd := exec.Command("tail", "-f", fmt.Sprintf("/proc/%d/fd/2", pid)) // nolint: gosec
|
||||
cmd := exec.Command("tail", "-f", fmt.Sprintf("/proc/%d/fd/2", pid)) //nolint: gosec
|
||||
|
||||
outFile, err := os.Create(filepath.Join(dir, "stacktrace.out"))
|
||||
if err != nil {
|
||||
|
||||
@@ -67,7 +67,7 @@ func copyConfig(home, dir string) error {
|
||||
func dumpProfile(dir, addr, profile string, debug int) error {
|
||||
endpoint := fmt.Sprintf("%s/debug/pprof/%s?debug=%d", addr, profile, debug)
|
||||
|
||||
resp, err := http.Get(endpoint) // nolint: gosec
|
||||
resp, err := http.Get(endpoint) //nolint: gosec
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to query for %s profile: %w", profile, err)
|
||||
}
|
||||
|
||||
232
cmd/tendermint/commands/reindex_event.go
Normal file
232
cmd/tendermint/commands/reindex_event.go
Normal file
@@ -0,0 +1,232 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
abcitypes "github.com/tendermint/tendermint/abci/types"
|
||||
tmcfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/libs/progressbar"
|
||||
"github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/state/indexer"
|
||||
blockidxkv "github.com/tendermint/tendermint/state/indexer/block/kv"
|
||||
"github.com/tendermint/tendermint/state/indexer/sink/psql"
|
||||
"github.com/tendermint/tendermint/state/txindex"
|
||||
"github.com/tendermint/tendermint/state/txindex/kv"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
const (
|
||||
reindexFailed = "event re-index failed: "
|
||||
)
|
||||
|
||||
var (
|
||||
ErrHeightNotAvailable = errors.New("height is not available")
|
||||
ErrInvalidRequest = errors.New("invalid request")
|
||||
)
|
||||
|
||||
// ReIndexEventCmd constructs a command to re-index events in a block height interval.
|
||||
var ReIndexEventCmd = &cobra.Command{
|
||||
Use: "reindex-event",
|
||||
Short: "Re-index events to the event store backends",
|
||||
Long: `
|
||||
reindex-event is an offline tooling to re-index block and tx events to the eventsinks.
|
||||
You can run this command when the event store backend dropped/disconnected or you want to
|
||||
replace the backend. The default start-height is 0, meaning the tooling will start
|
||||
reindex from the base block height(inclusive); and the default end-height is 0, meaning
|
||||
the tooling will reindex until the latest block height(inclusive). User can omit
|
||||
either or both arguments.
|
||||
|
||||
Note: This operation requires ABCIResponses. Do not set DiscardABCIResponses to true if you
|
||||
want to use this command.
|
||||
`,
|
||||
Example: `
|
||||
tendermint reindex-event
|
||||
tendermint reindex-event --start-height 2
|
||||
tendermint reindex-event --end-height 10
|
||||
tendermint reindex-event --start-height 2 --end-height 10
|
||||
`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
bs, ss, err := loadStateAndBlockStore(config)
|
||||
if err != nil {
|
||||
fmt.Println(reindexFailed, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkValidHeight(bs); err != nil {
|
||||
fmt.Println(reindexFailed, err)
|
||||
return
|
||||
}
|
||||
|
||||
bi, ti, err := loadEventSinks(config)
|
||||
if err != nil {
|
||||
fmt.Println(reindexFailed, err)
|
||||
return
|
||||
}
|
||||
|
||||
riArgs := eventReIndexArgs{
|
||||
startHeight: startHeight,
|
||||
endHeight: endHeight,
|
||||
blockIndexer: bi,
|
||||
txIndexer: ti,
|
||||
blockStore: bs,
|
||||
stateStore: ss,
|
||||
}
|
||||
if err := eventReIndex(cmd, riArgs); err != nil {
|
||||
panic(fmt.Errorf("%s: %w", reindexFailed, err))
|
||||
}
|
||||
|
||||
fmt.Println("event re-index finished")
|
||||
},
|
||||
}
|
||||
|
||||
var (
|
||||
startHeight int64
|
||||
endHeight int64
|
||||
)
|
||||
|
||||
func init() {
|
||||
ReIndexEventCmd.Flags().Int64Var(&startHeight, "start-height", 0, "the block height would like to start for re-index")
|
||||
ReIndexEventCmd.Flags().Int64Var(&endHeight, "end-height", 0, "the block height would like to finish for re-index")
|
||||
}
|
||||
|
||||
func loadEventSinks(cfg *tmcfg.Config) (indexer.BlockIndexer, txindex.TxIndexer, error) {
|
||||
switch strings.ToLower(cfg.TxIndex.Indexer) {
|
||||
case "null":
|
||||
return nil, nil, errors.New("found null event sink, please check the tx-index section in the config.toml")
|
||||
case "psql":
|
||||
conn := cfg.TxIndex.PsqlConn
|
||||
if conn == "" {
|
||||
return nil, nil, errors.New("the psql connection settings cannot be empty")
|
||||
}
|
||||
es, err := psql.NewEventSink(conn, cfg.ChainID())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return es.BlockIndexer(), es.TxIndexer(), nil
|
||||
case "kv":
|
||||
store, err := dbm.NewDB("tx_index", dbm.BackendType(cfg.DBBackend), cfg.DBDir())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
txIndexer := kv.NewTxIndex(store)
|
||||
blockIndexer := blockidxkv.New(dbm.NewPrefixDB(store, []byte("block_events")))
|
||||
return blockIndexer, txIndexer, nil
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unsupported event sink type: %s", cfg.TxIndex.Indexer)
|
||||
}
|
||||
}
|
||||
|
||||
type eventReIndexArgs struct {
|
||||
startHeight int64
|
||||
endHeight int64
|
||||
blockIndexer indexer.BlockIndexer
|
||||
txIndexer txindex.TxIndexer
|
||||
blockStore state.BlockStore
|
||||
stateStore state.Store
|
||||
}
|
||||
|
||||
func eventReIndex(cmd *cobra.Command, args eventReIndexArgs) error {
|
||||
var bar progressbar.Bar
|
||||
bar.NewOption(args.startHeight-1, args.endHeight)
|
||||
|
||||
fmt.Println("start re-indexing events:")
|
||||
defer bar.Finish()
|
||||
for i := args.startHeight; i <= args.endHeight; i++ {
|
||||
select {
|
||||
case <-cmd.Context().Done():
|
||||
return fmt.Errorf("event re-index terminated at height %d: %w", i, cmd.Context().Err())
|
||||
default:
|
||||
b := args.blockStore.LoadBlock(i)
|
||||
if b == nil {
|
||||
return fmt.Errorf("not able to load block at height %d from the blockstore", i)
|
||||
}
|
||||
|
||||
r, err := args.stateStore.LoadABCIResponses(i)
|
||||
if err != nil {
|
||||
return fmt.Errorf("not able to load ABCI Response at height %d from the statestore", i)
|
||||
}
|
||||
|
||||
e := types.EventDataNewBlockHeader{
|
||||
Header: b.Header,
|
||||
NumTxs: int64(len(b.Txs)),
|
||||
ResultBeginBlock: *r.BeginBlock,
|
||||
ResultEndBlock: *r.EndBlock,
|
||||
}
|
||||
|
||||
var batch *txindex.Batch
|
||||
if e.NumTxs > 0 {
|
||||
batch = txindex.NewBatch(e.NumTxs)
|
||||
|
||||
for i := range b.Data.Txs {
|
||||
tr := abcitypes.TxResult{
|
||||
Height: b.Height,
|
||||
Index: uint32(i),
|
||||
Tx: b.Data.Txs[i],
|
||||
Result: *(r.DeliverTxs[i]),
|
||||
}
|
||||
|
||||
if err = batch.Add(&tr); err != nil {
|
||||
return fmt.Errorf("adding tx to batch: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := args.txIndexer.AddBatch(batch); err != nil {
|
||||
return fmt.Errorf("tx event re-index at height %d failed: %w", i, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := args.blockIndexer.Index(e); err != nil {
|
||||
return fmt.Errorf("block event re-index at height %d failed: %w", i, err)
|
||||
}
|
||||
}
|
||||
|
||||
bar.Play(i)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkValidHeight(bs state.BlockStore) error {
|
||||
base := bs.Base()
|
||||
|
||||
if startHeight == 0 {
|
||||
startHeight = base
|
||||
fmt.Printf("set the start block height to the base height of the blockstore %d \n", base)
|
||||
}
|
||||
|
||||
if startHeight < base {
|
||||
return fmt.Errorf("%s (requested start height: %d, base height: %d)",
|
||||
ErrHeightNotAvailable, startHeight, base)
|
||||
}
|
||||
|
||||
height := bs.Height()
|
||||
|
||||
if startHeight > height {
|
||||
return fmt.Errorf(
|
||||
"%s (requested start height: %d, store height: %d)", ErrHeightNotAvailable, startHeight, height)
|
||||
}
|
||||
|
||||
if endHeight == 0 || endHeight > height {
|
||||
endHeight = height
|
||||
fmt.Printf("set the end block height to the latest height of the blockstore %d \n", height)
|
||||
}
|
||||
|
||||
if endHeight < base {
|
||||
return fmt.Errorf(
|
||||
"%s (requested end height: %d, base height: %d)", ErrHeightNotAvailable, endHeight, base)
|
||||
}
|
||||
|
||||
if endHeight < startHeight {
|
||||
return fmt.Errorf(
|
||||
"%s (requested the end height: %d is less than the start height: %d)",
|
||||
ErrInvalidRequest, startHeight, endHeight)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
192
cmd/tendermint/commands/reindex_event_test.go
Normal file
192
cmd/tendermint/commands/reindex_event_test.go
Normal file
@@ -0,0 +1,192 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abcitypes "github.com/tendermint/tendermint/abci/types"
|
||||
tmcfg "github.com/tendermint/tendermint/config"
|
||||
prototmstate "github.com/tendermint/tendermint/proto/tendermint/state"
|
||||
blockmocks "github.com/tendermint/tendermint/state/indexer/mocks"
|
||||
"github.com/tendermint/tendermint/state/mocks"
|
||||
txmocks "github.com/tendermint/tendermint/state/txindex/mocks"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
)
|
||||
|
||||
const (
|
||||
height int64 = 10
|
||||
base int64 = 2
|
||||
)
|
||||
|
||||
func setupReIndexEventCmd() *cobra.Command {
|
||||
reIndexEventCmd := &cobra.Command{
|
||||
Use: ReIndexEventCmd.Use,
|
||||
Run: func(cmd *cobra.Command, args []string) {},
|
||||
}
|
||||
|
||||
_ = reIndexEventCmd.ExecuteContext(context.Background())
|
||||
|
||||
return reIndexEventCmd
|
||||
}
|
||||
|
||||
func TestReIndexEventCheckHeight(t *testing.T) {
|
||||
mockBlockStore := &mocks.BlockStore{}
|
||||
mockBlockStore.
|
||||
On("Base").Return(base).
|
||||
On("Height").Return(height)
|
||||
|
||||
testCases := []struct {
|
||||
startHeight int64
|
||||
endHeight int64
|
||||
validHeight bool
|
||||
}{
|
||||
{0, 0, true},
|
||||
{0, base, true},
|
||||
{0, base - 1, false},
|
||||
{0, height, true},
|
||||
{0, height + 1, true},
|
||||
{0, 0, true},
|
||||
{base - 1, 0, false},
|
||||
{base, 0, true},
|
||||
{base, base, true},
|
||||
{base, base - 1, false},
|
||||
{base, height, true},
|
||||
{base, height + 1, true},
|
||||
{height, 0, true},
|
||||
{height, base, false},
|
||||
{height, height - 1, false},
|
||||
{height, height, true},
|
||||
{height, height + 1, true},
|
||||
{height + 1, 0, false},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
startHeight = tc.startHeight
|
||||
endHeight = tc.endHeight
|
||||
|
||||
err := checkValidHeight(mockBlockStore)
|
||||
if tc.validHeight {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadEventSink(t *testing.T) {
|
||||
testCases := []struct {
|
||||
sinks string
|
||||
connURL string
|
||||
loadErr bool
|
||||
}{
|
||||
{"", "", true},
|
||||
{"NULL", "", true},
|
||||
{"KV", "", false},
|
||||
{"PSQL", "", true}, // true because empty connect url
|
||||
// skip to test PSQL connect with correct url
|
||||
{"UnsupportedSinkType", "wrongUrl", true},
|
||||
}
|
||||
|
||||
for idx, tc := range testCases {
|
||||
cfg := tmcfg.TestConfig()
|
||||
cfg.TxIndex.Indexer = tc.sinks
|
||||
cfg.TxIndex.PsqlConn = tc.connURL
|
||||
_, _, err := loadEventSinks(cfg)
|
||||
if tc.loadErr {
|
||||
require.Error(t, err, idx)
|
||||
} else {
|
||||
require.NoError(t, err, idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadBlockStore(t *testing.T) {
|
||||
cfg := tmcfg.TestConfig()
|
||||
cfg.DBPath = t.TempDir()
|
||||
_, _, err := loadStateAndBlockStore(cfg)
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = dbm.NewDB("blockstore", dbm.GoLevelDBBackend, cfg.DBDir())
|
||||
require.NoError(t, err)
|
||||
|
||||
// Get StateStore
|
||||
_, err = dbm.NewDB("state", dbm.GoLevelDBBackend, cfg.DBDir())
|
||||
require.NoError(t, err)
|
||||
|
||||
bs, ss, err := loadStateAndBlockStore(cfg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, bs)
|
||||
require.NotNil(t, ss)
|
||||
|
||||
}
|
||||
|
||||
func TestReIndexEvent(t *testing.T) {
|
||||
mockBlockStore := &mocks.BlockStore{}
|
||||
mockStateStore := &mocks.Store{}
|
||||
mockBlockIndexer := &blockmocks.BlockIndexer{}
|
||||
mockTxIndexer := &txmocks.TxIndexer{}
|
||||
|
||||
mockBlockStore.
|
||||
On("Base").Return(base).
|
||||
On("Height").Return(height).
|
||||
On("LoadBlock", base).Return(nil).Once().
|
||||
On("LoadBlock", base).Return(&types.Block{Data: types.Data{Txs: types.Txs{make(types.Tx, 1)}}}).
|
||||
On("LoadBlock", height).Return(&types.Block{Data: types.Data{Txs: types.Txs{make(types.Tx, 1)}}})
|
||||
|
||||
dtx := abcitypes.ResponseDeliverTx{}
|
||||
abciResp := &prototmstate.ABCIResponses{
|
||||
DeliverTxs: []*abcitypes.ResponseDeliverTx{&dtx},
|
||||
EndBlock: &abcitypes.ResponseEndBlock{},
|
||||
BeginBlock: &abcitypes.ResponseBeginBlock{},
|
||||
}
|
||||
|
||||
mockBlockIndexer.
|
||||
On("Index", mock.AnythingOfType("types.EventDataNewBlockHeader")).Return(errors.New("")).Once().
|
||||
On("Index", mock.AnythingOfType("types.EventDataNewBlockHeader")).Return(nil)
|
||||
|
||||
mockTxIndexer.
|
||||
On("AddBatch", mock.AnythingOfType("*txindex.Batch")).Return(errors.New("")).Once().
|
||||
On("AddBatch", mock.AnythingOfType("*txindex.Batch")).Return(nil)
|
||||
|
||||
mockStateStore.
|
||||
On("LoadABCIResponses", base).Return(nil, errors.New("")).Once().
|
||||
On("LoadABCIResponses", base).Return(abciResp, nil).
|
||||
On("LoadABCIResponses", height).Return(abciResp, nil)
|
||||
|
||||
testCases := []struct {
|
||||
startHeight int64
|
||||
endHeight int64
|
||||
reIndexErr bool
|
||||
}{
|
||||
{base, height, true}, // LoadBlock error
|
||||
{base, height, true}, // LoadABCIResponses error
|
||||
{base, height, true}, // index block event error
|
||||
{base, height, true}, // index tx event error
|
||||
{base, base, false},
|
||||
{height, height, false},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
args := eventReIndexArgs{
|
||||
startHeight: tc.startHeight,
|
||||
endHeight: tc.endHeight,
|
||||
blockIndexer: mockBlockIndexer,
|
||||
txIndexer: mockTxIndexer,
|
||||
blockStore: mockBlockStore,
|
||||
stateStore: mockStateStore,
|
||||
}
|
||||
|
||||
err := eventReIndex(setupReIndexEventCmd(), args)
|
||||
if tc.reIndexErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,12 +25,17 @@ var keepAddrBook bool
|
||||
|
||||
// ResetStateCmd removes the database of the specified Tendermint core instance.
|
||||
var ResetStateCmd = &cobra.Command{
|
||||
Use: "reset-state",
|
||||
Short: "Remove all the data and WAL",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
Use: "reset-state",
|
||||
Short: "Remove all the data and WAL",
|
||||
PreRun: deprecateSnakeCase,
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
config, err = ParseConfig(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resetState(config.DBDir(), logger)
|
||||
},
|
||||
PreRun: deprecateSnakeCase,
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -42,21 +47,37 @@ var ResetPrivValidatorCmd = &cobra.Command{
|
||||
Use: "unsafe-reset-priv-validator",
|
||||
Aliases: []string{"unsafe_reset_priv_validator"},
|
||||
Short: "(unsafe) Reset this node's validator to genesis state",
|
||||
Run: resetPrivValidator,
|
||||
PreRun: deprecateSnakeCase,
|
||||
RunE: resetPrivValidator,
|
||||
}
|
||||
|
||||
// XXX: this is totally unsafe.
|
||||
// it's only suitable for testnets.
|
||||
func resetAllCmd(cmd *cobra.Command, args []string) error {
|
||||
return resetAll(config.DBDir(), config.P2P.AddrBookFile(), config.PrivValidatorKeyFile(),
|
||||
config.PrivValidatorStateFile(), logger)
|
||||
func resetAllCmd(cmd *cobra.Command, args []string) (err error) {
|
||||
config, err = ParseConfig(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resetAll(
|
||||
config.DBDir(),
|
||||
config.P2P.AddrBookFile(),
|
||||
config.PrivValidatorKeyFile(),
|
||||
config.PrivValidatorStateFile(),
|
||||
logger,
|
||||
)
|
||||
}
|
||||
|
||||
// XXX: this is totally unsafe.
|
||||
// it's only suitable for testnets.
|
||||
func resetPrivValidator(cmd *cobra.Command, args []string) {
|
||||
func resetPrivValidator(cmd *cobra.Command, args []string) (err error) {
|
||||
config, err = ParseConfig(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resetFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile(), logger)
|
||||
return nil
|
||||
}
|
||||
|
||||
// resetAll removes address book files plus all data, and resets the privValdiator data.
|
||||
@@ -66,12 +87,18 @@ func resetAll(dbDir, addrBookFile, privValKeyFile, privValStateFile string, logg
|
||||
} else {
|
||||
removeAddrBook(addrBookFile, logger)
|
||||
}
|
||||
|
||||
if err := os.RemoveAll(dbDir); err == nil {
|
||||
logger.Info("Removed all blockchain history", "dir", dbDir)
|
||||
} else {
|
||||
logger.Error("Error removing all blockchain history", "dir", dbDir, "err", err)
|
||||
}
|
||||
|
||||
if err := tmos.EnsureDir(dbDir, 0700); err != nil {
|
||||
logger.Error("unable to recreate dbDir", "err", err)
|
||||
}
|
||||
|
||||
// recreate the dbDir since the privVal state needs to live there
|
||||
resetFilePV(privValKeyFile, privValStateFile, logger)
|
||||
return nil
|
||||
}
|
||||
@@ -83,7 +110,6 @@ func resetState(dbDir string, logger log.Logger) error {
|
||||
wal := filepath.Join(dbDir, "cs.wal")
|
||||
evidence := filepath.Join(dbDir, "evidence.db")
|
||||
txIndex := filepath.Join(dbDir, "tx_index.db")
|
||||
peerstore := filepath.Join(dbDir, "peerstore.db")
|
||||
|
||||
if tmos.FileExists(blockdb) {
|
||||
if err := os.RemoveAll(blockdb); err == nil {
|
||||
@@ -125,13 +151,6 @@ func resetState(dbDir string, logger log.Logger) error {
|
||||
}
|
||||
}
|
||||
|
||||
if tmos.FileExists(peerstore) {
|
||||
if err := os.RemoveAll(peerstore); err == nil {
|
||||
logger.Info("Removed peerstore.db", "dir", peerstore)
|
||||
} else {
|
||||
logger.Error("error removing peerstore.db", "dir", peerstore, "err", err)
|
||||
}
|
||||
}
|
||||
if err := tmos.EnsureDir(dbDir, 0700); err != nil {
|
||||
logger.Error("unable to recreate dbDir", "err", err)
|
||||
}
|
||||
@@ -142,13 +161,19 @@ func resetFilePV(privValKeyFile, privValStateFile string, logger log.Logger) {
|
||||
if _, err := os.Stat(privValKeyFile); err == nil {
|
||||
pv := privval.LoadFilePVEmptyState(privValKeyFile, privValStateFile)
|
||||
pv.Reset()
|
||||
logger.Info("Reset private validator file to genesis state", "keyFile", privValKeyFile,
|
||||
"stateFile", privValStateFile)
|
||||
logger.Info(
|
||||
"Reset private validator file to genesis state",
|
||||
"keyFile", privValKeyFile,
|
||||
"stateFile", privValStateFile,
|
||||
)
|
||||
} else {
|
||||
pv := privval.GenFilePV(privValKeyFile, privValStateFile)
|
||||
pv.Save()
|
||||
logger.Info("Generated private validator file", "keyFile", privValKeyFile,
|
||||
"stateFile", privValStateFile)
|
||||
logger.Info(
|
||||
"Generated private validator file",
|
||||
"keyFile", privValKeyFile,
|
||||
"stateFile", privValStateFile,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
53
cmd/tendermint/commands/reset_test.go
Normal file
53
cmd/tendermint/commands/reset_test.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/privval"
|
||||
)
|
||||
|
||||
func Test_ResetAll(t *testing.T) {
|
||||
config := cfg.TestConfig()
|
||||
dir := t.TempDir()
|
||||
config.SetRoot(dir)
|
||||
cfg.EnsureRoot(dir)
|
||||
require.NoError(t, initFilesWithConfig(config))
|
||||
pv := privval.LoadFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile())
|
||||
pv.LastSignState.Height = 10
|
||||
pv.Save()
|
||||
require.NoError(t, resetAll(config.DBDir(), config.P2P.AddrBookFile(), config.PrivValidatorKeyFile(),
|
||||
config.PrivValidatorStateFile(), logger))
|
||||
require.DirExists(t, config.DBDir())
|
||||
require.NoFileExists(t, filepath.Join(config.DBDir(), "block.db"))
|
||||
require.NoFileExists(t, filepath.Join(config.DBDir(), "state.db"))
|
||||
require.NoFileExists(t, filepath.Join(config.DBDir(), "evidence.db"))
|
||||
require.NoFileExists(t, filepath.Join(config.DBDir(), "tx_index.db"))
|
||||
require.FileExists(t, config.PrivValidatorStateFile())
|
||||
pv = privval.LoadFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile())
|
||||
require.Equal(t, int64(0), pv.LastSignState.Height)
|
||||
}
|
||||
|
||||
func Test_ResetState(t *testing.T) {
|
||||
config := cfg.TestConfig()
|
||||
dir := t.TempDir()
|
||||
config.SetRoot(dir)
|
||||
cfg.EnsureRoot(dir)
|
||||
require.NoError(t, initFilesWithConfig(config))
|
||||
pv := privval.LoadFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile())
|
||||
pv.LastSignState.Height = 10
|
||||
pv.Save()
|
||||
require.NoError(t, resetState(config.DBDir(), logger))
|
||||
require.DirExists(t, config.DBDir())
|
||||
require.NoFileExists(t, filepath.Join(config.DBDir(), "block.db"))
|
||||
require.NoFileExists(t, filepath.Join(config.DBDir(), "state.db"))
|
||||
require.NoFileExists(t, filepath.Join(config.DBDir(), "evidence.db"))
|
||||
require.NoFileExists(t, filepath.Join(config.DBDir(), "tx_index.db"))
|
||||
require.FileExists(t, config.PrivValidatorStateFile())
|
||||
pv = privval.LoadFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile())
|
||||
// private validator state should still be in tact.
|
||||
require.Equal(t, int64(10), pv.LastSignState.Height)
|
||||
}
|
||||
@@ -2,12 +2,14 @@ package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/libs/os"
|
||||
"github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/store"
|
||||
)
|
||||
@@ -55,6 +57,10 @@ func RollbackState(config *cfg.Config) (int64, []byte, error) {
|
||||
func loadStateAndBlockStore(config *cfg.Config) (*store.BlockStore, state.Store, error) {
|
||||
dbType := dbm.BackendType(config.DBBackend)
|
||||
|
||||
if !os.FileExists(filepath.Join(config.DBDir(), "blockstore.db")) {
|
||||
return nil, nil, fmt.Errorf("no blockstore found in %v", config.DBDir())
|
||||
}
|
||||
|
||||
// Get BlockStore
|
||||
blockStoreDB, err := dbm.NewDB("blockstore", dbType, config.DBDir())
|
||||
if err != nil {
|
||||
@@ -62,12 +68,18 @@ func loadStateAndBlockStore(config *cfg.Config) (*store.BlockStore, state.Store,
|
||||
}
|
||||
blockStore := store.NewBlockStore(blockStoreDB)
|
||||
|
||||
if !os.FileExists(filepath.Join(config.DBDir(), "state.db")) {
|
||||
return nil, nil, fmt.Errorf("no statestore found in %v", config.DBDir())
|
||||
}
|
||||
|
||||
// Get StateStore
|
||||
stateDB, err := dbm.NewDB("state", dbType, config.DBDir())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
stateStore := state.NewStore(stateDB)
|
||||
stateStore := state.NewStore(stateDB, state.StoreOptions{
|
||||
DiscardABCIResponses: config.Storage.DiscardABCIResponses,
|
||||
})
|
||||
|
||||
return blockStore, stateStore, nil
|
||||
}
|
||||
|
||||
@@ -29,12 +29,25 @@ func registerFlagsRootCmd(cmd *cobra.Command) {
|
||||
|
||||
// ParseConfig retrieves the default environment configuration,
|
||||
// sets up the Tendermint root and ensures that the root exists
|
||||
func ParseConfig() (*cfg.Config, error) {
|
||||
func ParseConfig(cmd *cobra.Command) (*cfg.Config, error) {
|
||||
conf := cfg.DefaultConfig()
|
||||
err := viper.Unmarshal(conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var home string
|
||||
if os.Getenv("TMHOME") != "" {
|
||||
home = os.Getenv("TMHOME")
|
||||
} else {
|
||||
home, err = cmd.Flags().GetString(cli.HomeFlag)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
conf.RootDir = home
|
||||
|
||||
conf.SetRoot(conf.RootDir)
|
||||
cfg.EnsureRoot(conf.RootDir)
|
||||
if err := conf.ValidateBasic(); err != nil {
|
||||
@@ -52,7 +65,7 @@ var RootCmd = &cobra.Command{
|
||||
return nil
|
||||
}
|
||||
|
||||
config, err = ParseConfig()
|
||||
config, err = ParseConfig(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -63,6 +63,8 @@ func AddNodeFlags(cmd *cobra.Command) {
|
||||
"p2p.laddr",
|
||||
config.P2P.ListenAddress,
|
||||
"node listen address. (0.0.0.0:0 means any interface, any port)")
|
||||
cmd.Flags().String("p2p.external-address",
|
||||
config.P2P.ExternalAddress, "ip:port address to advertise to peers for them to dial")
|
||||
cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "comma-delimited ID@host:port seed nodes")
|
||||
cmd.Flags().String("p2p.persistent_peers", config.P2P.PersistentPeers, "comma-delimited ID@host:port persistent peers")
|
||||
cmd.Flags().String("p2p.unconditional_peer_ids",
|
||||
|
||||
@@ -18,6 +18,7 @@ func main() {
|
||||
cmd.InitFilesCmd,
|
||||
cmd.ProbeUpnpCmd,
|
||||
cmd.LightCmd,
|
||||
cmd.ReIndexEventCmd,
|
||||
cmd.ReplayCmd,
|
||||
cmd.ReplayConsoleCmd,
|
||||
cmd.ResetAllCmd,
|
||||
@@ -29,6 +30,7 @@ func main() {
|
||||
cmd.GenNodeKeyCmd,
|
||||
cmd.VersionCmd,
|
||||
cmd.RollbackStateCmd,
|
||||
cmd.CompactGoLevelDBCmd,
|
||||
debug.DebugCmd,
|
||||
cli.NewCompletionCmd(rootCmd, true),
|
||||
)
|
||||
|
||||
@@ -23,6 +23,11 @@ const (
|
||||
|
||||
// DefaultLogLevel defines a default log level as INFO.
|
||||
DefaultLogLevel = "info"
|
||||
|
||||
// Mempool versions. V1 is prioritized mempool, v0 is regular mempool.
|
||||
// Default is v0.
|
||||
MempoolV0 = "v0"
|
||||
MempoolV1 = "v1"
|
||||
)
|
||||
|
||||
// NOTE: Most of the structs & relevant comments + the
|
||||
@@ -69,6 +74,7 @@ type Config struct {
|
||||
StateSync *StateSyncConfig `mapstructure:"statesync"`
|
||||
FastSync *FastSyncConfig `mapstructure:"fastsync"`
|
||||
Consensus *ConsensusConfig `mapstructure:"consensus"`
|
||||
Storage *StorageConfig `mapstructure:"storage"`
|
||||
TxIndex *TxIndexConfig `mapstructure:"tx_index"`
|
||||
Instrumentation *InstrumentationConfig `mapstructure:"instrumentation"`
|
||||
}
|
||||
@@ -83,6 +89,7 @@ func DefaultConfig() *Config {
|
||||
StateSync: DefaultStateSyncConfig(),
|
||||
FastSync: DefaultFastSyncConfig(),
|
||||
Consensus: DefaultConsensusConfig(),
|
||||
Storage: DefaultStorageConfig(),
|
||||
TxIndex: DefaultTxIndexConfig(),
|
||||
Instrumentation: DefaultInstrumentationConfig(),
|
||||
}
|
||||
@@ -98,6 +105,7 @@ func TestConfig() *Config {
|
||||
StateSync: TestStateSyncConfig(),
|
||||
FastSync: TestFastSyncConfig(),
|
||||
Consensus: TestConsensusConfig(),
|
||||
Storage: TestStorageConfig(),
|
||||
TxIndex: TestTxIndexConfig(),
|
||||
Instrumentation: TestInstrumentationConfig(),
|
||||
}
|
||||
@@ -676,6 +684,13 @@ func DefaultFuzzConnConfig() *FuzzConnConfig {
|
||||
|
||||
// MempoolConfig defines the configuration options for the Tendermint mempool
|
||||
type MempoolConfig struct {
|
||||
// Mempool version to use:
|
||||
// 1) "v0" - (default) FIFO mempool.
|
||||
// 2) "v1" - prioritized mempool.
|
||||
// WARNING: There's a known memory leak with the prioritized mempool
|
||||
// that the team are working on. Read more here:
|
||||
// https://github.com/tendermint/tendermint/issues/8775
|
||||
Version string `mapstructure:"version"`
|
||||
RootDir string `mapstructure:"home"`
|
||||
Recheck bool `mapstructure:"recheck"`
|
||||
Broadcast bool `mapstructure:"broadcast"`
|
||||
@@ -699,20 +714,39 @@ type MempoolConfig struct {
|
||||
// Including space needed by encoding (one varint per transaction).
|
||||
// XXX: Unused due to https://github.com/tendermint/tendermint/issues/5796
|
||||
MaxBatchBytes int `mapstructure:"max_batch_bytes"`
|
||||
|
||||
// TTLDuration, if non-zero, defines the maximum amount of time a transaction
|
||||
// can exist for in the mempool.
|
||||
//
|
||||
// Note, if TTLNumBlocks is also defined, a transaction will be removed if it
|
||||
// has existed in the mempool at least TTLNumBlocks number of blocks or if it's
|
||||
// insertion time into the mempool is beyond TTLDuration.
|
||||
TTLDuration time.Duration `mapstructure:"ttl-duration"`
|
||||
|
||||
// TTLNumBlocks, if non-zero, defines the maximum number of blocks a transaction
|
||||
// can exist for in the mempool.
|
||||
//
|
||||
// Note, if TTLDuration is also defined, a transaction will be removed if it
|
||||
// has existed in the mempool at least TTLNumBlocks number of blocks or if
|
||||
// it's insertion time into the mempool is beyond TTLDuration.
|
||||
TTLNumBlocks int64 `mapstructure:"ttl-num-blocks"`
|
||||
}
|
||||
|
||||
// DefaultMempoolConfig returns a default configuration for the Tendermint mempool
|
||||
func DefaultMempoolConfig() *MempoolConfig {
|
||||
return &MempoolConfig{
|
||||
Version: MempoolV0,
|
||||
Recheck: true,
|
||||
Broadcast: true,
|
||||
WalPath: "",
|
||||
// Each signature verification takes .5ms, Size reduced until we implement
|
||||
// ABCI Recheck
|
||||
Size: 5000,
|
||||
MaxTxsBytes: 1024 * 1024 * 1024, // 1GB
|
||||
CacheSize: 10000,
|
||||
MaxTxBytes: 1024 * 1024, // 1MB
|
||||
Size: 5000,
|
||||
MaxTxsBytes: 1024 * 1024 * 1024, // 1GB
|
||||
CacheSize: 10000,
|
||||
MaxTxBytes: 1024 * 1024, // 1MB
|
||||
TTLDuration: 0 * time.Second,
|
||||
TTLNumBlocks: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1040,11 +1074,41 @@ func (cfg *ConsensusConfig) ValidateBasic() error {
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// StorageConfig
|
||||
|
||||
// StorageConfig allows more fine-grained control over certain storage-related
|
||||
// behavior.
|
||||
type StorageConfig struct {
|
||||
// Set to false to ensure ABCI responses are persisted. ABCI responses are
|
||||
// required for `/block_results` RPC queries, and to reindex events in the
|
||||
// command-line tool.
|
||||
DiscardABCIResponses bool `mapstructure:"discard_abci_responses"`
|
||||
}
|
||||
|
||||
// DefaultStorageConfig returns the default configuration options relating to
|
||||
// Tendermint storage optimization.
|
||||
func DefaultStorageConfig() *StorageConfig {
|
||||
return &StorageConfig{
|
||||
DiscardABCIResponses: false,
|
||||
}
|
||||
}
|
||||
|
||||
// TestStorageConfig returns storage configuration that can be used for
|
||||
// testing.
|
||||
func TestStorageConfig() *StorageConfig {
|
||||
return &StorageConfig{
|
||||
DiscardABCIResponses: false,
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// TxIndexConfig
|
||||
// Remember that Event has the following structure:
|
||||
// type: [
|
||||
// key: value,
|
||||
// ...
|
||||
//
|
||||
// key: value,
|
||||
// ...
|
||||
//
|
||||
// ]
|
||||
//
|
||||
// CompositeKeys are constructed by `type.key`
|
||||
|
||||
@@ -140,8 +140,8 @@ func TestFastSyncConfigValidateBasic(t *testing.T) {
|
||||
assert.Error(t, cfg.ValidateBasic())
|
||||
}
|
||||
|
||||
// nolint: lll
|
||||
func TestConsensusConfig_ValidateBasic(t *testing.T) {
|
||||
// nolint: lll
|
||||
testcases := map[string]struct {
|
||||
modify func(*ConsensusConfig)
|
||||
expectErr bool
|
||||
@@ -166,6 +166,7 @@ func TestConsensusConfig_ValidateBasic(t *testing.T) {
|
||||
"PeerQueryMaj23SleepDuration negative": {func(c *ConsensusConfig) { c.PeerQueryMaj23SleepDuration = -1 }, true},
|
||||
"DoubleSignCheckHeight negative": {func(c *ConsensusConfig) { c.DoubleSignCheckHeight = -1 }, true},
|
||||
}
|
||||
|
||||
for desc, tc := range testcases {
|
||||
tc := tc // appease linter
|
||||
t.Run(desc, func(t *testing.T) {
|
||||
|
||||
@@ -342,6 +342,11 @@ dial_timeout = "{{ .P2P.DialTimeout }}"
|
||||
#######################################################
|
||||
[mempool]
|
||||
|
||||
# Mempool version to use:
|
||||
# 1) "v0" - (default) FIFO mempool.
|
||||
# 2) "v1" - prioritized mempool.
|
||||
version = "{{ .Mempool.Version }}"
|
||||
|
||||
recheck = {{ .Mempool.Recheck }}
|
||||
broadcast = {{ .Mempool.Broadcast }}
|
||||
wal_dir = "{{ js .Mempool.WalPath }}"
|
||||
@@ -371,6 +376,22 @@ max_tx_bytes = {{ .Mempool.MaxTxBytes }}
|
||||
# XXX: Unused due to https://github.com/tendermint/tendermint/issues/5796
|
||||
max_batch_bytes = {{ .Mempool.MaxBatchBytes }}
|
||||
|
||||
# ttl-duration, if non-zero, defines the maximum amount of time a transaction
|
||||
# can exist for in the mempool.
|
||||
#
|
||||
# Note, if ttl-num-blocks is also defined, a transaction will be removed if it
|
||||
# has existed in the mempool at least ttl-num-blocks number of blocks or if it's
|
||||
# insertion time into the mempool is beyond ttl-duration.
|
||||
ttl-duration = "{{ .Mempool.TTLDuration }}"
|
||||
|
||||
# ttl-num-blocks, if non-zero, defines the maximum number of blocks a transaction
|
||||
# can exist for in the mempool.
|
||||
#
|
||||
# Note, if ttl-duration is also defined, a transaction will be removed if it
|
||||
# has existed in the mempool at least ttl-num-blocks number of blocks or if
|
||||
# it's insertion time into the mempool is beyond ttl-duration.
|
||||
ttl-num-blocks = {{ .Mempool.TTLNumBlocks }}
|
||||
|
||||
#######################################################
|
||||
### State Sync Configuration Options ###
|
||||
#######################################################
|
||||
@@ -459,6 +480,16 @@ create_empty_blocks_interval = "{{ .Consensus.CreateEmptyBlocksInterval }}"
|
||||
peer_gossip_sleep_duration = "{{ .Consensus.PeerGossipSleepDuration }}"
|
||||
peer_query_maj23_sleep_duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}"
|
||||
|
||||
#######################################################
|
||||
### Storage Configuration Options ###
|
||||
#######################################################
|
||||
|
||||
# Set to true to discard ABCI responses from the state store, which can save a
|
||||
# considerable amount of disk space. Set to false to ensure ABCI responses are
|
||||
# persisted. ABCI responses are required for /block_results RPC queries, and to
|
||||
# reindex events in the command-line tool.
|
||||
discard_abci_responses = {{ .Storage.DiscardABCIResponses}}
|
||||
|
||||
#######################################################
|
||||
### Transaction Indexer Configuration Options ###
|
||||
#######################################################
|
||||
@@ -473,8 +504,14 @@ peer_query_maj23_sleep_duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}"
|
||||
# 1) "null"
|
||||
# 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend).
|
||||
# - When "kv" is chosen "tx.height" and "tx.hash" will always be indexed.
|
||||
# 3) "psql" - the indexer services backed by PostgreSQL.
|
||||
# When "kv" or "psql" is chosen "tx.height" and "tx.hash" will always be indexed.
|
||||
indexer = "{{ .TxIndex.Indexer }}"
|
||||
|
||||
# The PostgreSQL connection configuration, the connection format:
|
||||
# postgresql://<user>:<password>@<host>:<port>/<db>?<opts>
|
||||
psql-conn = "{{ .TxIndex.PsqlConn }}"
|
||||
|
||||
#######################################################
|
||||
### Instrumentation Configuration Options ###
|
||||
#######################################################
|
||||
|
||||
@@ -21,6 +21,10 @@ import (
|
||||
"github.com/tendermint/tendermint/libs/service"
|
||||
tmsync "github.com/tendermint/tendermint/libs/sync"
|
||||
mempl "github.com/tendermint/tendermint/mempool"
|
||||
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
mempoolv0 "github.com/tendermint/tendermint/mempool/v0"
|
||||
mempoolv1 "github.com/tendermint/tendermint/mempool/v1"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
@@ -46,7 +50,9 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
|
||||
for i := 0; i < nValidators; i++ {
|
||||
logger := consensusLogger().With("test", "byzantine", "validator", i)
|
||||
stateDB := dbm.NewMemDB() // each state needs its own db
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc)
|
||||
thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
|
||||
defer os.RemoveAll(thisConfig.RootDir)
|
||||
@@ -58,14 +64,31 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
|
||||
blockDB := dbm.NewMemDB()
|
||||
blockStore := store.NewBlockStore(blockDB)
|
||||
|
||||
// one for mempool, one for consensus
|
||||
mtx := new(tmsync.Mutex)
|
||||
proxyAppConnMem := abcicli.NewLocalClient(mtx, app)
|
||||
// one for mempool, one for consensus
|
||||
proxyAppConnCon := abcicli.NewLocalClient(mtx, app)
|
||||
proxyAppConnConMem := abcicli.NewLocalClient(mtx, app)
|
||||
|
||||
// Make Mempool
|
||||
mempool := mempl.NewCListMempool(thisConfig.Mempool, proxyAppConnMem, 0)
|
||||
mempool.SetLogger(log.TestingLogger().With("module", "mempool"))
|
||||
var mempool mempl.Mempool
|
||||
|
||||
switch thisConfig.Mempool.Version {
|
||||
case cfg.MempoolV0:
|
||||
mempool = mempoolv0.NewCListMempool(config.Mempool,
|
||||
proxyAppConnConMem,
|
||||
state.LastBlockHeight,
|
||||
mempoolv0.WithPreCheck(sm.TxPreCheck(state)),
|
||||
mempoolv0.WithPostCheck(sm.TxPostCheck(state)))
|
||||
case cfg.MempoolV1:
|
||||
mempool = mempoolv1.NewTxMempool(logger,
|
||||
config.Mempool,
|
||||
proxyAppConnConMem,
|
||||
state.LastBlockHeight,
|
||||
mempoolv1.WithPreCheck(sm.TxPreCheck(state)),
|
||||
mempoolv1.WithPostCheck(sm.TxPostCheck(state)),
|
||||
)
|
||||
}
|
||||
|
||||
if thisConfig.Consensus.WaitForTxs() {
|
||||
mempool.EnableTxsAvailable()
|
||||
}
|
||||
@@ -399,7 +422,7 @@ func TestByzantineConflictingProposalsWithPartition(t *testing.T) {
|
||||
// wait for someone in the big partition (B) to make a block
|
||||
<-blocksSubs[ind2].Out()
|
||||
|
||||
t.Log("A block has been committed. Healing partition")
|
||||
t.Logf("A block has been committed. Healing partition")
|
||||
p2p.Connect2Switches(switches, ind0, ind1)
|
||||
p2p.Connect2Switches(switches, ind0, ind2)
|
||||
|
||||
@@ -425,8 +448,8 @@ func TestByzantineConflictingProposalsWithPartition(t *testing.T) {
|
||||
case <-done:
|
||||
case <-tick.C:
|
||||
for i, reactor := range reactors {
|
||||
t.Log(fmt.Sprintf("Consensus Reactor %v", i))
|
||||
t.Log(fmt.Sprintf("%v", reactor))
|
||||
t.Logf(fmt.Sprintf("Consensus Reactor %v", i))
|
||||
t.Logf(fmt.Sprintf("%v", reactor))
|
||||
}
|
||||
t.Fatalf("Timed out waiting for all validators to commit first block")
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ import (
|
||||
tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
|
||||
tmsync "github.com/tendermint/tendermint/libs/sync"
|
||||
mempl "github.com/tendermint/tendermint/mempool"
|
||||
mempoolv0 "github.com/tendermint/tendermint/mempool/v0"
|
||||
mempoolv1 "github.com/tendermint/tendermint/mempool/v1"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/privval"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
@@ -390,12 +392,34 @@ func newStateWithConfigAndBlockStore(
|
||||
|
||||
// one for mempool, one for consensus
|
||||
mtx := new(tmsync.Mutex)
|
||||
proxyAppConnMem := abcicli.NewLocalClient(mtx, app)
|
||||
|
||||
proxyAppConnCon := abcicli.NewLocalClient(mtx, app)
|
||||
proxyAppConnConMem := abcicli.NewLocalClient(mtx, app)
|
||||
// Make Mempool
|
||||
memplMetrics := mempl.NopMetrics()
|
||||
|
||||
// Make Mempool
|
||||
mempool := mempl.NewCListMempool(thisConfig.Mempool, proxyAppConnMem, 0)
|
||||
mempool.SetLogger(log.TestingLogger().With("module", "mempool"))
|
||||
var mempool mempl.Mempool
|
||||
|
||||
switch config.Mempool.Version {
|
||||
case cfg.MempoolV0:
|
||||
mempool = mempoolv0.NewCListMempool(config.Mempool,
|
||||
proxyAppConnConMem,
|
||||
state.LastBlockHeight,
|
||||
mempoolv0.WithMetrics(memplMetrics),
|
||||
mempoolv0.WithPreCheck(sm.TxPreCheck(state)),
|
||||
mempoolv0.WithPostCheck(sm.TxPostCheck(state)))
|
||||
case cfg.MempoolV1:
|
||||
logger := consensusLogger()
|
||||
mempool = mempoolv1.NewTxMempool(logger,
|
||||
config.Mempool,
|
||||
proxyAppConnConMem,
|
||||
state.LastBlockHeight,
|
||||
mempoolv1.WithMetrics(memplMetrics),
|
||||
mempoolv1.WithPreCheck(sm.TxPreCheck(state)),
|
||||
mempoolv1.WithPostCheck(sm.TxPostCheck(state)),
|
||||
)
|
||||
}
|
||||
if thisConfig.Consensus.WaitForTxs() {
|
||||
mempool.EnableTxsAvailable()
|
||||
}
|
||||
@@ -404,7 +428,9 @@ func newStateWithConfigAndBlockStore(
|
||||
|
||||
// Make State
|
||||
stateDB := blockDB
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
if err := stateStore.Save(state); err != nil { // for save height 1's validators info
|
||||
panic(err)
|
||||
}
|
||||
@@ -694,7 +720,9 @@ func randConsensusNet(nValidators int, testName string, tickerFunc func() Timeou
|
||||
configRootDirs := make([]string, 0, nValidators)
|
||||
for i := 0; i < nValidators; i++ {
|
||||
stateDB := dbm.NewMemDB() // each state needs its own db
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc)
|
||||
thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
|
||||
configRootDirs = append(configRootDirs, thisConfig.RootDir)
|
||||
@@ -732,7 +760,9 @@ func randConsensusNetWithPeers(
|
||||
configRootDirs := make([]string, 0, nPeers)
|
||||
for i := 0; i < nPeers; i++ {
|
||||
stateDB := dbm.NewMemDB() // each state needs its own db
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc)
|
||||
thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
|
||||
configRootDirs = append(configRootDirs, thisConfig.RootDir)
|
||||
|
||||
@@ -113,7 +113,7 @@ func deliverTxsRange(cs *State, start, end int) {
|
||||
func TestMempoolTxConcurrentWithCommit(t *testing.T) {
|
||||
state, privVals := randGenesisState(1, false, 10)
|
||||
blockDB := dbm.NewMemDB()
|
||||
stateStore := sm.NewStore(blockDB)
|
||||
stateStore := sm.NewStore(blockDB, sm.StoreOptions{DiscardABCIResponses: false})
|
||||
cs := newStateWithConfigAndBlockStore(config, state, privVals[0], NewCounterApplication(), blockDB)
|
||||
err := stateStore.Save(state)
|
||||
require.NoError(t, err)
|
||||
@@ -138,7 +138,7 @@ func TestMempoolRmBadTx(t *testing.T) {
|
||||
state, privVals := randGenesisState(1, false, 10)
|
||||
app := NewCounterApplication()
|
||||
blockDB := dbm.NewMemDB()
|
||||
stateStore := sm.NewStore(blockDB)
|
||||
stateStore := sm.NewStore(blockDB, sm.StoreOptions{DiscardABCIResponses: false})
|
||||
cs := newStateWithConfigAndBlockStore(config, state, privVals[0], app, blockDB)
|
||||
err := stateStore.Save(state)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -314,7 +314,7 @@ func TestWALMsgProto(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// nolint:lll //ignore line length for tests
|
||||
//nolint:lll //ignore line length for tests
|
||||
func TestConsMsgsVectors(t *testing.T) {
|
||||
date := time.Date(2018, 8, 30, 12, 0, 0, 0, time.UTC)
|
||||
psh := types.PartSetHeader{
|
||||
|
||||
@@ -1265,12 +1265,12 @@ func (ps *PeerState) SetHasVote(vote *types.Vote) {
|
||||
}
|
||||
|
||||
func (ps *PeerState) setHasVote(height int64, round int32, voteType tmproto.SignedMsgType, index int32) {
|
||||
logger := ps.logger.With(
|
||||
ps.logger.Debug("setHasVote",
|
||||
"peerH/R",
|
||||
fmt.Sprintf("%d/%d", ps.PRS.Height, ps.PRS.Round),
|
||||
log.NewLazySprintf("%d/%d", ps.PRS.Height, ps.PRS.Round),
|
||||
"H/R",
|
||||
fmt.Sprintf("%d/%d", height, round))
|
||||
logger.Debug("setHasVote", "type", voteType, "index", index)
|
||||
log.NewLazySprintf("%d/%d", height, round),
|
||||
"type", voteType, "index", index)
|
||||
|
||||
// NOTE: some may be nil BitArrays -> no side effects.
|
||||
psVotes := ps.getVoteBitArray(height, round, voteType)
|
||||
|
||||
@@ -29,6 +29,8 @@ import (
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmsync "github.com/tendermint/tendermint/libs/sync"
|
||||
mempl "github.com/tendermint/tendermint/mempool"
|
||||
mempoolv0 "github.com/tendermint/tendermint/mempool/v0"
|
||||
mempoolv1 "github.com/tendermint/tendermint/mempool/v1"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
p2pmock "github.com/tendermint/tendermint/p2p/mock"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
@@ -136,7 +138,9 @@ func TestReactorWithEvidence(t *testing.T) {
|
||||
logger := consensusLogger()
|
||||
for i := 0; i < nValidators; i++ {
|
||||
stateDB := dbm.NewMemDB() // each state needs its own db
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc)
|
||||
thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
|
||||
defer os.RemoveAll(thisConfig.RootDir)
|
||||
@@ -152,14 +156,33 @@ func TestReactorWithEvidence(t *testing.T) {
|
||||
blockDB := dbm.NewMemDB()
|
||||
blockStore := store.NewBlockStore(blockDB)
|
||||
|
||||
// one for mempool, one for consensus
|
||||
mtx := new(tmsync.Mutex)
|
||||
proxyAppConnMem := abcicli.NewLocalClient(mtx, app)
|
||||
memplMetrics := mempl.NopMetrics()
|
||||
// one for mempool, one for consensus
|
||||
proxyAppConnCon := abcicli.NewLocalClient(mtx, app)
|
||||
proxyAppConnConMem := abcicli.NewLocalClient(mtx, app)
|
||||
|
||||
// Make Mempool
|
||||
mempool := mempl.NewCListMempool(thisConfig.Mempool, proxyAppConnMem, 0)
|
||||
mempool.SetLogger(log.TestingLogger().With("module", "mempool"))
|
||||
var mempool mempl.Mempool
|
||||
|
||||
switch config.Mempool.Version {
|
||||
case cfg.MempoolV0:
|
||||
mempool = mempoolv0.NewCListMempool(config.Mempool,
|
||||
proxyAppConnConMem,
|
||||
state.LastBlockHeight,
|
||||
mempoolv0.WithMetrics(memplMetrics),
|
||||
mempoolv0.WithPreCheck(sm.TxPreCheck(state)),
|
||||
mempoolv0.WithPostCheck(sm.TxPostCheck(state)))
|
||||
case cfg.MempoolV1:
|
||||
mempool = mempoolv1.NewTxMempool(logger,
|
||||
config.Mempool,
|
||||
proxyAppConnConMem,
|
||||
state.LastBlockHeight,
|
||||
mempoolv1.WithMetrics(memplMetrics),
|
||||
mempoolv1.WithPreCheck(sm.TxPreCheck(state)),
|
||||
mempoolv1.WithPostCheck(sm.TxPostCheck(state)),
|
||||
)
|
||||
}
|
||||
if thisConfig.Consensus.WaitForTxs() {
|
||||
mempool.EnableTxsAvailable()
|
||||
}
|
||||
@@ -668,7 +691,7 @@ func capture() {
|
||||
// Ensure basic validation of structs is functioning
|
||||
|
||||
func TestNewRoundStepMessageValidateBasic(t *testing.T) {
|
||||
testCases := []struct { // nolint: maligned
|
||||
testCases := []struct {
|
||||
expectErr bool
|
||||
messageRound int32
|
||||
messageLastCommitRound int32
|
||||
@@ -707,7 +730,7 @@ func TestNewRoundStepMessageValidateBasic(t *testing.T) {
|
||||
|
||||
func TestNewRoundStepMessageValidateHeight(t *testing.T) {
|
||||
initialHeight := int64(10)
|
||||
testCases := []struct { // nolint: maligned
|
||||
testCases := []struct { //nolint: maligned
|
||||
expectErr bool
|
||||
messageLastCommitRound int32
|
||||
messageHeight int64
|
||||
@@ -857,7 +880,7 @@ func TestHasVoteMessageValidateBasic(t *testing.T) {
|
||||
invalidSignedMsgType tmproto.SignedMsgType = 0x03
|
||||
)
|
||||
|
||||
testCases := []struct { // nolint: maligned
|
||||
testCases := []struct { //nolint: maligned
|
||||
expectErr bool
|
||||
messageRound int32
|
||||
messageIndex int32
|
||||
@@ -902,7 +925,7 @@ func TestVoteSetMaj23MessageValidateBasic(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
testCases := []struct { // nolint: maligned
|
||||
testCases := []struct { //nolint: maligned
|
||||
expectErr bool
|
||||
messageRound int32
|
||||
messageHeight int64
|
||||
|
||||
@@ -418,7 +418,7 @@ func (h *Handshaker) ReplayBlocks(
|
||||
|
||||
case appBlockHeight == storeBlockHeight:
|
||||
// We ran Commit, but didn't save the state, so replayBlock with mock app.
|
||||
abciResponses, err := h.stateStore.LoadABCIResponses(storeBlockHeight)
|
||||
abciResponses, err := h.stateStore.LoadLastABCIResponse(storeBlockHeight)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -297,7 +297,9 @@ func newConsensusStateForReplay(config cfg.BaseConfig, csConfig *cfg.ConsensusCo
|
||||
if err != nil {
|
||||
tmos.Exit(err.Error())
|
||||
}
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
gdoc, err := sm.MakeGenesisDocFromFile(config.GenesisFile())
|
||||
if err != nil {
|
||||
tmos.Exit(err.Error())
|
||||
|
||||
@@ -15,12 +15,18 @@ type emptyMempool struct{}
|
||||
|
||||
var _ mempl.Mempool = emptyMempool{}
|
||||
|
||||
func (emptyMempool) Lock() {}
|
||||
func (emptyMempool) Unlock() {}
|
||||
func (emptyMempool) Size() int { return 0 }
|
||||
func (emptyMempool) Lock() {}
|
||||
func (emptyMempool) Unlock() {}
|
||||
func (emptyMempool) Size() int { return 0 }
|
||||
func (emptyMempool) SizeBytes() int64 { return 0 }
|
||||
func (emptyMempool) CheckTx(_ types.Tx, _ func(*abci.Response), _ mempl.TxInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txmp emptyMempool) RemoveTxByKey(txKey types.TxKey) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (emptyMempool) ReapMaxBytesMaxGas(_, _ int64) types.Txs { return types.Txs{} }
|
||||
func (emptyMempool) ReapMaxTxs(n int) types.Txs { return types.Txs{} }
|
||||
func (emptyMempool) Update(
|
||||
|
||||
@@ -159,7 +159,9 @@ LOOP:
|
||||
logger := log.NewNopLogger()
|
||||
blockDB := dbm.NewMemDB()
|
||||
stateDB := blockDB
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
state, err := sm.MakeGenesisStateFromFile(consensusReplayConfig.GenesisFile())
|
||||
require.NoError(t, err)
|
||||
privValidator := loadPrivValidator(consensusReplayConfig)
|
||||
@@ -290,7 +292,7 @@ func (w *crashingWAL) Start() error { return w.next.Start() }
|
||||
func (w *crashingWAL) Stop() error { return w.next.Stop() }
|
||||
func (w *crashingWAL) Wait() { w.next.Wait() }
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------
|
||||
type testSim struct {
|
||||
GenesisState sm.State
|
||||
Config *cfg.Config
|
||||
@@ -693,7 +695,9 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin
|
||||
stateDB, genesisState, store = stateAndStore(config, pubKey, kvstore.ProtocolVersion)
|
||||
|
||||
}
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
store.chain = chain
|
||||
store.commits = commits
|
||||
|
||||
@@ -712,7 +716,9 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin
|
||||
// use a throwaway tendermint state
|
||||
proxyApp := proxy.NewAppConns(clientCreator2)
|
||||
stateDB1 := dbm.NewMemDB()
|
||||
stateStore := sm.NewStore(stateDB1)
|
||||
stateStore := sm.NewStore(stateDB1, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
err := stateStore.Save(genesisState)
|
||||
require.NoError(t, err)
|
||||
buildAppStateFromChain(proxyApp, stateStore, genesisState, chain, nBlocks, mode)
|
||||
@@ -891,7 +897,9 @@ func TestHandshakePanicsIfAppReturnsWrongAppHash(t *testing.T) {
|
||||
pubKey, err := privVal.GetPubKey()
|
||||
require.NoError(t, err)
|
||||
stateDB, state, store := stateAndStore(config, pubKey, appVersion)
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
genDoc, _ := sm.MakeGenesisDocFromFile(config.GenesisFile())
|
||||
state.LastValidators = state.Validators.Copy()
|
||||
// mode = 0 for committing all the blocks
|
||||
@@ -1148,7 +1156,9 @@ func stateAndStore(
|
||||
pubKey crypto.PubKey,
|
||||
appVersion uint64) (dbm.DB, sm.State, *mockBlockStore) {
|
||||
stateDB := dbm.NewMemDB()
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
state, _ := sm.MakeGenesisStateFromFile(config.GenesisFile())
|
||||
state.Version.Consensus.App = appVersion
|
||||
store := newMockBlockStore(config, state.ConsensusParams)
|
||||
@@ -1225,7 +1235,9 @@ func TestHandshakeUpdatesValidators(t *testing.T) {
|
||||
pubKey, err := privVal.GetPubKey()
|
||||
require.NoError(t, err)
|
||||
stateDB, state, store := stateAndStore(config, pubKey, 0x0)
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
|
||||
oldValAddr := state.Validators.Validators[0].Address
|
||||
|
||||
|
||||
@@ -800,6 +800,8 @@ func (cs *State) receiveRoutine(maxSteps int) {
|
||||
|
||||
// state transitions on complete-proposal, 2/3-any, 2/3-one
|
||||
func (cs *State) handleMsg(mi msgInfo) {
|
||||
cs.mtx.Lock()
|
||||
defer cs.mtx.Unlock()
|
||||
var (
|
||||
added bool
|
||||
err error
|
||||
@@ -811,13 +813,10 @@ func (cs *State) handleMsg(mi msgInfo) {
|
||||
case *ProposalMessage:
|
||||
// will not cause transition.
|
||||
// once proposal is set, we can receive block parts
|
||||
cs.mtx.Lock()
|
||||
err = cs.setProposal(msg.Proposal)
|
||||
cs.mtx.Unlock()
|
||||
|
||||
case *BlockPartMessage:
|
||||
// if the proposal is complete, we'll enterPrevote or tryFinalizeCommit
|
||||
cs.mtx.Lock()
|
||||
added, err = cs.addProposalBlockPart(msg, peerID)
|
||||
|
||||
// We unlock here to yield to any routines that need to read the the RoundState.
|
||||
@@ -850,17 +849,14 @@ func (cs *State) handleMsg(mi msgInfo) {
|
||||
)
|
||||
err = nil
|
||||
}
|
||||
cs.mtx.Unlock()
|
||||
|
||||
case *VoteMessage:
|
||||
// attempt to add the vote and dupeout the validator if its a duplicate signature
|
||||
// if the vote gives us a 2/3-any or 2/3-one, we transition
|
||||
cs.mtx.Lock()
|
||||
added, err = cs.tryAddVote(msg.Vote, peerID)
|
||||
if added {
|
||||
cs.statsMsgQueue <- mi
|
||||
}
|
||||
cs.mtx.Unlock()
|
||||
|
||||
// if err == ErrAddingVote {
|
||||
// TODO: punish peer
|
||||
@@ -974,7 +970,9 @@ func (cs *State) handleTxsAvailable() {
|
||||
// Used internally by handleTimeout and handleMsg to make state transitions
|
||||
|
||||
// Enter: `timeoutNewHeight` by startTime (commitTime+timeoutCommit),
|
||||
// or, if SkipTimeoutCommit==true, after receiving all precommits from (height,round-1)
|
||||
//
|
||||
// or, if SkipTimeoutCommit==true, after receiving all precommits from (height,round-1)
|
||||
//
|
||||
// Enter: `timeoutPrecommits` after any +2/3 precommits from (height,round-1)
|
||||
// Enter: +2/3 precommits for nil at (height,round-1)
|
||||
// Enter: +2/3 prevotes any or +2/3 precommits for block or any from (height, round)
|
||||
@@ -985,7 +983,7 @@ func (cs *State) enterNewRound(height int64, round int32) {
|
||||
if cs.Height != height || round < cs.Round || (cs.Round == round && cs.Step != cstypes.RoundStepNewHeight) {
|
||||
logger.Debug(
|
||||
"entering new round with invalid args",
|
||||
"current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
"current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -994,7 +992,7 @@ func (cs *State) enterNewRound(height int64, round int32) {
|
||||
logger.Debug("need to set a buffer and log message here for sanity", "start_time", cs.StartTime, "now", now)
|
||||
}
|
||||
|
||||
logger.Debug("entering new round", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
logger.Debug("entering new round", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
|
||||
// increment validators if necessary
|
||||
validators := cs.Validators
|
||||
@@ -1059,7 +1057,9 @@ func (cs *State) needProofBlock(height int64) bool {
|
||||
|
||||
// Enter (CreateEmptyBlocks): from enterNewRound(height,round)
|
||||
// Enter (CreateEmptyBlocks, CreateEmptyBlocksInterval > 0 ):
|
||||
// after enterNewRound(height,round), after timeout of CreateEmptyBlocksInterval
|
||||
//
|
||||
// after enterNewRound(height,round), after timeout of CreateEmptyBlocksInterval
|
||||
//
|
||||
// Enter (!CreateEmptyBlocks) : after enterNewRound(height,round), once txs are in the mempool
|
||||
func (cs *State) enterPropose(height int64, round int32) {
|
||||
logger := cs.Logger.With("height", height, "round", round)
|
||||
@@ -1067,12 +1067,12 @@ func (cs *State) enterPropose(height int64, round int32) {
|
||||
if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPropose <= cs.Step) {
|
||||
logger.Debug(
|
||||
"entering propose step with invalid args",
|
||||
"current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
"current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
logger.Debug("entering propose step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
logger.Debug("entering propose step", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
|
||||
defer func() {
|
||||
// Done enterPropose:
|
||||
@@ -1234,7 +1234,7 @@ func (cs *State) enterPrevote(height int64, round int32) {
|
||||
if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrevote <= cs.Step) {
|
||||
logger.Debug(
|
||||
"entering prevote step with invalid args",
|
||||
"current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
"current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -1245,7 +1245,7 @@ func (cs *State) enterPrevote(height int64, round int32) {
|
||||
cs.newStep()
|
||||
}()
|
||||
|
||||
logger.Debug("entering prevote step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
logger.Debug("entering prevote step", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
|
||||
// Sign and broadcast vote as necessary
|
||||
cs.doPrevote(height, round)
|
||||
@@ -1294,7 +1294,7 @@ func (cs *State) enterPrevoteWait(height int64, round int32) {
|
||||
if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrevoteWait <= cs.Step) {
|
||||
logger.Debug(
|
||||
"entering prevote wait step with invalid args",
|
||||
"current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
"current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -1306,7 +1306,7 @@ func (cs *State) enterPrevoteWait(height int64, round int32) {
|
||||
))
|
||||
}
|
||||
|
||||
logger.Debug("entering prevote wait step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
logger.Debug("entering prevote wait step", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
|
||||
defer func() {
|
||||
// Done enterPrevoteWait:
|
||||
@@ -1330,12 +1330,12 @@ func (cs *State) enterPrecommit(height int64, round int32) {
|
||||
if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrecommit <= cs.Step) {
|
||||
logger.Debug(
|
||||
"entering precommit step with invalid args",
|
||||
"current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
"current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
logger.Debug("entering precommit step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
logger.Debug("entering precommit step", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
|
||||
defer func() {
|
||||
// Done enterPrecommit:
|
||||
@@ -1453,7 +1453,7 @@ func (cs *State) enterPrecommitWait(height int64, round int32) {
|
||||
logger.Debug(
|
||||
"entering precommit wait step with invalid args",
|
||||
"triggered_timeout", cs.TriggeredTimeoutPrecommit,
|
||||
"current", fmt.Sprintf("%v/%v", cs.Height, cs.Round),
|
||||
"current", log.NewLazySprintf("%v/%v", cs.Height, cs.Round),
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -1465,7 +1465,7 @@ func (cs *State) enterPrecommitWait(height int64, round int32) {
|
||||
))
|
||||
}
|
||||
|
||||
logger.Debug("entering precommit wait step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
logger.Debug("entering precommit wait step", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
|
||||
defer func() {
|
||||
// Done enterPrecommitWait:
|
||||
@@ -1484,12 +1484,12 @@ func (cs *State) enterCommit(height int64, commitRound int32) {
|
||||
if cs.Height != height || cstypes.RoundStepCommit <= cs.Step {
|
||||
logger.Debug(
|
||||
"entering commit step with invalid args",
|
||||
"current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
"current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
logger.Debug("entering commit step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
logger.Debug("entering commit step", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
|
||||
defer func() {
|
||||
// Done enterCommit:
|
||||
@@ -1522,7 +1522,7 @@ func (cs *State) enterCommit(height int64, commitRound int32) {
|
||||
if !cs.ProposalBlockParts.HasHeader(blockID.PartSetHeader) {
|
||||
logger.Info(
|
||||
"commit is for a block we do not know about; set ProposalBlock=nil",
|
||||
"proposal", cs.ProposalBlock.Hash(),
|
||||
"proposal", log.NewLazyBlockHash(cs.ProposalBlock),
|
||||
"commit", blockID.Hash,
|
||||
)
|
||||
|
||||
@@ -1559,7 +1559,7 @@ func (cs *State) tryFinalizeCommit(height int64) {
|
||||
// TODO: ^^ wait, why does it matter that we're a validator?
|
||||
logger.Debug(
|
||||
"failed attempt to finalize commit; we do not have the commit block",
|
||||
"proposal_block", cs.ProposalBlock.Hash(),
|
||||
"proposal_block", log.NewLazyBlockHash(cs.ProposalBlock),
|
||||
"commit_block", blockID.Hash,
|
||||
)
|
||||
return
|
||||
@@ -1575,7 +1575,7 @@ func (cs *State) finalizeCommit(height int64) {
|
||||
if cs.Height != height || cs.Step != cstypes.RoundStepCommit {
|
||||
logger.Debug(
|
||||
"entering finalize commit step",
|
||||
"current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
"current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step),
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -1601,11 +1601,11 @@ func (cs *State) finalizeCommit(height int64) {
|
||||
|
||||
logger.Info(
|
||||
"finalizing commit of block",
|
||||
"hash", block.Hash(),
|
||||
"hash", log.NewLazyBlockHash(block),
|
||||
"root", block.AppHash,
|
||||
"num_txs", len(block.Txs),
|
||||
)
|
||||
logger.Debug(fmt.Sprintf("%v", block))
|
||||
logger.Debug("committed block", "block", log.NewLazySprintf("%v", block))
|
||||
|
||||
fail.Fail() // XXX
|
||||
|
||||
@@ -1922,7 +1922,7 @@ func (cs *State) handleCompleteProposal(blockHeight int64) {
|
||||
cs.Logger.Debug(
|
||||
"updating valid block to new proposal block",
|
||||
"valid_round", cs.Round,
|
||||
"valid_block_hash", cs.ProposalBlock.Hash(),
|
||||
"valid_block_hash", log.NewLazyBlockHash(cs.ProposalBlock),
|
||||
)
|
||||
|
||||
cs.ValidRound = cs.Round
|
||||
@@ -1955,7 +1955,7 @@ func (cs *State) tryAddVote(vote *types.Vote, peerID p2p.ID) (bool, error) {
|
||||
// If the vote height is off, we'll just ignore it,
|
||||
// But if it's a conflicting sig, add it to the cs.evpool.
|
||||
// If it's otherwise invalid, punish peer.
|
||||
// nolint: gocritic
|
||||
//nolint: gocritic
|
||||
if voteErr, ok := err.(*types.ErrVoteConflictingVotes); ok {
|
||||
if cs.privValidatorPubKey == nil {
|
||||
return false, errPubKeyIsNotSet
|
||||
@@ -2096,7 +2096,7 @@ func (cs *State) addVote(vote *types.Vote, peerID p2p.ID) (added bool, err error
|
||||
} else {
|
||||
cs.Logger.Debug(
|
||||
"valid block we do not know about; set ProposalBlock=nil",
|
||||
"proposal", cs.ProposalBlock.Hash(),
|
||||
"proposal", log.NewLazyBlockHash(cs.ProposalBlock),
|
||||
"block_id", blockID.Hash,
|
||||
)
|
||||
|
||||
|
||||
@@ -47,7 +47,9 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) {
|
||||
}
|
||||
blockStoreDB := db.NewMemDB()
|
||||
stateDB := blockStoreDB
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
state, err := sm.MakeGenesisState(genDoc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to make genesis state: %w", err)
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"golang.org/x/crypto/openpgp/armor" // nolint: staticcheck
|
||||
"golang.org/x/crypto/openpgp/armor" //nolint: staticcheck
|
||||
)
|
||||
|
||||
func EncodeArmor(blockType string, headers map[string]string, data []byte) string {
|
||||
|
||||
@@ -12,20 +12,19 @@ second pre-image attacks. Hence, use this library with caution.
|
||||
Otherwise you might run into similar issues as, e.g., in early Bitcoin:
|
||||
https://bitcointalk.org/?topic=102395
|
||||
|
||||
*
|
||||
/ \
|
||||
/ \
|
||||
/ \
|
||||
/ \
|
||||
* *
|
||||
/ \ / \
|
||||
/ \ / \
|
||||
/ \ / \
|
||||
* * * h6
|
||||
/ \ / \ / \
|
||||
h0 h1 h2 h3 h4 h5
|
||||
*
|
||||
/ \
|
||||
/ \
|
||||
/ \
|
||||
/ \
|
||||
* *
|
||||
/ \ / \
|
||||
/ \ / \
|
||||
/ \ / \
|
||||
* * * h6
|
||||
/ \ / \ / \
|
||||
h0 h1 h2 h3 h4 h5
|
||||
|
||||
TODO(ismail): add 2nd pre-image protection or clarify further on how we use this and why this secure.
|
||||
|
||||
*/
|
||||
package merkle
|
||||
|
||||
@@ -85,8 +85,8 @@ func (op ValueOp) Run(args [][]byte) ([][]byte, error) {
|
||||
|
||||
bz := new(bytes.Buffer)
|
||||
// Wrap <op.Key, vhash> to hash the KVPair.
|
||||
encodeByteSlice(bz, op.key) // nolint: errcheck // does not error
|
||||
encodeByteSlice(bz, vhash) // nolint: errcheck // does not error
|
||||
encodeByteSlice(bz, op.key) //nolint: errcheck // does not error
|
||||
encodeByteSlice(bz, vhash) //nolint: errcheck // does not error
|
||||
kvhash := leafHash(bz.Bytes())
|
||||
|
||||
if !bytes.Equal(kvhash, op.Proof.LeafHash) {
|
||||
|
||||
@@ -47,10 +47,10 @@ func HashFromByteSlices(items [][]byte) []byte {
|
||||
//
|
||||
// These preliminary results suggest:
|
||||
//
|
||||
// 1. The performance of the HashFromByteSlice is pretty good
|
||||
// 2. Go has low overhead for recursive functions
|
||||
// 3. The performance of the HashFromByteSlice routine is dominated
|
||||
// by the actual hashing of data
|
||||
// 1. The performance of the HashFromByteSlice is pretty good
|
||||
// 2. Go has low overhead for recursive functions
|
||||
// 3. The performance of the HashFromByteSlice routine is dominated
|
||||
// by the actual hashing of data
|
||||
//
|
||||
// Although this work is in no way exhaustive, point #3 suggests that
|
||||
// optimization of this routine would need to take an alternative
|
||||
|
||||
@@ -9,13 +9,13 @@ import (
|
||||
"math/big"
|
||||
|
||||
secp256k1 "github.com/btcsuite/btcd/btcec"
|
||||
"golang.org/x/crypto/ripemd160" // nolint: staticcheck // necessary for Bitcoin address format
|
||||
"golang.org/x/crypto/ripemd160" //nolint: staticcheck // necessary for Bitcoin address format
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
)
|
||||
|
||||
//-------------------------------------
|
||||
// -------------------------------------
|
||||
const (
|
||||
PrivKeyName = "tendermint/PrivKeySecp256k1"
|
||||
PubKeyName = "tendermint/PubKeySecp256k1"
|
||||
@@ -124,8 +124,8 @@ func GenPrivKeySecp256k1(secret []byte) PrivKey {
|
||||
|
||||
// used to reject malleable signatures
|
||||
// see:
|
||||
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
|
||||
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39
|
||||
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
|
||||
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39
|
||||
var secp256k1halfN = new(big.Int).Rsh(secp256k1.S256().N, 1)
|
||||
|
||||
// Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg.
|
||||
|
||||
@@ -25,19 +25,19 @@ func TestRandom(t *testing.T) {
|
||||
plaintext := make([]byte, pl)
|
||||
_, err := cr.Read(key[:])
|
||||
if err != nil {
|
||||
t.Errorf("error on read: %w", err)
|
||||
t.Errorf("error on read: %v", err)
|
||||
}
|
||||
_, err = cr.Read(nonce[:])
|
||||
if err != nil {
|
||||
t.Errorf("error on read: %w", err)
|
||||
t.Errorf("error on read: %v", err)
|
||||
}
|
||||
_, err = cr.Read(ad)
|
||||
if err != nil {
|
||||
t.Errorf("error on read: %w", err)
|
||||
t.Errorf("error on read: %v", err)
|
||||
}
|
||||
_, err = cr.Read(plaintext)
|
||||
if err != nil {
|
||||
t.Errorf("error on read: %w", err)
|
||||
t.Errorf("error on read: %v", err)
|
||||
}
|
||||
|
||||
aead, err := New(key[:])
|
||||
|
||||
@@ -44,10 +44,6 @@ module.exports = {
|
||||
{
|
||||
title: 'Resources',
|
||||
children: [
|
||||
{
|
||||
title: 'Developer Sessions',
|
||||
path: '/DEV_SESSIONS.html'
|
||||
},
|
||||
{
|
||||
// TODO(creachadair): Figure out how to make this per-branch.
|
||||
// See: https://github.com/tendermint/tendermint/issues/7908
|
||||
|
||||
@@ -3,7 +3,7 @@ Package evidence handles all evidence storage and gossiping from detection to bl
|
||||
For the different types of evidence refer to the `evidence.go` file in the types package
|
||||
or https://github.com/tendermint/spec/blob/master/spec/consensus/light-client/accountability.md.
|
||||
|
||||
Gossiping
|
||||
# Gossiping
|
||||
|
||||
The core functionality begins with the evidence reactor (see reactor.
|
||||
go) which operates both the sending and receiving of evidence.
|
||||
@@ -29,7 +29,7 @@ There are two buckets that evidence can be stored in: Pending & Committed.
|
||||
|
||||
All evidence is proto encoded to disk.
|
||||
|
||||
Proposing
|
||||
# Proposing
|
||||
|
||||
When a new block is being proposed (in state/execution.go#CreateProposalBlock),
|
||||
`PendingEvidence(maxBytes)` is called to send up to the maxBytes of uncommitted evidence, from the evidence store,
|
||||
@@ -42,12 +42,11 @@ Once the proposed evidence is submitted,
|
||||
the evidence is marked as committed and is moved from the broadcasted set to the committed set.
|
||||
As a result it is also removed from the concurrent list so that it is no longer gossiped.
|
||||
|
||||
Minor Functionality
|
||||
# Minor Functionality
|
||||
|
||||
As all evidence (including POLC's) are bounded by an expiration date, those that exceed this are no longer needed
|
||||
and hence pruned. Currently, only committed evidence in which a marker to the height that the evidence was committed
|
||||
and hence very small is saved. All updates are made from the `Update(block, state)` function which should be called
|
||||
when a new block is committed.
|
||||
|
||||
*/
|
||||
package evidence
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// Code generated by mockery v0.0.0-dev. DO NOT EDIT.
|
||||
// Code generated by mockery. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
types "github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -58,3 +57,18 @@ func (_m *BlockStore) LoadBlockMeta(height int64) *types.BlockMeta {
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
type NewBlockStoreT interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewBlockStore creates a new instance of BlockStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewBlockStore(t NewBlockStoreT) *BlockStore {
|
||||
mock := &BlockStore{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -97,11 +97,11 @@ func (evpool *Pool) PendingEvidence(maxBytes int64) ([]types.Evidence, int64) {
|
||||
|
||||
// Update takes both the new state and the evidence committed at that height and performs
|
||||
// the following operations:
|
||||
// 1. Take any conflicting votes from consensus and use the state's LastBlockTime to form
|
||||
// DuplicateVoteEvidence and add it to the pool.
|
||||
// 2. Update the pool's state which contains evidence params relating to expiry.
|
||||
// 3. Moves pending evidence that has now been committed into the committed pool.
|
||||
// 4. Removes any expired evidence based on both height and time.
|
||||
// 1. Take any conflicting votes from consensus and use the state's LastBlockTime to form
|
||||
// DuplicateVoteEvidence and add it to the pool.
|
||||
// 2. Update the pool's state which contains evidence params relating to expiry.
|
||||
// 3. Moves pending evidence that has now been committed into the committed pool.
|
||||
// 4. Removes any expired evidence based on both height and time.
|
||||
func (evpool *Pool) Update(state sm.State, ev types.EvidenceList) {
|
||||
// sanity check
|
||||
if state.LastBlockHeight <= evpool.state.LastBlockHeight {
|
||||
|
||||
@@ -348,7 +348,9 @@ func TestRecoverPendingEvidence(t *testing.T) {
|
||||
|
||||
func initializeStateFromValidatorSet(valSet *types.ValidatorSet, height int64) sm.Store {
|
||||
stateDB := dbm.NewMemDB()
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
|
||||
DiscardABCIResponses: false,
|
||||
})
|
||||
state := sm.State{
|
||||
ChainID: evidenceChainID,
|
||||
InitialHeight: 1,
|
||||
|
||||
@@ -367,7 +367,7 @@ func exampleVote(t byte) *types.Vote {
|
||||
}
|
||||
}
|
||||
|
||||
// nolint:lll //ignore line length for tests
|
||||
//nolint:lll //ignore line length for tests
|
||||
func TestEvidenceVectors(t *testing.T) {
|
||||
|
||||
val := &types.Validator{
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
//go:generate mockery --case underscore --name BlockStore
|
||||
//go:generate ../scripts/mockery_generate.sh BlockStore
|
||||
|
||||
type BlockStore interface {
|
||||
LoadBlockMeta(height int64) *types.BlockMeta
|
||||
|
||||
@@ -102,13 +102,14 @@ func (evpool *Pool) verify(evidence types.Evidence) error {
|
||||
|
||||
// VerifyLightClientAttack verifies LightClientAttackEvidence against the state of the full node. This involves
|
||||
// the following checks:
|
||||
// - the common header from the full node has at least 1/3 voting power which is also present in
|
||||
// the conflicting header's commit
|
||||
// - 2/3+ of the conflicting validator set correctly signed the conflicting block
|
||||
// - the nodes trusted header at the same height as the conflicting header has a different hash
|
||||
// - the common header from the full node has at least 1/3 voting power which is also present in
|
||||
// the conflicting header's commit
|
||||
// - 2/3+ of the conflicting validator set correctly signed the conflicting block
|
||||
// - the nodes trusted header at the same height as the conflicting header has a different hash
|
||||
//
|
||||
// CONTRACT: must run ValidateBasic() on the evidence before verifying
|
||||
// must check that the evidence has not expired (i.e. is outside the maximum age threshold)
|
||||
//
|
||||
// must check that the evidence has not expired (i.e. is outside the maximum age threshold)
|
||||
func VerifyLightClientAttack(e *types.LightClientAttackEvidence, commonHeader, trustedHeader *types.SignedHeader,
|
||||
commonVals *types.ValidatorSet, now time.Time, trustPeriod time.Duration) error {
|
||||
// In the case of lunatic attack there will be a different commonHeader height. Therefore the node perform a single
|
||||
@@ -154,10 +155,10 @@ func VerifyLightClientAttack(e *types.LightClientAttackEvidence, commonHeader, t
|
||||
|
||||
// VerifyDuplicateVote verifies DuplicateVoteEvidence against the state of full node. This involves the
|
||||
// following checks:
|
||||
// - the validator is in the validator set at the height of the evidence
|
||||
// - the height, round, type and validator address of the votes must be the same
|
||||
// - the block ID's must be different
|
||||
// - The signatures must both be valid
|
||||
// - the validator is in the validator set at the height of the evidence
|
||||
// - the height, round, type and validator address of the votes must be the same
|
||||
// - the block ID's must be different
|
||||
// - The signatures must both be valid
|
||||
func VerifyDuplicateVote(e *types.DuplicateVoteEvidence, chainID string, valSet *types.ValidatorSet) error {
|
||||
_, val := valSet.GetByAddress(e.VoteA.ValidatorAddress)
|
||||
if val == nil {
|
||||
|
||||
251
go.mod
251
go.mod
@@ -1,41 +1,264 @@
|
||||
module github.com/tendermint/tendermint
|
||||
|
||||
go 1.15
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.0.0
|
||||
github.com/BurntSushi/toml v1.2.0
|
||||
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d
|
||||
github.com/Workiva/go-datastructures v1.0.53
|
||||
github.com/adlio/schema v1.3.0
|
||||
github.com/btcsuite/btcd v0.22.0-beta
|
||||
github.com/adlio/schema v1.3.3
|
||||
github.com/btcsuite/btcd v0.22.1
|
||||
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 // indirect
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
|
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 // indirect
|
||||
github.com/fortytw2/leaktest v1.3.0
|
||||
github.com/go-kit/kit v0.12.0
|
||||
github.com/go-kit/log v0.2.0
|
||||
github.com/go-kit/log v0.2.1
|
||||
github.com/go-logfmt/logfmt v0.5.1
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/google/orderedcode v0.0.1
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/gtank/merlin v0.1.1
|
||||
github.com/lib/pq v1.10.4
|
||||
github.com/libp2p/go-buffer-pool v0.0.2
|
||||
github.com/lib/pq v1.10.6
|
||||
github.com/libp2p/go-buffer-pool v0.1.0
|
||||
github.com/minio/highwayhash v1.0.2
|
||||
github.com/ory/dockertest v3.3.5+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.12.1
|
||||
github.com/prometheus/client_golang v1.12.2
|
||||
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0
|
||||
github.com/rs/cors v1.8.2
|
||||
github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa
|
||||
github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa
|
||||
github.com/spf13/cobra v1.4.0
|
||||
github.com/spf13/viper v1.10.1
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/spf13/cobra v1.5.0
|
||||
github.com/spf13/viper v1.12.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/tendermint/tm-db v0.6.6
|
||||
golang.org/x/crypto v0.0.0-20210915214749-c084706c2272
|
||||
golang.org/x/net v0.0.0-20211208012354-db4efeb81f4b
|
||||
google.golang.org/grpc v1.45.0
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
|
||||
golang.org/x/net v0.0.0-20220726230323-06994584191e
|
||||
google.golang.org/grpc v1.48.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bufbuild/buf v1.7.0
|
||||
github.com/creachadair/taskgroup v0.3.2
|
||||
github.com/golangci/golangci-lint v1.48.0
|
||||
github.com/prometheus/common v0.34.0 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca
|
||||
github.com/vektra/mockery/v2 v2.14.0
|
||||
)
|
||||
|
||||
require (
|
||||
4d63.com/gochecknoglobals v0.1.0 // indirect
|
||||
github.com/Antonboom/errname v0.1.7 // indirect
|
||||
github.com/Antonboom/nilnil v0.1.1 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/DataDog/zstd v1.4.1 // indirect
|
||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
|
||||
github.com/GaijinEntertainment/go-exhaustruct/v2 v2.2.2 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||
github.com/OpenPeeDeeP/depguard v1.1.0 // indirect
|
||||
github.com/alexkohler/prealloc v1.0.0 // indirect
|
||||
github.com/alingse/asasalint v0.0.11 // indirect
|
||||
github.com/ashanbrown/forbidigo v1.3.0 // indirect
|
||||
github.com/ashanbrown/makezero v1.1.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bkielbasa/cyclop v1.2.0 // indirect
|
||||
github.com/blizzy78/varnamelen v0.8.0 // indirect
|
||||
github.com/bombsimon/wsl/v3 v3.3.0 // indirect
|
||||
github.com/breml/bidichk v0.2.3 // indirect
|
||||
github.com/breml/errchkjson v0.3.0 // indirect
|
||||
github.com/bufbuild/connect-go v0.2.0 // indirect
|
||||
github.com/butuzov/ireturn v0.1.1 // indirect
|
||||
github.com/cespare/xxhash v1.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/charithe/durationcheck v0.0.9 // indirect
|
||||
github.com/chavacava/garif v0.0.0-20220316182200-5cad0b5181d4 // indirect
|
||||
github.com/containerd/containerd v1.6.6 // indirect
|
||||
github.com/containerd/continuity v0.3.0 // indirect
|
||||
github.com/containerd/typeurl v1.0.2 // indirect
|
||||
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/daixiang0/gci v0.6.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/denis-tingaikin/go-header v0.4.3 // indirect
|
||||
github.com/dgraph-io/badger/v2 v2.2007.2 // indirect
|
||||
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de // indirect
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect
|
||||
github.com/docker/distribution v2.8.1+incompatible // indirect
|
||||
github.com/docker/docker v20.10.17+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/esimonov/ifshort v1.0.4 // indirect
|
||||
github.com/ettle/strcase v0.1.1 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/fatih/structtag v1.2.0 // indirect
|
||||
github.com/firefart/nonamedreturns v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||
github.com/fzipp/gocyclo v0.6.0 // indirect
|
||||
github.com/go-chi/chi/v5 v5.0.7 // indirect
|
||||
github.com/go-critic/go-critic v0.6.3 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-toolsmith/astcast v1.0.0 // indirect
|
||||
github.com/go-toolsmith/astcopy v1.0.0 // indirect
|
||||
github.com/go-toolsmith/astequal v1.0.1 // indirect
|
||||
github.com/go-toolsmith/astfmt v1.0.0 // indirect
|
||||
github.com/go-toolsmith/astp v1.0.0 // indirect
|
||||
github.com/go-toolsmith/strparse v1.0.0 // indirect
|
||||
github.com/go-toolsmith/typep v1.0.2 // indirect
|
||||
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/gofrs/uuid v4.2.0+incompatible // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/snappy v0.0.1 // indirect
|
||||
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect
|
||||
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect
|
||||
github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect
|
||||
github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a // indirect
|
||||
github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect
|
||||
github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect
|
||||
github.com/golangci/misspell v0.3.5 // indirect
|
||||
github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect
|
||||
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect
|
||||
github.com/google/btree v1.0.0 // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect
|
||||
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
|
||||
github.com/gostaticanalysis/comment v1.4.2 // indirect
|
||||
github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect
|
||||
github.com/gostaticanalysis/nilerr v0.1.1 // indirect
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||
github.com/gtank/ristretto255 v0.1.2 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hexops/gotextdiff v1.0.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a // indirect
|
||||
github.com/jgautheron/goconst v1.5.1 // indirect
|
||||
github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f // indirect
|
||||
github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b // indirect
|
||||
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
|
||||
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
|
||||
github.com/jmhodges/levigo v1.0.0 // indirect
|
||||
github.com/julz/importas v0.1.0 // indirect
|
||||
github.com/kisielk/errcheck v1.6.2 // indirect
|
||||
github.com/kisielk/gotool v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.15.9 // indirect
|
||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||
github.com/kulti/thelper v0.6.3 // indirect
|
||||
github.com/kunwardeep/paralleltest v1.0.6 // indirect
|
||||
github.com/kyoh86/exportloopref v0.1.8 // indirect
|
||||
github.com/ldez/gomoddirectives v0.2.3 // indirect
|
||||
github.com/ldez/tagliatelle v0.3.1 // indirect
|
||||
github.com/leonklingele/grouper v1.1.0 // indirect
|
||||
github.com/lufeee/execinquery v1.2.1 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/maratori/testpackage v1.1.0 // indirect
|
||||
github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
github.com/mbilski/exhaustivestruct v1.2.0 // indirect
|
||||
github.com/mgechev/revive v1.2.1 // indirect
|
||||
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/moby/buildkit v0.10.3 // indirect
|
||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||
github.com/moricho/tparallel v0.2.1 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/nakabonne/nestif v0.3.1 // indirect
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect
|
||||
github.com/nishanths/exhaustive v0.8.1 // indirect
|
||||
github.com/nishanths/predeclared v0.2.2 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
|
||||
github.com/opencontainers/runc v1.1.3 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.2 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
|
||||
github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
|
||||
github.com/pkg/profile v1.6.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/polyfloyd/go-errorlint v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/quasilyte/go-ruleguard v0.3.16-0.20220213074421-6aa060fab41a // indirect
|
||||
github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 // indirect
|
||||
github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect
|
||||
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
|
||||
github.com/rs/zerolog v1.27.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/ryancurrah/gomodguard v1.2.4 // indirect
|
||||
github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect
|
||||
github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect
|
||||
github.com/sashamelentyev/usestdlibvars v1.8.0 // indirect
|
||||
github.com/securego/gosec/v2 v2.12.0 // indirect
|
||||
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/sivchari/containedctx v1.0.2 // indirect
|
||||
github.com/sivchari/nosnakecase v1.7.0 // indirect
|
||||
github.com/sivchari/tenv v1.7.0 // indirect
|
||||
github.com/sonatard/noctx v0.0.1 // indirect
|
||||
github.com/sourcegraph/go-diff v0.6.1 // indirect
|
||||
github.com/spf13/afero v1.8.2 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
|
||||
github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect
|
||||
github.com/stretchr/objx v0.4.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.0 // indirect
|
||||
github.com/sylvia7788/contextcheck v1.0.4 // indirect
|
||||
github.com/tdakkota/asciicheck v0.1.1 // indirect
|
||||
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect
|
||||
github.com/tetafro/godot v1.4.11 // indirect
|
||||
github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect
|
||||
github.com/tomarrell/wrapcheck/v2 v2.6.2 // indirect
|
||||
github.com/tommy-muehle/go-mnd/v2 v2.5.0 // indirect
|
||||
github.com/ultraware/funlen v0.0.3 // indirect
|
||||
github.com/ultraware/whitespace v0.0.5 // indirect
|
||||
github.com/uudashr/gocognit v1.0.6 // indirect
|
||||
github.com/yagipy/maintidx v1.0.0 // indirect
|
||||
github.com/yeya24/promlinter v0.2.0 // indirect
|
||||
gitlab.com/bosi/decorder v0.2.3 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.33.0 // indirect
|
||||
go.opentelemetry.io/otel v1.8.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.8.0 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/zap v1.21.0 // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
|
||||
golang.org/x/sys v0.0.0-20220727055044-e65921a090b8 // indirect
|
||||
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
gopkg.in/ini.v1 v1.66.6 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
honnef.co/go/tools v0.3.3 // indirect
|
||||
mvdan.cc/gofumpt v0.3.1 // indirect
|
||||
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect
|
||||
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect
|
||||
mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 // indirect
|
||||
)
|
||||
|
||||
@@ -17,7 +17,8 @@ const (
|
||||
// all other modules).
|
||||
//
|
||||
// Example:
|
||||
// ParseLogLevel("consensus:debug,mempool:debug,*:error", log.NewTMLogger(os.Stdout), "info")
|
||||
//
|
||||
// ParseLogLevel("consensus:debug,mempool:debug,*:error", log.NewTMLogger(os.Stdout), "info")
|
||||
func ParseLogLevel(lvl string, logger log.Logger, defaultLogLevelValue string) (log.Logger, error) {
|
||||
if lvl == "" {
|
||||
return nil, errors.New("empty log level")
|
||||
|
||||
@@ -24,7 +24,6 @@ import (
|
||||
const MaxLength = int(^uint(0) >> 1)
|
||||
|
||||
/*
|
||||
|
||||
CElement is an element of a linked-list
|
||||
Traversal from a CElement is goroutine-safe.
|
||||
|
||||
@@ -41,7 +40,6 @@ the for-loop. Use sync.Cond when you need serial access to the
|
||||
"condition". In our case our condition is if `next != nil || removed`,
|
||||
and there's no reason to serialize that condition for goroutines
|
||||
waiting on NextWait() (since it's just a read operation).
|
||||
|
||||
*/
|
||||
type CElement struct {
|
||||
mtx tmsync.RWMutex
|
||||
|
||||
@@ -68,6 +68,7 @@ func TestSmall(t *testing.T) {
|
||||
|
||||
// This test is quite hacky because it relies on SetFinalizer
|
||||
// which isn't guaranteed to run at all.
|
||||
|
||||
//nolint:unused,deadcode
|
||||
func _TestGCFifo(t *testing.T) {
|
||||
if runtime.GOARCH != "amd64" {
|
||||
@@ -117,6 +118,7 @@ func _TestGCFifo(t *testing.T) {
|
||||
|
||||
// This test is quite hacky because it relies on SetFinalizer
|
||||
// which isn't guaranteed to run at all.
|
||||
//
|
||||
//nolint:unused,deadcode
|
||||
func _TestGCRandom(t *testing.T) {
|
||||
if runtime.GOARCH != "amd64" {
|
||||
|
||||
@@ -39,10 +39,10 @@ type Monitor struct {
|
||||
// weight of each sample in the exponential moving average (EMA) calculation.
|
||||
// The exact formulas are:
|
||||
//
|
||||
// sampleTime = currentTime - prevSampleTime
|
||||
// sampleRate = byteCount / sampleTime
|
||||
// weight = 1 - exp(-sampleTime/windowSize)
|
||||
// newRate = weight*sampleRate + (1-weight)*oldRate
|
||||
// sampleTime = currentTime - prevSampleTime
|
||||
// sampleRate = byteCount / sampleTime
|
||||
// weight = 1 - exp(-sampleTime/windowSize)
|
||||
// newRate = weight*sampleRate + (1-weight)*oldRate
|
||||
//
|
||||
// The default values for sampleRate and windowSize (if <= 0) are 100ms and 1s,
|
||||
// respectively.
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
// compatibility with e.g. Javascript (which uses 64-bit floats for numbers, having 53-bit
|
||||
// precision):
|
||||
//
|
||||
// int32(32) // Output: 32
|
||||
// uint32(32) // Output: 32
|
||||
// int64(64) // Output: "64"
|
||||
// uint64(64) // Output: "64"
|
||||
// int(64) // Output: "64"
|
||||
// uint(64) // Output: "64"
|
||||
// int32(32) // Output: 32
|
||||
// uint32(32) // Output: 32
|
||||
// int64(64) // Output: "64"
|
||||
// uint64(64) // Output: "64"
|
||||
// int(64) // Output: "64"
|
||||
// uint(64) // Output: "64"
|
||||
//
|
||||
// Encoding of other scalars follows encoding/json:
|
||||
//
|
||||
@@ -50,7 +50,7 @@
|
||||
// Times are encoded as encoding/json, in RFC3339Nano format, but requiring UTC time zone (with zero
|
||||
// times emitted as "0001-01-01T00:00:00Z" as with encoding/json):
|
||||
//
|
||||
// time.Date(2020, 6, 8, 16, 21, 28, 123, time.FixedZone("UTC+2", 2*60*60))
|
||||
// time.Date(2020, 6, 8, 16, 21, 28, 123, time.FixedZone("UTC+2", 2*60*60))
|
||||
// // Output: "2020-06-08T14:21:28.000000123Z"
|
||||
// time.Time{} // Output: "0001-01-01T00:00:00Z"
|
||||
// (*time.Time)(nil) // Output: null
|
||||
@@ -95,5 +95,4 @@
|
||||
//
|
||||
// Struct{Car: &Car{Wheels: 4}, Vehicle: &Car{Wheels: 4}}
|
||||
// // Output: {"Car": {"Wheels: 4"}, "Vehicle": {"type":"vehicle/car","value":{"Wheels":4}}}
|
||||
//
|
||||
package json
|
||||
|
||||
@@ -69,18 +69,19 @@ func (l *filter) Error(msg string, keyvals ...interface{}) {
|
||||
// Allow*With methods, it is used as the logger's level.
|
||||
//
|
||||
// Examples:
|
||||
// logger = log.NewFilter(logger, log.AllowError(), log.AllowInfoWith("module", "crypto"))
|
||||
// logger.With("module", "crypto").Info("Hello") # produces "I... Hello module=crypto"
|
||||
//
|
||||
// logger = log.NewFilter(logger, log.AllowError(),
|
||||
// log.AllowInfoWith("module", "crypto"),
|
||||
// log.AllowNoneWith("user", "Sam"))
|
||||
// logger.With("module", "crypto", "user", "Sam").Info("Hello") # returns nil
|
||||
// logger = log.NewFilter(logger, log.AllowError(), log.AllowInfoWith("module", "crypto"))
|
||||
// logger.With("module", "crypto").Info("Hello") # produces "I... Hello module=crypto"
|
||||
//
|
||||
// logger = log.NewFilter(logger,
|
||||
// log.AllowError(),
|
||||
// log.AllowInfoWith("module", "crypto"), log.AllowNoneWith("user", "Sam"))
|
||||
// logger.With("user", "Sam").With("module", "crypto").Info("Hello") # produces "I... Hello module=crypto user=Sam"
|
||||
// logger = log.NewFilter(logger, log.AllowError(),
|
||||
// log.AllowInfoWith("module", "crypto"),
|
||||
// log.AllowNoneWith("user", "Sam"))
|
||||
// logger.With("module", "crypto", "user", "Sam").Info("Hello") # returns nil
|
||||
//
|
||||
// logger = log.NewFilter(logger,
|
||||
// log.AllowError(),
|
||||
// log.AllowInfoWith("module", "crypto"), log.AllowNoneWith("user", "Sam"))
|
||||
// logger.With("user", "Sam").With("module", "crypto").Info("Hello") # produces "I... Hello module=crypto user=Sam"
|
||||
func (l *filter) With(keyvals ...interface{}) Logger {
|
||||
keyInAllowedKeyvals := false
|
||||
|
||||
|
||||
42
libs/log/lazy.go
Normal file
42
libs/log/lazy.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||
)
|
||||
|
||||
type LazySprintf struct {
|
||||
format string
|
||||
args []interface{}
|
||||
}
|
||||
|
||||
// NewLazySprintf defers fmt.Sprintf until the Stringer interface is invoked.
|
||||
// This is particularly useful for avoiding calling Sprintf when debugging is not
|
||||
// active.
|
||||
func NewLazySprintf(format string, args ...interface{}) *LazySprintf {
|
||||
return &LazySprintf{format, args}
|
||||
}
|
||||
|
||||
func (l *LazySprintf) String() string {
|
||||
return fmt.Sprintf(l.format, l.args...)
|
||||
}
|
||||
|
||||
type LazyBlockHash struct {
|
||||
block hashable
|
||||
}
|
||||
|
||||
type hashable interface {
|
||||
Hash() tmbytes.HexBytes
|
||||
}
|
||||
|
||||
// NewLazyBlockHash defers block Hash until the Stringer interface is invoked.
|
||||
// This is particularly useful for avoiding calling Sprintf when debugging is not
|
||||
// active.
|
||||
func NewLazyBlockHash(block hashable) *LazyBlockHash {
|
||||
return &LazyBlockHash{block}
|
||||
}
|
||||
|
||||
func (l *LazyBlockHash) String() string {
|
||||
return l.block.Hash().String()
|
||||
}
|
||||
@@ -22,9 +22,9 @@ type Logger interface {
|
||||
//
|
||||
// If w implements the following interface, so does the returned writer.
|
||||
//
|
||||
// interface {
|
||||
// Fd() uintptr
|
||||
// }
|
||||
// interface {
|
||||
// Fd() uintptr
|
||||
// }
|
||||
func NewSyncWriter(w io.Writer) io.Writer {
|
||||
return kitlog.NewSyncWriter(w)
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func (l tmfmtLogger) Log(keyvals ...interface{}) error {
|
||||
switch keyvals[i] {
|
||||
case kitlevel.Key():
|
||||
excludeIndexes = append(excludeIndexes, i)
|
||||
switch keyvals[i+1].(type) { // nolint:gocritic
|
||||
switch keyvals[i+1].(type) { //nolint:gocritic
|
||||
case string:
|
||||
lvl = keyvals[i+1].(string)
|
||||
case kitlevel.Value:
|
||||
@@ -87,6 +87,12 @@ func (l tmfmtLogger) Log(keyvals ...interface{}) error {
|
||||
if b, ok := keyvals[i+1].([]byte); ok {
|
||||
keyvals[i+1] = strings.ToUpper(hex.EncodeToString(b))
|
||||
}
|
||||
|
||||
// Realize stringers
|
||||
if s, ok := keyvals[i+1].(fmt.Stringer); ok {
|
||||
keyvals[i+1] = s.String()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Form a custom Tendermint line
|
||||
|
||||
@@ -83,7 +83,7 @@ func benchmarkRunnerKitlog(b *testing.B, logger kitlog.Logger, f func(kitlog.Log
|
||||
}
|
||||
}
|
||||
|
||||
//nolint: errcheck // ignore errors
|
||||
// nolint: errcheck // ignore errors
|
||||
var (
|
||||
baseMessage = func(logger kitlog.Logger) { logger.Log("foo_key", "foo_value") }
|
||||
withMessage = func(logger kitlog.Logger) { kitlog.With(logger, "a", "b").Log("d", "f") }
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user