From 7d39f639f675429a5752e2e228a50d284382278f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Mar 2022 19:30:52 +0000 Subject: [PATCH 1/7] build(deps): Bump github.com/golangci/golangci-lint from 1.45.0 to 1.45.2 (#8192) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.45.0 to 1.45.2.
Release notes

Sourced from github.com/golangci/golangci-lint's releases.

v1.45.2

Changelog

v1.45.1

Changelog

Changelog

Sourced from github.com/golangci/golangci-lint's changelog.

v1.45.2

  1. misc:
    • fix: help command

v1.45.1

  1. updated linters:
    • interfacer: inactivate with go1.18
    • govet: inactivate unsupported analyzers (go1.18)
    • depguard: reduce requirements
    • structcheck: inactivate with go1.18
    • varnamelen: bump from v0.6.0 to v0.6.1
  2. misc:
    • Automatic Go version detection 🎉 (go1.18)
    • docker: update base images (go1.18)
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/golangci/golangci-lint&package-manager=go_modules&previous-version=1.45.0&new-version=1.45.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 6 +++--- go.sum | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index ae3936ba5..39e57a64a 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/go-kit/kit v0.12.0 github.com/gogo/protobuf v1.3.2 github.com/golang/protobuf v1.5.2 - github.com/golangci/golangci-lint v1.45.0 + github.com/golangci/golangci-lint v1.45.2 github.com/google/orderedcode v0.0.1 github.com/google/uuid v1.3.0 github.com/gorilla/websocket v1.5.0 @@ -61,7 +61,7 @@ require ( 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.6.0 // indirect + github.com/blizzy78/varnamelen v0.6.1 // indirect github.com/bombsimon/wsl/v3 v3.3.0 // indirect github.com/breml/bidichk v0.2.2 // indirect github.com/breml/errchkjson v0.2.3 // indirect @@ -119,7 +119,7 @@ require ( github.com/gostaticanalysis/nilerr v0.1.1 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-version v1.2.1 // indirect + github.com/hashicorp/go-version v1.4.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 diff --git a/go.sum b/go.sum index c3f0a36e9..a1f212eaf 100644 --- a/go.sum +++ b/go.sum @@ -140,8 +140,8 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A= github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= -github.com/blizzy78/varnamelen v0.6.0 h1:TOIDk9qRIMspALZKX8x+5hQfAjuvAFogppnxtvuNmBo= -github.com/blizzy78/varnamelen v0.6.0/go.mod h1:zy2Eic4qWqjrxa60jG34cfL0VXcSwzUrIx68eJPb4Q8= +github.com/blizzy78/varnamelen v0.6.1 h1:kttPCLzXFa+0nt++Cw9fb7GrSSM4KkyIAoX/vXsbuqA= +github.com/blizzy78/varnamelen v0.6.1/go.mod h1:zy2Eic4qWqjrxa60jG34cfL0VXcSwzUrIx68eJPb4Q8= github.com/bombsimon/wsl/v3 v3.3.0 h1:Mka/+kRLoQJq7g2rggtgQsjuI/K5Efd87WX96EWFxjM= github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= github.com/breml/bidichk v0.2.2 h1:w7QXnpH0eCBJm55zGCTJveZEkQBt6Fs5zThIdA6qQ9Y= @@ -400,8 +400,8 @@ github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZB github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.45.0 h1:T2oCVkYoeckBxcNS6DTYiSXN2QcTNuAWaHyLGfqzMlU= -github.com/golangci/golangci-lint v1.45.0/go.mod h1:Y6grRO3drH/7kGP88i9jSl9fGWwCrbA5u7i++jOXll4= +github.com/golangci/golangci-lint v1.45.2 h1:9I3PzkvscJkFAQpTQi5Ga0V4qWdJERajX1UZ7QqkW+I= +github.com/golangci/golangci-lint v1.45.2/go.mod h1:f20dpzMmUTRp+oYnX0OGjV1Au3Jm2JeI9yLqHq1/xsI= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= @@ -538,8 +538,9 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4= +github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= From 0af58409bfd7c53644f28221e7b03767c39696f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Mar 2022 12:39:20 -0700 Subject: [PATCH 2/7] build(deps): Bump minimist from 1.2.5 to 1.2.6 in /docs (#8196) Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6. - [Release notes](https://github.com/substack/minimist/releases) - [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6) --- updated-dependencies: - dependency-name: minimist dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 94c756f54..52f7b52a6 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -8876,9 +8876,9 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "node_modules/mississippi": { "version": "3.0.0", @@ -21113,9 +21113,9 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "mississippi": { "version": "3.0.0", From 394591592037484ffbbbc1f370c9f1aab8ee8f32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 09:20:46 -0400 Subject: [PATCH 3/7] build(deps): Bump bufbuild/buf-setup-action from 1.1.0 to 1.3.0 (#8199) --- .github/workflows/proto-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/proto-lint.yml b/.github/workflows/proto-lint.yml index 6e7016b40..2d4052f90 100644 --- a/.github/workflows/proto-lint.yml +++ b/.github/workflows/proto-lint.yml @@ -15,7 +15,7 @@ jobs: timeout-minutes: 5 steps: - uses: actions/checkout@v3 - - uses: bufbuild/buf-setup-action@v1.1.0 + - uses: bufbuild/buf-setup-action@v1.3.0 - uses: bufbuild/buf-lint-action@v1 with: input: 'proto' From 14f5588ce2a6d37e8087fb4a2ef6b316c64c1f44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 13:59:24 +0000 Subject: [PATCH 4/7] build(deps): Bump github.com/adlio/schema from 1.2.3 to 1.3.0 (#8201) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/adlio/schema](https://github.com/adlio/schema) from 1.2.3 to 1.3.0.
Release notes

Sourced from github.com/adlio/schema's releases.

1.3.0

What's Changed

New Contributors

Full Changelog: https://github.com/adlio/schema/compare/v1.2.3...v1.3.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/adlio/schema&package-manager=go_modules&previous-version=1.2.3&new-version=1.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 2 +- go.sum | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 39e57a64a..c4c4529d4 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/BurntSushi/toml v1.0.0 - github.com/adlio/schema v1.2.3 + github.com/adlio/schema v1.3.0 github.com/btcsuite/btcd v0.22.0-beta github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce github.com/fortytw2/leaktest v1.3.0 diff --git a/go.sum b/go.sum index a1f212eaf..8ba897684 100644 --- a/go.sum +++ b/go.sum @@ -62,6 +62,9 @@ github.com/Antonboom/errname v0.1.5 h1:IM+A/gz0pDhKmlt5KSNTVAvfLMb+65RxavBXpRtCU github.com/Antonboom/errname v0.1.5/go.mod h1:DugbBstvPFQbv/5uLcRRzfrNqKE9tVdVCqWCLp6Cifo= github.com/Antonboom/nilnil v0.1.0 h1:DLDavmg0a6G/F4Lt9t7Enrbgb3Oph6LnDE6YVsmTt74= github.com/Antonboom/nilnil v0.1.0/go.mod h1:PhHLvRPSghY5Y7mX4TW+BHZQYo1A8flE5H20D3IPZBo= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -96,8 +99,8 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/adlio/schema v1.2.3 h1:GfKThfEsjS9cCz7gaF8zdXv4cpTdUqdljkKGDTbJjys= -github.com/adlio/schema v1.2.3/go.mod h1:nD7ZWmMMbwU12Pqwg+qL0rTvHBrBXfNz+5UQxTfy38M= +github.com/adlio/schema v1.3.0 h1:eSVYLxYWbm/6ReZBCkLw4Fz7uqC+ZNoPvA39bOwi52A= +github.com/adlio/schema v1.3.0/go.mod h1:51QzxkpeFs6lRY11kPye26IaFPOV+HqEj01t5aXXKfs= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= @@ -232,6 +235,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= +github.com/denisenkom/go-mssqldb v0.12.0 h1:VtrkII767ttSPNRfFekePK3sctr+joXgO58stqQbtUA= +github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA= @@ -240,6 +245,7 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= @@ -352,6 +358,10 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 h1:+eHOFJl1BaXrQxKX+T06f78590z4qA2ZzBTqahsKSE4= +github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -719,6 +729,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= @@ -809,6 +820,7 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1101,6 +1113,7 @@ golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -1211,6 +1224,7 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= From 9d56520f7662ed0eb48811db158e1ca12328dd50 Mon Sep 17 00:00:00 2001 From: Sergio Mena Date: Mon, 28 Mar 2022 21:15:35 +0200 Subject: [PATCH 5/7] Update ABCI++ spec with decisions taken in the bi-weekly meeting (#8191) * Clarify 0-length vote extensions in the spec, according to #8174 * Update spec so that Tendermnit can propose more txs than the size limit in * Addressed Manu's comment * Reworded size limit following Manu's suggestion --- .../abci++_app_requirements_002_draft.md | 61 +++++++++++-------- .../abci++/abci++_basic_concepts_002_draft.md | 4 +- spec/abci++/abci++_methods_002_draft.md | 21 +++++-- ...bci++_tmint_expected_behavior_002_draft.md | 5 +- 4 files changed, 55 insertions(+), 36 deletions(-) diff --git a/spec/abci++/abci++_app_requirements_002_draft.md b/spec/abci++/abci++_app_requirements_002_draft.md index 1ba523d03..620b1cd5e 100644 --- a/spec/abci++/abci++_app_requirements_002_draft.md +++ b/spec/abci++/abci++_app_requirements_002_draft.md @@ -46,33 +46,43 @@ Full execution of blocks at `PrepareProposal` time stands on Tendermint's critic Requirement 3 ensures the Application will set a value for _TimeoutPropose_ such that the time it takes to fully execute blocks in `PrepareProposal` does not interfere with Tendermint's propose timer. -* Requirement 4 [`PrepareProposal`, `ProcessProposal`, coherence]: For any two correct processes $p$ and $q$, +* Requirement 4 [`PrepareProposal`, tx-size] When $p$'s Application calls `ResponsePrepareProposal`, the + total size in bytes of the transactions returned does not exceed `RequestPrepareProposal.max_tx_bytes`. + +Busy blockchains might seek to maximize the amount of transactions included in each block. Under those conditions, +Tendermint might choose to increase the transactions passed to the Application via `RequestPrepareProposal.txs` +beyond the `RequestPrepareProposal.max_tx_bytes` limit. The idea is that, if the Application drops some of +those transactions, it can still return a transaction list whose byte size is as close to +`RequestPrepareProposal.max_tx_bytes` as possible. Thus, Requirement 4 ensures that the size in bytes of the +transaction list returned by the application will never cause the resulting block to go beyond its byte limit. + +* Requirement 5 [`PrepareProposal`, `ProcessProposal`, coherence]: For any two correct processes $p$ and $q$, if $q$'s Tendermint calls `RequestProcessProposal` on $v'_p$, $q$'s Application returns Accept in `ResponseProcessProposal`. -Requirement 4 makes sure that blocks proposed by correct processes _always_ pass the correct receiving process's +Requirement 5 makes sure that blocks proposed by correct processes _always_ pass the correct receiving process's `ProcessProposal` check. On the other hand, if there is a deterministic bug in `PrepareProposal` or `ProcessProposal` (or in both), strictly speaking, this makes all processes that hit the bug byzantine. This is a problem in practice, as very often validators are running the Application from the same codebase, so potentially _all_ would likely hit the bug at the same time. This would result in most (or all) processes prevoting `nil`, with the -serious consequences on Tendermint's liveness that this entails. Due to its criticality, Requirement 4 is a +serious consequences on Tendermint's liveness that this entails. Due to its criticality, Requirement 5 is a target for extensive testing and automated verification. -* Requirement 5 [`ProcessProposal`, determinism-1]: `ProcessProposal` is a (deterministic) function of the current +* Requirement 6 [`ProcessProposal`, determinism-1]: `ProcessProposal` is a (deterministic) function of the current state and the block that is about to be applied. In other words, for any correct process $p$, and any arbitrary block $v'$, if $p$'s Tendermint calls `RequestProcessProposal` on $v'$ at height $h$, then $p$'s Application's acceptance or rejection **exclusively** depends on $v'$ and $s_{p,h-1}$. -* Requirement 6 [`ProcessProposal`, determinism-2]: For any two correct processes $p$ and $q$, and any arbitrary block $v'$, +* Requirement 7 [`ProcessProposal`, determinism-2]: For any two correct processes $p$ and $q$, and any arbitrary block $v'$, if $p$'s (resp. $q$'s) Tendermint calls `RequestProcessProposal` on $v'$ at height $h$, then $p$'s Application accepts $v'$ if and only if $q$'s Application accepts $v'$. - Note that this requirement follows from Requirement 5 and the Agreement property of consensus. + Note that this requirement follows from Requirement 6 and the Agreement property of consensus. -Requirements 5 and 6 ensure that all correct processes will react in the same way to a proposed block, even +Requirements 6 and 7 ensure that all correct processes will react in the same way to a proposed block, even if the proposer is Byzantine. However, `ProcessProposal` may contain a bug that renders the acceptance or rejection of the block non-deterministic, and therefore prevents processes hitting -the bug from fulfilling Requirements 5 or 6 (effectively making those processes Byzantine). +the bug from fulfilling Requirements 6 or 7 (effectively making those processes Byzantine). In such a scenario, Tendermint's liveness cannot be guaranteed. Again, this is a problem in practice if most validators are running the same software, as they are likely to hit the bug at the same point. There is currently no clear solution to help with this situation, so @@ -85,43 +95,43 @@ is about to broadcast a non-`nil` precommit message, a correct process can only Let $e^r_p$ be the vote extension that the Application of a correct process $p$ returns via `ResponseExtendVote` in round $r$, height $h$. Let $w^r_p$ be the proposed block that $p$'s Tendermint passes to the Application via `RequestExtendVote` in round $r$, height $h$. -* Requirement 7 [`ExtendVote`, `VerifyVoteExtension`, coherence]: For any two correct processes $p$ and $q$, if $q$ receives $e^r_p$ +* Requirement 8 [`ExtendVote`, `VerifyVoteExtension`, coherence]: For any two correct processes $p$ and $q$, if $q$ receives $e^r_p$ from $p$ in height $h$, $q$'s Application returns Accept in `ResponseVerifyVoteExtension`. -Requirement 7 constrains the creation and handling of vote extensions in a similar way as Requirement 4 +Requirement 8 constrains the creation and handling of vote extensions in a similar way as Requirement 5 contrains the creation and handling of proposed blocks. -Requirement 7 ensures that extensions created by correct processes _always_ pass the `VerifyVoteExtension` +Requirement 8 ensures that extensions created by correct processes _always_ pass the `VerifyVoteExtension` checks performed by correct processes receiving those extensions. However, if there is a (deterministic) bug in `ExtendVote` or `VerifyVoteExtension` (or in both), -we will face the same liveness issues as described for Requirement 4, as Precommit messages with invalid vote +we will face the same liveness issues as described for Requirement 5, as Precommit messages with invalid vote extensions will be discarded. -* Requirement 8 [`VerifyVoteExtension`, determinism-1]: `VerifyVoteExtension` is a (deterministic) function of +* Requirement 9 [`VerifyVoteExtension`, determinism-1]: `VerifyVoteExtension` is a (deterministic) function of the current state, the vote extension received, and the prepared proposal that the extension refers to. In other words, for any correct process $p$, and any arbitrary vote extension $e$, and any arbitrary block $w$, if $p$'s (resp. $q$'s) Tendermint calls `RequestVerifyVoteExtension` on $e$ and $w$ at height $h$, then $p$'s Application's acceptance or rejection **exclusively** depends on $e$, $w$ and $s_{p,h-1}$. -* Requirement 9 [`VerifyVoteExtension`, determinism-2]: For any two correct processes $p$ and $q$, +* Requirement 10 [`VerifyVoteExtension`, determinism-2]: For any two correct processes $p$ and $q$, and any arbitrary vote extension $e$, and any arbitrary block $w$, if $p$'s (resp. $q$'s) Tendermint calls `RequestVerifyVoteExtension` on $e$ and $w$ at height $h$, then $p$'s Application accepts $e$ if and only if $q$'s Application accepts $e$. - Note that this requirement follows from Requirement 8 and the Agreement property of consensus. + Note that this requirement follows from Requirement 9 and the Agreement property of consensus. -Requirements 8 and 9 ensure that the validation of vote extensions will be deterministic at all +Requirements 9 and 10 ensure that the validation of vote extensions will be deterministic at all correct processes. -Requirements 8 and 9 protect against arbitrary vote extension data from Byzantine processes -similarly to Requirements 5 and 6 and proposed blocks. -Requirements 8 and 9 can be violated by a bug inducing non-determinism in +Requirements 9 and 10 protect against arbitrary vote extension data from Byzantine processes +similarly to Requirements 6 and 7 and proposed blocks. +Requirements 9 and 10 can be violated by a bug inducing non-determinism in `VerifyVoteExtension`. In this case liveness can be compromised. Extra care should be put in the implementation of `ExtendVote` and `VerifyVoteExtension` and, as a general rule, `VerifyVoteExtension` _should_ always accept the vote extension. -* Requirement 10 [_all_, no-side-effects]: $p$'s calls to `RequestPrepareProposal`, +* Requirement 11 [_all_, no-side-effects]: $p$'s calls to `RequestPrepareProposal`, `RequestProcessProposal`, `RequestExtendVote`, and `RequestVerifyVoteExtension` at height $h$ do not modify $s_{p,h-1}$. -* Requirement 11 [`ExtendVote`, `FinalizeBlock`, non-dependency]: for any correct process $p$, +* Requirement 12 [`ExtendVote`, `FinalizeBlock`, non-dependency]: for any correct process $p$, and any vote extension $e$ that $p$ received at height $h$, the computation of $s_{p,h}$ does not depend on $e$. @@ -133,16 +143,13 @@ Additionally, * in same-block execution mode, $p$'s `PrepareProposal` creates a set of transaction results $T_{p,h}$ if $p$ was the proposer of $v_{p,h}$, otherwise `FinalizeBlock` creates $T_{p,h}$. ->**TODO** I have left out all the "events" as they don't have any impact in safety or liveness ->(same for consensus params, and validator set) - -* Requirement 12 [`FinalizeBlock`, determinism-1]: For any correct process $p$, +* Requirement 13 [`FinalizeBlock`, determinism-1]: For any correct process $p$, $s_{p,h}$ exclusively depends on $s_{p,h-1}$ and $v_{p,h}$. -* Requirement 13 [`FinalizeBlock`, determinism-2]: For any correct process $p$, +* Requirement 14 [`FinalizeBlock`, determinism-2]: For any correct process $p$, the contents of $T_{p,h}$ exclusively depend on $s_{p,h-1}$ and $v_{p,h}$. -Note that Requirements 12 and 13, combined with Agreement property of consensus ensure +Note that Requirements 13 and 14, combined with Agreement property of consensus ensure the Application state evolves consistently at all correct processes. Finally, notice that neither `PrepareProposal` nor `ExtendVote` have determinism-related diff --git a/spec/abci++/abci++_basic_concepts_002_draft.md b/spec/abci++/abci++_basic_concepts_002_draft.md index 86f235e9c..a1ad038a5 100644 --- a/spec/abci++/abci++_basic_concepts_002_draft.md +++ b/spec/abci++/abci++_basic_concepts_002_draft.md @@ -65,8 +65,8 @@ ignore the invalid part of the prepared proposal at block execution time. The data, called _vote extension_, will also be made available to the application in the next height, along with the vote it is extending, in the rounds where the local process is the proposer. -The Application may also choose not to include any vote extension. -Tendermint calls it when is about to send a non-`nil` precommit message. +If the Application does not have vote extension information to provide, it returns a 0-length byte array as its vote extension. +Tendermint calls `ExtendVote` when is about to send a non-`nil` precommit message. * [**VerifyVoteExtension:**](./abci++_methods_002_draft.md#verifyvoteextension) It allows validators to validate the vote extension data attached to a precommit message. If the validation fails, the precommit message will be deemed invalid and ignored by Tendermint. This has a negative impact on Tendermint's liveness, i.e., if vote extensions repeatedly cannot be verified by correct validators, Tendermint may not be able to finalize a block even if sufficiently many (+2/3) of the validators send precommit votes for that block. Thus, `VerifyVoteExtension` should be used with special care. diff --git a/spec/abci++/abci++_methods_002_draft.md b/spec/abci++/abci++_methods_002_draft.md index edc7ac717..545f6cde0 100644 --- a/spec/abci++/abci++_methods_002_draft.md +++ b/spec/abci++/abci++_methods_002_draft.md @@ -314,12 +314,16 @@ title: Methods * In this case, the Application should set `ResponsePrepareProposal.modified_tx_status` to `MODIFIED`. * The Application _can_ reorder, remove or add transactions to the raw proposal. Let `tx` be a transaction in `txs`: * If the Application considers that `tx` should not be proposed in this block, e.g., there are other transactions with higher priority, then it should not include it in `tx_records`. In this case, Tendermint won't remove `tx` from the mempool. The Application should be extra-careful, as abusing this feature may cause transactions to stay forever in the mempool. - * If the Application considers that a `tx` should not be included in the proposal and removed from the mempool, then the Application should include it in `tx_records` and _mark_ it as `REMOVE`. In this case, Tendermint will remove `tx` from the mempool. + * If the Application considers that a `tx` should not be included in the proposal and removed from the mempool, then the Application should include it in `tx_records` and _mark_ it as `REMOVED`. In this case, Tendermint will remove `tx` from the mempool. * If the Application wants to add a new transaction, then the Application should include it in `tx_records` and _mark_ it as `ADD`. In this case, Tendermint will add it to the mempool. * The Application should be aware that removing and adding transactions may compromise _traceability_. > Consider the following example: the Application transforms a client-submitted transaction `t1` into a second transaction `t2`, i.e., the Application asks Tendermint to remove `t1` and add `t2` to the mempool. If a client wants to eventually check what happened to `t1`, it will discover that `t_1` is not in the mempool or in a committed block, getting the wrong idea that `t_1` did not make it into a block. Note that `t_2` _will be_ in a committed block, but unless the Application tracks this information, no component will be aware of it. Thus, if the Application wants traceability, it is its responsability to support it. For instance, the Application could attach to a transformed transaction a list with the hashes of the transactions it derives from. - * If the Application modifies the set of transactions, the modified transactions MUST NOT exceed the configured maximum size `RequestPrepareProposal.max_tx_bytes`. * If the Application does not modify the preliminary set of transactions `txs`, then it sets `ResponsePrepareProposal.modified_tx_status` to `UNMODIFIED`. In this case, Tendermint will ignore the contents of `ResponsePrepareProposal.tx_records`. + * Tendermint MAY include a list of transactions in `RequestPrepareProposal.txs` whose total size in bytes exceeds `RequestPrepareProposal.max_tx_bytes`. + Therefore, if the size of `RequestPrepareProposal.txs` is greater than `RequestPrepareProposal.max_tx_bytes`: + * the Application MUST make sure that the `RequestPrepareProposal.max_tx_bytes` limit is respected by those + transaction records returned in `ResponsePrepareProposal.tx_records` that are marked as `UNMODIFIED` or `ADDED`. + * the Application MUST set `ResponsePrepareProposal.modified_tx_status` to `MODIFIED`. Tendermint will panic otherwise. * In same-block execution mode, the Application must provide values for `ResponsePrepareProposal.app_hash`, `ResponsePrepareProposal.tx_results`, `ResponsePrepareProposal.validator_updates`, and `ResponsePrepareProposal.consensus_param_updates`, as a result of fully executing the block. @@ -529,7 +533,7 @@ a [CanonicalVoteExtension](#canonicalvoteextension) field in the `precommit nil` | hash | bytes | The header hash of the propsed block that the vote extension refers to. | 1 | | validator_address | bytes | [Address](../core/data_structures.md#address) of the validator that signed the extension | 2 | | height | int64 | Height of the block (for sanity check). | 3 | - | vote_extension | bytes | Optional information signed by Tendermint. | 4 | + | vote_extension | bytes | Application-specific information signed by Tendermint. Can have 0 length | 4 | * **Response**: @@ -538,6 +542,9 @@ a [CanonicalVoteExtension](#canonicalvoteextension) field in the `precommit nil` | status | [VerifyStatus](#VerifyStatus) | `enum` signaling if the application accepts the vote extension | 1 | * **Usage**: + * `RequestVerifyVoteExtension.vote_extension` can be an empty byte array. The Application's interpretation of it should be + that the Application running at the process that sent the vote chose not to extend it. + Tendermint will always call `RequestVerifyVoteExtension`, even for 0 length vote extensions. * If `ResponseVerifyVoteExtension.status` is `REJECT`, Tendermint will reject the whole received vote. See the [Requirements](abci++_app_requirements_002_draft.md) section to understand the potential liveness implications of this. @@ -553,9 +560,11 @@ a [CanonicalVoteExtension](#canonicalvoteextension) field in the `precommit nil` When a validator _p_ is in Tendermint consensus round _r_, height _h_, state _prevote_ (**TODO** discuss: I think I must remove the state from this condition, but not sure), and _p_ receives a Precommit message for round _r_, height _h_ from _q_: -1. _p_'s Tendermint calls `RequestVerifyVoteExtension`. -2. The Application returns _accept_ or _reject_ via `ResponseVerifyVoteExtension.status`. -3. If the Application returns +1. If the Precommit message does not contain a vote extension with a valid signature, Tendermint discards the message as invalid. + * a 0-length vote extension is valid as long as its accompanying signature is also valid. +2. Else, _p_'s Tendermint calls `RequestVerifyVoteExtension`. +3. The Application returns _accept_ or _reject_ via `ResponseVerifyVoteExtension.status`. +4. If the Application returns * _accept_, _p_'s Tendermint will keep the received vote, together with its corresponding vote extension in its internal data structures. It will be used to populate the [ExtendedCommitInfo](#extendedcommitinfo) structure in calls to `RequestPrepareProposal`, in rounds of height _h + 1_ where _p_ is the proposer. diff --git a/spec/abci++/abci++_tmint_expected_behavior_002_draft.md b/spec/abci++/abci++_tmint_expected_behavior_002_draft.md index 18669a479..2616da4fa 100644 --- a/spec/abci++/abci++_tmint_expected_behavior_002_draft.md +++ b/spec/abci++/abci++_tmint_expected_behavior_002_draft.md @@ -202,7 +202,10 @@ to undergo any changes in their implementation. As for the new methods: -* `PrepareProposal` should set `ResponsePrepareProposal.modified_tx` to _false_ and return. +* `PrepareProposal` should check whether the size of transactions exceeds the byte limit. + * If it does: remove transactions at the end of the list until the total byte size conforms to the limit, + then set `ResponsePrepareProposal.modified_tx_status` to `MODIFIED` and return. + * Else, set `ResponsePrepareProposal.modified_tx_status` to `UNMODIFIED` and return. * `ProcessProposal` should set `ResponseProcessProposal.accept` to _true_ and return. * `ExtendVote` should set `ResponseExtendVote.extension` to an empty byte array and return. * `VerifyVoteExtension` should set `ResponseVerifyVoteExtension.accept` to _true_ if the extension is an empty byte array From 462c475abc2e8d7aa47bc2d5b8015c0ff926a93a Mon Sep 17 00:00:00 2001 From: William Banfield <4561443+williambanfield@users.noreply.github.com> Date: Mon, 28 Mar 2022 17:33:23 -0400 Subject: [PATCH 6/7] consensus: timeout params in toml used as overrides (#8186) Replaces the set of timeout parameters in the config.toml file with unsafe-*override versions of the corresponding ConsensusParams.Timeout field. These fields can be used for the duration of v0.36 to override the consensus param in case of emergency. Adds a set to the ./internal/consensus/State type for correctly calculating the value of each timeout based on the set of overrides specified. --- config/config.go | 96 ++++++++++++++------------------ config/config_test.go | 38 ++++++------- config/toml.go | 64 ++++++++++++++------- internal/consensus/state.go | 61 +++++++++++++++++--- internal/consensus/state_test.go | 70 +++++++++++------------ types/params.go | 20 +++---- types/params_test.go | 95 +++++++++++++++++++------------ 7 files changed, 260 insertions(+), 184 deletions(-) diff --git a/config/config.go b/config/config.go index e33b8dd7e..fd4923cce 100644 --- a/config/config.go +++ b/config/config.go @@ -956,27 +956,6 @@ type ConsensusConfig struct { WalPath string `mapstructure:"wal-file"` walFile string // overrides WalPath if set - // TODO: remove timeout configs, these should be global not local - // How long we wait for a proposal block before prevoting nil - TimeoutPropose time.Duration `mapstructure:"timeout-propose"` - // How much timeout-propose increases with each round - TimeoutProposeDelta time.Duration `mapstructure:"timeout-propose-delta"` - // How long we wait after receiving +2/3 prevotes for “anything” (ie. not a single block or nil) - TimeoutPrevote time.Duration `mapstructure:"timeout-prevote"` - // How much the timeout-prevote increases with each round - TimeoutPrevoteDelta time.Duration `mapstructure:"timeout-prevote-delta"` - // How long we wait after receiving +2/3 precommits for “anything” (ie. not a single block or nil) - TimeoutPrecommit time.Duration `mapstructure:"timeout-precommit"` - // How much the timeout-precommit increases with each round - TimeoutPrecommitDelta time.Duration `mapstructure:"timeout-precommit-delta"` - // How long we wait after committing a block, before starting on the new - // height (this gives us a chance to receive some more precommits, even - // though we already have +2/3). - TimeoutCommit time.Duration `mapstructure:"timeout-commit"` - - // Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) - SkipTimeoutCommit bool `mapstructure:"skip-timeout-commit"` - // EmptyBlocks mode and possible interval between empty blocks CreateEmptyBlocks bool `mapstructure:"create-empty-blocks"` CreateEmptyBlocksInterval time.Duration `mapstructure:"create-empty-blocks-interval"` @@ -986,20 +965,45 @@ type ConsensusConfig struct { PeerQueryMaj23SleepDuration time.Duration `mapstructure:"peer-query-maj23-sleep-duration"` DoubleSignCheckHeight int64 `mapstructure:"double-sign-check-height"` + + // TODO: The following fields are all temporary overrides that should exist only + // for the duration of the v0.36 release. The below fields should be completely + // removed in the v0.37 release of Tendermint. + // See: https://github.com/tendermint/tendermint/issues/8188 + + // UnsafeProposeTimeoutOverride provides an unsafe override of the Propose + // timeout consensus parameter. It configures how long the consensus engine + // will wait to receive a proposal block before prevoting nil. + UnsafeProposeTimeoutOverride time.Duration `mapstructure:"unsafe-propose-timeout-override"` + // UnsafeProposeTimeoutDeltaOverride provides an unsafe override of the + // ProposeDelta timeout consensus parameter. It configures how much the + // propose timeout increases with each round. + UnsafeProposeTimeoutDeltaOverride time.Duration `mapstructure:"unsafe-propose-timeout-delta-override"` + // UnsafeVoteTimeoutOverride provides an unsafe override of the Vote timeout + // consensus parameter. It configures how long the consensus engine will wait + // to gather additional votes after receiving +2/3 votes in a round. + UnsafeVoteTimeoutOverride time.Duration `mapstructure:"unsafe-vote-timeout-override"` + // UnsafeVoteTimeoutDeltaOverride provides an unsafe override of the VoteDelta + // timeout consensus parameter. It configures how much the vote timeout + // increases with each round. + UnsafeVoteTimeoutDeltaOverride time.Duration `mapstructure:"unsafe-vote-timeout-delta-override"` + // UnsafeCommitTimeoutOverride provides an unsafe override of the Commit timeout + // consensus parameter. It configures how long the consensus engine will wait + // after receiving +2/3 precommits before beginning the next height. + UnsafeCommitTimeoutOverride time.Duration `mapstructure:"unsafe-commit-timeout-override"` + + // UnsafeBypassCommitTimeoutOverride provides an unsafe override of the + // BypassCommitTimeout consensus parameter. It configures if the consensus + // engine will wait for the full Commit timeout before proceeding to the next height. + // If it is set to true, the consensus engine will proceed to the next height + // as soon as the node has gathered votes from all of the validators on the network. + UnsafeBypassCommitTimeoutOverride *bool `mapstructure:"unsafe-bypass-commit-timeout-override"` } // DefaultConsensusConfig returns a default configuration for the consensus service func DefaultConsensusConfig() *ConsensusConfig { return &ConsensusConfig{ WalPath: filepath.Join(defaultDataDir, "cs.wal", "wal"), - TimeoutPropose: 3000 * time.Millisecond, - TimeoutProposeDelta: 500 * time.Millisecond, - TimeoutPrevote: 1000 * time.Millisecond, - TimeoutPrevoteDelta: 500 * time.Millisecond, - TimeoutPrecommit: 1000 * time.Millisecond, - TimeoutPrecommitDelta: 500 * time.Millisecond, - TimeoutCommit: 1000 * time.Millisecond, - SkipTimeoutCommit: false, CreateEmptyBlocks: true, CreateEmptyBlocksInterval: 0 * time.Second, PeerGossipSleepDuration: 100 * time.Millisecond, @@ -1011,14 +1015,6 @@ func DefaultConsensusConfig() *ConsensusConfig { // TestConsensusConfig returns a configuration for testing the consensus service func TestConsensusConfig() *ConsensusConfig { cfg := DefaultConsensusConfig() - cfg.TimeoutPropose = 40 * time.Millisecond - cfg.TimeoutProposeDelta = 1 * time.Millisecond - cfg.TimeoutPrevote = 10 * time.Millisecond - cfg.TimeoutPrevoteDelta = 1 * time.Millisecond - cfg.TimeoutPrecommit = 10 * time.Millisecond - cfg.TimeoutPrecommitDelta = 1 * time.Millisecond - cfg.TimeoutCommit = 10 * time.Millisecond - cfg.SkipTimeoutCommit = true cfg.PeerGossipSleepDuration = 5 * time.Millisecond cfg.PeerQueryMaj23SleepDuration = 250 * time.Millisecond cfg.DoubleSignCheckHeight = int64(0) @@ -1046,26 +1042,20 @@ func (cfg *ConsensusConfig) SetWalFile(walFile string) { // ValidateBasic performs basic validation (checking param bounds, etc.) and // returns an error if any check fails. func (cfg *ConsensusConfig) ValidateBasic() error { - if cfg.TimeoutPropose < 0 { - return errors.New("timeout-propose can't be negative") + if cfg.UnsafeProposeTimeoutOverride < 0 { + return errors.New("unsafe-propose-timeout-override can't be negative") } - if cfg.TimeoutProposeDelta < 0 { - return errors.New("timeout-propose-delta can't be negative") + if cfg.UnsafeProposeTimeoutDeltaOverride < 0 { + return errors.New("unsafe-propose-timeout-delta-override can't be negative") } - if cfg.TimeoutPrevote < 0 { - return errors.New("timeout-prevote can't be negative") + if cfg.UnsafeVoteTimeoutOverride < 0 { + return errors.New("unsafe-vote-timeout-override can't be negative") } - if cfg.TimeoutPrevoteDelta < 0 { - return errors.New("timeout-prevote-delta can't be negative") + if cfg.UnsafeVoteTimeoutDeltaOverride < 0 { + return errors.New("unsafe-vote-timeout-delta-override can't be negative") } - if cfg.TimeoutPrecommit < 0 { - return errors.New("timeout-precommit can't be negative") - } - if cfg.TimeoutPrecommitDelta < 0 { - return errors.New("timeout-precommit-delta can't be negative") - } - if cfg.TimeoutCommit < 0 { - return errors.New("timeout-commit can't be negative") + if cfg.UnsafeCommitTimeoutOverride < 0 { + return errors.New("unsafe-commit-timeout-override can't be negative") } if cfg.CreateEmptyBlocksInterval < 0 { return errors.New("create-empty-blocks-interval can't be negative") diff --git a/config/config_test.go b/config/config_test.go index d768a1702..a86ab8463 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -29,8 +29,8 @@ func TestConfigValidateBasic(t *testing.T) { cfg := DefaultConfig() assert.NoError(t, cfg.ValidateBasic()) - // tamper with timeout_propose - cfg.Consensus.TimeoutPropose = -10 * time.Second + // tamper with unsafe-propose-timeout-override + cfg.Consensus.UnsafeProposeTimeoutOverride = -10 * time.Second assert.Error(t, cfg.ValidateBasic()) } @@ -106,25 +106,21 @@ func TestConsensusConfig_ValidateBasic(t *testing.T) { modify func(*ConsensusConfig) expectErr bool }{ - "TimeoutPropose": {func(c *ConsensusConfig) { c.TimeoutPropose = time.Second }, false}, - "TimeoutPropose negative": {func(c *ConsensusConfig) { c.TimeoutPropose = -1 }, true}, - "TimeoutProposeDelta": {func(c *ConsensusConfig) { c.TimeoutProposeDelta = time.Second }, false}, - "TimeoutProposeDelta negative": {func(c *ConsensusConfig) { c.TimeoutProposeDelta = -1 }, true}, - "TimeoutPrevote": {func(c *ConsensusConfig) { c.TimeoutPrevote = time.Second }, false}, - "TimeoutPrevote negative": {func(c *ConsensusConfig) { c.TimeoutPrevote = -1 }, true}, - "TimeoutPrevoteDelta": {func(c *ConsensusConfig) { c.TimeoutPrevoteDelta = time.Second }, false}, - "TimeoutPrevoteDelta negative": {func(c *ConsensusConfig) { c.TimeoutPrevoteDelta = -1 }, true}, - "TimeoutPrecommit": {func(c *ConsensusConfig) { c.TimeoutPrecommit = time.Second }, false}, - "TimeoutPrecommit negative": {func(c *ConsensusConfig) { c.TimeoutPrecommit = -1 }, true}, - "TimeoutPrecommitDelta": {func(c *ConsensusConfig) { c.TimeoutPrecommitDelta = time.Second }, false}, - "TimeoutPrecommitDelta negative": {func(c *ConsensusConfig) { c.TimeoutPrecommitDelta = -1 }, true}, - "TimeoutCommit": {func(c *ConsensusConfig) { c.TimeoutCommit = time.Second }, false}, - "TimeoutCommit negative": {func(c *ConsensusConfig) { c.TimeoutCommit = -1 }, true}, - "PeerGossipSleepDuration": {func(c *ConsensusConfig) { c.PeerGossipSleepDuration = time.Second }, false}, - "PeerGossipSleepDuration negative": {func(c *ConsensusConfig) { c.PeerGossipSleepDuration = -1 }, true}, - "PeerQueryMaj23SleepDuration": {func(c *ConsensusConfig) { c.PeerQueryMaj23SleepDuration = time.Second }, false}, - "PeerQueryMaj23SleepDuration negative": {func(c *ConsensusConfig) { c.PeerQueryMaj23SleepDuration = -1 }, true}, - "DoubleSignCheckHeight negative": {func(c *ConsensusConfig) { c.DoubleSignCheckHeight = -1 }, true}, + "UnsafeProposeTimeoutOverride": {func(c *ConsensusConfig) { c.UnsafeProposeTimeoutOverride = time.Second }, false}, + "UnsafeProposeTimeoutOverride negative": {func(c *ConsensusConfig) { c.UnsafeProposeTimeoutOverride = -1 }, true}, + "UnsafeProposeTimeoutDeltaOverride": {func(c *ConsensusConfig) { c.UnsafeProposeTimeoutDeltaOverride = time.Second }, false}, + "UnsafeProposeTimeoutDeltaOverride negative": {func(c *ConsensusConfig) { c.UnsafeProposeTimeoutDeltaOverride = -1 }, true}, + "UnsafePrevoteTimeoutOverride": {func(c *ConsensusConfig) { c.UnsafeVoteTimeoutOverride = time.Second }, false}, + "UnsafePrevoteTimeoutOverride negative": {func(c *ConsensusConfig) { c.UnsafeVoteTimeoutOverride = -1 }, true}, + "UnsafePrevoteTimeoutDeltaOverride": {func(c *ConsensusConfig) { c.UnsafeVoteTimeoutDeltaOverride = time.Second }, false}, + "UnsafePrevoteTimeoutDeltaOverride negative": {func(c *ConsensusConfig) { c.UnsafeVoteTimeoutDeltaOverride = -1 }, true}, + "UnsafeCommitTimeoutOverride": {func(c *ConsensusConfig) { c.UnsafeCommitTimeoutOverride = time.Second }, false}, + "UnsafeCommitTimeoutOverride negative": {func(c *ConsensusConfig) { c.UnsafeCommitTimeoutOverride = -1 }, true}, + "PeerGossipSleepDuration": {func(c *ConsensusConfig) { c.PeerGossipSleepDuration = time.Second }, false}, + "PeerGossipSleepDuration negative": {func(c *ConsensusConfig) { c.PeerGossipSleepDuration = -1 }, true}, + "PeerQueryMaj23SleepDuration": {func(c *ConsensusConfig) { c.PeerQueryMaj23SleepDuration = time.Second }, false}, + "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 diff --git a/config/toml.go b/config/toml.go index a82e7f59d..7ed1aaabf 100644 --- a/config/toml.go +++ b/config/toml.go @@ -450,32 +450,12 @@ fetchers = "{{ .StateSync.Fetchers }}" wal-file = "{{ js .Consensus.WalPath }}" -# How long we wait for a proposal block before prevoting nil -timeout-propose = "{{ .Consensus.TimeoutPropose }}" -# How much timeout-propose increases with each round -timeout-propose-delta = "{{ .Consensus.TimeoutProposeDelta }}" -# How long we wait after receiving +2/3 prevotes for “anything” (ie. not a single block or nil) -timeout-prevote = "{{ .Consensus.TimeoutPrevote }}" -# How much the timeout-prevote increases with each round -timeout-prevote-delta = "{{ .Consensus.TimeoutPrevoteDelta }}" -# How long we wait after receiving +2/3 precommits for “anything” (ie. not a single block or nil) -timeout-precommit = "{{ .Consensus.TimeoutPrecommit }}" -# How much the timeout-precommit increases with each round -timeout-precommit-delta = "{{ .Consensus.TimeoutPrecommitDelta }}" -# How long we wait after committing a block, before starting on the new -# height (this gives us a chance to receive some more precommits, even -# though we already have +2/3). -timeout-commit = "{{ .Consensus.TimeoutCommit }}" - # How many blocks to look back to check existence of the node's consensus votes before joining consensus # When non-zero, the node will panic upon restart # if the same consensus key was used to sign {double-sign-check-height} last blocks. # So, validators should stop the state machine, wait for some blocks, and then restart the state machine to avoid panic. double-sign-check-height = {{ .Consensus.DoubleSignCheckHeight }} -# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) -skip-timeout-commit = {{ .Consensus.SkipTimeoutCommit }} - # EmptyBlocks mode and possible interval between empty blocks create-empty-blocks = {{ .Consensus.CreateEmptyBlocks }} create-empty-blocks-interval = "{{ .Consensus.CreateEmptyBlocksInterval }}" @@ -484,6 +464,50 @@ create-empty-blocks-interval = "{{ .Consensus.CreateEmptyBlocksInterval }}" peer-gossip-sleep-duration = "{{ .Consensus.PeerGossipSleepDuration }}" peer-query-maj23-sleep-duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}" +### Unsafe Timeout Overrides ### + +# These fields provide temporary overrides for the Timeout consensus parameters. +# Use of these parameters is strongly discouraged. Using these parameters may have serious +# liveness implications for the validator and for the chain. +# +# These fields will be removed from the configuration file in the v0.37 release of Tendermint. +# For additional information, see ADR-74: +# https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-074-timeout-params.md + +# This field provides an unsafe override of the Propose timeout consensus parameter. +# This field configures how long the consensus engine will wait for a proposal block before prevoting nil. +# If this field is set to a value greater than 0, it will take effect. +# unsafe-propose-timeout-override = {{ .Consensus.UnsafeProposeTimeoutOverride }} + +# This field provides an unsafe override of the ProposeDelta timeout consensus parameter. +# This field configures how much the propose timeout increases with each round. +# If this field is set to a value greater than 0, it will take effect. +# unsafe-propose-timeout-delta-override = {{ .Consensus.UnsafeProposeTimeoutDeltaOverride }} + +# This field provides an unsafe override of the Vote timeout consensus parameter. +# This field configures how long the consensus engine will wait after +# receiving +2/3 votes in a around. +# If this field is set to a value greater than 0, it will take effect. +# unsafe-vote-timeout-override = {{ .Consensus.UnsafeVoteTimeoutOverride }} + +# This field provides an unsafe override of the VoteDelta timeout consensus parameter. +# This field configures how much the vote timeout increases with each round. +# If this field is set to a value greater than 0, it will take effect. +# unsafe-vote-timeout-delta-override = {{ .Consensus.UnsafeVoteTimeoutDeltaOverride }} + +# This field provides an unsafe override of the Commit timeout consensus parameter. +# This field configures how long the consensus engine will wait after receiving +# +2/3 precommits before beginning the next height. +# If this field is set to a value greater than 0, it will take effect. +# unsafe-commit-timeout-override = {{ .Consensus.UnsafeCommitTimeoutOverride }} + +# This field provides an unsafe override of the BypassCommitTimeout consensus parameter. +# This field configures if the consensus engine will wait for the full Commit timeout +# before proceeding to the next height. +# If this field is set to true, the consensus engine will proceed to the next height +# as soon as the node has gathered votes from all of the validators on the network. +# unsafe-bypass-commit-timeout-override = + ####################################################### ### Transaction Indexer Configuration Options ### ####################################################### diff --git a/internal/consensus/state.go b/internal/consensus/state.go index e27d971ca..74e07ca9d 100644 --- a/internal/consensus/state.go +++ b/internal/consensus/state.go @@ -787,9 +787,9 @@ func (cs *State) updateToState(ctx context.Context, state sm.State) { // to be gathered for the first block. // And alternative solution that relies on clocks: // cs.StartTime = state.LastBlockTime.Add(timeoutCommit) - cs.StartTime = cs.state.ConsensusParams.Timeout.CommitTime(tmtime.Now()) + cs.StartTime = cs.commitTime(tmtime.Now()) } else { - cs.StartTime = cs.state.ConsensusParams.Timeout.CommitTime(cs.CommitTime) + cs.StartTime = cs.commitTime(cs.CommitTime) } cs.Validators = validators @@ -1262,7 +1262,7 @@ func (cs *State) enterPropose(ctx context.Context, height int64, round int32) { }() // If we don't get the proposal and all block parts quick enough, enterPrevote - cs.scheduleTimeout(cs.state.ConsensusParams.Timeout.ProposeTimeout(round), height, round, cstypes.RoundStepPropose) + cs.scheduleTimeout(cs.proposeTimeout(round), height, round, cstypes.RoundStepPropose) // Nothing more to do if we're not a validator if cs.privValidator == nil { @@ -1620,7 +1620,7 @@ func (cs *State) enterPrevoteWait(ctx context.Context, height int64, round int32 }() // Wait for some more prevotes; enterPrecommit - cs.scheduleTimeout(cs.state.ConsensusParams.Timeout.VoteTimeout(round), height, round, cstypes.RoundStepPrevoteWait) + cs.scheduleTimeout(cs.voteTimeout(round), height, round, cstypes.RoundStepPrevoteWait) } // Enter: `timeoutPrevote` after any +2/3 prevotes. @@ -1773,7 +1773,7 @@ func (cs *State) enterPrecommitWait(ctx context.Context, height int64, round int }() // wait for some more precommits; enterNewRound - cs.scheduleTimeout(cs.state.ConsensusParams.Timeout.VoteTimeout(round), height, round, cstypes.RoundStepPrecommitWait) + cs.scheduleTimeout(cs.voteTimeout(round), height, round, cstypes.RoundStepPrecommitWait) } // Enter: +2/3 precommits for block @@ -2309,7 +2309,7 @@ func (cs *State) addVote( cs.evsw.FireEvent(ctx, types.EventVoteValue, vote) // if we can skip timeoutCommit and have all the votes now, - if cs.state.ConsensusParams.Timeout.BypassCommitTimeout && cs.LastCommit.HasAll() { + if cs.bypassCommitTimeout() && cs.LastCommit.HasAll() { // go straight to new round (skip timeout commit) // cs.scheduleTimeout(time.Duration(0), cs.Height, 0, cstypes.RoundStepNewHeight) cs.enterNewRound(ctx, cs.Height, 0) @@ -2422,7 +2422,7 @@ func (cs *State) addVote( if !blockID.IsNil() { cs.enterCommit(ctx, height, vote.Round) - if cs.state.ConsensusParams.Timeout.BypassCommitTimeout && precommits.HasAll() { + if cs.bypassCommitTimeout() && precommits.HasAll() { cs.enterNewRound(ctx, cs.Height, 0) } } else { @@ -2472,7 +2472,7 @@ func (cs *State) signVote( // If the signedMessageType is for precommit, // use our local precommit Timeout as the max wait time for getting a singed commit. The same goes for prevote. - timeout := cs.state.ConsensusParams.Timeout.VoteTimeout(cs.Round) + timeout := cs.voteTimeout(cs.Round) switch msgType { case tmproto.PrecommitType: @@ -2540,7 +2540,7 @@ func (cs *State) updatePrivValidatorPubKey(rctx context.Context) error { return nil } - timeout := cs.state.ConsensusParams.Timeout.VoteTimeout(cs.Round) + timeout := cs.voteTimeout(cs.Round) // no GetPubKey retry beyond the proposal/voting in RetrySignerClient if cs.Step >= cstypes.RoundStepPrecommit && cs.privValidatorType == types.RetrySignerClient { @@ -2666,6 +2666,49 @@ func repairWalFile(src, dst string) error { return nil } +func (cs *State) proposeTimeout(round int32) time.Duration { + p := cs.state.ConsensusParams.Timeout.Propose + if cs.config.UnsafeProposeTimeoutOverride != 0 { + p = cs.config.UnsafeProposeTimeoutOverride + } + pd := cs.state.ConsensusParams.Timeout.ProposeDelta + if cs.config.UnsafeProposeTimeoutDeltaOverride != 0 { + pd = cs.config.UnsafeProposeTimeoutDeltaOverride + } + return time.Duration( + p.Nanoseconds()+pd.Nanoseconds()*int64(round), + ) * time.Nanosecond +} + +func (cs *State) voteTimeout(round int32) time.Duration { + v := cs.state.ConsensusParams.Timeout.Vote + if cs.config.UnsafeVoteTimeoutOverride != 0 { + v = cs.config.UnsafeVoteTimeoutOverride + } + vd := cs.state.ConsensusParams.Timeout.VoteDelta + if cs.config.UnsafeVoteTimeoutDeltaOverride != 0 { + vd = cs.config.UnsafeVoteTimeoutDeltaOverride + } + return time.Duration( + v.Nanoseconds()+vd.Nanoseconds()*int64(round), + ) * time.Nanosecond +} + +func (cs *State) commitTime(t time.Time) time.Time { + c := cs.state.ConsensusParams.Timeout.Commit + if cs.config.UnsafeCommitTimeoutOverride != 0 { + c = cs.config.UnsafeProposeTimeoutOverride + } + return t.Add(c) +} + +func (cs *State) bypassCommitTimeout() bool { + if cs.config.UnsafeBypassCommitTimeoutOverride != nil { + return *cs.config.UnsafeBypassCommitTimeoutOverride + } + return cs.state.ConsensusParams.Timeout.BypassCommitTimeout +} + func (cs *State) calculateProposalTimestampDifferenceMetric() { if cs.Proposal != nil && cs.Proposal.POLRound == -1 { tp := types.SynchronyParams{ diff --git a/internal/consensus/state_test.go b/internal/consensus/state_test.go index fa614beb3..03bb85cf2 100644 --- a/internal/consensus/state_test.go +++ b/internal/consensus/state_test.go @@ -313,7 +313,7 @@ func TestStateOversizedBlock(t *testing.T) { // c1 should log an error with the block part message as it exceeds the consensus params. The // block is not added to cs.ProposalBlock so the node timeouts. - ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.state.ConsensusParams.Timeout.ProposeTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.proposeTimeout(round).Nanoseconds()) // and then should send nil prevote and precommit regardless of whether other validators prevote and // precommit on it @@ -481,7 +481,7 @@ func TestStateLock_NoPOL(t *testing.T) { // (note we're entering precommit for a second time this round) // but with invalid args. then we enterPrecommitWait, and the timeout to new round - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) /// @@ -494,7 +494,7 @@ func TestStateLock_NoPOL(t *testing.T) { incrementRound(vs2) // now we're on a new round and not the proposer, so wait for timeout - ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.state.ConsensusParams.Timeout.ProposeTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.proposeTimeout(round).Nanoseconds()) rs := cs1.GetRoundState() @@ -513,7 +513,7 @@ func TestStateLock_NoPOL(t *testing.T) { // now we're going to enter prevote again, but with invalid args // and then prevote wait, which should timeout. then wait for precommit - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) // the proposed block should still be locked block. // we should precommit nil and be locked on the proposal. ensurePrecommit(t, voteCh, height, round) @@ -525,7 +525,7 @@ func TestStateLock_NoPOL(t *testing.T) { // (note we're entering precommit for a second time this round, but with invalid args // then we enterPrecommitWait and timeout into NewRound - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) round++ // entering new round ensureNewRound(t, newRoundCh, height, round) @@ -552,7 +552,7 @@ func TestStateLock_NoPOL(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), newBlockID, vs2) ensurePrevote(t, voteCh, height, round) - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) ensurePrecommit(t, voteCh, height, round) // precommit validatePrecommit(ctx, t, cs1, round, 0, vss[0], nil, initialBlockID.Hash) // precommit nil but be locked on proposal @@ -567,7 +567,7 @@ func TestStateLock_NoPOL(t *testing.T) { vs2) // NOTE: conflicting precommits at same height ensurePrecommit(t, voteCh, height, round) - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) // cs1 is locked on a block at this point, so we must generate a new consensus // state to force a new proposal block to be generated. @@ -606,7 +606,7 @@ func TestStateLock_NoPOL(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), propBlockID, vs2) ensurePrevote(t, voteCh, height, round) - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) ensurePrecommit(t, voteCh, height, round) validatePrecommit(ctx, t, cs1, round, 0, vss[0], nil, initialBlockID.Hash) // precommit nil but locked on proposal @@ -683,7 +683,7 @@ func TestStateLock_POLUpdateLock(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{}, vs2, vs3, vs4) // timeout to new round. - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) /* Round 1: @@ -789,7 +789,7 @@ func TestStateLock_POLRelock(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{}, vs2, vs3, vs4) // timeout to new round. - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) /* Round 1: @@ -884,7 +884,7 @@ func TestStateLock_PrevoteNilWhenLockedAndMissProposal(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{}, vs2, vs3, vs4) // timeout to new round. - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) /* Round 1: @@ -970,7 +970,7 @@ func TestStateLock_PrevoteNilWhenLockedAndDifferentProposal(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{}, vs2, vs3, vs4) // timeout to new round. - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) /* Round 1: @@ -1078,7 +1078,7 @@ func TestStateLock_POLDoesNotUnlock(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), blockID, vs3) // timeout to new round - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) /* Round 1: @@ -1112,7 +1112,7 @@ func TestStateLock_POLDoesNotUnlock(t *testing.T) { validatePrecommit(ctx, t, cs1, round, 0, vss[0], nil, blockID.Hash) signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{}, vs2, vs3, vs4) - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) /* Round 2: @@ -1198,7 +1198,7 @@ func TestStateLock_MissingProposalWhenPOLSeenDoesNotUpdateLock(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{}, vs2, vs3, vs4) // timeout to new round - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) /* Round 1: @@ -1285,7 +1285,7 @@ func TestStateLock_DoesNotLockOnOldProposal(t *testing.T) { incrementRound(vs2, vs3, vs4) // timeout to new round - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) /* Round 1: @@ -1356,7 +1356,7 @@ func TestStateLock_POLSafety1(t *testing.T) { // cs1 precommit nil ensurePrecommit(t, voteCh, height, round) - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) incrementRound(vs2, vs3, vs4) round++ // moving to the next round @@ -1397,7 +1397,7 @@ func TestStateLock_POLSafety1(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{}, vs2, vs3, vs4) - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) incrementRound(vs2, vs3, vs4) round++ // moving to the next round @@ -1409,7 +1409,7 @@ func TestStateLock_POLSafety1(t *testing.T) { */ // timeout of propose - ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.state.ConsensusParams.Timeout.ProposeTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.proposeTimeout(round).Nanoseconds()) // finish prevote ensurePrevoteMatch(t, voteCh, height, round, nil) @@ -1493,7 +1493,7 @@ func TestStateLock_POLSafety2(t *testing.T) { incrementRound(vs2, vs3, vs4) // timeout of precommit wait to new round - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) round++ // moving to the next round // in round 2 we see the polkad block from round 0 @@ -1580,7 +1580,7 @@ func TestState_PrevotePOLFromPreviousRound(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{}, vs2, vs3, vs4) // timeout to new round. - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) /* Round 1: @@ -1621,7 +1621,7 @@ func TestState_PrevotePOLFromPreviousRound(t *testing.T) { ensurePrecommit(t, voteCh, height, round) // timeout to new round. - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) /* Create a new proposal for D, the same block from Round 1. @@ -1714,7 +1714,7 @@ func TestProposeValidBlock(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{}, vs2, vs3, vs4) - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) incrementRound(vs2, vs3, vs4) round++ // moving to the next round @@ -1722,7 +1722,7 @@ func TestProposeValidBlock(t *testing.T) { ensureNewRound(t, newRoundCh, height, round) // timeout of propose - ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.state.ConsensusParams.Timeout.ProposeTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.proposeTimeout(round).Nanoseconds()) // We did not see a valid proposal within this round, so prevote nil. ensurePrevoteMatch(t, voteCh, height, round, nil) @@ -1743,7 +1743,7 @@ func TestProposeValidBlock(t *testing.T) { ensureNewRound(t, newRoundCh, height, round) - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) round++ // moving to the next round @@ -1802,7 +1802,7 @@ func TestSetValidBlockOnDelayedPrevote(t *testing.T) { // vs3 send prevote nil signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), types.BlockID{}, vs3) - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) ensurePrecommit(t, voteCh, height, round) // we should have precommitted @@ -1856,7 +1856,7 @@ func TestSetValidBlockOnDelayedProposal(t *testing.T) { startTestRound(ctx, cs1, cs1.Height, round) ensureNewRound(t, newRoundCh, height, round) - ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.state.ConsensusParams.Timeout.ProposeTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.proposeTimeout(round).Nanoseconds()) ensurePrevoteMatch(t, voteCh, height, round, nil) @@ -1872,7 +1872,7 @@ func TestSetValidBlockOnDelayedProposal(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vs2, vs3, vs4) ensureNewValidBlock(t, validBlockCh, height, round) - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) ensurePrecommit(t, voteCh, height, round) validatePrecommit(ctx, t, cs1, round, -1, vss[0], nil, nil) @@ -2036,7 +2036,7 @@ func TestWaitingTimeoutOnNilPolka(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{}, vs2, vs3, vs4) - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) ensureNewRound(t, newRoundCh, height, round+1) } @@ -2074,7 +2074,7 @@ func TestWaitingTimeoutProposeOnNewRound(t *testing.T) { rs := cs1.GetRoundState() assert.True(t, rs.Step == cstypes.RoundStepPropose) // P0 does not prevote before timeoutPropose expires - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.ProposeTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.proposeTimeout(round).Nanoseconds()) ensurePrevoteMatch(t, voteCh, height, round, nil) } @@ -2113,7 +2113,7 @@ func TestRoundSkipOnNilPolkaFromHigherRound(t *testing.T) { ensurePrecommit(t, voteCh, height, round) validatePrecommit(ctx, t, cs1, round, -1, vss[0], nil, nil) - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) round++ // moving to the next round ensureNewRound(t, newRoundCh, height, round) @@ -2145,7 +2145,7 @@ func TestWaitTimeoutProposeOnNilPolkaForTheCurrentRound(t *testing.T) { incrementRound(vss[1:]...) signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), types.BlockID{}, vs2, vs3, vs4) - ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.state.ConsensusParams.Timeout.ProposeTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.proposeTimeout(round).Nanoseconds()) ensurePrevoteMatch(t, voteCh, height, round, nil) } @@ -2302,7 +2302,7 @@ func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) { signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), blockID, vs3) // wait till timeout occurs - ensureNewTimeout(t, precommitTimeoutCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, precommitTimeoutCh, height, round, cs1.voteTimeout(round).Nanoseconds()) ensureNewRound(t, newRoundCh, height, round+1) @@ -2313,7 +2313,7 @@ func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) { cs1.txNotifier.(*fakeTxNotifier).Notify() - ensureNewTimeout(t, timeoutProposeCh, height+1, round, cs1.state.ConsensusParams.Timeout.ProposeTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutProposeCh, height+1, round, cs1.proposeTimeout(round).Nanoseconds()) rs = cs1.GetRoundState() assert.False( t, @@ -2441,7 +2441,7 @@ func TestStateHalt1(t *testing.T) { incrementRound(vs2, vs3, vs4) // timeout to new round - ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.state.ConsensusParams.Timeout.VoteTimeout(round).Nanoseconds()) + ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.voteTimeout(round).Nanoseconds()) round++ // moving to the next round diff --git a/types/params.go b/types/params.go index b8cf7f2d8..be9217fa3 100644 --- a/types/params.go +++ b/types/params.go @@ -247,24 +247,24 @@ func (params ConsensusParams) ValidateConsensusParams() error { params.Synchrony.Precision) } - if params.Timeout.Propose < 0 { - return fmt.Errorf("timeout.ProposeDelta must not be negative. Got: %d", params.Timeout.Propose) + if params.Timeout.Propose <= 0 { + return fmt.Errorf("timeout.ProposeDelta must be greater than 0. Got: %d", params.Timeout.Propose) } - if params.Timeout.ProposeDelta < 0 { - return fmt.Errorf("timeout.ProposeDelta must not be negative. Got: %d", params.Timeout.ProposeDelta) + if params.Timeout.ProposeDelta <= 0 { + return fmt.Errorf("timeout.ProposeDelta must be greater than 0. Got: %d", params.Timeout.ProposeDelta) } - if params.Timeout.Vote < 0 { - return fmt.Errorf("timeout.Vote must not be negative. Got: %d", params.Timeout.Vote) + if params.Timeout.Vote <= 0 { + return fmt.Errorf("timeout.Vote must be greater than 0. Got: %d", params.Timeout.Vote) } - if params.Timeout.VoteDelta < 0 { - return fmt.Errorf("timeout.VoteDelta must not be negative. Got: %d", params.Timeout.VoteDelta) + if params.Timeout.VoteDelta <= 0 { + return fmt.Errorf("timeout.VoteDelta must be greater than 0. Got: %d", params.Timeout.VoteDelta) } - if params.Timeout.Commit < 0 { - return fmt.Errorf("timeout.Commit must not be negative. Got: %d", params.Timeout.Commit) + if params.Timeout.Commit <= 0 { + return fmt.Errorf("timeout.Commit must be greater than 0. Got: %d", params.Timeout.Commit) } if len(params.Validator.PubKeyTypes) == 0 { diff --git a/types/params_test.go b/types/params_test.go index dd21d1d1b..f19ed001b 100644 --- a/types/params_test.go +++ b/types/params_test.go @@ -19,11 +19,13 @@ var ( func TestConsensusParamsValidation(t *testing.T) { testCases := []struct { + name string params ConsensusParams valid bool }{ // test block params { + name: "block params valid", params: makeParams(makeParamsArgs{ blockBytes: 1, evidenceAge: 2, @@ -32,6 +34,7 @@ func TestConsensusParamsValidation(t *testing.T) { valid: true, }, { + name: "block params invalid MaxBytes", params: makeParams(makeParamsArgs{ blockBytes: 0, evidenceAge: 2, @@ -40,6 +43,7 @@ func TestConsensusParamsValidation(t *testing.T) { valid: false, }, { + name: "block params large MaxBytes", params: makeParams(makeParamsArgs{ blockBytes: 47 * 1024 * 1024, evidenceAge: 2, @@ -48,6 +52,7 @@ func TestConsensusParamsValidation(t *testing.T) { valid: true, }, { + name: "block params small MaxBytes", params: makeParams(makeParamsArgs{ blockBytes: 10, evidenceAge: 2, @@ -56,6 +61,7 @@ func TestConsensusParamsValidation(t *testing.T) { valid: true, }, { + name: "block params 100MB MaxBytes", params: makeParams(makeParamsArgs{ blockBytes: 100 * 1024 * 1024, evidenceAge: 2, @@ -64,6 +70,7 @@ func TestConsensusParamsValidation(t *testing.T) { valid: true, }, { + name: "block params MaxBytes too large", params: makeParams(makeParamsArgs{ blockBytes: 101 * 1024 * 1024, evidenceAge: 2, @@ -72,14 +79,7 @@ func TestConsensusParamsValidation(t *testing.T) { valid: false, }, { - params: makeParams(makeParamsArgs{ - blockBytes: 1024 * 1024 * 1024, - evidenceAge: 2, - precision: 1, - messageDelay: 1}), - valid: false, - }, - { + name: "block params 1GB MaxBytes", params: makeParams(makeParamsArgs{ blockBytes: 1024 * 1024 * 1024, evidenceAge: 2, @@ -89,6 +89,7 @@ func TestConsensusParamsValidation(t *testing.T) { }, // test evidence params { + name: "evidence MaxAge and MaxBytes 0", params: makeParams(makeParamsArgs{ blockBytes: 1, evidenceAge: 0, @@ -98,6 +99,7 @@ func TestConsensusParamsValidation(t *testing.T) { valid: false, }, { + name: "evidence MaxBytes greater than Block.MaxBytes", params: makeParams(makeParamsArgs{ blockBytes: 1, evidenceAge: 2, @@ -107,6 +109,7 @@ func TestConsensusParamsValidation(t *testing.T) { valid: false, }, { + name: "evidence size below Block.MaxBytes", params: makeParams(makeParamsArgs{ blockBytes: 1000, evidenceAge: 2, @@ -116,6 +119,7 @@ func TestConsensusParamsValidation(t *testing.T) { valid: true, }, { + name: "evidence MaxAgeDuration < 0", params: makeParams(makeParamsArgs{ blockBytes: 1, evidenceAge: -1, @@ -124,8 +128,8 @@ func TestConsensusParamsValidation(t *testing.T) { messageDelay: 1}), valid: false, }, - // test no pubkey type provided { + name: "no pubkey types", params: makeParams(makeParamsArgs{ evidenceAge: 2, pubkeyTypes: []string{}, @@ -133,8 +137,8 @@ func TestConsensusParamsValidation(t *testing.T) { messageDelay: 1}), valid: false, }, - // test invalid pubkey type provided { + name: "invalid pubkey types", params: makeParams(makeParamsArgs{ evidenceAge: 2, pubkeyTypes: []string{"potatoes make good pubkeys"}, @@ -142,8 +146,8 @@ func TestConsensusParamsValidation(t *testing.T) { messageDelay: 1}), valid: false, }, - // test invalid pubkey type provided { + name: "negative MessageDelay", params: makeParams(makeParamsArgs{ evidenceAge: 2, precision: 1, @@ -151,6 +155,7 @@ func TestConsensusParamsValidation(t *testing.T) { valid: false, }, { + name: "negative Precision", params: makeParams(makeParamsArgs{ evidenceAge: 2, precision: -1, @@ -159,11 +164,13 @@ func TestConsensusParamsValidation(t *testing.T) { }, } for i, tc := range testCases { - if tc.valid { - assert.NoErrorf(t, tc.params.ValidateConsensusParams(), "expected no error for valid params (#%d)", i) - } else { - assert.Errorf(t, tc.params.ValidateConsensusParams(), "expected error for non valid params (#%d)", i) - } + t.Run(tc.name, func(t *testing.T) { + if tc.valid { + assert.NoErrorf(t, tc.params.ValidateConsensusParams(), "expected no error for valid params (#%d)", i) + } else { + assert.Errorf(t, tc.params.ValidateConsensusParams(), "expected error for non valid params (#%d)", i) + } + }) } } @@ -175,18 +182,34 @@ type makeParamsArgs struct { pubkeyTypes []string precision time.Duration messageDelay time.Duration - propose time.Duration - proposeDelta time.Duration - vote time.Duration - voteDelta time.Duration - commit time.Duration bypassCommitTimeout bool + + propose *time.Duration + proposeDelta *time.Duration + vote *time.Duration + voteDelta *time.Duration + commit *time.Duration } func makeParams(args makeParamsArgs) ConsensusParams { if args.pubkeyTypes == nil { args.pubkeyTypes = valEd25519 } + if args.propose == nil { + args.propose = durationPtr(1) + } + if args.proposeDelta == nil { + args.proposeDelta = durationPtr(1) + } + if args.vote == nil { + args.vote = durationPtr(1) + } + if args.voteDelta == nil { + args.voteDelta = durationPtr(1) + } + if args.commit == nil { + args.commit = durationPtr(1) + } return ConsensusParams{ Block: BlockParams{ MaxBytes: args.blockBytes, @@ -205,11 +228,11 @@ func makeParams(args makeParamsArgs) ConsensusParams { MessageDelay: args.messageDelay, }, Timeout: TimeoutParams{ - Propose: args.propose, - ProposeDelta: args.proposeDelta, - Vote: args.vote, - VoteDelta: args.voteDelta, - Commit: args.commit, + Propose: *args.propose, + ProposeDelta: *args.proposeDelta, + Vote: *args.vote, + VoteDelta: *args.voteDelta, + Commit: *args.commit, BypassCommitTimeout: args.bypassCommitTimeout, }, } @@ -268,11 +291,11 @@ func TestConsensusParamsUpdate(t *testing.T) { { // update timeout params intialParams: makeParams(makeParamsArgs{ - propose: 3 * time.Second, - proposeDelta: 500 * time.Millisecond, - vote: time.Second, - voteDelta: 500 * time.Millisecond, - commit: time.Second, + propose: durationPtr(3 * time.Second), + proposeDelta: durationPtr(500 * time.Millisecond), + vote: durationPtr(time.Second), + voteDelta: durationPtr(500 * time.Millisecond), + commit: durationPtr(time.Second), bypassCommitTimeout: false, }), updates: &tmproto.ConsensusParams{ @@ -286,11 +309,11 @@ func TestConsensusParamsUpdate(t *testing.T) { }, }, updatedParams: makeParams(makeParamsArgs{ - propose: 2 * time.Second, - proposeDelta: 400 * time.Millisecond, - vote: 5 * time.Second, - voteDelta: 400 * time.Millisecond, - commit: time.Minute, + propose: durationPtr(2 * time.Second), + proposeDelta: durationPtr(400 * time.Millisecond), + vote: durationPtr(5 * time.Second), + voteDelta: durationPtr(400 * time.Millisecond), + commit: durationPtr(time.Minute), bypassCommitTimeout: true, }), }, From 41a1bf539bd9e3f312e5a52d2424de41d646be21 Mon Sep 17 00:00:00 2001 From: William Banfield <4561443+williambanfield@users.noreply.github.com> Date: Mon, 28 Mar 2022 18:25:19 -0400 Subject: [PATCH 7/7] timeout parameters take the default if not set (#8189) --- internal/consensus/state.go | 29 ++++++++++-------------- internal/rpc/core/consensus.go | 3 +++ types/params.go | 40 ++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/internal/consensus/state.go b/internal/consensus/state.go index 74e07ca9d..b96c9cecb 100644 --- a/internal/consensus/state.go +++ b/internal/consensus/state.go @@ -1452,11 +1452,7 @@ func (cs *State) enterPrevote(ctx context.Context, height int64, round int32) { } func (cs *State) proposalIsTimely() bool { - sp := types.SynchronyParams{ - Precision: cs.state.ConsensusParams.Synchrony.Precision, - MessageDelay: cs.state.ConsensusParams.Synchrony.MessageDelay, - } - + sp := cs.state.ConsensusParams.Synchrony.SynchronyParamsOrDefaults() return cs.Proposal.IsTimely(cs.ProposalReceiveTime, sp, cs.Round) } @@ -1482,6 +1478,7 @@ func (cs *State) defaultDoPrevote(ctx context.Context, height int64, round int32 return } + sp := cs.state.ConsensusParams.Synchrony.SynchronyParamsOrDefaults() if cs.Proposal.POLRound == -1 && cs.LockedRound == -1 && !cs.proposalIsTimely() { logger.Debug("prevote step: Proposal is not timely; prevoting nil", "proposed", @@ -1489,9 +1486,9 @@ func (cs *State) defaultDoPrevote(ctx context.Context, height int64, round int32 "received", tmtime.Canonical(cs.ProposalReceiveTime).Format(time.RFC3339Nano), "msg_delay", - cs.state.ConsensusParams.Synchrony.MessageDelay, + sp.MessageDelay, "precision", - cs.state.ConsensusParams.Synchrony.Precision) + sp.Precision) cs.signAddVote(ctx, tmproto.PrevoteType, nil, types.PartSetHeader{}) return } @@ -2667,11 +2664,12 @@ func repairWalFile(src, dst string) error { } func (cs *State) proposeTimeout(round int32) time.Duration { - p := cs.state.ConsensusParams.Timeout.Propose + tp := cs.state.ConsensusParams.Timeout.TimeoutParamsOrDefaults() + p := tp.Propose if cs.config.UnsafeProposeTimeoutOverride != 0 { p = cs.config.UnsafeProposeTimeoutOverride } - pd := cs.state.ConsensusParams.Timeout.ProposeDelta + pd := tp.ProposeDelta if cs.config.UnsafeProposeTimeoutDeltaOverride != 0 { pd = cs.config.UnsafeProposeTimeoutDeltaOverride } @@ -2681,11 +2679,12 @@ func (cs *State) proposeTimeout(round int32) time.Duration { } func (cs *State) voteTimeout(round int32) time.Duration { - v := cs.state.ConsensusParams.Timeout.Vote + tp := cs.state.ConsensusParams.Timeout.TimeoutParamsOrDefaults() + v := tp.Vote if cs.config.UnsafeVoteTimeoutOverride != 0 { v = cs.config.UnsafeVoteTimeoutOverride } - vd := cs.state.ConsensusParams.Timeout.VoteDelta + vd := tp.VoteDelta if cs.config.UnsafeVoteTimeoutDeltaOverride != 0 { vd = cs.config.UnsafeVoteTimeoutDeltaOverride } @@ -2711,12 +2710,8 @@ func (cs *State) bypassCommitTimeout() bool { func (cs *State) calculateProposalTimestampDifferenceMetric() { if cs.Proposal != nil && cs.Proposal.POLRound == -1 { - tp := types.SynchronyParams{ - Precision: cs.state.ConsensusParams.Synchrony.Precision, - MessageDelay: cs.state.ConsensusParams.Synchrony.MessageDelay, - } - - isTimely := cs.Proposal.IsTimely(cs.ProposalReceiveTime, tp, cs.Round) + sp := cs.state.ConsensusParams.Synchrony.SynchronyParamsOrDefaults() + isTimely := cs.Proposal.IsTimely(cs.ProposalReceiveTime, sp, cs.Round) cs.metrics.ProposalTimestampDifference.With("is_timely", fmt.Sprintf("%t", isTimely)). Observe(cs.ProposalReceiveTime.Sub(cs.Proposal.Timestamp).Seconds()) } diff --git a/internal/rpc/core/consensus.go b/internal/rpc/core/consensus.go index b30209b38..f10f37ebc 100644 --- a/internal/rpc/core/consensus.go +++ b/internal/rpc/core/consensus.go @@ -113,6 +113,9 @@ func (env *Environment) ConsensusParams(ctx context.Context, heightPtr *int64) ( return nil, err } + consensusParams.Synchrony = consensusParams.Synchrony.SynchronyParamsOrDefaults() + consensusParams.Timeout = consensusParams.Timeout.TimeoutParamsOrDefaults() + return &coretypes.ResultConsensusParams{ BlockHeight: height, ConsensusParams: consensusParams}, nil diff --git a/types/params.go b/types/params.go index be9217fa3..c0e5e3a00 100644 --- a/types/params.go +++ b/types/params.go @@ -147,7 +147,22 @@ func DefaultSynchronyParams() SynchronyParams { Precision: 505 * time.Millisecond, MessageDelay: 12 * time.Second, } +} +// SynchronyParamsOrDefaults returns the SynchronyParams, filling in any zero values +// with the Tendermint defined default values. +func (s SynchronyParams) SynchronyParamsOrDefaults() SynchronyParams { + // TODO: Remove this method and all uses once development on v0.37 begins. + // See: https://github.com/tendermint/tendermint/issues/8187 + + defaults := DefaultSynchronyParams() + if s.Precision == 0 { + s.Precision = defaults.Precision + } + if s.MessageDelay == 0 { + s.MessageDelay = defaults.MessageDelay + } + return s } func DefaultTimeoutParams() TimeoutParams { @@ -161,6 +176,31 @@ func DefaultTimeoutParams() TimeoutParams { } } +// TimeoutParamsOrDefaults returns the SynchronyParams, filling in any zero values +// with the Tendermint defined default values. +func (t TimeoutParams) TimeoutParamsOrDefaults() TimeoutParams { + // TODO: Remove this method and all uses once development on v0.37 begins. + // See: https://github.com/tendermint/tendermint/issues/8187 + + defaults := DefaultTimeoutParams() + if t.Propose == 0 { + t.Propose = defaults.Propose + } + if t.ProposeDelta == 0 { + t.ProposeDelta = defaults.ProposeDelta + } + if t.Vote == 0 { + t.Vote = defaults.Vote + } + if t.VoteDelta == 0 { + t.VoteDelta = defaults.VoteDelta + } + if t.Commit == 0 { + t.Commit = defaults.Commit + } + return t +} + // ProposeTimeout returns the amount of time to wait for a proposal. func (t TimeoutParams) ProposeTimeout(round int32) time.Duration { return time.Duration(